1 // Copyright (C) 2015 James Turner - zakalawe@mac.com
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # include <simgear_config.h>
22 #include <simgear/misc/test_macros.hxx>
28 #include <simgear/package/Catalog.hxx>
29 #include <simgear/package/Root.hxx>
30 #include <simgear/package/Package.hxx>
31 #include <simgear/package/Install.hxx>
33 #include <simgear/misc/test_macros.hxx>
34 #include <simgear/misc/sg_dir.hxx>
35 #include <simgear/timing/timestamp.hxx>
37 #include <simgear/io/test_HTTP.hxx>
38 #include <simgear/io/HTTPClient.hxx>
39 #include <simgear/io/sg_file.hxx>
40 #include <simgear/structure/exception.hxx>
42 using namespace simgear;
44 std::string readFileIntoString(const SGPath& path)
50 if (!f.open(SG_IO_IN)) {
51 throw sg_io_exception("Couldn't open file", path);
55 while ((readLen = f.read(buf, 8192)) > 0) {
56 contents += std::string(buf, readLen);
62 SGPath global_serverFilesRoot;
64 class TestPackageChannel : public TestServerChannel
68 virtual void processRequestHeaders()
72 SGPath localPath(global_serverFilesRoot);
73 localPath.append(path);
75 //SG_LOG(SG_IO, SG_INFO, "local path is:" << localPath.str());
77 if (localPath.exists()) {
78 std::string content = readFileIntoString(localPath);
80 d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
81 d << "Content-Length:" << content.size() << "\r\n";
82 d << "\r\n"; // final CRLF to terminate the headers
85 std::string ds(d.str());
86 bufferSend(ds.data(), ds.size());
88 sendErrorResponse(404, false, "");
93 TestServer<TestPackageChannel> testServer;
95 void waitForUpdateComplete(HTTP::Client* cl, pkg::Root* root)
97 SGTimeStamp start(SGTimeStamp::now());
98 while (start.elapsedMSec() < 10000) {
102 if (!cl->hasActiveRequests()) {
106 SGTimeStamp::sleepForMSec(15);
109 std::cerr << "timed out" << std::endl;
114 SGPath rootPath = simgear::Dir::current().path();
115 rootPath.append("testRoot");
116 pkg::Root* root = new pkg::Root(rootPath, "8.1.12");
117 pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTest1"));
121 COMPARE(cat->id(), "org.flightgear.test.catalog1");
122 COMPARE(cat->url(), "http://download.flightgear.org/catalog1/catalog.xml");
123 COMPARE(cat->description(), "First test catalog");
125 // check the packages too
126 COMPARE(cat->packages().size(), 3);
128 pkg::PackageRef p1 = cat->packages().front();
129 COMPARE(p1->catalog(), cat.ptr());
131 COMPARE(p1->id(), "alpha");
132 COMPARE(p1->qualifiedId(), "org.flightgear.test.catalog1.alpha");
133 COMPARE(p1->name(), "Alpha package");
134 COMPARE(p1->revision(), 8);
135 COMPARE(p1->fileSizeBytes(), 593);
138 pkg::PackageRef p2 = cat->getPackageById("c172p");
140 COMPARE(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
141 COMPARE(p2->description(), "A plane made by Cessna");
145 // test filtering / searching too
146 string_set tags(p2->tags());
147 COMPARE(tags.size(), 4);
148 VERIFY(tags.find("ifr") != tags.end());
149 VERIFY(tags.find("cessna") != tags.end());
150 VERIFY(tags.find("jet") == tags.end());
153 SGPropertyNode_ptr queryA(new SGPropertyNode);
154 queryA->setStringValue("tag", "ifr");
155 VERIFY(p2->matches(queryA.ptr()));
157 SGPropertyNode_ptr queryB(new SGPropertyNode);
158 queryB->setStringValue("name", "ces");
159 VERIFY(p2->matches(queryB.ptr()));
161 SGPropertyNode_ptr queryC(new SGPropertyNode);
162 queryC->setStringValue("name", "foo");
163 VERIFY(!p2->matches(queryC.ptr()));
165 SGPropertyNode_ptr queryD(new SGPropertyNode);
166 queryD->setIntValue("rating-FDM", 3);
167 VERIFY(p2->matches(queryD.ptr()));
169 SGPropertyNode_ptr queryE(new SGPropertyNode);
170 queryE->setIntValue("rating-model", 5);
171 queryE->setStringValue("description", "cessna");
172 VERIFY(p2->matches(queryE.ptr()));
179 void testAddCatalog(HTTP::Client* cl)
182 SGPath rootPath(simgear::Dir::current().path());
183 rootPath.append("pkg_add_catalog");
184 simgear::Dir pd(rootPath);
188 pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
189 // specify a test dir
190 root->setHTTPClient(cl);
192 pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
194 waitForUpdateComplete(cl, root);
196 // verify on disk state
198 p.append("org.flightgear.test.catalog1");
199 p.append("catalog.xml");
201 COMPARE(root->allPackages().size(), 3);
202 COMPARE(root->catalogs().size(), 1);
204 pkg::PackageRef p1 = root->getPackageById("alpha");
205 COMPARE(p1->id(), "alpha");
207 pkg::PackageRef p2 = root->getPackageById("org.flightgear.test.catalog1.c172p");
208 COMPARE(p2->id(), "c172p");
209 COMPARE(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
213 void testInstallPackage(HTTP::Client* cl)
215 SGPath rootPath(simgear::Dir::current().path());
216 rootPath.append("pkg_install_with_dep");
217 simgear::Dir pd(rootPath);
220 pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
221 // specify a test dir
222 root->setHTTPClient(cl);
224 pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
225 waitForUpdateComplete(cl, root);
227 pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.c172p");
228 pkg::InstallRef ins = p1->install();
230 VERIFY(ins->isQueued());
232 waitForUpdateComplete(cl, root);
233 VERIFY(p1->isInstalled());
234 VERIFY(p1->existingInstall() == ins);
236 pkg::PackageRef commonDeps = root->getPackageById("common-sounds");
237 VERIFY(commonDeps->existingInstall());
239 // verify on disk state
241 p.append("org.flightgear.test.catalog1");
242 p.append("Aircraft");
245 COMPARE(p, ins->path());
247 p.append("c172p-floats-set.xml");
251 p2.append("org.flightgear.test.catalog1");
252 p2.append("Aircraft");
254 p2.append("sharedfile.txt");
258 void testUninstall(HTTP::Client* cl)
260 SGPath rootPath(simgear::Dir::current().path());
261 rootPath.append("pkg_uninstall");
262 simgear::Dir pd(rootPath);
265 pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
266 root->setHTTPClient(cl);
268 pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
269 waitForUpdateComplete(cl, root);
271 pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.c172p");
272 pkg::InstallRef ins = p1->install();
274 waitForUpdateComplete(cl, root);
276 VERIFY(p1->isInstalled());
280 VERIFY(!ins->path().exists());
283 void testRemoveCatalog()
288 void testRefreshCatalog()
291 // check for pending updates
295 int main(int argc, char* argv[])
297 sglog().setLogLevels( SG_ALL, SG_DEBUG );
300 cl.setMaxConnections(1);
302 global_serverFilesRoot = SGPath(SRC_DIR);
308 testInstallPackage(&cl);
312 std::cout << "Successfully passed all tests!" << std::endl;