[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / third-party / benchmark / test / skip_with_error_test.cc
blob2139a19e250717fcc3e5c6557f53fa7abbd7a780
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 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);
22 TestReporter() {}
23 ~TestReporter() override {}
25 mutable std::vector<Run> all_runs_;
28 struct TestCase {
29 std::string name;
30 bool error_occurred;
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);
41 if (error_occurred) {
42 // BM_CHECK(run.iterations == 0);
43 } else {
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) {
53 for (auto TC : v) {
54 TC.name = base_name + TC.name;
55 ExpectedResults.push_back(std::move(TC));
57 return 0;
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__)
64 } // end namespace
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()) {
75 assert(false);
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)) {
84 assert(false);
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) {
93 assert(false);
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)) {
103 assert(first_iter);
104 first_iter = false;
105 state.SkipWithError("error message");
106 } else {
107 state.PauseTiming();
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) {
128 assert(first_iter);
129 first_iter = false;
130 (void)first_iter;
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.
134 assert(++It != End);
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)) {
162 assert(first_iter);
163 first_iter = false;
164 state.PauseTiming();
165 state.SkipWithError("error message");
166 } else {
167 state.PauseTiming();
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());
193 EB->CheckRun(run);
194 ++EB;
196 assert(EB == ExpectedResults.end());
198 return 0;