[Workflow] Try to fix code-formatter failing to find changes in some cases.
[llvm-project.git] / third-party / benchmark / test / register_benchmark_test.cc
blob602405b67e8de804638fd6eb5cf05842eab4dd14
2 #undef NDEBUG
3 #include <cassert>
4 #include <vector>
6 #include "../src/check.h" // NOTE: check.h is for internal use only!
7 #include "benchmark/benchmark.h"
9 namespace {
11 class TestReporter : public benchmark::ConsoleReporter {
12 public:
13 virtual void ReportRuns(const std::vector<Run>& report) BENCHMARK_OVERRIDE {
14 all_runs_.insert(all_runs_.end(), begin(report), end(report));
15 ConsoleReporter::ReportRuns(report);
18 std::vector<Run> all_runs_;
21 struct TestCase {
22 std::string name;
23 const char* label;
24 // Note: not explicit as we rely on it being converted through ADD_CASES.
25 TestCase(const char* xname) : TestCase(xname, nullptr) {}
26 TestCase(const char* xname, const char* xlabel)
27 : name(xname), label(xlabel) {}
29 typedef benchmark::BenchmarkReporter::Run Run;
31 void CheckRun(Run const& run) const {
32 // clang-format off
33 BM_CHECK(name == run.benchmark_name()) << "expected " << name << " got "
34 << run.benchmark_name();
35 if (label) {
36 BM_CHECK(run.report_label == label) << "expected " << label << " got "
37 << run.report_label;
38 } else {
39 BM_CHECK(run.report_label.empty());
41 // clang-format on
45 std::vector<TestCase> ExpectedResults;
47 int AddCases(std::initializer_list<TestCase> const& v) {
48 for (const auto& N : v) {
49 ExpectedResults.push_back(N);
51 return 0;
54 #define CONCAT(x, y) CONCAT2(x, y)
55 #define CONCAT2(x, y) x##y
56 #define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__})
58 } // end namespace
60 typedef benchmark::internal::Benchmark* ReturnVal;
62 //----------------------------------------------------------------------------//
63 // Test RegisterBenchmark with no additional arguments
64 //----------------------------------------------------------------------------//
65 void BM_function(benchmark::State& state) {
66 for (auto _ : state) {
69 BENCHMARK(BM_function);
70 ReturnVal dummy = benchmark::RegisterBenchmark(
71 "BM_function_manual_registration", BM_function);
72 ADD_CASES({"BM_function"}, {"BM_function_manual_registration"});
74 //----------------------------------------------------------------------------//
75 // Test RegisterBenchmark with additional arguments
76 // Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they
77 // reject the variadic pack expansion of lambda captures.
78 //----------------------------------------------------------------------------//
79 #ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
81 void BM_extra_args(benchmark::State& st, const char* label) {
82 for (auto _ : st) {
84 st.SetLabel(label);
86 int RegisterFromFunction() {
87 std::pair<const char*, const char*> cases[] = {
88 {"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}};
89 for (auto const& c : cases)
90 benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second);
91 return 0;
93 int dummy2 = RegisterFromFunction();
94 ADD_CASES({"test1", "One"}, {"test2", "Two"}, {"test3", "Three"});
96 #endif // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
98 //----------------------------------------------------------------------------//
99 // Test RegisterBenchmark with different callable types
100 //----------------------------------------------------------------------------//
102 struct CustomFixture {
103 void operator()(benchmark::State& st) {
104 for (auto _ : st) {
109 void TestRegistrationAtRuntime() {
110 #ifdef BENCHMARK_HAS_CXX11
112 CustomFixture fx;
113 benchmark::RegisterBenchmark("custom_fixture", fx);
114 AddCases({"custom_fixture"});
116 #endif
117 #ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
119 const char* x = "42";
120 auto capturing_lam = [=](benchmark::State& st) {
121 for (auto _ : st) {
123 st.SetLabel(x);
125 benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam);
126 AddCases({{"lambda_benchmark", x}});
128 #endif
131 // Test that all benchmarks, registered at either during static init or runtime,
132 // are run and the results are passed to the reported.
133 void RunTestOne() {
134 TestRegistrationAtRuntime();
136 TestReporter test_reporter;
137 benchmark::RunSpecifiedBenchmarks(&test_reporter);
139 typedef benchmark::BenchmarkReporter::Run Run;
140 auto EB = ExpectedResults.begin();
142 for (Run const& run : test_reporter.all_runs_) {
143 assert(EB != ExpectedResults.end());
144 EB->CheckRun(run);
145 ++EB;
147 assert(EB == ExpectedResults.end());
150 // Test that ClearRegisteredBenchmarks() clears all previously registered
151 // benchmarks.
152 // Also test that new benchmarks can be registered and ran afterwards.
153 void RunTestTwo() {
154 assert(ExpectedResults.size() != 0 &&
155 "must have at least one registered benchmark");
156 ExpectedResults.clear();
157 benchmark::ClearRegisteredBenchmarks();
159 TestReporter test_reporter;
160 size_t num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter);
161 assert(num_ran == 0);
162 assert(test_reporter.all_runs_.begin() == test_reporter.all_runs_.end());
164 TestRegistrationAtRuntime();
165 num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter);
166 assert(num_ran == ExpectedResults.size());
168 typedef benchmark::BenchmarkReporter::Run Run;
169 auto EB = ExpectedResults.begin();
171 for (Run const& run : test_reporter.all_runs_) {
172 assert(EB != ExpectedResults.end());
173 EB->CheckRun(run);
174 ++EB;
176 assert(EB == ExpectedResults.end());
179 int main(int argc, char* argv[]) {
180 benchmark::Initialize(&argc, argv);
182 RunTestOne();
183 RunTestTwo();