complete serialize/recovery PoolQuery
[platform/upstream/libzypp.git] / tests / zypp / PoolQuery_test.cc
1 #include <stdio.h>
2 #include <iostream>
3 #include <iterator>
4 #include <boost/test/auto_unit_test.hpp>
5 #include <list>
6
7 #include "zypp/ZYppFactory.h"
8 #include "zypp/PoolQuery.h"
9 #include "zypp/PoolQueryUtil.tcc"
10 #include "zypp/TmpPath.h"
11
12 #define BOOST_TEST_MODULE PoolQuery
13
14 using std::cout;
15 using std::endl;
16 using std::string;
17 using namespace zypp;
18 using namespace boost::unit_test;
19
20 bool result_cb( const sat::Solvable & solvable )
21 {
22   zypp::PoolItem pi( zypp::ResPool::instance().find( solvable ) );
23   cout << pi.resolvable() << endl;
24   // name: yast2-sound 2.16.2-9 i586
25   return true;
26 }
27
28 static void init_pool()
29 {
30   Pathname dir(TESTS_SRC_DIR);
31   dir += "/zypp/data/PoolQuery";
32
33   ZYpp::Ptr z = getZYpp();
34   ZConfig::instance().setSystemArchitecture(Arch("i586"));
35
36   RepoInfo i1; i1.setAlias("factory");
37   sat::Pool::instance().addRepoSolv(dir / "factory.solv", i1);
38   RepoInfo i2; i2.setAlias("factory-nonoss");
39   sat::Pool::instance().addRepoSolv(dir / "factory-nonoss.solv", i2);
40   RepoInfo i3; i3.setAlias("zypp_svn");
41   sat::Pool::instance().addRepoSolv(dir / "zypp_svn.solv", i3);
42   RepoInfo i4; i4.setAlias("@System");
43   sat::Pool::instance().addRepoSolv(dir / "@System.solv", i4);
44 }
45
46 BOOST_AUTO_TEST_CASE(pool_query_init)
47 {
48   init_pool();
49 }
50
51 BOOST_AUTO_TEST_CASE(pool_query_exp)
52 {
53   cout << "****exp****"  << endl;
54   
55   PoolQuery q;
56   q.addString("zypper");
57   q.addAttribute(sat::SolvAttr::name);
58
59   // should list 2 selectables
60   for (PoolQuery::Selectable_iterator it = q.selectableBegin();
61        it != q.selectableEnd(); ++it)
62   {
63     ui::Selectable::Ptr s = *it;
64     cout << s->kind() << ":" << s->name() << " hasinstalled: " << s->installedEmpty() << endl;
65   }
66
67   std::for_each(q.begin(), q.end(), &result_cb);
68 }
69
70 /////////////////////////////////////////////////////////////////////////////
71 //  0xx basic queries
72 /////////////////////////////////////////////////////////////////////////////
73
74 // no conditions, default query
75 // result: all available resolvables
76 BOOST_AUTO_TEST_CASE(pool_query_000)
77 {
78   cout << "****000****"  << endl;
79   PoolQuery q;
80   cout << q.size() << endl;
81   BOOST_CHECK(q.size() == 11451);
82   /**!\todo should be 11453 probably according to:
83    * dumpsolv factory.solv factory-nonoss.solv zypp_svn.solv \@System.solv | \
84    * grep '^name:.*\(noarch\|i386\|i586\|i686\|src\)$' | wc -l
85    */
86 }
87
88 // default query + one search string
89 // q.addString("foo");
90 // result: all resolvables having at least one attribute matching foo
91 BOOST_AUTO_TEST_CASE(pool_query_001)
92 {
93   cout << "****001****"  << endl;
94   PoolQuery q;
95   q.addString("zypper");
96
97   std::for_each(q.begin(), q.end(), &result_cb);
98   BOOST_CHECK(q.size() == 16);
99 }
100
101 // default query + one attribute + one string
102 // q.addAttribute(foo, bar);
103 // should be the same as
104 // q.addAttribute(foo); q.addString(bar);
105 // result: resolvables with foo containing bar
106 BOOST_AUTO_TEST_CASE(pool_query_002)
107 {
108   cout << "****002****"  << endl;
109   PoolQuery q;
110   q.addString("zypper");
111   q.addAttribute(sat::SolvAttr::name);
112
113   std::for_each(q.begin(), q.end(), &result_cb);
114   BOOST_CHECK(q.size() == 6);
115
116   cout << endl;
117
118   PoolQuery q1;
119   q1.addAttribute(sat::SolvAttr::name, "zypper");
120
121   std::for_each(q1.begin(), q1.end(), &result_cb);
122   BOOST_CHECK(q1.size() == 6);
123 }
124
125 // kind filter
126 BOOST_AUTO_TEST_CASE(pool_query_003)
127 {
128   cout << "****003****"  << endl;
129   PoolQuery q;
130   q.addString("zypper");
131   q.addAttribute(sat::SolvAttr::name);
132   q.addKind(ResTraits<Package>::kind);
133
134   std::for_each(q.begin(), q.end(), &result_cb);
135   BOOST_CHECK(q.size() == 3);
136 }
137
138 // match exact
139 BOOST_AUTO_TEST_CASE(pool_query_004)
140 {
141   cout << "****004****"  << endl;
142   PoolQuery q;
143   q.addString("vim");
144   q.addAttribute(sat::SolvAttr::name);
145   q.setMatchExact();
146
147   std::for_each(q.begin(), q.end(), &result_cb);
148   BOOST_CHECK(q.size() == 3);
149
150   PoolQuery q1;
151   q1.addString("zypp");
152   q1.addAttribute(sat::SolvAttr::name);
153   q1.setMatchExact();
154
155   std::for_each(q1.begin(), q1.end(), &result_cb);
156   BOOST_CHECK(q1.empty());
157 }
158
159 // use globs
160 BOOST_AUTO_TEST_CASE(pool_query_005)
161 {
162   cout << "****005.1****"  << endl;
163   PoolQuery q;
164   q.addString("z?p*");
165   q.addAttribute(sat::SolvAttr::name);
166   q.setMatchGlob();
167
168   std::for_each(q.begin(), q.end(), &result_cb);
169   BOOST_CHECK(q.size() == 11);
170
171   cout << "****005.2****"  << endl;
172
173   PoolQuery q1;
174   q1.addString("*zypp*");
175   q1.addAttribute(sat::SolvAttr::name);
176   q1.setMatchGlob();
177
178   std::for_each(q1.begin(), q1.end(), &result_cb);
179   BOOST_CHECK(q1.size() == 28);
180
181   cout << "****005.3****"  << endl;
182
183   // should be the same as above
184   PoolQuery q2;
185   q2.addString("zypp");
186   q2.addAttribute(sat::SolvAttr::name);
187
188   BOOST_CHECK(q2.size() == 28);
189 }
190
191 // use regex
192 BOOST_AUTO_TEST_CASE(pool_query_006)
193 {
194   cout << "****006.1***"  << endl;
195
196   // should be the same as 005 1
197   PoolQuery q;
198   q.addString("^z.p.*");
199   q.addAttribute(sat::SolvAttr::name);
200   q.setMatchRegex();
201
202   std::for_each(q.begin(), q.end(), &result_cb);
203   BOOST_CHECK(q.size() == 11);
204
205   cout << "****006.2***"  << endl;
206
207   PoolQuery q1;
208   q1.addString("zypper|smart");
209   q1.addAttribute(sat::SolvAttr::name);
210   q1.setMatchRegex();
211
212   std::for_each(q1.begin(), q1.end(), &result_cb);
213   BOOST_CHECK(q1.size() == 21);
214
215   cout << "****006.3***"  << endl;
216
217   // invalid regex
218   PoolQuery q2;
219   q2.addString("zypp\\");
220   q2.setMatchRegex();
221   BOOST_CHECK_THROW(q2.size(), Exception);
222 }
223
224
225 // match by installed status (basically by system vs. repo)
226 BOOST_AUTO_TEST_CASE(pool_query_050)
227 {
228   cout << "****050****"  << endl;
229   PoolQuery q;
230   q.addString("zypper");
231   q.addAttribute(sat::SolvAttr::name);
232   q.setMatchExact();
233   q.setInstalledOnly();
234
235   std::for_each(q.begin(), q.end(), &result_cb);
236   BOOST_CHECK(q.size() == 1);
237
238   cout << endl;
239
240   PoolQuery q1;
241   q1.addString("zypper");
242   q1.addAttribute(sat::SolvAttr::name);
243   q1.setMatchExact();
244   q1.setUninstalledOnly();
245
246   std::for_each(q1.begin(), q1.end(), &result_cb);
247   BOOST_CHECK(q1.size() == 5);
248 }
249
250
251 /////////////////////////////////////////////////////////////////////////////
252 //  1xx multiple attribute queries
253 /////////////////////////////////////////////////////////////////////////////
254
255
256 BOOST_AUTO_TEST_CASE(pool_query_100)
257 {
258   cout << "****100****"  << endl;
259   PoolQuery q;
260   /* This string is found sometimes only in solvable names (e.g. novell-lum),
261      sometimes only in summary (e.g. yast2-casa-ats) and sometimes only
262      in descriptions (e.g. beagle-quickfinder).  novell-lum doesn't exist
263      in our test solv file, but let's ignore this.  I didn't find a string
264      with the same characteristics giving fewer matches :-/  */
265   q.addString("novell");
266   q.addAttribute(sat::SolvAttr::name);
267   q.addAttribute(sat::SolvAttr::summary);
268   q.addAttribute(sat::SolvAttr::description);
269
270   std::for_each(q.begin(), q.end(), &result_cb);
271   BOOST_CHECK(q.size() == 74);
272
273   cout << endl;
274
275   PoolQuery q1;
276   q1.addString("mp3");
277   q1.addAttribute(sat::SolvAttr::name);
278
279   std::for_each(q1.begin(), q1.end(), &result_cb);
280   BOOST_CHECK(q1.size() == 7);
281 }
282
283
284 // multi attr (same value) substring matching (case sensitive and insensitive)
285 BOOST_AUTO_TEST_CASE(pool_query_101)
286 {
287   cout << "****101****"  << endl;
288
289   PoolQuery q;
290   q.addString("ZYpp");
291   q.addAttribute(sat::SolvAttr::name);
292   q.addAttribute(sat::SolvAttr::summary);
293   q.addAttribute(sat::SolvAttr::description);
294
295   std::for_each(q.begin(), q.end(), &result_cb);
296   BOOST_CHECK(q.size() == 30);
297
298   cout << endl;
299
300   PoolQuery q2;
301   q2.addString("ZYpp");
302   q2.addAttribute(sat::SolvAttr::name);
303   q2.addAttribute(sat::SolvAttr::summary);
304   q2.addAttribute(sat::SolvAttr::description);
305   q2.setCaseSensitive();
306
307   std::for_each(q2.begin(), q2.end(), &result_cb);
308   BOOST_CHECK(q2.size() == 2);
309 }
310
311
312 // multi attr (same value) glob matching (case sensitive and insensitive)
313 BOOST_AUTO_TEST_CASE(pool_query_102)
314 {
315   cout << "****102****"  << endl;
316   PoolQuery q;
317   q.addString("pack*");
318   q.addAttribute(sat::SolvAttr::name);
319   q.addAttribute(sat::SolvAttr::summary);
320   q.setMatchGlob();
321
322   std::for_each(q.begin(), q.end(), &result_cb);
323   BOOST_CHECK(q.size() == 35);
324 }
325
326
327 // multi attr (same value via addAttribute())
328 BOOST_AUTO_TEST_CASE(pool_query_103)
329 {
330   cout << "****103.1****"  << endl;
331   PoolQuery q;
332   q.addAttribute(sat::SolvAttr::name, "novell");
333   q.addAttribute(sat::SolvAttr::summary, "novell");
334
335 //  std::for_each(q.begin(), q.end(), &result_cb);
336   BOOST_CHECK(q.size() == 42);
337
338   cout << "****103.2****"  << endl;
339
340   PoolQuery q1;
341   q1.addString("novell");
342   q1.addAttribute(sat::SolvAttr::name);
343   q1.addAttribute(sat::SolvAttr::summary);
344
345 //  std::for_each(q1.begin(), q1.end(), &result_cb);
346   BOOST_CHECK(q1.size() == 42);
347
348   cout << endl;
349 }
350
351 // multiple attributes, different search strings (one string per attrbute)
352 BOOST_AUTO_TEST_CASE(pool_query_104)
353 {
354   cout << "****104****"  << endl;
355   PoolQuery q;
356   q.addAttribute(sat::SolvAttr::name, "novell");
357   q.addAttribute(sat::SolvAttr::summary, "package management");
358
359   std::for_each(q.begin(), q.end(), &result_cb);
360   BOOST_CHECK(q.size() == 22);
361 }
362
363 // multiple attributes, different search strings (one string per attrbute), regex matching
364 BOOST_AUTO_TEST_CASE(pool_query_105)
365 {
366   cout << "****105****"  << endl;
367   PoolQuery q;
368   q.addAttribute(sat::SolvAttr::name, "no.ell");
369   q.addAttribute(sat::SolvAttr::summary, "package management");
370   q.setMatchRegex();
371
372   std::for_each(q.begin(), q.end(), &result_cb);
373   BOOST_CHECK(q.size() == 22);
374 }
375
376 /////////////////////////////////////////////////////////////////////////////
377 //  3xx repo filter queries (addRepo(alias_str))
378 /////////////////////////////////////////////////////////////////////////////
379
380 // default query + one attribute(one string) + one repo
381 BOOST_AUTO_TEST_CASE(pool_query_300)
382 {
383   cout << "****300****"  << endl;
384   PoolQuery q;
385   q.addAttribute(sat::SolvAttr::name, "zypper");
386   q.addRepo("zypp_svn");
387
388   std::for_each(q.begin(), q.end(), &result_cb);
389   BOOST_CHECK(q.size() == 3);
390 }
391
392 // default query + one repo
393 BOOST_AUTO_TEST_CASE(pool_query_301)
394 {
395   cout << "****301****"  << endl;
396   PoolQuery q;
397   q.addRepo("zypp_svn");
398
399   std::for_each(q.begin(), q.end(), &result_cb);
400   BOOST_CHECK(q.size() == 21);
401 }
402
403 // multiple repos + one attribute
404 BOOST_AUTO_TEST_CASE(pool_query_302)
405 {
406   cout << "****302****"  << endl;
407   PoolQuery q;
408   q.addString("ma");
409   q.addAttribute(sat::SolvAttr::name);
410   q.addRepo("factory-nonoss");
411   q.addRepo("zypp_svn");
412
413   std::for_each(q.begin(), q.end(), &result_cb);
414   BOOST_CHECK(q.size() == 8);
415 }
416
417 /*
418 BOOST_AUTO_TEST_CASE(pool_query_X)
419 {
420   cout << "****X****"  << endl;
421   PoolQuery q;
422   q.addString("pack*");
423   q.addAttribute(sat::SolvAttr::name);
424
425   std::for_each(q.begin(), q.end(), &result_cb);
426   BOOST_CHECK(q.size() == 28);
427 }
428 */
429
430 #if 1
431 BOOST_AUTO_TEST_CASE(pool_query_recovery)
432 {
433   Pathname testfile(TESTS_SRC_DIR);
434     testfile += "/zypp/data/PoolQuery/savedqueries";
435   cout << "****recovery****"  << endl;
436   std::vector<PoolQuery> queries;
437   std::insert_iterator<std::vector<PoolQuery> > ii( queries,queries.begin());
438   readPoolQueriesFromFile(testfile,ii);
439   BOOST_REQUIRE_MESSAGE(queries.size()==2,"Bad count of readed queries.");
440   BOOST_CHECK(queries[0].size() == 8);
441   PoolQuery q;
442   q.addString("ma*");
443   q.addRepo("factory");
444   q.addKind(Resolvable::Kind::patch);
445   q.setMatchRegex();
446   q.setRequireAll();
447   q.setCaseSensitive();
448   q.setUninstalledOnly();
449   BOOST_CHECK(q==queries[1]);
450 }
451
452 #endif
453
454 BOOST_AUTO_TEST_CASE(pool_query_serialize)
455 {
456   PoolQuery q;
457   q.addString("ma");
458   q.addAttribute(sat::SolvAttr::name);
459   q.addRepo("factory-nonoss");
460   q.addRepo("zypp_svn");
461   PoolQuery q2;
462   q2.addAttribute(sat::SolvAttr::name,"ma");
463   q2.addRepo("factory-nonoss");
464   q2.addRepo("zypp_svn");
465
466
467 //  Pathname testfile(TESTS_SRC_DIR);
468   //  testfile += "/zypp/data/PoolQuery/testqueries";
469   filesystem::TmpFile testfile;
470   cout << "****serialize****"  << endl;
471   std::vector<PoolQuery> queries;
472   queries.push_back(q);
473   queries.push_back(q2);
474   writePoolQueriesToFile(testfile,queries.begin(),queries.end());
475   BOOST_REQUIRE_MESSAGE(queries.size()==2,"Bad count of added queries.");
476
477   std::insert_iterator<std::vector<PoolQuery> > ii( queries,queries.end());
478   readPoolQueriesFromFile(testfile,ii);
479   BOOST_REQUIRE_MESSAGE(queries.size()==4,"Bad count of writed/readed queries.");
480   BOOST_CHECK(queries[2] == queries[0]);
481   BOOST_CHECK(queries[3] == queries[1]);
482 }
483
484
485 // test matching
486 BOOST_AUTO_TEST_CASE(pool_query_equal)
487 {
488   cout << "****equal****"  << endl;
489   PoolQuery q;
490   q.addString("zypp");
491   q.addAttribute(sat::SolvAttr::name);
492   q.setMatchGlob();
493   PoolQuery q2;
494   q2.addString("zypp");
495   q2.addAttribute(sat::SolvAttr::name);
496   q2.setMatchGlob();
497   PoolQuery q3;
498   q3.addString("zypp");
499   q3.addAttribute(sat::SolvAttr::name);
500   q3.setMatchGlob();
501   q3.setRequireAll(true);
502   PoolQuery q4;
503   q4.addAttribute(sat::SolvAttr::name,"zypp");
504   q4.setMatchGlob();
505
506   BOOST_CHECK(q==q2);
507   BOOST_CHECK(q!=q3);
508   BOOST_CHECK(q==q4);
509   BOOST_CHECK(q4!=q3);
510 }