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