xref: /aosp_15_r20/external/google-benchmark/test/register_benchmark_test.cc (revision dbb99499c3810fa1611fa2242a2fc446be01a57c)
1*dbb99499SAndroid Build Coastguard Worker 
2*dbb99499SAndroid Build Coastguard Worker #undef NDEBUG
3*dbb99499SAndroid Build Coastguard Worker #include <cassert>
4*dbb99499SAndroid Build Coastguard Worker #include <vector>
5*dbb99499SAndroid Build Coastguard Worker 
6*dbb99499SAndroid Build Coastguard Worker #include "../src/check.h"  // NOTE: check.h is for internal use only!
7*dbb99499SAndroid Build Coastguard Worker #include "benchmark/benchmark.h"
8*dbb99499SAndroid Build Coastguard Worker 
9*dbb99499SAndroid Build Coastguard Worker namespace {
10*dbb99499SAndroid Build Coastguard Worker 
11*dbb99499SAndroid Build Coastguard Worker class TestReporter : public benchmark::ConsoleReporter {
12*dbb99499SAndroid Build Coastguard Worker  public:
ReportRuns(const std::vector<Run> & report)13*dbb99499SAndroid Build Coastguard Worker   void ReportRuns(const std::vector<Run>& report) override {
14*dbb99499SAndroid Build Coastguard Worker     all_runs_.insert(all_runs_.end(), begin(report), end(report));
15*dbb99499SAndroid Build Coastguard Worker     ConsoleReporter::ReportRuns(report);
16*dbb99499SAndroid Build Coastguard Worker   }
17*dbb99499SAndroid Build Coastguard Worker 
18*dbb99499SAndroid Build Coastguard Worker   std::vector<Run> all_runs_;
19*dbb99499SAndroid Build Coastguard Worker };
20*dbb99499SAndroid Build Coastguard Worker 
21*dbb99499SAndroid Build Coastguard Worker struct TestCase {
22*dbb99499SAndroid Build Coastguard Worker   const std::string name;
23*dbb99499SAndroid Build Coastguard Worker   const std::string label;
24*dbb99499SAndroid Build Coastguard Worker   // Note: not explicit as we rely on it being converted through ADD_CASES.
TestCase__anon3d8d12fc0111::TestCase25*dbb99499SAndroid Build Coastguard Worker   TestCase(const std::string& xname) : TestCase(xname, "") {}
TestCase__anon3d8d12fc0111::TestCase26*dbb99499SAndroid Build Coastguard Worker   TestCase(const std::string& xname, const std::string& xlabel)
27*dbb99499SAndroid Build Coastguard Worker       : name(xname), label(xlabel) {}
28*dbb99499SAndroid Build Coastguard Worker 
29*dbb99499SAndroid Build Coastguard Worker   typedef benchmark::BenchmarkReporter::Run Run;
30*dbb99499SAndroid Build Coastguard Worker 
CheckRun__anon3d8d12fc0111::TestCase31*dbb99499SAndroid Build Coastguard Worker   void CheckRun(Run const& run) const {
32*dbb99499SAndroid Build Coastguard Worker     // clang-format off
33*dbb99499SAndroid Build Coastguard Worker     BM_CHECK(name == run.benchmark_name()) << "expected " << name << " got "
34*dbb99499SAndroid Build Coastguard Worker                                       << run.benchmark_name();
35*dbb99499SAndroid Build Coastguard Worker     if (!label.empty()) {
36*dbb99499SAndroid Build Coastguard Worker       BM_CHECK(run.report_label == label) << "expected " << label << " got "
37*dbb99499SAndroid Build Coastguard Worker                                        << run.report_label;
38*dbb99499SAndroid Build Coastguard Worker     } else {
39*dbb99499SAndroid Build Coastguard Worker       BM_CHECK(run.report_label.empty());
40*dbb99499SAndroid Build Coastguard Worker     }
41*dbb99499SAndroid Build Coastguard Worker     // clang-format on
42*dbb99499SAndroid Build Coastguard Worker   }
43*dbb99499SAndroid Build Coastguard Worker };
44*dbb99499SAndroid Build Coastguard Worker 
45*dbb99499SAndroid Build Coastguard Worker std::vector<TestCase> ExpectedResults;
46*dbb99499SAndroid Build Coastguard Worker 
AddCases(std::initializer_list<TestCase> const & v)47*dbb99499SAndroid Build Coastguard Worker int AddCases(std::initializer_list<TestCase> const& v) {
48*dbb99499SAndroid Build Coastguard Worker   for (const auto& N : v) {
49*dbb99499SAndroid Build Coastguard Worker     ExpectedResults.push_back(N);
50*dbb99499SAndroid Build Coastguard Worker   }
51*dbb99499SAndroid Build Coastguard Worker   return 0;
52*dbb99499SAndroid Build Coastguard Worker }
53*dbb99499SAndroid Build Coastguard Worker 
54*dbb99499SAndroid Build Coastguard Worker #define CONCAT(x, y) CONCAT2(x, y)
55*dbb99499SAndroid Build Coastguard Worker #define CONCAT2(x, y) x##y
56*dbb99499SAndroid Build Coastguard Worker #define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__})
57*dbb99499SAndroid Build Coastguard Worker 
58*dbb99499SAndroid Build Coastguard Worker }  // end namespace
59*dbb99499SAndroid Build Coastguard Worker 
60*dbb99499SAndroid Build Coastguard Worker typedef benchmark::internal::Benchmark* ReturnVal;
61*dbb99499SAndroid Build Coastguard Worker 
62*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
63*dbb99499SAndroid Build Coastguard Worker // Test RegisterBenchmark with no additional arguments
64*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
BM_function(benchmark::State & state)65*dbb99499SAndroid Build Coastguard Worker void BM_function(benchmark::State& state) {
66*dbb99499SAndroid Build Coastguard Worker   for (auto _ : state) {
67*dbb99499SAndroid Build Coastguard Worker   }
68*dbb99499SAndroid Build Coastguard Worker }
69*dbb99499SAndroid Build Coastguard Worker BENCHMARK(BM_function);
70*dbb99499SAndroid Build Coastguard Worker ReturnVal dummy = benchmark::RegisterBenchmark(
71*dbb99499SAndroid Build Coastguard Worker     "BM_function_manual_registration", BM_function);
72*dbb99499SAndroid Build Coastguard Worker ADD_CASES({"BM_function"}, {"BM_function_manual_registration"});
73*dbb99499SAndroid Build Coastguard Worker 
74*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
75*dbb99499SAndroid Build Coastguard Worker // Test RegisterBenchmark with additional arguments
76*dbb99499SAndroid Build Coastguard Worker // Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they
77*dbb99499SAndroid Build Coastguard Worker //       reject the variadic pack expansion of lambda captures.
78*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
79*dbb99499SAndroid Build Coastguard Worker #ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
80*dbb99499SAndroid Build Coastguard Worker 
BM_extra_args(benchmark::State & st,const char * label)81*dbb99499SAndroid Build Coastguard Worker void BM_extra_args(benchmark::State& st, const char* label) {
82*dbb99499SAndroid Build Coastguard Worker   for (auto _ : st) {
83*dbb99499SAndroid Build Coastguard Worker   }
84*dbb99499SAndroid Build Coastguard Worker   st.SetLabel(label);
85*dbb99499SAndroid Build Coastguard Worker }
RegisterFromFunction()86*dbb99499SAndroid Build Coastguard Worker int RegisterFromFunction() {
87*dbb99499SAndroid Build Coastguard Worker   std::pair<const char*, const char*> cases[] = {
88*dbb99499SAndroid Build Coastguard Worker       {"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}};
89*dbb99499SAndroid Build Coastguard Worker   for (auto const& c : cases)
90*dbb99499SAndroid Build Coastguard Worker     benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second);
91*dbb99499SAndroid Build Coastguard Worker   return 0;
92*dbb99499SAndroid Build Coastguard Worker }
93*dbb99499SAndroid Build Coastguard Worker int dummy2 = RegisterFromFunction();
94*dbb99499SAndroid Build Coastguard Worker ADD_CASES({"test1", "One"}, {"test2", "Two"}, {"test3", "Three"});
95*dbb99499SAndroid Build Coastguard Worker 
96*dbb99499SAndroid Build Coastguard Worker #endif  // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
97*dbb99499SAndroid Build Coastguard Worker 
98*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
99*dbb99499SAndroid Build Coastguard Worker // Test RegisterBenchmark with DISABLED_ benchmark
100*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
DISABLED_BM_function(benchmark::State & state)101*dbb99499SAndroid Build Coastguard Worker void DISABLED_BM_function(benchmark::State& state) {
102*dbb99499SAndroid Build Coastguard Worker   for (auto _ : state) {
103*dbb99499SAndroid Build Coastguard Worker   }
104*dbb99499SAndroid Build Coastguard Worker }
105*dbb99499SAndroid Build Coastguard Worker BENCHMARK(DISABLED_BM_function);
106*dbb99499SAndroid Build Coastguard Worker ReturnVal dummy3 = benchmark::RegisterBenchmark("DISABLED_BM_function_manual",
107*dbb99499SAndroid Build Coastguard Worker                                                 DISABLED_BM_function);
108*dbb99499SAndroid Build Coastguard Worker // No need to add cases because we don't expect them to run.
109*dbb99499SAndroid Build Coastguard Worker 
110*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
111*dbb99499SAndroid Build Coastguard Worker // Test RegisterBenchmark with different callable types
112*dbb99499SAndroid Build Coastguard Worker //----------------------------------------------------------------------------//
113*dbb99499SAndroid Build Coastguard Worker 
114*dbb99499SAndroid Build Coastguard Worker struct CustomFixture {
operator ()CustomFixture115*dbb99499SAndroid Build Coastguard Worker   void operator()(benchmark::State& st) {
116*dbb99499SAndroid Build Coastguard Worker     for (auto _ : st) {
117*dbb99499SAndroid Build Coastguard Worker     }
118*dbb99499SAndroid Build Coastguard Worker   }
119*dbb99499SAndroid Build Coastguard Worker };
120*dbb99499SAndroid Build Coastguard Worker 
TestRegistrationAtRuntime()121*dbb99499SAndroid Build Coastguard Worker void TestRegistrationAtRuntime() {
122*dbb99499SAndroid Build Coastguard Worker #ifdef BENCHMARK_HAS_CXX11
123*dbb99499SAndroid Build Coastguard Worker   {
124*dbb99499SAndroid Build Coastguard Worker     CustomFixture fx;
125*dbb99499SAndroid Build Coastguard Worker     benchmark::RegisterBenchmark("custom_fixture", fx);
126*dbb99499SAndroid Build Coastguard Worker     AddCases({std::string("custom_fixture")});
127*dbb99499SAndroid Build Coastguard Worker   }
128*dbb99499SAndroid Build Coastguard Worker #endif
129*dbb99499SAndroid Build Coastguard Worker #ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
130*dbb99499SAndroid Build Coastguard Worker   {
131*dbb99499SAndroid Build Coastguard Worker     const char* x = "42";
132*dbb99499SAndroid Build Coastguard Worker     auto capturing_lam = [=](benchmark::State& st) {
133*dbb99499SAndroid Build Coastguard Worker       for (auto _ : st) {
134*dbb99499SAndroid Build Coastguard Worker       }
135*dbb99499SAndroid Build Coastguard Worker       st.SetLabel(x);
136*dbb99499SAndroid Build Coastguard Worker     };
137*dbb99499SAndroid Build Coastguard Worker     benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam);
138*dbb99499SAndroid Build Coastguard Worker     AddCases({{"lambda_benchmark", x}});
139*dbb99499SAndroid Build Coastguard Worker   }
140*dbb99499SAndroid Build Coastguard Worker #endif
141*dbb99499SAndroid Build Coastguard Worker }
142*dbb99499SAndroid Build Coastguard Worker 
143*dbb99499SAndroid Build Coastguard Worker // Test that all benchmarks, registered at either during static init or runtime,
144*dbb99499SAndroid Build Coastguard Worker // are run and the results are passed to the reported.
RunTestOne()145*dbb99499SAndroid Build Coastguard Worker void RunTestOne() {
146*dbb99499SAndroid Build Coastguard Worker   TestRegistrationAtRuntime();
147*dbb99499SAndroid Build Coastguard Worker 
148*dbb99499SAndroid Build Coastguard Worker   TestReporter test_reporter;
149*dbb99499SAndroid Build Coastguard Worker   benchmark::RunSpecifiedBenchmarks(&test_reporter);
150*dbb99499SAndroid Build Coastguard Worker 
151*dbb99499SAndroid Build Coastguard Worker   typedef benchmark::BenchmarkReporter::Run Run;
152*dbb99499SAndroid Build Coastguard Worker   auto EB = ExpectedResults.begin();
153*dbb99499SAndroid Build Coastguard Worker 
154*dbb99499SAndroid Build Coastguard Worker   for (Run const& run : test_reporter.all_runs_) {
155*dbb99499SAndroid Build Coastguard Worker     assert(EB != ExpectedResults.end());
156*dbb99499SAndroid Build Coastguard Worker     EB->CheckRun(run);
157*dbb99499SAndroid Build Coastguard Worker     ++EB;
158*dbb99499SAndroid Build Coastguard Worker   }
159*dbb99499SAndroid Build Coastguard Worker   assert(EB == ExpectedResults.end());
160*dbb99499SAndroid Build Coastguard Worker }
161*dbb99499SAndroid Build Coastguard Worker 
162*dbb99499SAndroid Build Coastguard Worker // Test that ClearRegisteredBenchmarks() clears all previously registered
163*dbb99499SAndroid Build Coastguard Worker // benchmarks.
164*dbb99499SAndroid Build Coastguard Worker // Also test that new benchmarks can be registered and ran afterwards.
RunTestTwo()165*dbb99499SAndroid Build Coastguard Worker void RunTestTwo() {
166*dbb99499SAndroid Build Coastguard Worker   assert(ExpectedResults.size() != 0 &&
167*dbb99499SAndroid Build Coastguard Worker          "must have at least one registered benchmark");
168*dbb99499SAndroid Build Coastguard Worker   ExpectedResults.clear();
169*dbb99499SAndroid Build Coastguard Worker   benchmark::ClearRegisteredBenchmarks();
170*dbb99499SAndroid Build Coastguard Worker 
171*dbb99499SAndroid Build Coastguard Worker   TestReporter test_reporter;
172*dbb99499SAndroid Build Coastguard Worker   size_t num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter);
173*dbb99499SAndroid Build Coastguard Worker   assert(num_ran == 0);
174*dbb99499SAndroid Build Coastguard Worker   assert(test_reporter.all_runs_.begin() == test_reporter.all_runs_.end());
175*dbb99499SAndroid Build Coastguard Worker 
176*dbb99499SAndroid Build Coastguard Worker   TestRegistrationAtRuntime();
177*dbb99499SAndroid Build Coastguard Worker   num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter);
178*dbb99499SAndroid Build Coastguard Worker   assert(num_ran == ExpectedResults.size());
179*dbb99499SAndroid Build Coastguard Worker 
180*dbb99499SAndroid Build Coastguard Worker   typedef benchmark::BenchmarkReporter::Run Run;
181*dbb99499SAndroid Build Coastguard Worker   auto EB = ExpectedResults.begin();
182*dbb99499SAndroid Build Coastguard Worker 
183*dbb99499SAndroid Build Coastguard Worker   for (Run const& run : test_reporter.all_runs_) {
184*dbb99499SAndroid Build Coastguard Worker     assert(EB != ExpectedResults.end());
185*dbb99499SAndroid Build Coastguard Worker     EB->CheckRun(run);
186*dbb99499SAndroid Build Coastguard Worker     ++EB;
187*dbb99499SAndroid Build Coastguard Worker   }
188*dbb99499SAndroid Build Coastguard Worker   assert(EB == ExpectedResults.end());
189*dbb99499SAndroid Build Coastguard Worker }
190*dbb99499SAndroid Build Coastguard Worker 
main(int argc,char * argv[])191*dbb99499SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
192*dbb99499SAndroid Build Coastguard Worker   benchmark::Initialize(&argc, argv);
193*dbb99499SAndroid Build Coastguard Worker 
194*dbb99499SAndroid Build Coastguard Worker   RunTestOne();
195*dbb99499SAndroid Build Coastguard Worker   RunTestTwo();
196*dbb99499SAndroid Build Coastguard Worker }
197