38#include <boost/algorithm/string.hpp>
39#include <boost/asio/ip/host_name.hpp>
40#include <boost/core/ignore_unused.hpp>
41#include <boost/lexical_cast.hpp>
69 if (
m_type !=
"EXECUTIONTIME")
75 TiXmlElement *regex = metric->FirstChildElement(
"regex");
79 ASSERTL0(regex->GetText(),
"Failed to read regex element.");
85 m_regex = R
"(^.*Total Computation Time\s*=\s*(\d+\.?\d*).*)";
98 TiXmlElement *value = metric->FirstChildElement(
"value");
101 bool hostnameMatch =
false;
104 ASSERTL0(value->Attribute(
"tolerance"),
105 "Missing tolerance in execution time metric.");
106 ASSERTL0(value->Attribute(
"hostname"),
107 "Missing hostname in execution time metric.");
109 "Missing value in execution time metric.");
112 if (value->Attribute(
"hostname") == boost::asio::ip::host_name())
115 val.
m_value = value->GetText();
116 val.
m_tolerance = atof(value->Attribute(
"tolerance"));
119 hostnameMatch =
true;
125 value = value->NextSiblingElement(
"value");
131 cerr <<
"WARNING: No execution time value provided for host "
132 << boost::asio::ip::host_name() <<
". Skipping metric." << endl;
156 boost::ignore_unused(pStdout, pStderr);
166 vector<double> times;
167 bool matched =
false;
170 while (getline(is, line))
173 if (std::regex_match(line, matches,
m_regex))
176 if (matches.size() == 1)
178 cerr <<
"No test sections in regex!" << endl;
183 for (
int i = 1; i < matches.size(); ++i)
186 string match(matches[i].first, matches[i].second);
190 val = boost::lexical_cast<double>(match);
193 times.push_back(val);
196 catch (boost::bad_lexical_cast &e)
198 cerr <<
"Could not convert match " << match <<
" to double"
209 cerr <<
"No execution times were found in the test output. Consider "
210 "providing a custom regex for this test metric."
216 double minTime = times[0];
217 for (
unsigned int i = 0; i < times.size(); ++i)
219 minTime = (times[i] < minTime) ? times[i] : minTime;
226 cerr <<
"Minimum execution time for host "
227 << boost::asio::ip::host_name() <<
": " << minTime << endl;
232 "No test conditions defined for execution time.");
235 if (fabs(minTime - boost::lexical_cast<double>(
m_match.
m_value)) >
240 cerr <<
"Failed tolerance match." << endl;
241 cerr <<
" Expected min execution time: " <<
m_match.
m_value <<
" +/- "
243 cerr <<
" Actual min: " << minTime << endl;
245 for (
unsigned int i = 0; i < times.size(); ++i)
247 cerr <<
" Run " << i <<
": " << times[i] << endl;
268 boost::ignore_unused(pStderr);
277 vector<double> sampleTimes;
278 bool matched =
false;
281 while (getline(is, line))
284 if (std::regex_match(line, matches,
m_regex))
287 ASSERTL0(matches.size() != 1,
"No test sections in regex!");
290 for (
int i = 1; i < matches.size(); ++i)
293 string match(matches[i].first, matches[i].second);
297 val = boost::lexical_cast<double>(match);
299 sampleTimes.push_back(val);
302 catch (boost::bad_lexical_cast &e)
304 cerr <<
"Could not convert match " << match <<
" to double"
318 double minTime = sampleTimes[0];
319 for (
unsigned int i = 0; i < sampleTimes.size(); ++i)
321 minTime = (sampleTimes[i] < minTime ? sampleTimes[i] : minTime);
324 okValue.
m_value = to_string(minTime);
329 cerr <<
"No execution times were found in the test output. Value set "
335 if (
m_type ==
"EXECUTIONTIME")
338 while (
m_metric->FirstChildElement(
"value"))
342 "Couldn't remove value from metric!");
345 TiXmlElement *val =
new TiXmlElement(
"value");
347 val->SetAttribute(
"tolerance",
349 val->SetAttribute(
"hostname", boost::asio::ip::host_name());
#define ASSERTL0(condition, msg)
std::regex m_regex
Regex used to match an execution time in a test output.
bool v_Test(std::istream &pStdout, std::istream &pStderr) override
Test output against a regular expression and its expected value.
bool m_useStderr
If true, use stderr for testing/generation instead of stdout.
void v_Generate(std::istream &pStdout, std::istream &pStderr) override
Generate an accepted execution time value using a test output or error stream.
static MetricSharedPtr create(TiXmlElement *metric, bool generate)
MetricExecutionTime(TiXmlElement *metric, bool generate)
Construct a new MetricExecutionTime object.
MetricExecutionTimeFieldValue m_match
Stores each execution time found in the test output.
std::string RegisterCreatorFunction(std::string key, CreatorFunction func)
Base class for all metrics. Metric represents a test metric that can be used to evaluate the function...
TiXmlElement * m_metric
Pointer to XML structure containing metric definition.
bool m_average
Indicates whether a metric supports averaging results from multiple runs.
std::string m_type
Stores the type of this metric (uppercase).
bool m_generate
Determines whether to generate this metric or not.
bool EmptyString(const char *s)
Check to see whether the given string s is empty (or null).
MetricFactory & GetMetricFactory()
Data structure for an execution time field value.
double m_tolerance
The tolerance to use for checking the execution time. Defaults to 5.0.
std::string m_value
The value to match. Defaults to empty string.
bool m_skip
Indicates whether the metric should be skipped. Defaults to false.