6 #include "../src/check.h" // NOTE: check.h is for internal use only!
7 #include "benchmark/benchmark.h"
11 class TestReporter
: public benchmark::ConsoleReporter
{
13 virtual bool ReportContext(const Context
& context
) {
14 return ConsoleReporter::ReportContext(context
);
17 virtual void ReportRuns(const std::vector
<Run
>& report
) {
18 all_runs_
.insert(all_runs_
.end(), begin(report
), end(report
));
19 ConsoleReporter::ReportRuns(report
);
23 virtual ~TestReporter() {}
25 mutable std::vector
<Run
> all_runs_
;
31 std::string error_message
;
33 typedef benchmark::BenchmarkReporter::Run Run
;
35 void CheckRun(Run
const& run
) const {
36 CHECK(name
== run
.benchmark_name())
37 << "expected " << name
<< " got " << run
.benchmark_name();
38 CHECK(error_occurred
== run
.error_occurred
);
39 CHECK(error_message
== run
.error_message
);
41 // CHECK(run.iterations == 0);
43 CHECK(run
.iterations
!= 0);
48 std::vector
<TestCase
> ExpectedResults
;
50 int AddCases(const char* base_name
, std::initializer_list
<TestCase
> const& v
) {
52 TC
.name
= base_name
+ TC
.name
;
53 ExpectedResults
.push_back(std::move(TC
));
58 #define CONCAT(x, y) CONCAT2(x, y)
59 #define CONCAT2(x, y) x##y
60 #define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__)
64 void BM_error_no_running(benchmark::State
& state
) {
65 state
.SkipWithError("error message");
67 BENCHMARK(BM_error_no_running
);
68 ADD_CASES("BM_error_no_running", {{"", true, "error message"}});
70 void BM_error_before_running(benchmark::State
& state
) {
71 state
.SkipWithError("error message");
72 while (state
.KeepRunning()) {
76 BENCHMARK(BM_error_before_running
);
77 ADD_CASES("BM_error_before_running", {{"", true, "error message"}});
79 void BM_error_before_running_batch(benchmark::State
& state
) {
80 state
.SkipWithError("error message");
81 while (state
.KeepRunningBatch(17)) {
85 BENCHMARK(BM_error_before_running_batch
);
86 ADD_CASES("BM_error_before_running_batch", {{"", true, "error message"}});
88 void BM_error_before_running_range_for(benchmark::State
& state
) {
89 state
.SkipWithError("error message");
90 for (auto _
: state
) {
94 BENCHMARK(BM_error_before_running_range_for
);
95 ADD_CASES("BM_error_before_running_range_for", {{"", true, "error message"}});
97 void BM_error_during_running(benchmark::State
& state
) {
98 int first_iter
= true;
99 while (state
.KeepRunning()) {
100 if (state
.range(0) == 1 && state
.thread_index
<= (state
.threads
/ 2)) {
103 state
.SkipWithError("error message");
106 state
.ResumeTiming();
110 BENCHMARK(BM_error_during_running
)->Arg(1)->Arg(2)->ThreadRange(1, 8);
111 ADD_CASES("BM_error_during_running", {{"/1/threads:1", true, "error message"},
112 {"/1/threads:2", true, "error message"},
113 {"/1/threads:4", true, "error message"},
114 {"/1/threads:8", true, "error message"},
115 {"/2/threads:1", false, ""},
116 {"/2/threads:2", false, ""},
117 {"/2/threads:4", false, ""},
118 {"/2/threads:8", false, ""}});
120 void BM_error_during_running_ranged_for(benchmark::State
& state
) {
121 assert(state
.max_iterations
> 3 && "test requires at least a few iterations");
122 int first_iter
= true;
123 // NOTE: Users should not write the for loop explicitly.
124 for (auto It
= state
.begin(), End
= state
.end(); It
!= End
; ++It
) {
125 if (state
.range(0) == 1) {
128 state
.SkipWithError("error message");
129 // Test the unfortunate but documented behavior that the ranged-for loop
130 // doesn't automatically terminate when SkipWithError is set.
132 break; // Required behavior
136 BENCHMARK(BM_error_during_running_ranged_for
)->Arg(1)->Arg(2)->Iterations(5);
137 ADD_CASES("BM_error_during_running_ranged_for",
138 {{"/1/iterations:5", true, "error message"},
139 {"/2/iterations:5", false, ""}});
141 void BM_error_after_running(benchmark::State
& state
) {
142 for (auto _
: state
) {
143 benchmark::DoNotOptimize(state
.iterations());
145 if (state
.thread_index
<= (state
.threads
/ 2))
146 state
.SkipWithError("error message");
148 BENCHMARK(BM_error_after_running
)->ThreadRange(1, 8);
149 ADD_CASES("BM_error_after_running", {{"/threads:1", true, "error message"},
150 {"/threads:2", true, "error message"},
151 {"/threads:4", true, "error message"},
152 {"/threads:8", true, "error message"}});
154 void BM_error_while_paused(benchmark::State
& state
) {
155 bool first_iter
= true;
156 while (state
.KeepRunning()) {
157 if (state
.range(0) == 1 && state
.thread_index
<= (state
.threads
/ 2)) {
161 state
.SkipWithError("error message");
164 state
.ResumeTiming();
168 BENCHMARK(BM_error_while_paused
)->Arg(1)->Arg(2)->ThreadRange(1, 8);
169 ADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"},
170 {"/1/threads:2", true, "error message"},
171 {"/1/threads:4", true, "error message"},
172 {"/1/threads:8", true, "error message"},
173 {"/2/threads:1", false, ""},
174 {"/2/threads:2", false, ""},
175 {"/2/threads:4", false, ""},
176 {"/2/threads:8", false, ""}});
178 int main(int argc
, char* argv
[]) {
179 benchmark::Initialize(&argc
, argv
);
181 TestReporter test_reporter
;
182 benchmark::RunSpecifiedBenchmarks(&test_reporter
);
184 typedef benchmark::BenchmarkReporter::Run Run
;
185 auto EB
= ExpectedResults
.begin();
187 for (Run
const& run
: test_reporter
.all_runs_
) {
188 assert(EB
!= ExpectedResults
.end());
192 assert(EB
== ExpectedResults
.end());