]> git.mxchange.org Git - simgear.git/blob - simgear/package/CatalogTest.cxx
Expand package-system unit-tests.
[simgear.git] / simgear / package / CatalogTest.cxx
1 // Copyright (C) 2015  James Turner - zakalawe@mac.com
2 //
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.
7 //
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.
12 //
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.
16 //
17
18 #ifdef HAVE_CONFIG_H
19 #  include <simgear_config.h>
20 #endif
21
22 #include <simgear/misc/test_macros.hxx>
23
24 #include <cstdlib>
25 #include <iostream>
26 #include <fstream>
27
28 #include <simgear/package/Catalog.hxx>
29 #include <simgear/package/Root.hxx>
30 #include <simgear/package/Package.hxx>
31 #include <simgear/package/Install.hxx>
32
33 #include <simgear/misc/test_macros.hxx>
34 #include <simgear/misc/sg_dir.hxx>
35 #include <simgear/timing/timestamp.hxx>
36
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>
41
42 using namespace simgear;
43
44 std::string readFileIntoString(const SGPath& path)
45 {
46     std::string contents;
47
48     size_t readLen;
49     SGFile f(path.str());
50     if (!f.open(SG_IO_IN)) {
51         throw sg_io_exception("Couldn't open file", path);
52     }
53
54     char buf[8192];
55     while ((readLen = f.read(buf, 8192)) > 0) {
56         contents += std::string(buf, readLen);
57     }
58
59     return contents;
60 }
61
62 SGPath global_serverFilesRoot;
63
64 class TestPackageChannel : public TestServerChannel
65 {
66 public:
67
68     virtual void processRequestHeaders()
69     {
70         state = STATE_IDLE;
71
72         SGPath localPath(global_serverFilesRoot);
73         localPath.append(path);
74
75         //SG_LOG(SG_IO, SG_INFO, "local path is:" << localPath.str());
76
77         if (localPath.exists()) {
78             std::string content = readFileIntoString(localPath);
79             std::stringstream d;
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
83             d << content;
84
85             std::string ds(d.str());
86             bufferSend(ds.data(), ds.size());
87         } else {
88             sendErrorResponse(404, false, "");
89         }
90     }
91 };
92
93 TestServer<TestPackageChannel> testServer;
94
95 void waitForUpdateComplete(HTTP::Client* cl, pkg::Root* root)
96 {
97     SGTimeStamp start(SGTimeStamp::now());
98     while (start.elapsedMSec() <  10000) {
99         cl->update();
100         testServer.poll();
101
102         if (!cl->hasActiveRequests()) {
103             return;
104         }
105
106         SGTimeStamp::sleepForMSec(15);
107     }
108
109     std::cerr << "timed out" << std::endl;
110 }
111
112 int parseTest()
113 {
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"));
118
119     VERIFY(cat.valid());
120
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");
124
125 // check the packages too
126     COMPARE(cat->packages().size(), 3);
127
128     pkg::PackageRef p1 = cat->packages().front();
129     COMPARE(p1->catalog(), cat.ptr());
130
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);
136
137
138     pkg::PackageRef p2 = cat->getPackageById("c172p");
139     VERIFY(p2.valid());
140     COMPARE(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
141     COMPARE(p2->description(), "A plane made by Cessna");
142
143
144
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());
151
152
153     SGPropertyNode_ptr queryA(new SGPropertyNode);
154     queryA->setStringValue("tag", "ifr");
155     VERIFY(p2->matches(queryA.ptr()));
156
157     SGPropertyNode_ptr queryB(new SGPropertyNode);
158     queryB->setStringValue("name", "ces");
159     VERIFY(p2->matches(queryB.ptr()));
160
161     SGPropertyNode_ptr queryC(new SGPropertyNode);
162     queryC->setStringValue("name", "foo");
163     VERIFY(!p2->matches(queryC.ptr()));
164
165     SGPropertyNode_ptr queryD(new SGPropertyNode);
166     queryD->setIntValue("rating-FDM", 3);
167     VERIFY(p2->matches(queryD.ptr()));
168
169     SGPropertyNode_ptr queryE(new SGPropertyNode);
170     queryE->setIntValue("rating-model", 5);
171     queryE->setStringValue("description", "cessna");
172     VERIFY(p2->matches(queryE.ptr()));
173
174
175     delete root;
176     return EXIT_SUCCESS;
177 }
178
179 void testAddCatalog(HTTP::Client* cl)
180 {
181 // erase dir
182     SGPath rootPath(simgear::Dir::current().path());
183     rootPath.append("pkg_add_catalog");
184     simgear::Dir pd(rootPath);
185     pd.removeChildren();
186
187
188     pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
189     // specify a test dir
190     root->setHTTPClient(cl);
191
192     pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
193
194     waitForUpdateComplete(cl, root);
195
196 // verify on disk state
197     SGPath p(rootPath);
198     p.append("org.flightgear.test.catalog1");
199     p.append("catalog.xml");
200     VERIFY(p.exists());
201     COMPARE(root->allPackages().size(), 3);
202     COMPARE(root->catalogs().size(), 1);
203
204     pkg::PackageRef p1 = root->getPackageById("alpha");
205     COMPARE(p1->id(), "alpha");
206
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");
210
211 }
212
213 void testInstallPackage(HTTP::Client* cl)
214 {
215     SGPath rootPath(simgear::Dir::current().path());
216     rootPath.append("pkg_install_with_dep");
217     simgear::Dir pd(rootPath);
218     pd.removeChildren();
219
220     pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
221     // specify a test dir
222     root->setHTTPClient(cl);
223
224     pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
225     waitForUpdateComplete(cl, root);
226
227     pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.c172p");
228     pkg::InstallRef ins = p1->install();
229
230     VERIFY(ins->isQueued());
231
232     waitForUpdateComplete(cl, root);
233     VERIFY(p1->isInstalled());
234     VERIFY(p1->existingInstall() == ins);
235
236     pkg::PackageRef commonDeps = root->getPackageById("common-sounds");
237     VERIFY(commonDeps->existingInstall());
238
239     // verify on disk state
240     SGPath p(rootPath);
241     p.append("org.flightgear.test.catalog1");
242     p.append("Aircraft");
243     p.append("c172p");
244
245     COMPARE(p, ins->path());
246
247     p.append("c172p-floats-set.xml");
248     VERIFY(p.exists());
249
250     SGPath p2(rootPath);
251     p2.append("org.flightgear.test.catalog1");
252     p2.append("Aircraft");
253     p2.append("sounds");
254     p2.append("sharedfile.txt");
255     VERIFY(p2.exists());
256 }
257
258 void testUninstall(HTTP::Client* cl)
259 {
260     SGPath rootPath(simgear::Dir::current().path());
261     rootPath.append("pkg_uninstall");
262     simgear::Dir pd(rootPath);
263     pd.removeChildren();
264
265     pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
266     root->setHTTPClient(cl);
267
268     pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
269     waitForUpdateComplete(cl, root);
270
271     pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.c172p");
272     pkg::InstallRef ins = p1->install();
273
274     waitForUpdateComplete(cl, root);
275
276     VERIFY(p1->isInstalled());
277
278     ins->uninstall();
279
280     VERIFY(!ins->path().exists());
281 }
282
283 void testRemoveCatalog()
284 {
285
286 }
287
288 void testRefreshCatalog()
289 {
290
291   // check for pending updates
292 }
293
294
295 int main(int argc, char* argv[])
296 {
297     sglog().setLogLevels( SG_ALL, SG_DEBUG );
298
299     HTTP::Client cl;
300     cl.setMaxConnections(1);
301
302     global_serverFilesRoot = SGPath(SRC_DIR);
303
304     testAddCatalog(&cl);
305
306     parseTest();
307
308     testInstallPackage(&cl);
309     
310     testUninstall(&cl);
311     
312     std::cout << "Successfully passed all tests!" << std::endl;
313     return EXIT_SUCCESS;
314 }