Nektar++
Loading...
Searching...
No Matches
TestData.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestData.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Encapsulation of test XML file.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <boost/algorithm/string.hpp>
36#include <boost/core/ignore_unused.hpp>
37#include <boost/lexical_cast.hpp>
38
39#include <TestData.h>
40#include <TestException.hpp>
41
42using namespace std;
43
44namespace Nektar
45{
46
47/**
48 * @brief TestData constructor.
49 *
50 * The class is constructed with the path to the test XML file and a
51 * `po::variables_map` object containing the command-line options passed to the
52 * program.
53 *
54 * @param pFilename
55 * @param pVm
56 */
57
58TestData::TestData(TiXmlElement *pElmt, po::variables_map &pVm)
59 : m_cmdoptions(pVm)
60{
61 Parse(pElmt);
62}
63
65{
66 boost::ignore_unused(pSrc);
67}
68
69/// Returns the description of a test.
70const std::string &TestData::GetDescription() const
71{
72 return m_description;
73}
74
75const Command &TestData::GetCommand(unsigned int pId) const
76{
77 ASSERTL0(pId < m_commands.size(),
78 "Command ID '" + std::to_string(pId) + "' not found");
79 return m_commands[pId];
80}
81
82unsigned int TestData::GetNumCommands() const
83{
84 return m_commands.size();
85}
86
87/// Returns the type of metric to be collected for a given metric ID.
88std::string TestData::GetMetricType(unsigned int pId) const
89{
90 ASSERTL0(pId < m_metrics.size(), "Metric ID out of range.");
91
92 // read the property name
93 ASSERTL0(m_metrics[pId]->Attribute("type"),
94 "Missing 'type' attribute in metric " +
95 boost::lexical_cast<string>(pId) + ").");
96 return boost::to_upper_copy(string(m_metrics[pId]->Attribute("type")));
97}
98
99/// Returns the number of metrics to be collected for the test.
100unsigned int TestData::GetNumMetrics() const
101{
102 return m_metrics.size();
103}
104
105/// Returns a pointer to the `TiXmlElement` object representing the metric for a
106/// given metric ID.
107TiXmlElement *TestData::GetMetric(unsigned int pId)
108{
109 ASSERTL0(pId < m_metrics.size(), "Metric index out of range.");
110 return m_metrics[pId];
111}
112
113/// Returns the ID of the metric for a given metric ID.
114unsigned int TestData::GetMetricId(unsigned int pId)
115{
116 ASSERTL0(pId < m_metrics.size(), "Metric index out of range.");
117 const char *id = m_metrics[pId]->Attribute("id");
118 ASSERTL0(id, "No ID found for metric!");
119 return boost::lexical_cast<unsigned int>(id);
120}
121
123{
124 ASSERTL0(pId < m_files.size(), "File index out of range.");
125 return m_files[pId];
126}
127
128/// Returns the number of dependent files required for the test.
130{
131 return m_files.size();
132}
133
134/// Returns the number of runs to be performed for the test.
135unsigned int TestData::GetNumRuns() const
136{
137 return m_runs;
138}
139
140Command TestData::ParseCommand(TiXmlElement *elmt) const
141{
142 Command cmd;
143 TiXmlElement *tmp;
144
145 cmd.m_pythonTest = false;
146
147 std::string commandType = "none";
148 if (elmt->Attribute("type"))
149 {
150 commandType = elmt->Attribute("type");
151
152 if (commandType == "none")
153 {
154 cmd.m_commandType = eNone;
155 }
156 else if (commandType == "parallel")
157 {
159 }
160 else if (commandType == "sequential")
161 {
163 }
164 }
165
166 // Parse executable tag. Do not enforce a check because this might be
167 // overridden on the command line.
168 if (elmt->FirstChildElement("executable"))
169 {
170 tmp = elmt->FirstChildElement("executable");
171 cmd.m_executable = fs::path(tmp->GetText());
172 // Test to see if this test requires Python
173 std::string needsPython;
174 tmp->QueryStringAttribute("python", &needsPython);
175 cmd.m_pythonTest = needsPython == "true";
176
177#if defined(RELWITHDEBINFO)
178 cmd.m_executable += cmd.m_pythonTest ? "" : "-rg";
179#elif !defined(NDEBUG)
180 cmd.m_executable += cmd.m_pythonTest ? "" : "-g";
181#endif
182 }
183
184 // Find associated parameters.
185 tmp = elmt->FirstChildElement("parameters");
186 ASSERTL0(tmp, "Cannot find 'parameters' for test.");
187 if (tmp->GetText())
188 {
189 cmd.m_parameters = string(tmp->GetText());
190 }
191
192 // Find parallel processes tah.
193 tmp = elmt->FirstChildElement("processes");
194 if (tmp)
195 {
196 cmd.m_processes = atoi(tmp->GetText());
197 }
198 else
199 {
200 cmd.m_processes = 1;
201 }
202
203 return cmd;
204}
205
206/// Parse the test file and populate member variables for the test.
207void TestData::Parse(TiXmlElement *testElement)
208{
209 TiXmlElement *tmp, *metrics, *files;
210
211 // Find the desired number of test runs
212 unsigned int runs = 1;
213 testElement->QueryUnsignedAttribute("runs", &runs);
214 ASSERTL0(runs > 0, "Number of runs must be greater than zero.");
215 m_runs = runs;
216
217 // Find description tag.
218 tmp = testElement->FirstChildElement("description");
219 ASSERTL0(tmp, "Cannot find 'description' for test.");
220 m_description = string(tmp->GetText());
221
222 // Find command(s) to run.
223 if (m_cmdoptions.count("executable"))
224 {
225 m_commands.push_back(ParseCommand(testElement));
226 m_commands.back().m_executable =
227 fs::path(m_cmdoptions["executable"].as<std::string>());
228 }
229 else if (testElement->FirstChildElement("executable"))
230 {
231 m_commands.push_back(ParseCommand(testElement));
232 }
233 else if ((tmp = testElement->FirstChildElement("segment")))
234 {
235 ASSERTL0(m_cmdoptions.count("executable") == 0,
236 "Test files defining more than one command in segment "
237 "blocks cannot use --executable.");
238
239 while (tmp)
240 {
241 m_commands.push_back(ParseCommand(tmp));
242 tmp = tmp->NextSiblingElement("segment");
243 }
244
245 for (int i = 1; i < m_commands.size(); ++i)
246 {
247 ASSERTL0(m_commands[i].m_commandType == m_commands[0].m_commandType,
248 "All segment commands should be of the same type.");
249 }
250 }
251
252 ASSERTL0(m_commands.size() > 0,
253 "No executable / command segments specified for test.");
254
255 // Extract metric tags
256 metrics = testElement->FirstChildElement("metrics");
257 ASSERTL0(metrics, "No metrics defined for test.");
258
259 tmp = metrics->FirstChildElement("metric");
260 while (tmp)
261 {
262 m_metrics.push_back(tmp);
263 tmp = tmp->NextSiblingElement("metric");
264 }
265
266 // Extract list of dependent files
267 files = testElement->FirstChildElement("files");
268 if (files)
269 {
270 tmp = files->FirstChildElement("file");
271 while (tmp)
272 {
274 f.m_filename = string(tmp->GetText());
275 if (tmp->Attribute("description"))
276 {
277 f.m_description = string(tmp->Attribute("description"));
278 }
279 m_files.push_back(f);
280 tmp = tmp->NextSiblingElement("file");
281 }
282 }
283}
284} // namespace Nektar
#define ASSERTL0(condition, msg)
The TestData class is responsible for parsing a test XML file and storing the data.
Definition TestData.h:79
std::vector< TiXmlElement * > m_metrics
Definition TestData.h:102
DependentFile GetDependentFile(unsigned int pId) const
Definition TestData.cpp:122
unsigned int GetMetricId(unsigned int pId)
Returns the ID of the metric for a given metric ID.
Definition TestData.cpp:114
std::vector< Command > m_commands
Definition TestData.h:101
unsigned int GetNumDependentFiles() const
Returns the number of dependent files required for the test.
Definition TestData.cpp:129
TestData(TiXmlElement *pElmt, po::variables_map &pVm)
TestData constructor.
Definition TestData.cpp:58
unsigned int GetNumMetrics() const
Returns the number of metrics to be collected for the test.
Definition TestData.cpp:100
unsigned int m_runs
The number of times to run the test.
Definition TestData.h:105
void Parse(TiXmlElement *pElmt)
Parse the test file and populate member variables for the test.
Definition TestData.cpp:207
Command ParseCommand(TiXmlElement *pElmt) const
Definition TestData.cpp:140
unsigned int GetNumRuns() const
Returns the number of runs to be performed for the test.
Definition TestData.cpp:135
TiXmlElement * GetMetric(unsigned int pId)
Returns a pointer to the TiXmlElement object representing the metric for a given metric ID.
Definition TestData.cpp:107
unsigned int GetNumCommands() const
Definition TestData.cpp:82
const std::string & GetDescription() const
Returns the description of a test.
Definition TestData.cpp:70
std::string GetMetricType(unsigned int pId) const
Returns the type of metric to be collected for a given metric ID.
Definition TestData.cpp:88
po::variables_map m_cmdoptions
Definition TestData.h:99
const Command & GetCommand(unsigned int pId) const
Definition TestData.cpp:75
std::vector< DependentFile > m_files
Definition TestData.h:103
std::string m_description
Definition TestData.h:100
@ eSequential
Definition TestData.h:60
@ eParallel
Definition TestData.h:61
@ eNone
Definition TestData.h:59
STL namespace.
bool m_pythonTest
Definition TestData.h:69
fs::path m_executable
Definition TestData.h:66
std::string m_parameters
Definition TestData.h:67
CommandType m_commandType
Definition TestData.h:70
unsigned int m_processes
Definition TestData.h:68
std::string m_filename
Definition TestData.h:54
std::string m_description
Definition TestData.h:53