1 #ifndef INCLUDE_TESTSETUP
2 #define INCLUDE_TESTSETUP
5 #ifndef INCLUDE_TESTSETUP_WITHOUT_BOOST
6 #include <boost/test/auto_unit_test.hpp>
7 using boost::unit_test::test_case;
10 #include <zypp/base/LogControl.h>
11 #include <zypp/base/LogTools.h>
12 #include <zypp/base/InputStream.h>
13 #include <zypp/base/IOStream.h>
14 #include <zypp/base/Flags.h>
15 #include <zypp/ZYppFactory.h>
16 #include <zypp/ZYpp.h>
17 #include <zypp/TmpPath.h>
18 #include <zypp/Glob.h>
19 #include <zypp/PathInfo.h>
20 #include <zypp/RepoManager.h>
21 #include <zypp/Target.h>
22 #include <zypp/ResPool.h>
23 #include <zypp/misc/LoadTestcase.h>
32 #ifndef BOOST_CHECK_NE
33 #define BOOST_CHECK_NE( L, R ) BOOST_CHECK( (L) != (R) )
36 #define LABELED(V) #V << ":\t" << V
38 enum TestSetupOptionBits
40 TSO_CLEANROOT = (1 << 0), // wipe rootdir in ctor
41 TSO_REPO_DEFAULT_GPG = (1 << 1), // dont turn off gpgcheck in repos
43 ZYPP_DECLARE_FLAGS_AND_OPERATORS( TestSetupOptions, TestSetupOptionBits );
45 /** Build a test environment below a temp. root directory.
46 * If a \c rootdir_r was provided to the ctor, this directory
47 * will be used and it will \b not be removed.
49 * \note The lifetime of this objects is the lifetime of the temp. root directory.
52 * #include "TestSetup.h"
54 * BOOST_AUTO_TEST_CASE(WhatProvides)
56 * // enabls loging fot the scope of this block:
57 * // base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "/tmp/YLOG" ) );
59 * TestSetup test( Arch_x86_64 );
60 * // test.loadTarget(); // initialize and load target
61 * test.loadRepo( TESTS_SRC_DIR"/data/openSUSE-11.1" );
63 * // Here the pool is ready to be used.
71 typedef TestSetupOptions Options;
74 struct InitLaterType {};
75 static constexpr InitLaterType initLater = InitLaterType();
77 TestSetup( InitLaterType )
80 TestSetup( const Arch & sysarch_r = Arch_empty, const Options & options_r = Options() )
81 : _pimpl { new Impl( Pathname(), sysarch_r, options_r ) }
84 TestSetup( const Pathname & rootdir_r, const Arch & sysarch_r = Arch_empty, const Options & options_r = Options() )
85 : _pimpl { new Impl( rootdir_r, sysarch_r, options_r ) }
88 TestSetup( const Pathname & rootdir_r, const Options & options_r )
89 : _pimpl { new Impl( rootdir_r, Arch_empty, options_r ) }
96 /** Whether directory \a path_r contains a solver testcase. */
97 static bool isTestcase( const Pathname & path_r )
99 return zypp::misc::testcase::LoadTestcase::None != zypp::misc::testcase::LoadTestcase::testcaseTypeAt( path_r );
102 /** Whether directory \a path_r contains a testsetup. */
103 static bool isTestSetup( const Pathname & path_r )
105 return filesystem::PathInfo( path_r / "repos.d" ).isDir() && filesystem::PathInfo( path_r / "raw" ).isDir();
109 const Pathname & root() const { return _pimpl->_rootdir; }
111 Target & target() { if ( ! getZYpp()->getTarget() ) getZYpp()->initializeTarget( _pimpl->_rootdir ); return *getZYpp()->getTarget(); }
112 RepoManager repomanager() { return RepoManager( RepoManagerOptions::makeTestSetup( _pimpl->_rootdir ) ); }
113 ResPool pool() { return ResPool::instance(); }
114 ResPoolProxy poolProxy() { return pool().proxy(); }
115 sat::Pool satpool() { return sat::Pool::instance(); }
116 Resolver & resolver() { return *getZYpp()->resolver(); }
119 /** Load target repo. */
122 /** Fake @System repo from url. */
123 void loadTargetRepo( const Url & url_r )
124 { loadRepo( url_r, sat::Pool::systemRepoAlias() ); }
125 /** Fake @System repo from Path. */
126 void loadTargetRepo( const Pathname & path_r )
127 { loadRepo( path_r, sat::Pool::systemRepoAlias() ); }
128 /** Fake @System repo from helix repo. */
129 void loadTargetHelix( const Pathname & path_r )
130 { loadHelix( path_r, sat::Pool::systemRepoAlias() ); }
133 /** Directly load repoinfo to pool. */
134 void loadRepo( RepoInfo nrepo )
136 RepoManager rmanager( repomanager() );
137 if ( rmanager.hasRepo( nrepo ) )
138 nrepo.setAlias( RepoManager::makeStupidAlias( nrepo.url() ) );
139 rmanager.addRepository( nrepo );
140 rmanager.buildCache( nrepo );
141 rmanager.loadFromCache( nrepo );
143 /** Directly load repo from url to pool. */
144 void loadRepo( const Url & url_r, const std::string & alias_r = std::string() )
147 nrepo.setAlias( alias_r.empty() ? url_r.getHost()+":"+Pathname::basename(url_r.getPathName()) : alias_r );
148 nrepo.addBaseUrl( url_r );
149 if ( ! _pimpl->_options.testFlag( TSO_REPO_DEFAULT_GPG ) )
150 nrepo.setGpgCheck( false );
153 /** Directly load repo from metadata(dir) or solvfile(file) to pool.
154 * An empty alias is guessed.
156 void loadRepo( const Pathname & path_r, const std::string & alias_r = std::string() )
158 if ( filesystem::PathInfo( path_r ).isDir() )
160 loadRepo( path_r.asUrl(), alias_r );
163 // .solv file is loaded directly using a faked RepoInfo
165 nrepo.setAlias( alias_r.empty() ? path_r.basename() : alias_r );
166 satpool().addRepoSolv( path_r, nrepo );
168 /** Directly load repo from some location (url or absolute(!)path).
169 * An empty alias is guessed.
171 void loadRepo( const std::string & loc_r, const std::string & alias_r = std::string() )
173 if ( *loc_r.c_str() == '/' )
175 loadRepo( Pathname( loc_r ), alias_r );
179 loadRepo( Url( loc_r ), alias_r );
182 /** Directly load repo from some location (url or absolute(!)path).
183 * An empty alias is guessed.
185 void loadRepo( const char * loc_r, const std::string & alias_r = std::string() )
186 { loadRepo( std::string( loc_r ? loc_r : "" ), alias_r ); }
188 /** Directly load a helix repo from some testcase.
189 ** An empty alias is guessed.
191 void loadHelix( const Pathname & path_r, const std::string & alias_r = std::string() )
193 // .solv file is loaded directly using a faked RepoInfo
195 nrepo.setAlias( alias_r.empty() ? path_r.basename() : alias_r );
196 satpool().addRepoHelix( path_r, nrepo );
199 // Load repos included in a solver testcase.
200 void loadTestcaseRepos( const Pathname & path_r )
202 zypp::misc::testcase::LoadTestcase loader;
204 if (!loader.loadTestcaseAt( path_r, &err ) ) {
205 ZYPP_THROW( Exception(err) );
208 const auto &setup = loader.setupInfo();
209 auto tempRepoManager = repomanager();
210 if ( !setup.applySetup( tempRepoManager ) ) {
211 ZYPP_THROW( Exception("Failed to apply setup!") );
215 base::SetTracker<LocaleSet> localesTracker = setup.localesTracker;
216 localesTracker.removed().insert( localesTracker.current().begin(), localesTracker.current().end() );
217 satpool().initRequestedLocales( localesTracker.removed() );
219 localesTracker.added().insert( localesTracker.current().begin(), localesTracker.current().end() );
220 satpool().setRequestedLocales( localesTracker.added() );
222 poolProxy(); // prepare
226 /** Load all enabled repos in repos.d to pool. */
229 RepoManager repoManager( repomanager() );
230 RepoInfoList repos = repoManager.knownRepositories();
231 for ( RepoInfoList::iterator it = repos.begin(); it != repos.end(); ++it )
233 RepoInfo & nrepo( *it );
234 USR << nrepo << endl;
236 if ( ! nrepo.enabled() )
239 if ( ! repoManager.isCached( nrepo ) || nrepo.type() == repo::RepoType::RPMPLAINDIR )
241 if ( repoManager.isCached( nrepo ) )
243 USR << "cleanCache" << endl;
244 repoManager.cleanCache( nrepo );
246 //USR << "refreshMetadata" << endl;
247 //repoManager.refreshMetadata( nrepo );
248 USR << "buildCache" << endl;
249 repoManager.buildCache( nrepo );
251 USR << "Create from cache" << endl;
252 repoManager.loadFromCache( nrepo );
257 /** Detect and load the system located at \a sysRoot.
259 * \a sysRoot needs to be a directory containing either a SolverTestcase,
260 * a TestSetup system or a real system. The provided repostitories are
261 * loaded into the pool (without refresh).
263 static void LoadSystemAt( const Pathname & sysRoot, const Arch & _testSetupArch_r = Arch_x86_64 )
265 if ( ! PathInfo( sysRoot ).isDir() )
266 ZYPP_THROW( Exception("sysRoot argument needs to be a directory") );
268 if ( TestSetup::isTestcase( sysRoot ) )
270 USR << str::form( "*** Load Testcase from '%s'", sysRoot.c_str() ) << endl;
272 test.loadTestcaseRepos( sysRoot );
274 else if ( TestSetup::isTestSetup( sysRoot ) )
276 USR << str::form( "*** Load TestSetup from '%s'", sysRoot.c_str() ) << endl;
278 TestSetup test( sysRoot, _testSetupArch_r );
281 Pathname solvCachePath( RepoManagerOptions::makeTestSetup( test.root() ).repoSolvCachePath );
282 Pathname fakeTargetSolv( solvCachePath / sat::Pool::systemRepoAlias() / "solv" );
283 if ( PathInfo( fakeTargetSolv ).isFile() )
285 USR << str::form( "*** Fake TestSetup Target from '%s'", fakeTargetSolv.c_str() ) << endl;
287 test.loadTargetRepo( fakeTargetSolv );
292 sat::Pool satpool( sat::Pool::instance() );
294 USR << str::form( "*** Load system at '%s'", sysRoot.c_str() ) << endl;
297 USR << "*** load target '" << Repository::systemRepoAlias() << "'\t" << endl;
298 getZYpp()->initializeTarget( sysRoot );
299 getZYpp()->target()->load();
300 USR << satpool.systemRepo() << endl;
305 RepoManager repoManager( sysRoot );
306 RepoInfoList repos = repoManager.knownRepositories();
307 for_( it, repos.begin(), repos.end() )
309 RepoInfo & nrepo( *it );
311 if ( ! nrepo.enabled() )
314 if ( ! repoManager.isCached( nrepo ) )
316 USR << str::form( "*** omit uncached repo '%s' (do 'zypper refresh')", nrepo.name().c_str() ) << endl;
320 USR << str::form( "*** load repo '%s'\t", nrepo.name().c_str() ) << flush;
323 repoManager.loadFromCache( nrepo );
324 USR << satpool.reposFind( nrepo.alias() ) << endl;
326 catch ( const Exception & exp )
328 USR << exp.asString() + "\n" + exp.historyAsString() << endl;
329 USR << str::form( "*** omit broken repo '%s' (do 'zypper refresh')", nrepo.name().c_str() ) << endl;
340 Impl( const Pathname & rootdir_r, const Arch & sysarch_r, const Options & options_r )
342 _options = options_r;
344 if ( rootdir_r.empty() )
345 _rootdir = _tmprootdir.path();
348 filesystem::assert_dir( (_rootdir = rootdir_r) );
349 if ( _options.testFlag( TSO_CLEANROOT ) )
350 filesystem::clean_dir( _rootdir );
353 // erase any old pool content...
354 getZYpp()->finishTarget();
355 sat::Pool::instance().reposEraseAll();
356 // prepare for the new one...
357 ZConfig::instance().setRepoManagerRoot( _rootdir );
359 if ( ! sysarch_r.empty() )
360 ZConfig::instance().setSystemArchitecture( sysarch_r );
361 USR << "CREATED TESTSETUP below " << _rootdir << endl;
365 { USR << (_tmprootdir.path() == _rootdir ? "DELETE" : "KEEP") << " TESTSETUP below " << _rootdir << endl; }
367 filesystem::TmpDir _tmprootdir;
372 std::unique_ptr<Impl> _pimpl; // maybe worth creating RW_pointer traits for it
376 #endif //INCLUDE_TESTSETUP