libzypp: zypp/misc/LoadTestcase.cc Source File

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