register_benchmark_test.cc revision 30b48cb1b3a0c4fcc1887259bd215ad8738d21b4
1
2#undef NDEBUG
3#include "benchmark/benchmark.h"
4#include "../src/check.h" // NOTE: check.h is for internal use only!
5#include <cassert>
6#include <vector>
7
8namespace {
9
10class TestReporter : public benchmark::ConsoleReporter {
11public:
12  virtual void ReportRuns(const std::vector<Run>& report) {
13    all_runs_.insert(all_runs_.end(), begin(report), end(report));
14    ConsoleReporter::ReportRuns(report);
15  }
16
17  std::vector<Run> all_runs_;
18};
19
20struct TestCase {
21  std::string name;
22  const char* label;
23  TestCase(const char* xname) : name(xname), label(nullptr) {}
24  TestCase(const char* xname, const char* xlabel)
25    : name(xname), label(xlabel) {}
26
27  typedef benchmark::BenchmarkReporter::Run Run;
28
29  void CheckRun(Run const& run) const {
30    CHECK(name == run.benchmark_name) << "expected " << name
31                                      << " got " << run.benchmark_name;
32    if (label) {
33      CHECK(run.report_label == label) << "expected " << label
34                                       << " got " << run.report_label;
35    } else {
36      CHECK(run.report_label == "");
37    }
38  }
39};
40
41std::vector<TestCase> ExpectedResults;
42
43int AddCases(std::initializer_list<TestCase> const& v) {
44  for (auto N : v) {
45    ExpectedResults.push_back(N);
46  }
47  return 0;
48}
49
50#define CONCAT(x, y) CONCAT2(x, y)
51#define CONCAT2(x, y) x##y
52#define ADD_CASES(...) \
53int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__})
54
55}  // end namespace
56
57typedef benchmark::internal::Benchmark* ReturnVal;
58
59//----------------------------------------------------------------------------//
60// Test RegisterBenchmark with no additional arguments
61//----------------------------------------------------------------------------//
62void BM_function(benchmark::State& state) { while (state.KeepRunning()) {} }
63BENCHMARK(BM_function);
64ReturnVal dummy = benchmark::RegisterBenchmark(
65    "BM_function_manual_registration",
66     BM_function);
67ADD_CASES({"BM_function"}, {"BM_function_manual_registration"});
68
69//----------------------------------------------------------------------------//
70// Test RegisterBenchmark with additional arguments
71// Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they
72//       reject the variadic pack expansion of lambda captures.
73//----------------------------------------------------------------------------//
74#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
75
76void BM_extra_args(benchmark::State& st, const char* label) {
77  while (st.KeepRunning()) {}
78  st.SetLabel(label);
79}
80int RegisterFromFunction() {
81  std::pair<const char*, const char*> cases[] = {
82      {"test1", "One"},
83      {"test2", "Two"},
84      {"test3", "Three"}
85  };
86  for (auto& c : cases)
87    benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second);
88  return 0;
89}
90int dummy2 = RegisterFromFunction();
91ADD_CASES(
92  {"test1", "One"},
93  {"test2", "Two"},
94  {"test3", "Three"}
95);
96
97#endif // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
98
99//----------------------------------------------------------------------------//
100// Test RegisterBenchmark with different callable types
101//----------------------------------------------------------------------------//
102
103struct CustomFixture {
104  void operator()(benchmark::State& st) {
105    while (st.KeepRunning()) {}
106  }
107};
108
109void TestRegistrationAtRuntime() {
110#ifdef BENCHMARK_HAS_CXX11
111  {
112    CustomFixture fx;
113    benchmark::RegisterBenchmark("custom_fixture", fx);
114    AddCases({"custom_fixture"});
115  }
116#endif
117#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
118  {
119    int x = 42;
120    auto capturing_lam = [=](benchmark::State& st) {
121      while (st.KeepRunning()) {}
122      st.SetLabel(std::to_string(x));
123    };
124    benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam);
125    AddCases({{"lambda_benchmark", "42"}});
126  }
127#endif
128}
129
130int main(int argc, char* argv[]) {
131  TestRegistrationAtRuntime();
132
133  benchmark::Initialize(&argc, argv);
134
135  TestReporter test_reporter;
136  benchmark::RunSpecifiedBenchmarks(&test_reporter);
137
138  typedef benchmark::BenchmarkReporter::Run Run;
139  auto EB = ExpectedResults.begin();
140
141  for (Run const& run : test_reporter.all_runs_) {
142    assert(EB != ExpectedResults.end());
143    EB->CheckRun(run);
144    ++EB;
145  }
146  assert(EB == ExpectedResults.end());
147
148  return 0;
149}
150