- check whether regex compiled allright if matchRegex()
[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 /////////////////////////////////////////////////////////////////////////////
52 //  0xx basic queries
53 /////////////////////////////////////////////////////////////////////////////
54
55 // no conditions, default query
56 // result: all available resolvables
57 BOOST_AUTO_TEST_CASE(pool_query_000)
58 {
59   cout << "****000****"  << endl;
60   PoolQuery q;
61   cout << q.size() << endl;
62   BOOST_CHECK(q.size() == 11451);
63   /**!\todo should be 11453 probably according to:
64    * dumpsolv factory.solv factory-nonoss.solv zypp_svn.solv \@System.solv | \
65    * grep '^name:.*\(noarch\|i386\|i586\|i686\|src\)$' | wc -l
66    */
67 }
68
69 // default query + one search string
70 // q.addString("foo");
71 // result: all resolvables having at least one attribute matching foo
72 BOOST_AUTO_TEST_CASE(pool_query_001)
73 {
74   cout << "****001****"  << endl;
75   PoolQuery q;
76   q.addString("zypper");
77
78   std::for_each(q.begin(), q.end(), &result_cb);
79   BOOST_CHECK(q.size() == 16);
80 }
81
82 // default query + one attribute + one string
83 // q.addAttribute(foo, bar);
84 // should be the same as
85 // q.addAttribute(foo); q.addString(bar);
86 // result: resolvables with foo containing bar
87 BOOST_AUTO_TEST_CASE(pool_query_002)
88 {
89   cout << "****002****"  << endl;
90   PoolQuery q;
91   q.addString("zypper");
92   q.addAttribute(sat::SolvAttr::name);
93
94   std::for_each(q.begin(), q.end(), &result_cb);
95   BOOST_CHECK(q.size() == 6);
96
97   cout << endl;
98
99   PoolQuery q1;
100   q1.addAttribute(sat::SolvAttr::name, "zypper");
101
102   std::for_each(q1.begin(), q1.end(), &result_cb);
103   BOOST_CHECK(q1.size() == 6);
104 }
105
106 // kind filter
107 BOOST_AUTO_TEST_CASE(pool_query_003)
108 {
109   cout << "****003****"  << endl;
110   PoolQuery q;
111   q.addString("zypper");
112   q.addAttribute(sat::SolvAttr::name);
113   q.addKind(ResTraits<Package>::kind);
114
115   std::for_each(q.begin(), q.end(), &result_cb);
116   BOOST_CHECK(q.size() == 3);
117 }
118
119 // match exact
120 BOOST_AUTO_TEST_CASE(pool_query_004)
121 {
122   cout << "****004****"  << endl;
123   PoolQuery q;
124   q.addString("vim");
125   q.addAttribute(sat::SolvAttr::name);
126   q.setMatchExact();
127
128   std::for_each(q.begin(), q.end(), &result_cb);
129   BOOST_CHECK(q.size() == 3);
130
131   PoolQuery q1;
132   q1.addString("zypp");
133   q1.addAttribute(sat::SolvAttr::name);
134   q1.setMatchExact();
135
136   std::for_each(q1.begin(), q1.end(), &result_cb);
137   BOOST_CHECK(q1.empty());
138 }
139
140 // use globs
141 BOOST_AUTO_TEST_CASE(pool_query_005)
142 {
143   cout << "****005.1****"  << endl;
144   PoolQuery q;
145   q.addString("z?p*");
146   q.addAttribute(sat::SolvAttr::name);
147   q.setMatchGlob();
148
149   std::for_each(q.begin(), q.end(), &result_cb);
150   BOOST_CHECK(q.size() == 11);
151
152   cout << "****005.2****"  << endl;
153
154   PoolQuery q1;
155   q1.addString("*zypp*");
156   q1.addAttribute(sat::SolvAttr::name);
157   q1.setMatchGlob();
158
159   std::for_each(q1.begin(), q1.end(), &result_cb);
160   BOOST_CHECK(q1.size() == 28);
161
162   cout << "****005.3****"  << endl;
163
164   // should be the same as above
165   PoolQuery q2;
166   q2.addString("zypp");
167   q2.addAttribute(sat::SolvAttr::name);
168
169   BOOST_CHECK(q2.size() == 28);
170 }
171
172 // use regex
173 BOOST_AUTO_TEST_CASE(pool_query_006)
174 {
175   cout << "****006.1***"  << endl;
176
177   // should be the same as 005 1
178   PoolQuery q;
179   q.addString("^z.p.*");
180   q.addAttribute(sat::SolvAttr::name);
181   q.setMatchRegex();
182
183   std::for_each(q.begin(), q.end(), &result_cb);
184   BOOST_CHECK(q.size() == 11);
185
186   cout << "****006.2***"  << endl;
187
188   PoolQuery q1;
189   q1.addString("zypper|smart");
190   q1.addAttribute(sat::SolvAttr::name);
191   q1.setMatchRegex();
192
193   std::for_each(q1.begin(), q1.end(), &result_cb);
194   BOOST_CHECK(q1.size() == 21);
195
196   cout << "****006.3***"  << endl;
197
198   // invalid regex
199   PoolQuery q2;
200   q2.addString("zypp\\");
201   q2.setMatchRegex();
202   BOOST_CHECK_THROW(q2.size(), Exception);
203 }
204
205
206 // match by installed status (basically by system vs. repo)
207 BOOST_AUTO_TEST_CASE(pool_query_050)
208 {
209   cout << "****050****"  << endl;
210   PoolQuery q;
211   q.addString("zypper");
212   q.addAttribute(sat::SolvAttr::name);
213   q.setMatchExact();
214   q.setInstalledOnly();
215
216   std::for_each(q.begin(), q.end(), &result_cb);
217   BOOST_CHECK(q.size() == 1);
218
219   cout << endl;
220
221   PoolQuery q1;
222   q1.addString("zypper");
223   q1.addAttribute(sat::SolvAttr::name);
224   q1.setMatchExact();
225   q1.setUninstalledOnly();
226
227   std::for_each(q1.begin(), q1.end(), &result_cb);
228   BOOST_CHECK(q1.size() == 5);
229 }
230
231 /////////////////////////////////////////////////////////////////////////////
232 //  1xx multiple attribute queries
233 /////////////////////////////////////////////////////////////////////////////
234
235
236 BOOST_AUTO_TEST_CASE(pool_query_100)
237 {
238   cout << "****100****"  << endl;
239   PoolQuery q;
240   /* This string is found sometimes only in solvable names (e.g. novell-lum),
241      sometimes only in summary (e.g. yast2-casa-ats) and sometimes only
242      in descriptions (e.g. beagle-quickfinder).  novell-lum doesn't exist
243      in our test solv file, but let's ignore this.  I didn't find a string
244      with the same characteristics giving fewer matches :-/  */
245   q.addString("novell");
246   q.addAttribute(sat::SolvAttr::name);
247   q.addAttribute(sat::SolvAttr::summary);
248   q.addAttribute(sat::SolvAttr::description);
249
250   std::for_each(q.begin(), q.end(), &result_cb);
251   BOOST_CHECK(q.size() == 74);
252
253   cout << endl;
254
255   PoolQuery q1;
256   q1.addString("mp3");
257   q1.addAttribute(sat::SolvAttr::name);
258
259   std::for_each(q1.begin(), q1.end(), &result_cb);
260   BOOST_CHECK(q1.size() == 7);
261 }
262
263 // multi attr (same value) substring matching (case sensitive and insensitive)
264 BOOST_AUTO_TEST_CASE(pool_query_101)
265 {
266   cout << "****101****"  << endl;
267
268   PoolQuery q;
269   q.addString("ZYpp");
270   q.addAttribute(sat::SolvAttr::name);
271   q.addAttribute(sat::SolvAttr::summary);
272   q.addAttribute(sat::SolvAttr::description);
273
274   std::for_each(q.begin(), q.end(), &result_cb);
275   BOOST_CHECK(q.size() == 30);
276
277   cout << endl;
278
279   PoolQuery q2;
280   q2.addString("ZYpp");
281   q2.addAttribute(sat::SolvAttr::name);
282   q2.addAttribute(sat::SolvAttr::summary);
283   q2.addAttribute(sat::SolvAttr::description);
284   q2.setCaseSensitive();
285
286   std::for_each(q2.begin(), q2.end(), &result_cb);
287   BOOST_CHECK(q2.size() == 2);
288 }
289
290
291 // multi attr (same value) glob matching (case sensitive and insensitive)
292 BOOST_AUTO_TEST_CASE(pool_query_102)
293 {
294   cout << "****102****"  << endl;
295   PoolQuery q;
296   q.addString("pack*");
297   q.addAttribute(sat::SolvAttr::name);
298   q.addAttribute(sat::SolvAttr::summary);
299   q.setMatchGlob();
300
301   std::for_each(q.begin(), q.end(), &result_cb);
302   BOOST_CHECK(q.size() == 35);
303 }
304
305
306 /////////////////////////////////////////////////////////////////////////////
307 //  3xx repo filter queries (addRepo(alias_str))
308 /////////////////////////////////////////////////////////////////////////////
309
310 // default query + one attribute(one string) + one repo
311 BOOST_AUTO_TEST_CASE(pool_query_300)
312 {
313   cout << "****300****"  << endl;
314   PoolQuery q;
315   q.addAttribute(sat::SolvAttr::name, "zypper");
316   q.addRepo("zypp_svn");
317
318   std::for_each(q.begin(), q.end(), &result_cb);
319   BOOST_CHECK(q.size() == 3);
320 }
321
322 // default query + one repo
323 BOOST_AUTO_TEST_CASE(pool_query_301)
324 {
325   cout << "****301****"  << endl;
326   PoolQuery q;
327   q.addRepo("zypp_svn");
328
329   std::for_each(q.begin(), q.end(), &result_cb);
330   BOOST_CHECK(q.size() == 21);
331 }
332
333 // multiple repos + one attribute
334 BOOST_AUTO_TEST_CASE(pool_query_302)
335 {
336   cout << "****302****"  << endl;
337   PoolQuery q;
338   q.addString("ma");
339   q.addAttribute(sat::SolvAttr::name);
340   q.addRepo("factory-nonoss");
341   q.addRepo("zypp_svn");
342
343   std::for_each(q.begin(), q.end(), &result_cb);
344   BOOST_CHECK(q.size() == 8);
345 }
346
347 /*
348 BOOST_AUTO_TEST_CASE(pool_query_X)
349 {
350   cout << "****X****"  << endl;
351   PoolQuery q;
352   q.addString("pack*");
353   q.addAttribute(sat::SolvAttr::name);
354
355   std::for_each(q.begin(), q.end(), &result_cb);
356   BOOST_CHECK(q.size() == 28);
357 }
358 */
359
360 // test matching
361 BOOST_AUTO_TEST_CASE(pool_query_equal)
362 {
363   cout << "****equal****"  << endl;
364   PoolQuery q;
365   q.addString("zypp");
366   q.addAttribute(sat::SolvAttr::name);
367   q.setMatchGlob();
368   PoolQuery q2;
369   q2.addString("zypp");
370   q2.addAttribute(sat::SolvAttr::name);
371   q2.setMatchGlob();
372   PoolQuery q3;
373   q3.addString("zypp");
374   q3.addAttribute(sat::SolvAttr::name);
375   q3.setMatchGlob();
376   q3.setRequireAll(true);
377   PoolQuery q4;
378   q4.addAttribute(sat::SolvAttr::name,"zypp");
379   q4.setMatchGlob();
380
381   BOOST_CHECK(equal(q,q2));
382   BOOST_CHECK(!equal(q,q3));
383   //only exact equal! \TODO maybe change
384   BOOST_CHECK(!equal(q,q4));
385   BOOST_CHECK(!equal(q4,q3));
386 }
387
388 // save/load query
389 BOOST_AUTO_TEST_CASE(pool_query_save_restore)
390 {
391 #warning CAN NOT USE A FIX SOLV FILE
392 // must store some raw metadata and generate the solv file
393 // otherwise trestcases break whenever the solv format changes
394 #if 0
395   Pathname dir(TESTS_SRC_DIR);
396   dir += "/zypp/data/PoolQuery";
397
398   ZYpp::Ptr z = getZYpp();
399
400   sat::Pool::instance().addRepoSolv(dir + "foo.solv");
401
402   PoolQuery query;
403   //query.setInstalledOnly();
404   query.execute("kde", &result_cb);
405
406   cout << "search done." << endl;
407
408   query.setMatchExact(true);
409   query.execute("kde", &result_cb);
410
411   cout << "search done." << endl;
412 #endif
413
414 //test recovery from file
415   Pathname pathToQueries(TESTS_SRC_DIR);
416   pathToQueries += "/zypp/data/PoolQuery/savedqueries";
417
418   std::list<PoolQuery> savedQueries;
419
420   std::insert_iterator<std::list<PoolQuery> > ii(savedQueries, savedQueries.end());
421   readPoolQueriesFromFile(pathToQueries,ii);
422   BOOST_CHECK( savedQueries.size() == 2 );
423
424   filesystem::TmpFile tmp;
425   Pathname tmpPath = tmp.path();
426
427   savedQueries.clear();
428
429   PoolQuery q1;
430   PoolQuery q2;
431
432   q1.addKind( Resolvable::Kind::patch );
433   q2.addKind( Resolvable::Kind::patch );
434   q2.addKind( Resolvable::Kind::pattern );
435
436   savedQueries.push_front( q1 );
437   savedQueries.push_front( q2 );
438
439   writePoolQueriesToFile ( tmpPath, savedQueries.begin(), savedQueries.end() );
440   std::insert_iterator<std::list<PoolQuery> > ii2(savedQueries,
441       savedQueries.end());
442   //reread writed queries
443   readPoolQueriesFromFile( tmpPath, ii2);
444   //TODO test if 0==2 and 1==3
445   BOOST_CHECK( savedQueries.size() == 4 );
446
447 }