Commit 92034a8b by Joao Paulo Magalhaes

Make result checkers execute on all regex-matching benchmarks.

parent 738fcd9e
...@@ -71,7 +71,8 @@ typedef std::function< void(ResultsCheckerEntry const&) > ResultsCheckFn; ...@@ -71,7 +71,8 @@ typedef std::function< void(ResultsCheckerEntry const&) > ResultsCheckFn;
struct ResultsCheckerEntry { struct ResultsCheckerEntry {
std::string name; std::string name;
std::map< std::string, std::string > values; std::map< std::string, std::string > values;
ResultsCheckFn check_fn;
ResultsCheckerEntry(std::string const& n) : name(n) {}
int NumThreads() const { int NumThreads() const {
auto pos = name.find_last_of("/threads:"); auto pos = name.find_last_of("/threads:");
......
...@@ -162,10 +162,17 @@ namespace internal { ...@@ -162,10 +162,17 @@ namespace internal {
class ResultsChecker { class ResultsChecker {
public: public:
std::map< std::string, ResultsCheckerEntry > results; struct PatternAndFn : public TestCase { // reusing TestCase for its regexes
std::vector< std::string > result_names; PatternAndFn(const std::string& regex, ResultsCheckFn fn_)
: TestCase(regex), fn(fn_) {}
ResultsCheckFn fn;
};
std::vector< PatternAndFn > check_patterns;
std::vector< ResultsCheckerEntry > results;
std::vector< std::string > field_names;
void Add(const std::string& entry_name, ResultsCheckFn fn); void Add(const std::string& entry_pattern, ResultsCheckFn fn);
void CheckResults(std::stringstream& output); void CheckResults(std::stringstream& output);
...@@ -188,8 +195,8 @@ ResultsChecker& GetResultsChecker() { ...@@ -188,8 +195,8 @@ ResultsChecker& GetResultsChecker() {
} }
// add a results checker for a benchmark // add a results checker for a benchmark
void ResultsChecker::Add(const std::string& entry_name, ResultsCheckFn fn) { void ResultsChecker::Add(const std::string& entry_pattern, ResultsCheckFn fn) {
results[entry_name] = {entry_name, {}, fn}; check_patterns.emplace_back(entry_pattern, fn);
} }
// check the results of all subscribed benchmarks // check the results of all subscribed benchmarks
...@@ -219,44 +226,47 @@ void ResultsChecker::CheckResults(std::stringstream& output) ...@@ -219,44 +226,47 @@ void ResultsChecker::CheckResults(std::stringstream& output)
SetValues_(line); SetValues_(line);
} }
// finally we can call the subscribed check functions // finally we can call the subscribed check functions
for(const auto& p : results) { for(const auto& p : check_patterns) {
VLOG(1) << "Checking results of " << p.second.name << ": ... \n"; VLOG(2) << "--------------------------------\n";
CHECK(p.second.check_fn); VLOG(2) << "checking for benchmarks matching " << p.regex_str << "...\n";
p.second.check_fn(p.second); for(const auto& r : results) {
VLOG(1) << "Checking results of " << p.second.name << ": OK.\n"; if(!p.regex->Match(r.name)) {
VLOG(2) << p.regex_str << " is not matched by " << r.name << "\n";
continue;
}
else {
VLOG(2) << p.regex_str << " is matched by " << r.name << "\n";
}
VLOG(1) << "Checking results of " << r.name << ": ... \n";
p.fn(r);
VLOG(1) << "Checking results of " << r.name << ": OK.\n";
}
} }
} }
// prepare for the names in this header // prepare for the names in this header
void ResultsChecker::SetHeader_(const std::string& csv_header) { void ResultsChecker::SetHeader_(const std::string& csv_header) {
result_names = SplitCsv_(csv_header); field_names = SplitCsv_(csv_header);
} }
// set the values for subscribed benchmarks, and silently ignore all others // set the values for subscribed benchmarks, and silently ignore all others
void ResultsChecker::SetValues_(const std::string& entry_csv_line) { void ResultsChecker::SetValues_(const std::string& entry_csv_line) {
CHECK(!result_names.empty()); CHECK(!field_names.empty());
auto vals = SplitCsv_(entry_csv_line); auto vals = SplitCsv_(entry_csv_line);
if(vals.empty()) return; if(vals.empty()) return;
CHECK_EQ(vals.size(), result_names.size()); CHECK_EQ(vals.size(), field_names.size());
ResultsCheckerEntry* entry = Find_(vals[0]); results.emplace_back(vals[0]); // vals[0] is the benchmark name
if(!entry) return; auto &entry = results.back();
for (size_t i = 1, e = vals.size(); i < e; ++i) { for (size_t i = 1, e = vals.size(); i < e; ++i) {
entry->values[result_names[i]] = vals[i]; entry.values[field_names[i]] = vals[i];
} }
} }
// find a subscribed benchmark, or return null
ResultsCheckerEntry* ResultsChecker::Find_(const std::string& entry_name) {
auto it = results.find(entry_name);
if(it == results.end()) return nullptr;
return &it->second;
}
// a quick'n'dirty csv splitter (eliminating quotes) // a quick'n'dirty csv splitter (eliminating quotes)
std::vector< std::string > ResultsChecker::SplitCsv_(std::string const& line) { std::vector< std::string > ResultsChecker::SplitCsv_(std::string const& line) {
std::vector< std::string > out; std::vector< std::string > out;
if(line.empty()) return out; if(line.empty()) return out;
if(!result_names.empty()) out.reserve(result_names.size()); if(!field_names.empty()) out.reserve(field_names.size());
size_t prev = 0, pos = line.find_first_of(','), curr = pos; size_t prev = 0, pos = line.find_first_of(','), curr = pos;
while(pos != line.npos) { while(pos != line.npos) {
CHECK(curr > 0); CHECK(curr > 0);
......
...@@ -132,6 +132,10 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"}, ...@@ -132,6 +132,10 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
{"\"foo\": %float$", MR_Next}, {"\"foo\": %float$", MR_Next},
{"}", 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",
[](ResultsCheckerEntry const& e) {
std::cout << "BOO: " << e.name << "\n";
});
// ========================================================================= // // ========================================================================= //
// ---------------------- ThreadAvg Counters Output ------------------------ // // ---------------------- ThreadAvg Counters Output ------------------------ //
......
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