1a8c51b3fSopenharmony_ci 2a8c51b3fSopenharmony_ci#undef NDEBUG 3a8c51b3fSopenharmony_ci#include <cassert> 4a8c51b3fSopenharmony_ci#include <vector> 5a8c51b3fSopenharmony_ci 6a8c51b3fSopenharmony_ci#include "../src/check.h" // NOTE: check.h is for internal use only! 7a8c51b3fSopenharmony_ci#include "benchmark/benchmark.h" 8a8c51b3fSopenharmony_ci 9a8c51b3fSopenharmony_cinamespace { 10a8c51b3fSopenharmony_ci 11a8c51b3fSopenharmony_ciclass TestReporter : public benchmark::ConsoleReporter { 12a8c51b3fSopenharmony_ci public: 13a8c51b3fSopenharmony_ci bool ReportContext(const Context& context) override { 14a8c51b3fSopenharmony_ci return ConsoleReporter::ReportContext(context); 15a8c51b3fSopenharmony_ci }; 16a8c51b3fSopenharmony_ci 17a8c51b3fSopenharmony_ci void ReportRuns(const std::vector<Run>& report) override { 18a8c51b3fSopenharmony_ci all_runs_.insert(all_runs_.end(), begin(report), end(report)); 19a8c51b3fSopenharmony_ci ConsoleReporter::ReportRuns(report); 20a8c51b3fSopenharmony_ci } 21a8c51b3fSopenharmony_ci 22a8c51b3fSopenharmony_ci TestReporter() {} 23a8c51b3fSopenharmony_ci ~TestReporter() override {} 24a8c51b3fSopenharmony_ci 25a8c51b3fSopenharmony_ci mutable std::vector<Run> all_runs_; 26a8c51b3fSopenharmony_ci}; 27a8c51b3fSopenharmony_ci 28a8c51b3fSopenharmony_cistruct TestCase { 29a8c51b3fSopenharmony_ci std::string name; 30a8c51b3fSopenharmony_ci bool error_occurred; 31a8c51b3fSopenharmony_ci std::string error_message; 32a8c51b3fSopenharmony_ci 33a8c51b3fSopenharmony_ci typedef benchmark::BenchmarkReporter::Run Run; 34a8c51b3fSopenharmony_ci 35a8c51b3fSopenharmony_ci void CheckRun(Run const& run) const { 36a8c51b3fSopenharmony_ci BM_CHECK(name == run.benchmark_name()) 37a8c51b3fSopenharmony_ci << "expected " << name << " got " << run.benchmark_name(); 38a8c51b3fSopenharmony_ci BM_CHECK_EQ(error_occurred, 39a8c51b3fSopenharmony_ci benchmark::internal::SkippedWithError == run.skipped); 40a8c51b3fSopenharmony_ci BM_CHECK(error_message == run.skip_message); 41a8c51b3fSopenharmony_ci if (error_occurred) { 42a8c51b3fSopenharmony_ci // BM_CHECK(run.iterations == 0); 43a8c51b3fSopenharmony_ci } else { 44a8c51b3fSopenharmony_ci BM_CHECK(run.iterations != 0); 45a8c51b3fSopenharmony_ci } 46a8c51b3fSopenharmony_ci } 47a8c51b3fSopenharmony_ci}; 48a8c51b3fSopenharmony_ci 49a8c51b3fSopenharmony_cistd::vector<TestCase> ExpectedResults; 50a8c51b3fSopenharmony_ci 51a8c51b3fSopenharmony_ciint AddCases(const std::string& base_name, 52a8c51b3fSopenharmony_ci std::initializer_list<TestCase> const& v) { 53a8c51b3fSopenharmony_ci for (auto TC : v) { 54a8c51b3fSopenharmony_ci TC.name = base_name + TC.name; 55a8c51b3fSopenharmony_ci ExpectedResults.push_back(std::move(TC)); 56a8c51b3fSopenharmony_ci } 57a8c51b3fSopenharmony_ci return 0; 58a8c51b3fSopenharmony_ci} 59a8c51b3fSopenharmony_ci 60a8c51b3fSopenharmony_ci#define CONCAT(x, y) CONCAT2(x, y) 61a8c51b3fSopenharmony_ci#define CONCAT2(x, y) x##y 62a8c51b3fSopenharmony_ci#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__) 63a8c51b3fSopenharmony_ci 64a8c51b3fSopenharmony_ci} // end namespace 65a8c51b3fSopenharmony_ci 66a8c51b3fSopenharmony_civoid BM_error_no_running(benchmark::State& state) { 67a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 68a8c51b3fSopenharmony_ci} 69a8c51b3fSopenharmony_ciBENCHMARK(BM_error_no_running); 70a8c51b3fSopenharmony_ciADD_CASES("BM_error_no_running", {{"", true, "error message"}}); 71a8c51b3fSopenharmony_ci 72a8c51b3fSopenharmony_civoid BM_error_before_running(benchmark::State& state) { 73a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 74a8c51b3fSopenharmony_ci while (state.KeepRunning()) { 75a8c51b3fSopenharmony_ci assert(false); 76a8c51b3fSopenharmony_ci } 77a8c51b3fSopenharmony_ci} 78a8c51b3fSopenharmony_ciBENCHMARK(BM_error_before_running); 79a8c51b3fSopenharmony_ciADD_CASES("BM_error_before_running", {{"", true, "error message"}}); 80a8c51b3fSopenharmony_ci 81a8c51b3fSopenharmony_civoid BM_error_before_running_batch(benchmark::State& state) { 82a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 83a8c51b3fSopenharmony_ci while (state.KeepRunningBatch(17)) { 84a8c51b3fSopenharmony_ci assert(false); 85a8c51b3fSopenharmony_ci } 86a8c51b3fSopenharmony_ci} 87a8c51b3fSopenharmony_ciBENCHMARK(BM_error_before_running_batch); 88a8c51b3fSopenharmony_ciADD_CASES("BM_error_before_running_batch", {{"", true, "error message"}}); 89a8c51b3fSopenharmony_ci 90a8c51b3fSopenharmony_civoid BM_error_before_running_range_for(benchmark::State& state) { 91a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 92a8c51b3fSopenharmony_ci for (auto _ : state) { 93a8c51b3fSopenharmony_ci assert(false); 94a8c51b3fSopenharmony_ci } 95a8c51b3fSopenharmony_ci} 96a8c51b3fSopenharmony_ciBENCHMARK(BM_error_before_running_range_for); 97a8c51b3fSopenharmony_ciADD_CASES("BM_error_before_running_range_for", {{"", true, "error message"}}); 98a8c51b3fSopenharmony_ci 99a8c51b3fSopenharmony_civoid BM_error_during_running(benchmark::State& state) { 100a8c51b3fSopenharmony_ci int first_iter = true; 101a8c51b3fSopenharmony_ci while (state.KeepRunning()) { 102a8c51b3fSopenharmony_ci if (state.range(0) == 1 && state.thread_index() <= (state.threads() / 2)) { 103a8c51b3fSopenharmony_ci assert(first_iter); 104a8c51b3fSopenharmony_ci first_iter = false; 105a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 106a8c51b3fSopenharmony_ci } else { 107a8c51b3fSopenharmony_ci state.PauseTiming(); 108a8c51b3fSopenharmony_ci state.ResumeTiming(); 109a8c51b3fSopenharmony_ci } 110a8c51b3fSopenharmony_ci } 111a8c51b3fSopenharmony_ci} 112a8c51b3fSopenharmony_ciBENCHMARK(BM_error_during_running)->Arg(1)->Arg(2)->ThreadRange(1, 8); 113a8c51b3fSopenharmony_ciADD_CASES("BM_error_during_running", {{"/1/threads:1", true, "error message"}, 114a8c51b3fSopenharmony_ci {"/1/threads:2", true, "error message"}, 115a8c51b3fSopenharmony_ci {"/1/threads:4", true, "error message"}, 116a8c51b3fSopenharmony_ci {"/1/threads:8", true, "error message"}, 117a8c51b3fSopenharmony_ci {"/2/threads:1", false, ""}, 118a8c51b3fSopenharmony_ci {"/2/threads:2", false, ""}, 119a8c51b3fSopenharmony_ci {"/2/threads:4", false, ""}, 120a8c51b3fSopenharmony_ci {"/2/threads:8", false, ""}}); 121a8c51b3fSopenharmony_ci 122a8c51b3fSopenharmony_civoid BM_error_during_running_ranged_for(benchmark::State& state) { 123a8c51b3fSopenharmony_ci assert(state.max_iterations > 3 && "test requires at least a few iterations"); 124a8c51b3fSopenharmony_ci bool first_iter = true; 125a8c51b3fSopenharmony_ci // NOTE: Users should not write the for loop explicitly. 126a8c51b3fSopenharmony_ci for (auto It = state.begin(), End = state.end(); It != End; ++It) { 127a8c51b3fSopenharmony_ci if (state.range(0) == 1) { 128a8c51b3fSopenharmony_ci assert(first_iter); 129a8c51b3fSopenharmony_ci first_iter = false; 130a8c51b3fSopenharmony_ci (void)first_iter; 131a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 132a8c51b3fSopenharmony_ci // Test the unfortunate but documented behavior that the ranged-for loop 133a8c51b3fSopenharmony_ci // doesn't automatically terminate when SkipWithError is set. 134a8c51b3fSopenharmony_ci assert(++It != End); 135a8c51b3fSopenharmony_ci break; // Required behavior 136a8c51b3fSopenharmony_ci } 137a8c51b3fSopenharmony_ci } 138a8c51b3fSopenharmony_ci} 139a8c51b3fSopenharmony_ciBENCHMARK(BM_error_during_running_ranged_for)->Arg(1)->Arg(2)->Iterations(5); 140a8c51b3fSopenharmony_ciADD_CASES("BM_error_during_running_ranged_for", 141a8c51b3fSopenharmony_ci {{"/1/iterations:5", true, "error message"}, 142a8c51b3fSopenharmony_ci {"/2/iterations:5", false, ""}}); 143a8c51b3fSopenharmony_ci 144a8c51b3fSopenharmony_civoid BM_error_after_running(benchmark::State& state) { 145a8c51b3fSopenharmony_ci for (auto _ : state) { 146a8c51b3fSopenharmony_ci auto iterations = state.iterations(); 147a8c51b3fSopenharmony_ci benchmark::DoNotOptimize(iterations); 148a8c51b3fSopenharmony_ci } 149a8c51b3fSopenharmony_ci if (state.thread_index() <= (state.threads() / 2)) 150a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 151a8c51b3fSopenharmony_ci} 152a8c51b3fSopenharmony_ciBENCHMARK(BM_error_after_running)->ThreadRange(1, 8); 153a8c51b3fSopenharmony_ciADD_CASES("BM_error_after_running", {{"/threads:1", true, "error message"}, 154a8c51b3fSopenharmony_ci {"/threads:2", true, "error message"}, 155a8c51b3fSopenharmony_ci {"/threads:4", true, "error message"}, 156a8c51b3fSopenharmony_ci {"/threads:8", true, "error message"}}); 157a8c51b3fSopenharmony_ci 158a8c51b3fSopenharmony_civoid BM_error_while_paused(benchmark::State& state) { 159a8c51b3fSopenharmony_ci bool first_iter = true; 160a8c51b3fSopenharmony_ci while (state.KeepRunning()) { 161a8c51b3fSopenharmony_ci if (state.range(0) == 1 && state.thread_index() <= (state.threads() / 2)) { 162a8c51b3fSopenharmony_ci assert(first_iter); 163a8c51b3fSopenharmony_ci first_iter = false; 164a8c51b3fSopenharmony_ci state.PauseTiming(); 165a8c51b3fSopenharmony_ci state.SkipWithError("error message"); 166a8c51b3fSopenharmony_ci } else { 167a8c51b3fSopenharmony_ci state.PauseTiming(); 168a8c51b3fSopenharmony_ci state.ResumeTiming(); 169a8c51b3fSopenharmony_ci } 170a8c51b3fSopenharmony_ci } 171a8c51b3fSopenharmony_ci} 172a8c51b3fSopenharmony_ciBENCHMARK(BM_error_while_paused)->Arg(1)->Arg(2)->ThreadRange(1, 8); 173a8c51b3fSopenharmony_ciADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"}, 174a8c51b3fSopenharmony_ci {"/1/threads:2", true, "error message"}, 175a8c51b3fSopenharmony_ci {"/1/threads:4", true, "error message"}, 176a8c51b3fSopenharmony_ci {"/1/threads:8", true, "error message"}, 177a8c51b3fSopenharmony_ci {"/2/threads:1", false, ""}, 178a8c51b3fSopenharmony_ci {"/2/threads:2", false, ""}, 179a8c51b3fSopenharmony_ci {"/2/threads:4", false, ""}, 180a8c51b3fSopenharmony_ci {"/2/threads:8", false, ""}}); 181a8c51b3fSopenharmony_ci 182a8c51b3fSopenharmony_ciint main(int argc, char* argv[]) { 183a8c51b3fSopenharmony_ci benchmark::Initialize(&argc, argv); 184a8c51b3fSopenharmony_ci 185a8c51b3fSopenharmony_ci TestReporter test_reporter; 186a8c51b3fSopenharmony_ci benchmark::RunSpecifiedBenchmarks(&test_reporter); 187a8c51b3fSopenharmony_ci 188a8c51b3fSopenharmony_ci typedef benchmark::BenchmarkReporter::Run Run; 189a8c51b3fSopenharmony_ci auto EB = ExpectedResults.begin(); 190a8c51b3fSopenharmony_ci 191a8c51b3fSopenharmony_ci for (Run const& run : test_reporter.all_runs_) { 192a8c51b3fSopenharmony_ci assert(EB != ExpectedResults.end()); 193a8c51b3fSopenharmony_ci EB->CheckRun(run); 194a8c51b3fSopenharmony_ci ++EB; 195a8c51b3fSopenharmony_ci } 196a8c51b3fSopenharmony_ci assert(EB == ExpectedResults.end()); 197a8c51b3fSopenharmony_ci 198a8c51b3fSopenharmony_ci return 0; 199a8c51b3fSopenharmony_ci} 200