libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

register_benchmark_test.cc (5441B)


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