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 void ReportRuns(const std::vector<Run>& report) override { 14a8c51b3fSopenharmony_ci all_runs_.insert(all_runs_.end(), begin(report), end(report)); 15a8c51b3fSopenharmony_ci ConsoleReporter::ReportRuns(report); 16a8c51b3fSopenharmony_ci } 17a8c51b3fSopenharmony_ci 18a8c51b3fSopenharmony_ci std::vector<Run> all_runs_; 19a8c51b3fSopenharmony_ci}; 20a8c51b3fSopenharmony_ci 21a8c51b3fSopenharmony_cistruct TestCase { 22a8c51b3fSopenharmony_ci const std::string name; 23a8c51b3fSopenharmony_ci const std::string label; 24a8c51b3fSopenharmony_ci // Note: not explicit as we rely on it being converted through ADD_CASES. 25a8c51b3fSopenharmony_ci TestCase(const std::string& xname) : TestCase(xname, "") {} 26a8c51b3fSopenharmony_ci TestCase(const std::string& xname, const std::string& xlabel) 27a8c51b3fSopenharmony_ci : name(xname), label(xlabel) {} 28a8c51b3fSopenharmony_ci 29a8c51b3fSopenharmony_ci typedef benchmark::BenchmarkReporter::Run Run; 30a8c51b3fSopenharmony_ci 31a8c51b3fSopenharmony_ci void CheckRun(Run const& run) const { 32a8c51b3fSopenharmony_ci // clang-format off 33a8c51b3fSopenharmony_ci BM_CHECK(name == run.benchmark_name()) << "expected " << name << " got " 34a8c51b3fSopenharmony_ci << run.benchmark_name(); 35a8c51b3fSopenharmony_ci if (!label.empty()) { 36a8c51b3fSopenharmony_ci BM_CHECK(run.report_label == label) << "expected " << label << " got " 37a8c51b3fSopenharmony_ci << run.report_label; 38a8c51b3fSopenharmony_ci } else { 39a8c51b3fSopenharmony_ci BM_CHECK(run.report_label.empty()); 40a8c51b3fSopenharmony_ci } 41a8c51b3fSopenharmony_ci // clang-format on 42a8c51b3fSopenharmony_ci } 43a8c51b3fSopenharmony_ci}; 44a8c51b3fSopenharmony_ci 45a8c51b3fSopenharmony_cistd::vector<TestCase> ExpectedResults; 46a8c51b3fSopenharmony_ci 47a8c51b3fSopenharmony_ciint AddCases(std::initializer_list<TestCase> const& v) { 48a8c51b3fSopenharmony_ci for (const auto& N : v) { 49a8c51b3fSopenharmony_ci ExpectedResults.push_back(N); 50a8c51b3fSopenharmony_ci } 51a8c51b3fSopenharmony_ci return 0; 52a8c51b3fSopenharmony_ci} 53a8c51b3fSopenharmony_ci 54a8c51b3fSopenharmony_ci#define CONCAT(x, y) CONCAT2(x, y) 55a8c51b3fSopenharmony_ci#define CONCAT2(x, y) x##y 56a8c51b3fSopenharmony_ci#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__}) 57a8c51b3fSopenharmony_ci 58a8c51b3fSopenharmony_ci} // end namespace 59a8c51b3fSopenharmony_ci 60a8c51b3fSopenharmony_citypedef benchmark::internal::Benchmark* ReturnVal; 61a8c51b3fSopenharmony_ci 62a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 63a8c51b3fSopenharmony_ci// Test RegisterBenchmark with no additional arguments 64a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 65a8c51b3fSopenharmony_civoid BM_function(benchmark::State& state) { 66a8c51b3fSopenharmony_ci for (auto _ : state) { 67a8c51b3fSopenharmony_ci } 68a8c51b3fSopenharmony_ci} 69a8c51b3fSopenharmony_ciBENCHMARK(BM_function); 70a8c51b3fSopenharmony_ciReturnVal dummy = benchmark::RegisterBenchmark( 71a8c51b3fSopenharmony_ci "BM_function_manual_registration", BM_function); 72a8c51b3fSopenharmony_ciADD_CASES({"BM_function"}, {"BM_function_manual_registration"}); 73a8c51b3fSopenharmony_ci 74a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 75a8c51b3fSopenharmony_ci// Test RegisterBenchmark with additional arguments 76a8c51b3fSopenharmony_ci// Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they 77a8c51b3fSopenharmony_ci// reject the variadic pack expansion of lambda captures. 78a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 79a8c51b3fSopenharmony_ci#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK 80a8c51b3fSopenharmony_ci 81a8c51b3fSopenharmony_civoid BM_extra_args(benchmark::State& st, const char* label) { 82a8c51b3fSopenharmony_ci for (auto _ : st) { 83a8c51b3fSopenharmony_ci } 84a8c51b3fSopenharmony_ci st.SetLabel(label); 85a8c51b3fSopenharmony_ci} 86a8c51b3fSopenharmony_ciint RegisterFromFunction() { 87a8c51b3fSopenharmony_ci std::pair<const char*, const char*> cases[] = { 88a8c51b3fSopenharmony_ci {"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}}; 89a8c51b3fSopenharmony_ci for (auto const& c : cases) 90a8c51b3fSopenharmony_ci benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second); 91a8c51b3fSopenharmony_ci return 0; 92a8c51b3fSopenharmony_ci} 93a8c51b3fSopenharmony_ciint dummy2 = RegisterFromFunction(); 94a8c51b3fSopenharmony_ciADD_CASES({"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}); 95a8c51b3fSopenharmony_ci 96a8c51b3fSopenharmony_ci#endif // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK 97a8c51b3fSopenharmony_ci 98a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 99a8c51b3fSopenharmony_ci// Test RegisterBenchmark with DISABLED_ benchmark 100a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 101a8c51b3fSopenharmony_civoid DISABLED_BM_function(benchmark::State& state) { 102a8c51b3fSopenharmony_ci for (auto _ : state) { 103a8c51b3fSopenharmony_ci } 104a8c51b3fSopenharmony_ci} 105a8c51b3fSopenharmony_ciBENCHMARK(DISABLED_BM_function); 106a8c51b3fSopenharmony_ciReturnVal dummy3 = benchmark::RegisterBenchmark("DISABLED_BM_function_manual", 107a8c51b3fSopenharmony_ci DISABLED_BM_function); 108a8c51b3fSopenharmony_ci// No need to add cases because we don't expect them to run. 109a8c51b3fSopenharmony_ci 110a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 111a8c51b3fSopenharmony_ci// Test RegisterBenchmark with different callable types 112a8c51b3fSopenharmony_ci//----------------------------------------------------------------------------// 113a8c51b3fSopenharmony_ci 114a8c51b3fSopenharmony_cistruct CustomFixture { 115a8c51b3fSopenharmony_ci void operator()(benchmark::State& st) { 116a8c51b3fSopenharmony_ci for (auto _ : st) { 117a8c51b3fSopenharmony_ci } 118a8c51b3fSopenharmony_ci } 119a8c51b3fSopenharmony_ci}; 120a8c51b3fSopenharmony_ci 121a8c51b3fSopenharmony_civoid TestRegistrationAtRuntime() { 122a8c51b3fSopenharmony_ci#ifdef BENCHMARK_HAS_CXX11 123a8c51b3fSopenharmony_ci { 124a8c51b3fSopenharmony_ci CustomFixture fx; 125a8c51b3fSopenharmony_ci benchmark::RegisterBenchmark("custom_fixture", fx); 126a8c51b3fSopenharmony_ci AddCases({std::string("custom_fixture")}); 127a8c51b3fSopenharmony_ci } 128a8c51b3fSopenharmony_ci#endif 129a8c51b3fSopenharmony_ci#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK 130a8c51b3fSopenharmony_ci { 131a8c51b3fSopenharmony_ci const char* x = "42"; 132a8c51b3fSopenharmony_ci auto capturing_lam = [=](benchmark::State& st) { 133a8c51b3fSopenharmony_ci for (auto _ : st) { 134a8c51b3fSopenharmony_ci } 135a8c51b3fSopenharmony_ci st.SetLabel(x); 136a8c51b3fSopenharmony_ci }; 137a8c51b3fSopenharmony_ci benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam); 138a8c51b3fSopenharmony_ci AddCases({{"lambda_benchmark", x}}); 139a8c51b3fSopenharmony_ci } 140a8c51b3fSopenharmony_ci#endif 141a8c51b3fSopenharmony_ci} 142a8c51b3fSopenharmony_ci 143a8c51b3fSopenharmony_ci// Test that all benchmarks, registered at either during static init or runtime, 144a8c51b3fSopenharmony_ci// are run and the results are passed to the reported. 145a8c51b3fSopenharmony_civoid RunTestOne() { 146a8c51b3fSopenharmony_ci TestRegistrationAtRuntime(); 147a8c51b3fSopenharmony_ci 148a8c51b3fSopenharmony_ci TestReporter test_reporter; 149a8c51b3fSopenharmony_ci benchmark::RunSpecifiedBenchmarks(&test_reporter); 150a8c51b3fSopenharmony_ci 151a8c51b3fSopenharmony_ci typedef benchmark::BenchmarkReporter::Run Run; 152a8c51b3fSopenharmony_ci auto EB = ExpectedResults.begin(); 153a8c51b3fSopenharmony_ci 154a8c51b3fSopenharmony_ci for (Run const& run : test_reporter.all_runs_) { 155a8c51b3fSopenharmony_ci assert(EB != ExpectedResults.end()); 156a8c51b3fSopenharmony_ci EB->CheckRun(run); 157a8c51b3fSopenharmony_ci ++EB; 158a8c51b3fSopenharmony_ci } 159a8c51b3fSopenharmony_ci assert(EB == ExpectedResults.end()); 160a8c51b3fSopenharmony_ci} 161a8c51b3fSopenharmony_ci 162a8c51b3fSopenharmony_ci// Test that ClearRegisteredBenchmarks() clears all previously registered 163a8c51b3fSopenharmony_ci// benchmarks. 164a8c51b3fSopenharmony_ci// Also test that new benchmarks can be registered and ran afterwards. 165a8c51b3fSopenharmony_civoid RunTestTwo() { 166a8c51b3fSopenharmony_ci assert(ExpectedResults.size() != 0 && 167a8c51b3fSopenharmony_ci "must have at least one registered benchmark"); 168a8c51b3fSopenharmony_ci ExpectedResults.clear(); 169a8c51b3fSopenharmony_ci benchmark::ClearRegisteredBenchmarks(); 170a8c51b3fSopenharmony_ci 171a8c51b3fSopenharmony_ci TestReporter test_reporter; 172a8c51b3fSopenharmony_ci size_t num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter); 173a8c51b3fSopenharmony_ci assert(num_ran == 0); 174a8c51b3fSopenharmony_ci assert(test_reporter.all_runs_.begin() == test_reporter.all_runs_.end()); 175a8c51b3fSopenharmony_ci 176a8c51b3fSopenharmony_ci TestRegistrationAtRuntime(); 177a8c51b3fSopenharmony_ci num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter); 178a8c51b3fSopenharmony_ci assert(num_ran == ExpectedResults.size()); 179a8c51b3fSopenharmony_ci 180a8c51b3fSopenharmony_ci typedef benchmark::BenchmarkReporter::Run Run; 181a8c51b3fSopenharmony_ci auto EB = ExpectedResults.begin(); 182a8c51b3fSopenharmony_ci 183a8c51b3fSopenharmony_ci for (Run const& run : test_reporter.all_runs_) { 184a8c51b3fSopenharmony_ci assert(EB != ExpectedResults.end()); 185a8c51b3fSopenharmony_ci EB->CheckRun(run); 186a8c51b3fSopenharmony_ci ++EB; 187a8c51b3fSopenharmony_ci } 188a8c51b3fSopenharmony_ci assert(EB == ExpectedResults.end()); 189a8c51b3fSopenharmony_ci} 190a8c51b3fSopenharmony_ci 191a8c51b3fSopenharmony_ciint main(int argc, char* argv[]) { 192a8c51b3fSopenharmony_ci benchmark::Initialize(&argc, argv); 193a8c51b3fSopenharmony_ci 194a8c51b3fSopenharmony_ci RunTestOne(); 195a8c51b3fSopenharmony_ci RunTestTwo(); 196a8c51b3fSopenharmony_ci} 197