libzypp 17.37.10

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
18 namespace zypp::misc::testcase {
19
20 static const std::string helixControlFile = "solver-test.xml";
21 static const std::string yamlControlFile = "zypp-control.yaml";
22
23 struct LoadTestcase::Impl {
24 TestcaseSetup _setup;
25 TestcaseTrials _trials;
26
27 bool loadHelix (const Pathname &filename, std::string *err);
28
29 bool loadYaml ( const Pathname &path, std::string *err);
30 };
31
32
33 struct TestcaseTrial::Impl
34 {
35 std::vector<Node> nodes;
36 Impl *clone() const { return new Impl(*this); }
37 };
38
39 struct TestcaseTrial::Node::Impl
40 {
41 std::string name;
42 std::string value;
43 std::map<std::string, std::string> properties;
44 std::vector<std::shared_ptr<Node>> children;
45 Impl *clone() const { return new Impl(*this); }
46 };
47
48 TestcaseTrial::TestcaseTrial() : _pimpl ( new Impl() )
49 { }
50
51 TestcaseTrial::~TestcaseTrial()
52 { }
53
54 const std::vector<TestcaseTrial::Node> &TestcaseTrial::nodes() const
55 { return _pimpl->nodes; }
56
57 std::vector<TestcaseTrial::Node> &TestcaseTrial::nodes()
58 { return _pimpl->nodes; }
59
60 TestcaseTrial::Node::Node() : _pimpl ( new Impl() )
61 { }
62
63 TestcaseTrial::Node::~Node()
64 { }
65
66 const std::string &TestcaseTrial::Node::name() const
67 { return _pimpl->name; }
68
69 std::string &TestcaseTrial::Node::name()
70 { return _pimpl->name; }
71
72 const std::string &TestcaseTrial::Node::value() const
73 { return _pimpl->value; }
74
75 std::string &TestcaseTrial::Node::value()
76 { return _pimpl->value; }
77
78 const std::string &TestcaseTrial::Node::getProp( const std::string &name, const std::string &def ) const
79 {
80 auto it { _pimpl->properties.find( name ) };
81 return it == _pimpl->properties.end() ? def : it->second;
82 }
83
84 const std::map<std::string, std::string> &TestcaseTrial::Node::properties() const
85 { return _pimpl->properties; }
86
87 std::map<std::string, std::string> &TestcaseTrial::Node::properties()
88 { return _pimpl->properties; }
89
90 const std::vector<std::shared_ptr<TestcaseTrial::Node> > &TestcaseTrial::Node::children() const
91 { return _pimpl->children; }
92
93 std::vector<std::shared_ptr<TestcaseTrial::Node> > &TestcaseTrial::Node::children()
94 { return _pimpl->children; }
95
96 bool LoadTestcase::Impl::loadHelix(const zypp::filesystem::Pathname &filename, std::string *err)
97 {
98 xmlDocPtr xml_doc = xmlParseFile ( filename.c_str() );
99 if (xml_doc == NULL) {
100 if ( err ) *err = (str::Str() << "Can't parse test file '" << filename << "'");
101 return false;
102 }
103
104
105 auto root = helix::detail::XmlNode (xmlDocGetRootElement (xml_doc));
106
107 DBG << "Parsing file '" << filename << "'" << std::endl;
108
109 if (!root.equals("test")) {
110 if ( err ) *err = (str::Str() << "Node not 'test' in parse_xml_test():" << root.name() << "'");
111 return false;
112 }
113
114 bool setupDone = false;
115 auto node = root.children();
116 while (node) {
117 if (node->type() == XML_ELEMENT_NODE) {
118 if (node->equals( "setup" )) {
119 if ( setupDone ) {
120 if ( err ) *err = "Multiple setup tags found, this is not supported";
121 return false;
122 }
123 setupDone = true;
124 if ( !helix::detail::parseSetup( *node, _setup, err ) )
125 return false;
126
127 } else if (node->equals( "trial" )) {
128 if ( !setupDone ) {
129 if ( err ) *err = "Any trials must be preceded by the setup!";
130 return false;
131 }
132 TestcaseTrial trial;
133 if ( !helix::detail::parseTrial( *node, trial, err ) )
134 return false;
135 _trials.push_back( trial );
136 } else {
137 ERR << "Unknown tag '" << node->name() << "' in test" << std::endl;
138 }
139 }
140 node = ( node->next() );
141 }
142 xmlFreeDoc (xml_doc);
143 return true;
144 }
145
146 bool LoadTestcase::Impl::loadYaml(const zypp::filesystem::Pathname &path, std::string *err)
147 {
148 DBG << "Parsing file '" << path << "'" << std::endl;
149
150 const auto makeError = [&]( const std::string_view &errStr ){
151 if ( err ) *err = errStr;
152 return false;
153 };
154
155 YAML::Node control;
156 try {
157 control = YAML::LoadFile( path.asString() );
158
159 if ( control.Type() != YAML::NodeType::Map )
160 return makeError("Root node must be of type Map.");
161
162 const auto &setup = control["setup"];
163 if ( !setup )
164 return makeError("The 'setup' section is required.");
165
166 if ( !yamltest::detail::parseSetup( setup, _setup, err) )
167 return false;
168
169 const auto &trials = control["trials"];
170 if ( !trials )
171 return makeError("The 'trials' section is required.");
172 if ( trials.Type() != YAML::NodeType::Sequence )
173 return makeError("The 'trials' section must be of type Sequence.");
174
175 for ( const auto &trial : trials ) {
176 zypp::misc::testcase::TestcaseTrial t;
177 if ( !trial["trial"] )
178 return makeError("Every element in the trials sequence needs to have the 'trial' key.");
179
180 if ( !yamltest::detail::parseTrial( trial["trial"], t, _setup.data().globalPath, err) )
181 return false;
182 _trials.push_back( t );
183 }
184 } catch ( YAML::Exception &e ) {
185 if ( err ) *err = e.what();
186 return false;
187 } catch ( ... ) {
188 if ( err ) *err = "Unknown error when parsing the control file";
189 return false;
190 }
191 return true;
192 }
193
194 LoadTestcase::LoadTestcase() : _pimpl( new Impl() )
195 { }
196
197 LoadTestcase::~LoadTestcase()
198 { }
199
200 bool LoadTestcase::loadTestcaseAt(const zypp::filesystem::Pathname &path, std::string *err)
201 {
202 const auto t = testcaseTypeAt( path );
203 if ( t == LoadTestcase::None ) {
204 if ( err ) *err = "Unsopported or no testcase in directory";
205 return false;
206 }
207
208 // reset everything
209 _pimpl.reset( new Impl() );
210 _pimpl->_setup.data().globalPath = path;
211
212 switch (t) {
213 case LoadTestcase::Helix:
214 return _pimpl->loadHelix( path / helixControlFile, err );
215 case LoadTestcase::Yaml:
216 return _pimpl->loadYaml( path / yamlControlFile, err );
217 default:
218 return false;
219 }
220 }
221
222 LoadTestcase::Type LoadTestcase::testcaseTypeAt(const zypp::filesystem::Pathname &path)
223 {
224 if ( filesystem::PathInfo( path / helixControlFile ).isFile() ) {
225 return LoadTestcase::Helix;
226 } else if ( filesystem::PathInfo( path / yamlControlFile ).isFile() ) {
227 return LoadTestcase::Yaml;
228 }
229 return LoadTestcase::None;
230 }
231
232 const TestcaseSetup &LoadTestcase::setupInfo() const
233 {
234 return _pimpl->_setup;
235 }
236
237 const LoadTestcase::TestcaseTrials &LoadTestcase::trialInfo() const
238 {
239 return _pimpl->_trials;
240 }
241
242}
HelixHelpers.h
LoadTestcase.h
YamlTestcaseHelpers.h
helix::detail::XmlNode
Definition HelixHelpers.h:38
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:112
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:93
zypp::misc::testcase::LoadTestcase::setupInfo
const TestcaseSetup & setupInfo() const
Definition LoadTestcase.cc:232
zypp::misc::testcase::LoadTestcase::LoadTestcase
LoadTestcase()
Definition LoadTestcase.cc:194
zypp::misc::testcase::LoadTestcase::~LoadTestcase
~LoadTestcase()
Definition LoadTestcase.cc:197
zypp::misc::testcase::LoadTestcase::trialInfo
const TestcaseTrials & trialInfo() const
Definition LoadTestcase.cc:237
zypp::misc::testcase::LoadTestcase::_pimpl
std::unique_ptr< Impl > _pimpl
Definition LoadTestcase.h:81
zypp::misc::testcase::LoadTestcase::testcaseTypeAt
static Type testcaseTypeAt(const zypp::Pathname &path)
Definition LoadTestcase.cc:222
zypp::misc::testcase::LoadTestcase::loadTestcaseAt
bool loadTestcaseAt(const zypp::Pathname &path, std::string *err)
Definition LoadTestcase.cc:200
zypp::misc::testcase::LoadTestcase::TestcaseTrials
std::vector< TestcaseTrial > TestcaseTrials
Definition LoadTestcase.h:63
zypp::misc::testcase::LoadTestcase::Type
Type
Definition LoadTestcase.h:65
zypp::misc::testcase::LoadTestcase::Helix
@ Helix
Definition LoadTestcase.h:67
zypp::misc::testcase::LoadTestcase::Yaml
@ Yaml
Definition LoadTestcase.h:68
zypp::misc::testcase::LoadTestcase::None
@ None
Definition LoadTestcase.h:66
zypp::misc::testcase::TestcaseSetup
Definition TestcaseSetup.h:79
helix::detail::parseTrial
bool parseTrial(const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *)
Definition HelixHelpers.h:303
helix::detail::parseSetup
bool parseSetup(const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &t, std::string *err)
Definition HelixHelpers.h:138
yamltest::detail::parseSetup
bool parseSetup(const YAML::Node &setup, zypp::misc::testcase::TestcaseSetup &t, std::string *err)
Definition YamlTestcaseHelpers.h:25
yamltest::detail::parseTrial
bool parseTrial(const YAML::Node &trial, zypp::misc::testcase::TestcaseTrial &target, const zypp::Pathname &testcaseDir, std::string *err)
Definition YamlTestcaseHelpers.h:324
zypp::misc::testcase
Definition LoadTestcase.cc:18
zypp::misc::testcase::yamlControlFile
static const std::string yamlControlFile
Definition LoadTestcase.cc:21
zypp::misc::testcase::helixControlFile
static const std::string helixControlFile
Definition LoadTestcase.cc:20
zypp::misc::testcase::LoadTestcase::Impl
Definition LoadTestcase.cc:23
zypp::misc::testcase::LoadTestcase::Impl::loadHelix
bool loadHelix(const Pathname &filename, std::string *err)
Definition LoadTestcase.cc:96
zypp::misc::testcase::LoadTestcase::Impl::loadYaml
bool loadYaml(const Pathname &path, std::string *err)
Definition LoadTestcase.cc:146
zypp::misc::testcase::LoadTestcase::Impl::_trials
TestcaseTrials _trials
Definition LoadTestcase.cc:25
zypp::misc::testcase::LoadTestcase::Impl::_setup
TestcaseSetup _setup
Definition LoadTestcase.cc:24
zypp::misc::testcase::TestcaseTrial::Impl
Definition LoadTestcase.cc:34
zypp::misc::testcase::TestcaseTrial::Impl::clone
Impl * clone() const
Definition LoadTestcase.cc:36
zypp::misc::testcase::TestcaseTrial::Impl::nodes
std::vector< Node > nodes
Definition LoadTestcase.cc:35
zypp::misc::testcase::TestcaseTrial::Node::Impl
Definition LoadTestcase.cc:40
zypp::misc::testcase::TestcaseTrial::Node::Impl::clone
Impl * clone() const
Definition LoadTestcase.cc:45
zypp::misc::testcase::TestcaseTrial::Node::Impl::properties
std::map< std::string, std::string > properties
Definition LoadTestcase.cc:43
zypp::misc::testcase::TestcaseTrial::Node::Impl::name
std::string name
Definition LoadTestcase.cc:41
zypp::misc::testcase::TestcaseTrial::Node::Impl::children
std::vector< std::shared_ptr< Node > > children
Definition LoadTestcase.cc:44
zypp::misc::testcase::TestcaseTrial::Node::Impl::value
std::string value
Definition LoadTestcase.cc:42
zypp::misc::testcase::TestcaseTrial::Node::children
const std::vector< std::shared_ptr< Node > > & children() const
Definition LoadTestcase.cc:90
zypp::misc::testcase::TestcaseTrial::Node::Node
Node()
Definition LoadTestcase.cc:60
zypp::misc::testcase::TestcaseTrial::Node::name
const std::string & name() const
Definition LoadTestcase.cc:66
zypp::misc::testcase::TestcaseTrial::Node::getProp
const std::string & getProp(const std::string &name, const std::string &def=std::string()) const
Definition LoadTestcase.cc:78
zypp::misc::testcase::TestcaseTrial::Node::properties
const std::map< std::string, std::string > & properties() const
Definition LoadTestcase.cc:84
zypp::misc::testcase::TestcaseTrial::Node::_pimpl
RWCOW_pointer< Impl > _pimpl
Definition LoadTestcase.h:46
zypp::misc::testcase::TestcaseTrial::Node::value
const std::string & value() const
Definition LoadTestcase.cc:72
zypp::misc::testcase::TestcaseTrial::Node::~Node
~Node()
Definition LoadTestcase.cc:63
zypp::misc::testcase::TestcaseTrial
Definition LoadTestcase.h:28
zypp::misc::testcase::TestcaseTrial::nodes
const std::vector< Node > & nodes() const
Definition LoadTestcase.cc:54
zypp::misc::testcase::TestcaseTrial::_pimpl
RWCOW_pointer< Impl > _pimpl
Definition LoadTestcase.h:56
zypp::misc::testcase::TestcaseTrial::~TestcaseTrial
~TestcaseTrial()
Definition LoadTestcase.cc:51
zypp::misc::testcase::TestcaseTrial::TestcaseTrial
TestcaseTrial()
Definition LoadTestcase.cc:48
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
DBG
#define DBG
Definition Logger.h:99
ERR
#define ERR
Definition Logger.h:102
PathInfo.h
LogControl.h