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 bool ReportContext(const Context
& context
) override
{
14 return ConsoleReporter::ReportContext(context
);
17 void ReportRuns(const std::vector
<Run
>& report
) override
{
18 all_runs_
.insert(all_runs_
.end(), begin(report
), end(report
));
19 ConsoleReporter::ReportRuns(report
);
23 ~TestReporter() override
{}
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 BM_CHECK(name
== run
.benchmark_name())
37 << "expected " << name
<< " got " << run
.benchmark_name();
38 BM_CHECK_EQ(error_occurred
,
39 benchmark::internal::SkippedWithError
== run
.skipped
);
40 BM_CHECK(error_message
== run
.skip_message
);
42 // BM_CHECK(run.iterations == 0);
44 BM_CHECK(run
.iterations
!= 0);
49 std::vector
<TestCase
> ExpectedResults
;
51 int AddCases(const std::string
& base_name
,
52 std::initializer_list
<TestCase
> const& v
) {
54 TC
.name
= base_name
+ TC
.name
;
55 ExpectedResults
.push_back(std::move(TC
));
60 #define CONCAT(x, y) CONCAT2(x, y)
61 #define CONCAT2(x, y) x##y
62 #define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__)
66 void BM_error_no_running(benchmark::State
& state
) {
67 state
.SkipWithError("error message");
69 BENCHMARK(BM_error_no_running
);
70 ADD_CASES("BM_error_no_running", {{"", true, "error message"}});
72 void BM_error_before_running(benchmark::State
& state
) {
73 state
.SkipWithError("error message");
74 while (state
.KeepRunning()) {
78 BENCHMARK(BM_error_before_running
);
79 ADD_CASES("BM_error_before_running", {{"", true, "error message"}});
81 void BM_error_before_running_batch(benchmark::State
& state
) {
82 state
.SkipWithError("error message");
83 while (state
.KeepRunningBatch(17)) {
87 BENCHMARK(BM_error_before_running_batch
);
88 ADD_CASES("BM_error_before_running_batch", {{"", true, "error message"}});
90 void BM_error_before_running_range_for(benchmark::State
& state
) {
91 state
.SkipWithError("error message");
92 for (auto _
: state
) {
96 BENCHMARK(BM_error_before_running_range_for
);
97 ADD_CASES("BM_error_before_running_range_for", {{"", true, "error message"}});
99 void BM_error_during_running(benchmark::State
& state
) {
100 int first_iter
= true;
101 while (state
.KeepRunning()) {
102 if (state
.range(0) == 1 && state
.thread_index() <= (state
.threads() / 2)) {
105 state
.SkipWithError("error message");
108 state
.ResumeTiming();
112 BENCHMARK(BM_error_during_running
)->Arg(1)->Arg(2)->ThreadRange(1, 8);
113 ADD_CASES("BM_error_during_running", {{"/1/threads:1", true, "error message"},
114 {"/1/threads:2", true, "error message"},
115 {"/1/threads:4", true, "error message"},
116 {"/1/threads:8", true, "error message"},
117 {"/2/threads:1", false, ""},
118 {"/2/threads:2", false, ""},
119 {"/2/threads:4", false, ""},
120 {"/2/threads:8", false, ""}});
122 void BM_error_during_running_ranged_for(benchmark::State
& state
) {
123 assert(state
.max_iterations
> 3 && "test requires at least a few iterations");
124 bool first_iter
= true;
125 // NOTE: Users should not write the for loop explicitly.
126 for (auto It
= state
.begin(), End
= state
.end(); It
!= End
; ++It
) {
127 if (state
.range(0) == 1) {
131 state
.SkipWithError("error message");
132 // Test the unfortunate but documented behavior that the ranged-for loop
133 // doesn't automatically terminate when SkipWithError is set.
135 break; // Required behavior
139 BENCHMARK(BM_error_during_running_ranged_for
)->Arg(1)->Arg(2)->Iterations(5);
140 ADD_CASES("BM_error_during_running_ranged_for",
141 {{"/1/iterations:5", true, "error message"},
142 {"/2/iterations:5", false, ""}});
144 void BM_error_after_running(benchmark::State
& state
) {
145 for (auto _
: state
) {
146 auto iterations
= double(state
.iterations()) * double(state
.iterations());
147 benchmark::DoNotOptimize(iterations
);
149 if (state
.thread_index() <= (state
.threads() / 2))
150 state
.SkipWithError("error message");
152 BENCHMARK(BM_error_after_running
)->ThreadRange(1, 8);
153 ADD_CASES("BM_error_after_running", {{"/threads:1", true, "error message"},
154 {"/threads:2", true, "error message"},
155 {"/threads:4", true, "error message"},
156 {"/threads:8", true, "error message"}});
158 void BM_error_while_paused(benchmark::State
& state
) {
159 bool first_iter
= true;
160 while (state
.KeepRunning()) {
161 if (state
.range(0) == 1 && state
.thread_index() <= (state
.threads() / 2)) {
165 state
.SkipWithError("error message");
168 state
.ResumeTiming();
172 BENCHMARK(BM_error_while_paused
)->Arg(1)->Arg(2)->ThreadRange(1, 8);
173 ADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"},
174 {"/1/threads:2", true, "error message"},
175 {"/1/threads:4", true, "error message"},
176 {"/1/threads:8", true, "error message"},
177 {"/2/threads:1", false, ""},
178 {"/2/threads:2", false, ""},
179 {"/2/threads:4", false, ""},
180 {"/2/threads:8", false, ""}});
182 int main(int argc
, char* argv
[]) {
183 benchmark::Initialize(&argc
, argv
);
185 TestReporter test_reporter
;
186 benchmark::RunSpecifiedBenchmarks(&test_reporter
);
188 typedef benchmark::BenchmarkReporter::Run Run
;
189 auto EB
= ExpectedResults
.begin();
191 for (Run
const& run
: test_reporter
.all_runs_
) {
192 assert(EB
!= ExpectedResults
.end());
196 assert(EB
== ExpectedResults
.end());