Commit 180719d0 by Joao Paulo Magalhaes

Rename ResultsCheckerEntry to Results.

parent f3b82a8e
...@@ -62,22 +62,24 @@ void RunOutputTests(int argc, char* argv[]); ...@@ -62,22 +62,24 @@ void RunOutputTests(int argc, char* argv[]);
// ------------------------- Results checking ------------------------------ // // ------------------------- Results checking ------------------------------ //
// ========================================================================= // // ========================================================================= //
struct ResultsCheckerEntry; struct Results;
typedef std::function< void(ResultsCheckerEntry const&) > ResultsCheckFn; typedef std::function< void(Results const&) > ResultsCheckFn;
// Add a function to check the (CSV) results of a benchmark. These // Add a function to check the (CSV) results of a benchmark. These
// functions will be called only after the output was successfully // functions will be called only after the output was successfully
// checked. // checked.
size_t AddChecker(const char* bm_name, ResultsCheckFn fn); // bm_name_pattern: a name or a regex which will be matched agains
// all the benchmark names. Matching benchmarks
// Class to test the results of a benchmark. // will be the subject of a call to fn
// It inspects the results by looking at the CSV output of a subscribed size_t AddChecker(const char* bm_name_pattern, ResultsCheckFn fn);
// benchmark.
struct ResultsCheckerEntry { // Class to hold the (CSV!) results of a benchmark.
std::string name; // It is passed in calls to checker functions.
struct Results {
std::string name; // the benchmark name
std::map< std::string, std::string > values; std::map< std::string, std::string > values;
ResultsCheckerEntry(const std::string& n) : name(n) {} Results(const std::string& n) : name(n) {}
int NumThreads() const; int NumThreads() const;
...@@ -99,21 +101,14 @@ struct ResultsCheckerEntry { ...@@ -99,21 +101,14 @@ struct ResultsCheckerEntry {
} }
// get a result by name, parsed as a specific type. // get a result by name, parsed as a specific type.
// For counters, use GetCounterAs instead. // NOTE: for counters, use GetCounterAs instead.
template< class T > T GetAs(const char* entry_name) const { template <class T>
auto *sv = Get(entry_name); T GetAs(const char* entry_name) const;
CHECK(sv != nullptr && !sv->empty());
std::stringstream ss;
ss << *sv;
T out;
ss >> out;
CHECK(!ss.fail());
return out;
}
// counters are written as doubles, so they have to be read first // counters are written as doubles, so they have to be read first
// as a double, and only then converted to the asked type. // as a double, and only then converted to the asked type.
template< class T > T GetCounterAs(const char* entry_name) const { template <class T>
T GetCounterAs(const char* entry_name) const {
double dval = GetAs< double >(entry_name); double dval = GetAs< double >(entry_name);
T tval = static_cast< T >(dval); T tval = static_cast< T >(dval);
return tval; return tval;
...@@ -123,6 +118,18 @@ struct ResultsCheckerEntry { ...@@ -123,6 +118,18 @@ struct ResultsCheckerEntry {
double GetTime(const char* which) const; double GetTime(const char* which) const;
}; };
template <class T>
T Results::GetAs(const char* entry_name) const {
auto *sv = Get(entry_name);
CHECK(sv != nullptr && !sv->empty());
std::stringstream ss;
ss << *sv;
T out;
ss >> out;
CHECK(!ss.fail());
return out;
}
//---------------------------------- //----------------------------------
// Macros to help in result checking. Do not use them with arguments causing // Macros to help in result checking. Do not use them with arguments causing
// side-effects. // side-effects.
......
...@@ -169,7 +169,7 @@ class ResultsChecker { ...@@ -169,7 +169,7 @@ class ResultsChecker {
}; };
std::vector< PatternAndFn > check_patterns; std::vector< PatternAndFn > check_patterns;
std::vector< ResultsCheckerEntry > results; std::vector< Results > results;
std::vector< std::string > field_names; std::vector< std::string > field_names;
void Add(const std::string& entry_pattern, ResultsCheckFn fn); void Add(const std::string& entry_pattern, ResultsCheckFn fn);
...@@ -178,7 +178,7 @@ class ResultsChecker { ...@@ -178,7 +178,7 @@ class ResultsChecker {
private: private:
ResultsCheckerEntry* Find_(const std::string& entry_name); Results* Find_(const std::string& entry_name);
void SetHeader_(const std::string& csv_header); void SetHeader_(const std::string& csv_header);
void SetValues_(const std::string& entry_csv_line); void SetValues_(const std::string& entry_csv_line);
...@@ -293,7 +293,7 @@ size_t AddChecker(const char* bm_name, ResultsCheckFn fn) ...@@ -293,7 +293,7 @@ size_t AddChecker(const char* bm_name, ResultsCheckFn fn)
return rc.results.size(); return rc.results.size();
} }
int ResultsCheckerEntry::NumThreads() const { int Results::NumThreads() const {
auto pos = name.find("/threads:"); auto pos = name.find("/threads:");
if(pos == name.npos) return 1; if(pos == name.npos) return 1;
auto end = name.find('/', pos + 9); auto end = name.find('/', pos + 9);
...@@ -305,7 +305,7 @@ int ResultsCheckerEntry::NumThreads() const { ...@@ -305,7 +305,7 @@ int ResultsCheckerEntry::NumThreads() const {
return num; return num;
} }
double ResultsCheckerEntry::GetTime(const char* which) const { double Results::GetTime(const char* which) const {
double val = GetAs< double >(which); double val = GetAs< double >(which);
auto unit = Get("time_unit"); auto unit = Get("time_unit");
CHECK(unit); CHECK(unit);
......
...@@ -35,7 +35,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Simple\",$"}, ...@@ -35,7 +35,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Simple\",$"},
{"\"foo\": %float$", MR_Next}, {"\"foo\": %float$", MR_Next},
{"}", MR_Next}}); {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Simple\",%csv_report,%float,%float$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Simple\",%csv_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", [](ResultsCheckerEntry const& e) { CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", [](Results const& e) {
double its = e.GetAs< double >("iterations"); double its = e.GetAs< double >("iterations");
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
// check that the value of bar is within 0.1% of the expected value // check that the value of bar is within 0.1% of the expected value
...@@ -72,7 +72,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"}, ...@@ -72,7 +72,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"},
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec\"," ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec\","
"%csv_bytes_items_report,%float,%float$"}}); "%csv_bytes_items_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec", CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec",
[](ResultsCheckerEntry const& e) { [](Results const& e) {
double t = e.DurationCPUTime(); // this (and not real time) is the time used double t = e.DurationCPUTime(); // this (and not real time) is the time used
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
CHECK_COUNTER_VALUE(e, int, "bar", EQ, num_calls1); CHECK_COUNTER_VALUE(e, int, "bar", EQ, num_calls1);
...@@ -104,7 +104,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Rate\",$"}, ...@@ -104,7 +104,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Rate\",$"},
{"}", MR_Next}}); {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Rate\",%csv_report,%float,%float$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Rate\",%csv_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", CHECK_BENCHMARK_RESULTS("BM_Counters_Rate",
[](ResultsCheckerEntry const& e) { [](Results const& e) {
double t = e.DurationCPUTime(); // this (and not real time) is the time used double t = e.DurationCPUTime(); // this (and not real time) is the time used
// check that the values are within 0.1% of the expected values // check that the values are within 0.1% of the expected values
CHECK_COUNTER_VALUE_EPS(e, "foo", EQ_EPS, 1./t, 0.001); CHECK_COUNTER_VALUE_EPS(e, "foo", EQ_EPS, 1./t, 0.001);
...@@ -133,7 +133,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"}, ...@@ -133,7 +133,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
{"}", MR_Next}}); {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int",
[](ResultsCheckerEntry const& e) { [](Results const& e) {
CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads()); CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads());
CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads()); CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
}); });
...@@ -161,7 +161,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"}, ...@@ -161,7 +161,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
{"}", MR_Next}}); {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int", CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
[](ResultsCheckerEntry const& e) { [](Results const& e) {
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2); CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2);
}); });
...@@ -189,7 +189,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$ ...@@ -189,7 +189,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$
{"}", MR_Next}}); {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/threads:%int\",%csv_report,%float,%float$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/threads:%int\",%csv_report,%float,%float$"}});
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int", CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
[](ResultsCheckerEntry const& e) { [](Results const& e) {
CHECK_COUNTER_VALUE_EPS(e, "foo", EQ_EPS, 1./e.DurationCPUTime(), 0.001); CHECK_COUNTER_VALUE_EPS(e, "foo", EQ_EPS, 1./e.DurationCPUTime(), 0.001);
CHECK_COUNTER_VALUE_EPS(e, "bar", EQ_EPS, 2./e.DurationCPUTime(), 0.001); CHECK_COUNTER_VALUE_EPS(e, "bar", EQ_EPS, 2./e.DurationCPUTime(), 0.001);
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment