2 #include "zypp/ResStatus.h"
4 #define BOOST_TEST_MODULE ResStatus
6 BOOST_AUTO_TEST_CASE(Default)
10 BOOST_CHECK( s.isUninstalled() );
11 BOOST_CHECK_EQUAL( s.isInstalled(), ! s.isUninstalled() );
12 BOOST_CHECK_EQUAL( s.getTransactValue(), ResStatus::KEEP_STATE );
13 BOOST_CHECK_EQUAL( s.getTransactByValue(), ResStatus::SOLVER );
17 BOOST_CHECK( s.isInstalled() );
18 BOOST_CHECK_EQUAL( s.isInstalled(), ! s.isUninstalled() );
19 BOOST_CHECK_EQUAL( s.getTransactValue(), ResStatus::KEEP_STATE );
20 BOOST_CHECK_EQUAL( s.getTransactByValue(), ResStatus::SOLVER );
24 ////////////////////////////////////////////////////////////////////////////////
26 ////////////////////////////////////////////////////////////////////////////////
28 inline const _Tp & max( const _Tp & lhs, const _Tp & rhs )
29 { return lhs < rhs ? rhs : lhs; }
31 template<class _Tp, int N>
32 inline _Tp * begin( _Tp (& _array)[N] ) { return _array; }
34 template<class _Tp, int N>
35 inline _Tp * end( _Tp (& _array)[N] ) { return _array + (sizeof(_array)/sizeof(_Tp)); }
37 ResStatus::TransactByValue transactByValues[] = {
38 ResStatus::USER, ResStatus::APPL_HIGH, ResStatus::APPL_LOW, ResStatus::SOLVER
41 ResStatus::TransactValue transactValues[] = {
42 ResStatus::TRANSACT, ResStatus::KEEP_STATE, ResStatus::LOCKED
49 // Status transition like setTransact, setLock, setSoftTransact
50 typedef bool (ResStatus::* Transition)( bool, ResStatus::TransactByValue );
53 typedef void (* Evaluate)( ResStatus::TransactValue, ResStatus::TransactByValue, /* fromState, fromBy */
54 bool, ResStatus::TransactByValue, /* toState, toBy */
55 bool, ResStatus ); /* done, result */
57 // build status and return whether the comination is supported. (e.g currently no LOCKED state below APPL_HIGH)
58 inline bool initStatus( ResStatus::TransactValue fromState, ResStatus::TransactByValue fromBy, ResStatus & from )
61 if ( fromState == ResStatus::KEEP_STATE )
63 from.setSoftLock( fromBy );
67 from.setTransactValue( fromState, fromBy );
68 if ( fromState == ResStatus::LOCKED && ! from.isLocked() )
69 return false; // no lock at this level (by now just USER APPL_HIGH)
74 void testTable( Transition transition, Evaluate evaluate )
76 // Table: For each causer combination (fromBy -> toBy) invoke transition:
78 // bool ok = ResStatus(fromState,fromBy).transition( toState, toBy )
80 // And evaluate the result.
82 for ( ResStatus::TransactByValue * toBy = begin( transactByValues ); toBy != end( transactByValues ); ++toBy )
84 for ( ResStatus::TransactByValue * fromBy = begin( transactByValues ); fromBy != end( transactByValues ); ++fromBy )
86 INT << "=== " << *fromBy << " ==> " << *toBy << " ===" << endl;
87 for ( ResStatus::TransactValue * fromState = begin( transactValues ); fromState != end( transactValues ); ++fromState )
90 if ( ! initStatus( *fromState, *fromBy, from ) )
92 //WAR << "Unsupported ResStatus(" << *fromState << "," << *fromBy << ")" << endl;
93 continue; // Unsupported ResStatus
95 for ( bool * toState = begin( transactTo ); toState != end( transactTo ); ++toState )
97 ResStatus result( from );
98 bool done = (result.*transition)( *toState, *toBy );
100 BOOST_CHECK_EQUAL( from, result ); // status stays unchaged on failure!
101 evaluate( *fromState, *fromBy, *toState, *toBy, done, result );
108 // BOOST_CHECK_EQUAL or BOOST_REQUIRE_EQUAL
109 #define X BOOST_CHECK_EQUAL
112 // Transition must succeeds always
113 #define CHECK_DONE_ALWAYS X( done, true ); if ( ! done ) return
115 // Transition succeeds if same or higher TransactByValue
116 #define CHECK_DONE_IFCAUSER X( done, toBy >= fromBy ); if ( ! done ) return
118 // Transition succeeds if a locker (APPL_HIGH or USER)
119 #define CHECK_DONE_ALWAYS_IFLOCKER X( done, toBy >= ResStatus::APPL_HIGH ); if ( ! done ) return
121 // Transition succeeds if a locker (APPL_HIGH or USER) and same or higher TransactByValue
122 #define CHECK_DONE_IFCAUSER_ISLOCKER X( done, toBy >= max(fromBy,ResStatus::APPL_HIGH) ); if ( ! done ) return
125 // Expected target state after transistion
126 #define CHECK_STATE(NEW) X( result.getTransactValue(), ResStatus::NEW )
129 // Transition result: Remember the causer (i.e. may downgrade superior causer of previous state)
130 #define CHECK_CAUSER_SET X( result.getTransactByValue(), toBy )
132 // Transition result: Remember a superior causer
133 #define CHECK_CAUSER_RAISED X( result.getTransactByValue(), max(fromBy,toBy) )
135 // Transition result: Causer stays the same
136 #define CHECK_CAUSER_STAYS X( result.getTransactByValue(), fromBy )
138 // Transition result: Causer reset to least (SOLVER) level.
139 #define CHECK_CAUSER_TO_SOLVER X( result.getTransactByValue(), ResStatus::SOLVER )
142 ////////////////////////////////////////////////////////////////////////////////
143 // test cases (see BOOST_AUTO_TEST_CASE(transition))
144 ////////////////////////////////////////////////////////////////////////////////
145 // All tests below should define 3 checks, abbrev. by defines
147 // CHECK_DONE_*: When does the tranaction succeed? (return if not)
148 // CHECK_STATE( NEXT ): The state the transition leads to (if successfull)
149 // CHECK_CAUSER_*: Changes to the remembered causer (if successfull)
152 #define DOCHECK( FROMSTATE, TOSTATE, C_DONE, C_STATE, C_CAUSER ) \
153 if ( ResStatus::FROMSTATE == fromState && TOSTATE == toState ) { C_DONE; CHECK_STATE( C_STATE ); C_CAUSER; }
155 void evaluateSetTransact( ResStatus::TransactValue fromState, ResStatus::TransactByValue fromBy,
156 bool toState, ResStatus::TransactByValue toBy,
157 bool done, ResStatus result )
160 initStatus( fromState, fromBy, from );
161 MIL << from << " =setTransact("<<toState<<","<<toBy<<")=>\t" << done << ":" << result << endl;
163 DOCHECK( TRANSACT, true, CHECK_DONE_ALWAYS, TRANSACT, CHECK_CAUSER_RAISED );
164 DOCHECK( TRANSACT, false, CHECK_DONE_IFCAUSER, KEEP_STATE, CHECK_CAUSER_RAISED ); // from transact into softlock
165 DOCHECK( KEEP_STATE, true, CHECK_DONE_ALWAYS, TRANSACT, CHECK_CAUSER_SET );
166 DOCHECK( KEEP_STATE, false, CHECK_DONE_ALWAYS, KEEP_STATE, CHECK_CAUSER_STAYS ); // keep is not raised to softlock
167 DOCHECK( LOCKED, true, CHECK_DONE_IFCAUSER, TRANSACT, CHECK_CAUSER_SET );
168 DOCHECK( LOCKED, false, CHECK_DONE_ALWAYS, LOCKED, CHECK_CAUSER_STAYS );
171 void evaluateSetSoftTransact( ResStatus::TransactValue fromState, ResStatus::TransactByValue fromBy,
172 bool toState, ResStatus::TransactByValue toBy,
173 bool done, ResStatus result )
176 initStatus( fromState, fromBy, from );
177 MIL << from << " =setSoftTransact("<<toState<<","<<toBy<<")=>\t" << done << ":" << result << endl;
179 DOCHECK( TRANSACT, true, CHECK_DONE_ALWAYS, TRANSACT, CHECK_CAUSER_RAISED );
180 DOCHECK( TRANSACT, false, CHECK_DONE_IFCAUSER, KEEP_STATE, CHECK_CAUSER_RAISED ); // from transact into softlock
181 DOCHECK( KEEP_STATE, true, CHECK_DONE_IFCAUSER, TRANSACT, CHECK_CAUSER_SET ); // leaving KEEP requires sup. causer
182 DOCHECK( KEEP_STATE, false, CHECK_DONE_ALWAYS, KEEP_STATE, CHECK_CAUSER_STAYS ); // keep is not raised to softlock
183 DOCHECK( LOCKED, true, CHECK_DONE_IFCAUSER, TRANSACT, CHECK_CAUSER_SET );
184 DOCHECK( LOCKED, false, CHECK_DONE_ALWAYS, LOCKED, CHECK_CAUSER_STAYS );
187 // Check whether failures are ok and whether success lead to the correct state
188 void evaluateSetLock( ResStatus::TransactValue fromState, ResStatus::TransactByValue fromBy,
189 bool toState, ResStatus::TransactByValue toBy,
190 bool done, ResStatus result )
193 initStatus( fromState, fromBy, from );
194 MIL << from << " =setLock("<<toState<<","<<toBy<<")=>\t" << done << ":" << result << endl;
196 DOCHECK( TRANSACT, true, CHECK_DONE_IFCAUSER_ISLOCKER, LOCKED, CHECK_CAUSER_SET ); // transact is 'not locked'
197 DOCHECK( TRANSACT, false, CHECK_DONE_ALWAYS, TRANSACT, CHECK_CAUSER_STAYS );
198 DOCHECK( KEEP_STATE, true, CHECK_DONE_ALWAYS_IFLOCKER, LOCKED, CHECK_CAUSER_SET );
199 DOCHECK( KEEP_STATE, false, CHECK_DONE_ALWAYS, KEEP_STATE, CHECK_CAUSER_STAYS );
200 DOCHECK( LOCKED, true, CHECK_DONE_ALWAYS, LOCKED, CHECK_CAUSER_RAISED );
201 DOCHECK( LOCKED, false, CHECK_DONE_IFCAUSER, KEEP_STATE, CHECK_CAUSER_TO_SOLVER );
204 BOOST_AUTO_TEST_CASE(transition)
206 //base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "-" ) );
208 testTable( &ResStatus::setTransact, &evaluateSetTransact );
209 testTable( &ResStatus::setSoftTransact, &evaluateSetSoftTransact );
210 testTable( &ResStatus::setLock, &evaluateSetLock );
214 bool WhilePoolItemSameStateIsPrivate( ResStatus ostatus, ResStatus nstatus )
216 if ( nstatus == ostatus )
218 // some bits changed...
219 if ( nstatus.getTransactValue() != ostatus.getTransactValue()
220 && ( ! nstatus.isBySolver() // ignore solver state changes
221 // removing a user lock also goes to bySolver
222 || ostatus.getTransactValue() == ResStatus::LOCKED ) )
224 if ( nstatus.isLicenceConfirmed() != ostatus.isLicenceConfirmed() )
229 BOOST_AUTO_TEST_CASE(savestate)
234 BOOST_CHECK_EQUAL( WhilePoolItemSameStateIsPrivate( ostatus, nstatus ), true );
235 nstatus.setLock( true, ResStatus::USER );
236 BOOST_CHECK_EQUAL( WhilePoolItemSameStateIsPrivate( ostatus, nstatus ), false );
238 nstatus.setLock( false, ResStatus::USER );
239 BOOST_CHECK_EQUAL( WhilePoolItemSameStateIsPrivate( ostatus, nstatus ), false );