127 lines · plain
1#include <queue>2#include <string>3#include <vector>4 5#include "../src/commandlineflags.h"6#include "../src/string_util.h"7#include "benchmark/benchmark.h"8#include "gmock/gmock.h"9#include "gtest/gtest.h"10 11namespace benchmark {12 13BM_DECLARE_bool(benchmark_enable_random_interleaving);14BM_DECLARE_string(benchmark_filter);15BM_DECLARE_int32(benchmark_repetitions);16 17namespace internal {18namespace {19 20class EventQueue : public std::queue<std::string> {21 public:22 void Put(const std::string& event) { push(event); }23 24 void Clear() {25 while (!empty()) {26 pop();27 }28 }29 30 std::string Get() {31 std::string event = front();32 pop();33 return event;34 }35};36 37EventQueue* queue = new EventQueue();38 39class NullReporter : public BenchmarkReporter {40 public:41 bool ReportContext(const Context& /*context*/) override { return true; }42 void ReportRuns(const std::vector<Run>& /* report */) override {}43};44 45class BenchmarkTest : public testing::Test {46 public:47 static void SetupHook(int /* num_threads */) { queue->push("Setup"); }48 49 static void TeardownHook(int /* num_threads */) { queue->push("Teardown"); }50 51 void Execute(const std::string& pattern) {52 queue->Clear();53 54 std::unique_ptr<BenchmarkReporter> reporter(new NullReporter());55 FLAGS_benchmark_filter = pattern;56 RunSpecifiedBenchmarks(reporter.get());57 58 queue->Put("DONE"); // End marker59 }60};61 62void BM_Match1(benchmark::State& state) {63 const int64_t arg = state.range(0);64 65 for (auto _ : state) {66 }67 queue->Put(StrFormat("BM_Match1/%d", static_cast<int>(arg)));68}69BENCHMARK(BM_Match1)70 ->Iterations(100)71 ->Arg(1)72 ->Arg(2)73 ->Arg(3)74 ->Range(10, 80)75 ->Args({90})76 ->Args({100});77 78TEST_F(BenchmarkTest, Match1) {79 Execute("BM_Match1");80 ASSERT_EQ("BM_Match1/1", queue->Get());81 ASSERT_EQ("BM_Match1/2", queue->Get());82 ASSERT_EQ("BM_Match1/3", queue->Get());83 ASSERT_EQ("BM_Match1/10", queue->Get());84 ASSERT_EQ("BM_Match1/64", queue->Get());85 ASSERT_EQ("BM_Match1/80", queue->Get());86 ASSERT_EQ("BM_Match1/90", queue->Get());87 ASSERT_EQ("BM_Match1/100", queue->Get());88 ASSERT_EQ("DONE", queue->Get());89}90 91TEST_F(BenchmarkTest, Match1WithRepetition) {92 FLAGS_benchmark_repetitions = 2;93 94 Execute("BM_Match1/(64|80)");95 ASSERT_EQ("BM_Match1/64", queue->Get());96 ASSERT_EQ("BM_Match1/64", queue->Get());97 ASSERT_EQ("BM_Match1/80", queue->Get());98 ASSERT_EQ("BM_Match1/80", queue->Get());99 ASSERT_EQ("DONE", queue->Get());100}101 102TEST_F(BenchmarkTest, Match1WithRandomInterleaving) {103 FLAGS_benchmark_enable_random_interleaving = true;104 FLAGS_benchmark_repetitions = 100;105 106 std::map<std::string, int> element_count;107 std::map<std::string, int> interleaving_count;108 Execute("BM_Match1/(64|80)");109 for (int i = 0; i < 100; ++i) {110 std::vector<std::string> interleaving;111 interleaving.push_back(queue->Get());112 interleaving.push_back(queue->Get());113 element_count[interleaving[0]]++;114 element_count[interleaving[1]]++;115 interleaving_count[StrFormat("%s,%s", interleaving[0].c_str(),116 interleaving[1].c_str())]++;117 }118 EXPECT_EQ(element_count["BM_Match1/64"], 100) << "Unexpected repetitions.";119 EXPECT_EQ(element_count["BM_Match1/80"], 100) << "Unexpected repetitions.";120 EXPECT_GE(interleaving_count.size(), 2) << "Interleaving was not randomized.";121 ASSERT_EQ("DONE", queue->Get());122}123 124} // namespace125} // namespace internal126} // namespace benchmark127