Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / tests / zypp / Selectable_test.cc
1 #include "TestSetup.h"
2 #include "zypp/ResPool.h"
3 #include "zypp/ui/Selectable.h"
4
5 #define BOOST_TEST_MODULE Selectable
6
7 /////////////////////////////////////////////////////////////////////////////
8
9 static TestSetup test;
10
11 BOOST_AUTO_TEST_CASE(testcase_init)
12 {
13 //   zypp::base::LogControl::instance().logToStdErr();
14   test.loadTestcaseRepos( TESTS_SRC_DIR"/data/TCSelectable" );
15
16 //   dumpRange( USR, test.pool().knownRepositoriesBegin(),
17 //                   test.pool().knownRepositoriesEnd() ) << endl;
18 //   USR << "pool: " << test.pool() << endl;
19 }
20 /////////////////////////////////////////////////////////////////////////////
21
22 BOOST_AUTO_TEST_CASE(candiadate)
23 {
24   ResPoolProxy poolProxy( test.poolProxy() );
25   ui::Selectable::Ptr s( poolProxy.lookup( ResKind::package, "candidate" ) );
26   //   (I 1) {
27   //   I__s_(8)candidate-1-1.i586(@System)(openSUSE)
28   // } (A 6) {
29   //   U__s_(2)candidate-4-1.x86_64(RepoHIGH)(unkown)
30   //   U__s_(3)candidate-4-1.i586(RepoHIGH)(unkown) <- (update) candidate if allowVendorChange
31   //   U__s_(6)candidate-0-1.x86_64(RepoMID)(SUSE)
32   //   U__s_(7)candidate-0-1.i586(RepoMID)(SUSE) <- candidate (highest prio matching arch and vendor)
33   //   U__s_(4)candidate-2-1.x86_64(RepoLOW)(openSUSE)
34   //   U__s_(5)candidate-2-1.i586(RepoLOW)(openSUSE)
35   // }
36   if ( ZConfig::instance().solver_allowVendorChange() )
37   {
38     BOOST_CHECK_EQUAL( s->candidateObj()->repoInfo().alias(), "RepoHIGH" );
39     BOOST_CHECK_EQUAL( s->candidateObj()->edition(), Edition("4-1") );
40     BOOST_CHECK_EQUAL( s->candidateObj()->arch(), Arch_i586 );
41     // updateCandidate:
42     BOOST_CHECK_EQUAL( s->updateCandidateObj(), s->candidateObj() );
43   }
44   else
45   {
46     BOOST_CHECK_EQUAL( s->candidateObj()->repoInfo().alias(), "RepoMID" );
47     BOOST_CHECK_EQUAL( s->candidateObj()->edition(), Edition("0-1") );
48     BOOST_CHECK_EQUAL( s->candidateObj()->arch(), Arch_i586 );
49     // no updateCandidate due to low version
50     BOOST_CHECK_EQUAL( s->updateCandidateObj(), PoolItem() );
51   }
52 }
53
54 BOOST_AUTO_TEST_CASE(candiadatenoarch)
55 {
56   ResPoolProxy poolProxy( test.poolProxy() );
57   ui::Selectable::Ptr s( poolProxy.lookup( ResKind::package, "candidatenoarch" ) );
58 /*[package]candidatenoarch: S_KeepInstalled
59    (I 1) {
60    I__s_(17)candidatenoarch-1-1.i586(@System)
61 }  (A 8) {
62  C U__s_(4)candidatenoarch-5-1.noarch(RepoHIGH) <- candidate (arch/noarch change)
63    U__s_(5)candidatenoarch-4-1.x86_64(RepoHIGH)
64    U__s_(6)candidatenoarch-4-1.i586(RepoHIGH)
65    U__s_(7)candidatenoarch-4-1.noarch(RepoHIGH)
66    U__s_(12)candidatenoarch-0-2.noarch(RepoMID)
67    U__s_(13)candidatenoarch-0-1.x86_64(RepoMID)
68    U__s_(14)candidatenoarch-0-1.i586(RepoMID)
69    U__s_(15)candidatenoarch-0-1.noarch(RepoMID)
70 }  */
71   BOOST_CHECK_EQUAL( s->candidateObj()->repoInfo().alias(), "RepoHIGH" );
72   BOOST_CHECK_EQUAL( s->candidateObj()->edition(), Edition("5-1") );
73   BOOST_CHECK_EQUAL( s->candidateObj()->arch(), Arch_noarch );
74   // no updateCandidate due to low version
75   BOOST_CHECK_EQUAL( s->updateCandidateObj(), s->candidateObj() );
76 }
77
78
79 /////////////////////////////////////////////////////////////////////////////
80 //
81 // Status change tests
82 //
83 /////////////////////////////////////////////////////////////////////////////
84
85 // build ResStatus and return whether the comination is supported. (e.g currently no LOCKED state below APPL_HIGH)
86 inline bool initStatus( ResStatus::TransactValue fromState, ResStatus::TransactByValue fromBy, ResStatus & from )
87 {
88   from = ResStatus();
89   if ( fromState == ResStatus::KEEP_STATE )
90   {
91     from.setSoftLock( fromBy );
92   }
93   else
94   {
95     from.setTransactValue( fromState, fromBy );
96     if ( fromState == ResStatus::LOCKED && ! from.isLocked() )
97       return false; // no lock at this level (by now just USER APPL_HIGH)
98   }
99   return true;
100 }
101
102 /////////////////////////////////////////////////////////////////////////////
103 // status verification helper
104 /////////////////////////////////////////////////////////////////////////////
105 //     enum TransactValue
106 //       {
107 //         KEEP_STATE = bit::RangeValue<TransactField,0>::value,
108 //         LOCKED     = bit::RangeValue<TransactField,1>::value, // locked, must not transact
109 //         TRANSACT   = bit::RangeValue<TransactField,2>::value  // transact according to state
110 //       };
111
112 template <class _Iter>
113 inline bool _all( _Iter begin_r, _Iter end_r, ResStatus::TransactValue val_r )
114 {
115   for_( it, begin_r, end_r )
116   {
117     if ( it->status().getTransactValue() != val_r )
118       return false;
119   }
120   return true;
121 }
122
123 template <class _Iter>
124 inline bool _none( _Iter begin_r, _Iter end_r, ResStatus::TransactValue val_r )
125 {
126   for_( it, begin_r, end_r )
127   {
128     if ( it->status().getTransactValue() == val_r )
129       return false;
130   }
131   return true;
132 }
133
134 template <class _Iter>
135 inline bool _atLeastOne( _Iter begin_r, _Iter end_r, ResStatus::TransactValue val_r )
136 { return ! _none( begin_r, end_r, val_r ); }
137
138 inline bool _allBySolver( ui::Selectable::Ptr sel )
139 {
140   for_( it, sel->installedBegin(), sel->installedEnd() )
141   {
142     if ( it->status().transacts() && ! it->status().isBySolver() )
143       return false;
144   }
145   for_( it, sel->availableBegin(), sel->availableEnd() )
146   {
147     if ( it->status().transacts() && ! it->status().isBySolver() )
148       return false;
149   }
150   return true;
151 }
152
153 inline bool _allInstalled( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )            { return _all( sel->installedBegin(), sel->installedEnd(), val_r ); }
154 inline bool _noneInstalled( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )           { return _none( sel->installedBegin(), sel->installedEnd(), val_r ); }
155 inline bool _atLeastOneInstalled( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )     { return _atLeastOne( sel->installedBegin(), sel->installedEnd(), val_r ); }
156
157 inline bool _allAvailable( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )            { return _all( sel->availableBegin(), sel->availableEnd(), val_r ); }
158 inline bool _noneAvailable( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )           { return _none( sel->availableBegin(), sel->availableEnd(), val_r ); }
159 inline bool _atLeastOneAvailable( ui::Selectable::Ptr sel, ResStatus::TransactValue val_r )     { return _atLeastOne( sel->availableBegin(), sel->availableEnd(), val_r ); }
160
161 inline bool _haveInstalled( ui::Selectable::Ptr sel )                                           { return ! sel->installedEmpty(); }
162 inline bool _haveAvailable( ui::Selectable::Ptr sel )                                           { return ! sel->availableEmpty(); }
163
164 inline bool _noInstalled( ui::Selectable::Ptr sel )                                             { return sel->installedEmpty(); }
165 inline bool _noAvailable( ui::Selectable::Ptr sel )                                             { return sel->availableEmpty(); }
166
167 #define allInstalled(V)                 _allInstalled(sel,ResStatus::V)
168 #define noneInstalled(V)                _noneInstalled(sel,ResStatus::V)
169 #define atLeastOneInstalled(V)          _atLeastOneInstalled(sel,ResStatus::V)
170
171 #define allAvailable(V)                 _allAvailable(sel,ResStatus::V)
172 #define noneAvailable(V)                _noneAvailable(sel,ResStatus::V)
173 #define atLeastOneAvailable(V)          _atLeastOneAvailable(sel,ResStatus::V)
174
175 #define haveInstalled                   _haveInstalled(sel)
176 #define haveAvailable                   _haveAvailable(sel)
177 #define noInstalled                     _noInstalled(sel)
178 #define noAvailable                     _noAvailable(sel)
179
180 #define allBySolver                     _allBySolver(sel)
181
182 // Verify Selectable::status computes the right value.
183 //
184 //       S_Protected,           // Keep this unmodified ( have installedObj && S_Protected )
185 //       S_Taboo,               // Keep this unmodified ( have no installedObj && S_Taboo)
186 //       // requested by user:
187 //       S_Del,                 // delete  installedObj ( clears S_Protected if set )
188 //       S_Update,              // install candidateObj ( have installedObj, clears S_Protected if set )
189 //       S_Install,             // install candidateObj ( have no installedObj, clears S_Taboo if set )
190 //       // not requested by user:
191 //       S_AutoDel,             // delete  installedObj
192 //       S_AutoUpdate,          // install candidateObj ( have installedObj )
193 //       S_AutoInstall,         // install candidateObj ( have no installedObj )
194 //       // no modification:
195 //       S_KeepInstalled,       // no modification      ( have installedObj && !S_Protected, clears S_Protected if set )
196 //       S_NoInst,              // no modification      ( have no installedObj && !S_Taboo, clears S_Taboo if set )
197 void verifyState( ui::Selectable::Ptr sel )
198 {
199   ui::Status status( sel->status() );
200   SEC << dump(sel) << endl;
201   switch ( status )
202   {
203     case ui::S_Update:
204     case ui::S_AutoUpdate:
205       BOOST_CHECK( haveInstalled );
206       BOOST_CHECK( atLeastOneAvailable(TRANSACT) );
207       BOOST_CHECK_EQUAL( allBySolver, status==ui::S_AutoUpdate );
208       break;
209
210     case ui::S_Del:
211     case ui::S_AutoDel:
212       BOOST_CHECK( haveInstalled );
213       BOOST_CHECK( noneAvailable(TRANSACT) );   // else would be UPDATE
214       BOOST_CHECK( atLeastOneInstalled(TRANSACT) );
215       BOOST_CHECK_EQUAL( allBySolver, status==ui::S_AutoDel );
216       break;
217
218     case ui::S_Protected:
219       BOOST_CHECK( haveInstalled );
220       BOOST_CHECK( noneAvailable(TRANSACT) );   // else would be UPDATE
221       BOOST_CHECK( noneInstalled(TRANSACT) );   // else would be DEL
222       BOOST_CHECK( allInstalled(LOCKED) );      // implies noneInstalled(TRANSACT)
223       break;
224
225     case ui::S_KeepInstalled:
226       BOOST_CHECK( haveInstalled );
227       BOOST_CHECK( noneAvailable(TRANSACT) );   // else would be UPDATE
228       BOOST_CHECK( noneInstalled(TRANSACT) );   // else would be DEL
229       BOOST_CHECK( ! allInstalled(LOCKED) );    // else would be PROTECTED
230       break;
231
232
233     case ui::S_Install:
234     case ui::S_AutoInstall:
235       BOOST_CHECK( noInstalled );
236       BOOST_CHECK( atLeastOneAvailable(TRANSACT) );
237       BOOST_CHECK_EQUAL( allBySolver, status==ui::S_AutoInstall );
238       break;
239
240     case ui::S_Taboo:
241       BOOST_CHECK( noInstalled );
242       BOOST_CHECK( noneAvailable(TRANSACT) );   // else would be INSTALL
243       BOOST_CHECK( allAvailable(LOCKED) );      // implies noneAvailable(TRANSACT)
244       break;
245
246
247     case ui::S_NoInst:
248       BOOST_CHECK( noInstalled );
249       BOOST_CHECK( noneAvailable(TRANSACT) );   // else would be INSTALL
250       BOOST_CHECK( ! allAvailable(LOCKED) );    // else would be TABOO
251       break;
252   }
253 }
254
255 // Create all ResStatus combinations over a Selectables PoolItems
256 struct StatusCombination
257 {
258   StatusCombination()
259   {}
260   StatusCombination( ui::Selectable::Ptr sel_r )
261   {
262    _items.insert( _items.end(), sel_r->installedBegin(), sel_r->installedEnd() );
263    _items.insert( _items.end(), sel_r->availableBegin(), sel_r->availableEnd() );
264   }
265   bool next()
266   {
267     for (auto i : _items)
268     {
269       switch ( i.status().getTransactValue() )
270       {
271         case ResStatus::KEEP_STATE:
272           i.status().setTransactValue( ResStatus::LOCKED, ResStatus::USER );
273           return true;
274           break;
275         case ResStatus::LOCKED:
276           i.status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
277           return true;
278           break;
279         case ResStatus::TRANSACT:
280           i.status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
281           break;
282       }
283     }
284     return false; // back at the beginning
285   }
286
287   std::vector<PoolItem> _items;
288 };
289
290 // Create all ResStatus combinations over the Selectables PoolItems and verify the result.
291 void testStatusTable( ui::Selectable::Ptr sel )
292 {
293   StatusCombination comb( sel );
294   do {
295     verifyState( sel );
296   } while ( comb.next() );
297 }
298
299 BOOST_AUTO_TEST_CASE(status_change)
300 {
301   // this verifies the Selectables computes ui::Status
302   ResPoolProxy poolProxy( test.poolProxy() );
303   poolProxy.saveState();
304   {
305     ui::Selectable::Ptr sel( poolProxy.lookup( ResKind::package, "installed_only" ) );
306     BOOST_REQUIRE( !sel->installedEmpty() );
307     BOOST_REQUIRE( sel->availableEmpty() );
308     BOOST_CHECK_EQUAL( sel->status(), ui::S_KeepInstalled );
309     testStatusTable( sel );
310   }
311   {
312     ui::Selectable::Ptr sel( poolProxy.lookup( ResKind::package, "installed_and_available" ) );
313     BOOST_REQUIRE( !sel->installedEmpty() );
314     BOOST_REQUIRE( !sel->availableEmpty() );
315     BOOST_CHECK_EQUAL( sel->status(), ui::S_KeepInstalled );
316     testStatusTable( sel );
317   }
318   {
319     ui::Selectable::Ptr sel( poolProxy.lookup( ResKind::package, "available_only" ) );
320     BOOST_REQUIRE( sel->installedEmpty() );
321     BOOST_REQUIRE( !sel->availableEmpty() );
322     BOOST_CHECK_EQUAL( sel->status(), ui::S_NoInst );
323     testStatusTable( sel );
324   }
325
326   // TODO: Test the pickStatus computation (w./w.o. multiinstall)
327   // TODO: Test status/pickStatus transactions (w./w.o. multiinstall)
328 }
329
330 /////////////////////////////////////////////////////////////////////////////
331