libzypp  17.25.2
LoadTestcase.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include "LoadTestcase.h"
13 #include "HelixHelpers.h"
14 #include "YamlTestcaseHelpers.h"
15 #include <zypp/PathInfo.h>
16 #include <zypp/base/LogControl.h>
17 #include <zypp/Repository.h>
18 #include <zypp/RepoManager.h>
19 #include <zypp/sat/Pool.h>
20 
21 #define ZYPP_USE_RESOLVER_INTERNALS
23 
25 
26  static const std::string helixControlFile = "solver-test.xml";
27  static const std::string yamlControlFile = "zypp-control.yaml";
28 
31  std::vector<TestcaseTrial> _trials;
32 
33  bool loadHelix (const Pathname &filename, std::string *err);
34 
35  bool loadYaml ( const Pathname &path, std::string *err);
36  };
37 
38 
39  bool LoadTestcase::Impl::loadHelix(const zypp::filesystem::Pathname &filename, std::string *err)
40  {
41  xmlDocPtr xml_doc = xmlParseFile ( filename.c_str() );
42  if (xml_doc == NULL) {
43  if ( err ) *err = (str::Str() << "Can't parse test file '" << filename << "'");
44  return false;
45  }
46 
47 
48  auto root = helix::detail::XmlNode (xmlDocGetRootElement (xml_doc));
49 
50  DBG << "Parsing file '" << filename << "'" << std::endl;
51 
52  if (!root.equals("test")) {
53  if ( err ) *err = (str::Str() << "Node not 'test' in parse_xml_test():" << root.name() << "'");
54  return false;
55  }
56 
57  bool setupDone = false;
58  auto node = root.children();
59  while (node) {
60  if (node->type() == XML_ELEMENT_NODE) {
61  if (node->equals( "setup" )) {
62  if ( setupDone ) {
63  if ( err ) *err = "Multiple setup tags found, this is not supported";
64  return false;
65  }
66  setupDone = true;
67  if ( !helix::detail::parseSetup( *node, _setup, err ) )
68  return false;
69 
70  } else if (node->equals( "trial" )) {
71  if ( !setupDone ) {
72  if ( err ) *err = "Any trials must be preceeded by the setup!";
73  return false;
74  }
75  TestcaseTrial trial;
76  if ( !helix::detail::parseTrial( *node, trial, err ) )
77  return false;
78  _trials.push_back( trial );
79  } else {
80  ERR << "Unknown tag '" << node->name() << "' in test" << std::endl;
81  }
82  }
83  node = ( node->next() );
84  }
85  xmlFreeDoc (xml_doc);
86  return true;
87  }
88 
89  bool LoadTestcase::Impl::loadYaml(const zypp::filesystem::Pathname &path, std::string *err)
90  {
91  DBG << "Parsing file '" << path << "'" << std::endl;
92 
93  const auto makeError = [&]( const std::string_view &errStr ){
94  if ( err ) *err = errStr;
95  return false;
96  };
97 
98  YAML::Node control;
99  try {
100  control = YAML::LoadFile( path.asString() );
101 
102  if ( control.Type() != YAML::NodeType::Map )
103  return makeError("Root node must be of type Map.");
104 
105  const auto &setup = control["setup"];
106  if ( !setup )
107  return makeError("The 'setup' section is required.");
108 
109  if ( !yamltest::detail::parseSetup( setup, _setup, err) )
110  return false;
111 
112  const auto &trials = control["trials"];
113  if ( !trials )
114  return makeError("The 'trials' section is required.");
115  if ( trials.Type() != YAML::NodeType::Sequence )
116  return makeError("The 'trials' section must be of type Sequence.");
117 
118  for ( const auto &trial : trials ) {
120  if ( !trial["trial"] )
121  return makeError("Every element in the trials sequence needs to have the 'trial' key.");
122 
123  if ( !yamltest::detail::parseTrial( trial["trial"], t, err) )
124  return false;
125  _trials.push_back( t );
126  }
127  } catch ( YAML::Exception &e ) {
128  if ( err ) *err = e.what();
129  return false;
130  } catch ( ... ) {
131  if ( err ) *err = "Unknown error when parsing the control file";
132  return false;
133  }
134  return true;
135  }
136 
138  { }
139 
141  { }
142 
143  bool LoadTestcase::loadTestcaseAt(const zypp::filesystem::Pathname &path, std::string *err)
144  {
145  const auto t = testcaseTypeAt( path );
146  if ( t == LoadTestcase::None ) {
147  if ( err ) *err = "Unsopported or no testcase in directory";
148  return false;
149  }
150 
151  // reset everything
152  _pimpl.reset( new Impl() );
153  _pimpl->_setup.globalPath = path;
154 
155  switch (t) {
156  case LoadTestcase::Helix:
157  return _pimpl->loadHelix( path / helixControlFile, err );
158  case LoadTestcase::Yaml:
159  return _pimpl->loadYaml( path / yamlControlFile, err );
160  default:
161  return false;
162  }
163  }
164 
166  {
167  if ( filesystem::PathInfo( path / helixControlFile ).isFile() ) {
168  return LoadTestcase::Helix;
169  } else if ( filesystem::PathInfo( path / yamlControlFile ).isFile() ) {
170  return LoadTestcase::Yaml;
171  }
172  return LoadTestcase::None;
173  }
174 
176  {
177  return _pimpl->_setup;
178  }
179 
180  const std::vector<TestcaseTrial> &LoadTestcase::trialInfo() const
181  {
182  return _pimpl->_trials;
183  }
184 
185  const std::string &TestcaseTrial::Node::getProp( const std::string &name, const std::string &def ) const
186  {
187  if ( properties.find( name) == properties.end() )
188  return def;
189  return properties.at( name );
190  }
191 
193  {
194  const auto &setup = *this;
195  if ( !setup.architecture.empty() )
196  {
197  MIL << "Setting architecture to '" << setup.architecture << "'" << std::endl;
198  ZConfig::instance().setSystemArchitecture( setup.architecture );
199  setenv ("ZYPP_TESTSUITE_FAKE_ARCH", setup.architecture.c_str(), 1);
200  }
201 
202  if ( setup.systemRepo ) {
203  if (!loadRepo( manager, setup, *setup.systemRepo ) )
204  {
205  ERR << "Can't setup 'system'" << std::endl;
206  return false;
207  }
208  }
209 
210  if ( !setup.hardwareInfoFile.empty() ) {
211  setenv( "ZYPP_MODALIAS_SYSFS", setup.hardwareInfoFile.asString().c_str(), 1 );
212  MIL << "setting HardwareInfo to: " << setup.hardwareInfoFile.asString() << std::endl;
213  }
214 
215  for ( const auto &channel : setup.repos ) {
216  if ( !loadRepo( manager, setup, channel ) )
217  {
218  ERR << "Can't setup 'channel'" << std::endl;
219  return false;
220  }
221  }
222 
223  if ( !setup.systemCheck.empty() ) {
224  MIL << "setting systemCheck to: " << setup.systemCheck.asString() << std::endl;
225  SystemCheck::instance().setFile( setup.systemCheck );
226  }
227 
228  return true;
229  }
230 
231  bool TestcaseSetup::loadRepo( zypp::RepoManager &manager, const TestcaseSetup &setup, const RepoData &data )
232  {
233  Pathname pathname = setup.globalPath + data.path;
234  MIL << "'" << pathname << "'" << std::endl;
235 
236  Repository repo;
237 
239 
240  if ( data.type == TrType::Url ) {
241  try {
242  MIL << "Load from Url '" << data.path << "'" << std::endl;
243 
244  RepoInfo nrepo;
245  nrepo.setAlias ( data.alias );
246  nrepo.setName ( data.alias );
247  nrepo.setEnabled ( true );
248  nrepo.setAutorefresh( false );
249  nrepo.setPriority ( data.priority );
250  nrepo.addBaseUrl ( Url(data.path) );
251 
252  manager.refreshMetadata( nrepo );
253  manager.buildCache( nrepo );
254  manager.loadFromCache( nrepo );
255  }
256  catch ( Exception & excpt_r ) {
257  ZYPP_CAUGHT (excpt_r);
258  ERR << "Couldn't load packages from Url '" << data.path << "'" << std::endl;
259  return false;
260  }
261  }
262  else {
263  try {
264  MIL << "Load from File '" << pathname << "'" << std::endl;
265  zypp::Repository satRepo;
266 
267  if ( data.alias == "@System" ) {
269  } else {
270  satRepo = zypp::sat::Pool::instance().reposInsert( data.alias );
271  }
272 
273  RepoInfo nrepo;
274 
275  nrepo.setAlias ( data.alias );
276  nrepo.setName ( data.alias );
277  nrepo.setEnabled ( true );
278  nrepo.setAutorefresh( false );
279  nrepo.setPriority ( data.priority );
280  nrepo.addBaseUrl ( pathname.asUrl() );
281 
282  satRepo.setInfo (nrepo);
283  if ( data.type == TrType::Helix )
284  satRepo.addHelix( pathname );
285  else
286  satRepo.addTesttags( pathname );
287  MIL << "Loaded " << satRepo.solvablesSize() << " resolvables from " << ( data.path.empty()?pathname.asString():data.path) << "." << std::endl;
288  }
289  catch ( Exception & excpt_r ) {
290  ZYPP_CAUGHT (excpt_r);
291  ERR << "Couldn't load packages from XML file '" << data.path << "'" << std::endl;
292  return false;
293  }
294  }
295  return true;
296  }
297 
298 
299 
300 }
zypp::sat::Pool::instance
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
zypp::RepoManager::buildCache
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
Definition: RepoManager.cc:2584
zypp::misc::testcase::LoadTestcase::Type
Type
Definition: LoadTestcase.h:116
zypp::misc::testcase::LoadTestcase::trialInfo
const std::vector< TestcaseTrial > & trialInfo() const
Definition: LoadTestcase.cc:180
LogControl.h
yamltest::detail::parseSetup
bool parseSetup(const YAML::Node &setup, zypp::misc::testcase::TestcaseSetup &target, std::string *err)
Definition: YamlTestcaseHelpers.h:24
zypp::misc::testcase::TestcaseTrial
Definition: LoadTestcase.h:98
PathInfo.h
zypp::RepoManager::refreshMetadata
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
Definition: RepoManager.cc:2572
zypp::misc::testcase::RepoData::type
TestcaseRepoType type
Definition: LoadTestcase.h:42
zypp::Exception
Base class for Exception.
Definition: Exception.h:146
zypp::RepoInfo
What is known about a repository.
Definition: RepoInfo.h:72
zypp::repo::RepoInfoBase::setAutorefresh
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:91
zypp::xmlout::node
std::ostream & node(std::ostream &out_r, const std::string &name_r, Node::Attr attr_r)
Definition: Xml.h:203
zypp::repo::RepoInfoBase::setName
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:97
zypp::misc::testcase::TestcaseSetup::loadRepo
static bool loadRepo(zypp::RepoManager &manager, const TestcaseSetup &setup, const RepoData &data)
Definition: LoadTestcase.cc:231
MIL
#define MIL
Definition: Logger.h:79
zypp::misc::testcase::LoadTestcase::Impl::_trials
std::vector< TestcaseTrial > _trials
Definition: LoadTestcase.cc:31
zypp::misc::testcase::LoadTestcase::Impl
Definition: LoadTestcase.cc:29
zypp::misc::testcase::LoadTestcase::setupInfo
const TestcaseSetup & setupInfo() const
Definition: LoadTestcase.cc:175
LoadTestcase.h
zypp::misc::testcase::TestcaseTrial::Node::properties
std::map< std::string, std::string > properties
Definition: LoadTestcase.h:105
zypp::Repository::addHelix
void addHelix(const Pathname &file_r)
Load Solvables from a helix-file.
Definition: Repository.cc:339
zypp::RepoManager::loadFromCache
void loadFromCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Load resolvables into the pool.
Definition: RepoManager.cc:2593
zypp::RepoInfo::setPriority
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:400
YamlTestcaseHelpers.h
zypp::misc::testcase::TestcaseSetup::globalPath
Pathname globalPath
Definition: LoadTestcase.h:64
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::misc::testcase::LoadTestcase::LoadTestcase
LoadTestcase()
Definition: LoadTestcase.cc:137
zypp::misc::testcase::TestcaseSetup::applySetup
bool applySetup(zypp::RepoManager &manager) const
Definition: LoadTestcase.cc:192
zypp::misc::testcase::LoadTestcase::Impl::_setup
TestcaseSetup _setup
Definition: LoadTestcase.cc:30
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
zypp::misc::testcase::LoadTestcase::Yaml
@ Yaml
Definition: LoadTestcase.h:119
zypp::misc::testcase::LoadTestcase::testcaseTypeAt
static Type testcaseTypeAt(const zypp::Pathname &path)
Definition: LoadTestcase.cc:165
zypp::ZConfig::setSystemArchitecture
void setSystemArchitecture(const Arch &arch_r)
Override the zypp system architecture.
Definition: ZConfig.cc:852
zypp::misc::testcase::TestcaseSetup
Definition: LoadTestcase.h:55
zypp::Repository::solvablesSize
size_type solvablesSize() const
Number of solvables in Repository.
Definition: Repository.cc:225
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp::RepoInfo::addBaseUrl
void addBaseUrl(const Url &url)
Add a base url.
Definition: RepoInfo.cc:629
zypp::misc::testcase::LoadTestcase::None
@ None
Definition: LoadTestcase.h:117
zypp::misc::testcase::LoadTestcase::~LoadTestcase
~LoadTestcase()
Definition: LoadTestcase.cc:140
SystemCheck.h
Pool.h
zypp::misc::testcase::LoadTestcase::Impl::loadHelix
bool loadHelix(const Pathname &filename, std::string *err)
Definition: LoadTestcase.cc:39
zypp::misc::testcase::RepoData::path
std::string path
Definition: LoadTestcase.h:45
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209
zypp::misc::testcase::RepoData::alias
std::string alias
Definition: LoadTestcase.h:43
zypp::misc::testcase::TestcaseTrial::Node::getProp
const std::string & getProp(const std::string &name, const std::string &def=std::string()) const
Definition: LoadTestcase.cc:185
zypp::repo::RepoInfoBase::setEnabled
void setEnabled(bool enabled)
enable or disable the repository
Definition: RepoInfoBase.cc:88
helix::detail::XmlNode
Definition: HelixHelpers.h:37
zypp::misc::testcase::LoadTestcase::_pimpl
std::unique_ptr< Impl > _pimpl
Definition: LoadTestcase.h:132
zypp::misc::testcase::RepoData
Definition: LoadTestcase.h:41
zypp::misc::testcase::helixControlFile
static const std::string helixControlFile
Definition: LoadTestcase.cc:26
zypp::misc::testcase::TestcaseRepoType
TestcaseRepoType
Definition: LoadTestcase.h:35
zypp::Repository::addTesttags
void addTesttags(const Pathname &file_r)
Load Solvables from a libsolv testtags-file.
Definition: Repository.cc:361
helix::detail::parseSetup
bool parseSetup(const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &target, std::string *err)
Definition: HelixHelpers.h:137
zypp::misc::testcase::TestcaseTrial::Node::name
std::string name
Definition: LoadTestcase.h:100
zypp::misc::testcase::LoadTestcase::Helix
@ Helix
Definition: LoadTestcase.h:118
zypp::misc::testcase::LoadTestcase::Impl::loadYaml
bool loadYaml(const Pathname &path, std::string *err)
Definition: LoadTestcase.cc:89
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
ERR
#define ERR
Definition: Logger.h:81
Repository.h
DBG
#define DBG
Definition: Logger.h:78
helix::detail::parseTrial
bool parseTrial(const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *)
Definition: HelixHelpers.h:301
HelixHelpers.h
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:94
zypp::misc::testcase::LoadTestcase::loadTestcaseAt
bool loadTestcaseAt(const zypp::Pathname &path, std::string *err)
Definition: LoadTestcase.cc:143
zypp::sat::Pool::reposInsert
Repository reposInsert(const std::string &alias_r)
Return a Repository named alias_r.
Definition: Pool.cc:143
zypp::Repository::setInfo
void setInfo(const RepoInfo &info_r)
Set RepoInfo for this repository.
Definition: Repository.cc:279
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
yamltest::detail::parseTrial
bool parseTrial(const YAML::Node &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *err)
Definition: YamlTestcaseHelpers.h:304
zypp::Url
Url manipulation class.
Definition: Url.h:88
zypp::Repository
Definition: Repository.h:40
zypp::misc::testcase::RepoData::priority
uint priority
Definition: LoadTestcase.h:44
RepoManager.h
zypp::RepoManager
creates and provides information about known sources.
Definition: RepoManager.h:106
zypp::sat::Pool::systemRepo
Repository systemRepo()
Return the system repository, create it if missing.
Definition: Pool.cc:178
zypp::misc::testcase::yamlControlFile
static const std::string yamlControlFile
Definition: LoadTestcase.cc:27
zypp::misc::testcase
Definition: LoadTestcase.cc:24
zypp::filesystem::Pathname::asUrl
Url asUrl(const std::string &scheme_r) const
Url representation using scheme_r schema .
Definition: Pathname.cc:171