benchmark/test/output_test.h
Go to the documentation of this file.
1 #ifndef TEST_OUTPUT_TEST_H
2 #define TEST_OUTPUT_TEST_H
3 
4 #undef NDEBUG
5 #include <functional>
6 #include <initializer_list>
7 #include <memory>
8 #include <sstream>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "../src/re.h"
14 #include "benchmark/benchmark.h"
15 
16 #define CONCAT2(x, y) x##y
17 #define CONCAT(x, y) CONCAT2(x, y)
18 
19 #define ADD_CASES(...) int CONCAT(dummy, __LINE__) = ::AddCases(__VA_ARGS__)
20 
21 #define SET_SUBSTITUTIONS(...) \
22  int CONCAT(dummy, __LINE__) = ::SetSubstitutions(__VA_ARGS__)
23 
24 enum MatchRules {
25  MR_Default, // Skip non-matching lines until a match is found.
26  MR_Next, // Match must occur on the next line.
27  MR_Not // No line between the current position and the next match matches
28  // the regex
29 };
30 
31 struct TestCase {
32  TestCase(std::string re, int rule = MR_Default);
33 
37  std::shared_ptr<benchmark::Regex> regex;
38 };
39 
40 enum TestCaseID {
47 
48  TC_NumID // PRIVATE
49 };
50 
51 // Add a list of test cases to be run against the output specified by
52 // 'ID'
53 int AddCases(TestCaseID ID, std::initializer_list<TestCase> il);
54 
55 // Add or set a list of substitutions to be performed on constructed regex's
56 // See 'output_test_helper.cc' for a list of default substitutions.
58  std::initializer_list<std::pair<std::string, std::string>> il);
59 
60 // Run all output tests.
61 void RunOutputTests(int argc, char* argv[]);
62 
63 // Count the number of 'pat' substrings in the 'haystack' string.
64 int SubstrCnt(const std::string& haystack, const std::string& pat);
65 
66 // Run registered benchmarks with file reporter enabled, and return the content
67 // outputted by the file reporter.
68 std::string GetFileReporterOutput(int argc, char* argv[]);
69 
70 // ========================================================================= //
71 // ------------------------- Results checking ------------------------------ //
72 // ========================================================================= //
73 
74 // Call this macro to register a benchmark for checking its results. This
75 // should be all that's needed. It subscribes a function to check the (CSV)
76 // results of a benchmark. This is done only after verifying that the output
77 // strings are really as expected.
78 // bm_name_pattern: a name or a regex pattern which will be matched against
79 // all the benchmark names. Matching benchmarks
80 // will be the subject of a call to checker_function
81 // checker_function: should be of type ResultsCheckFn (see below)
82 #define CHECK_BENCHMARK_RESULTS(bm_name_pattern, checker_function) \
83  size_t CONCAT(dummy, __LINE__) = AddChecker(bm_name_pattern, checker_function)
84 
85 struct Results;
86 typedef std::function<void(Results const&)> ResultsCheckFn;
87 
88 size_t AddChecker(const char* bm_name_pattern, ResultsCheckFn fn);
89 
90 // Class holding the results of a benchmark.
91 // It is passed in calls to checker functions.
92 struct Results {
93  // the benchmark name
95  // the benchmark fields
96  std::map<std::string, std::string> values;
97 
98  Results(const std::string& n) : name(n) {}
99 
100  int NumThreads() const;
101 
102  double NumIterations() const;
103 
104  typedef enum { kCpuTime, kRealTime } BenchmarkTime;
105 
106  // get cpu_time or real_time in seconds
107  double GetTime(BenchmarkTime which) const;
108 
109  // get the real_time duration of the benchmark in seconds.
110  // it is better to use fuzzy float checks for this, as the float
111  // ASCII formatting is lossy.
112  double DurationRealTime() const {
113  return NumIterations() * GetTime(kRealTime);
114  }
115  // get the cpu_time duration of the benchmark in seconds
116  double DurationCPUTime() const {
117  return NumIterations() * GetTime(kCpuTime);
118  }
119 
120  // get the string for a result by name, or nullptr if the name
121  // is not found
122  const std::string* Get(const char* entry_name) const {
123  auto it = values.find(entry_name);
124  if (it == values.end()) return nullptr;
125  return &it->second;
126  }
127 
128  // get a result by name, parsed as a specific type.
129  // NOTE: for counters, use GetCounterAs instead.
130  template <class T>
131  T GetAs(const char* entry_name) const;
132 
133  // counters are written as doubles, so they have to be read first
134  // as a double, and only then converted to the asked type.
135  template <class T>
136  T GetCounterAs(const char* entry_name) const {
137  double dval = GetAs<double>(entry_name);
138  T tval = static_cast<T>(dval);
139  return tval;
140  }
141 };
142 
143 template <class T>
144 T Results::GetAs(const char* entry_name) const {
145  auto* sv = Get(entry_name);
146  BM_CHECK(sv != nullptr && !sv->empty());
147  std::stringstream ss;
148  ss << *sv;
149  T out;
150  ss >> out;
151  BM_CHECK(!ss.fail());
152  return out;
153 }
154 
155 //----------------------------------
156 // Macros to help in result checking. Do not use them with arguments causing
157 // side-effects.
158 
159 // clang-format off
160 
161 #define CHECK_RESULT_VALUE_IMPL(entry, getfn, var_type, var_name, relationship, value) \
162  CONCAT(BM_CHECK_, relationship) \
163  (entry.getfn< var_type >(var_name), (value)) << "\n" \
164  << __FILE__ << ":" << __LINE__ << ": " << (entry).name << ":\n" \
165  << __FILE__ << ":" << __LINE__ << ": " \
166  << "expected (" << #var_type << ")" << (var_name) \
167  << "=" << (entry).getfn< var_type >(var_name) \
168  << " to be " #relationship " to " << (value) << "\n"
169 
170 // check with tolerance. eps_factor is the tolerance window, which is
171 // interpreted relative to value (eg, 0.1 means 10% of value).
172 #define CHECK_FLOAT_RESULT_VALUE_IMPL(entry, getfn, var_type, var_name, relationship, value, eps_factor) \
173  CONCAT(BM_CHECK_FLOAT_, relationship) \
174  (entry.getfn< var_type >(var_name), (value), (eps_factor) * (value)) << "\n" \
175  << __FILE__ << ":" << __LINE__ << ": " << (entry).name << ":\n" \
176  << __FILE__ << ":" << __LINE__ << ": " \
177  << "expected (" << #var_type << ")" << (var_name) \
178  << "=" << (entry).getfn< var_type >(var_name) \
179  << " to be " #relationship " to " << (value) << "\n" \
180  << __FILE__ << ":" << __LINE__ << ": " \
181  << "with tolerance of " << (eps_factor) * (value) \
182  << " (" << (eps_factor)*100. << "%), " \
183  << "but delta was " << ((entry).getfn< var_type >(var_name) - (value)) \
184  << " (" << (((entry).getfn< var_type >(var_name) - (value)) \
185  / \
186  ((value) > 1.e-5 || value < -1.e-5 ? value : 1.e-5)*100.) \
187  << "%)"
188 
189 #define CHECK_RESULT_VALUE(entry, var_type, var_name, relationship, value) \
190  CHECK_RESULT_VALUE_IMPL(entry, GetAs, var_type, var_name, relationship, value)
191 
192 #define CHECK_COUNTER_VALUE(entry, var_type, var_name, relationship, value) \
193  CHECK_RESULT_VALUE_IMPL(entry, GetCounterAs, var_type, var_name, relationship, value)
194 
195 #define CHECK_FLOAT_RESULT_VALUE(entry, var_name, relationship, value, eps_factor) \
196  CHECK_FLOAT_RESULT_VALUE_IMPL(entry, GetAs, double, var_name, relationship, value, eps_factor)
197 
198 #define CHECK_FLOAT_COUNTER_VALUE(entry, var_name, relationship, value, eps_factor) \
199  CHECK_FLOAT_RESULT_VALUE_IMPL(entry, GetCounterAs, double, var_name, relationship, value, eps_factor)
200 
201 // clang-format on
202 
203 // ========================================================================= //
204 // --------------------------- Misc Utilities ------------------------------ //
205 // ========================================================================= //
206 
207 namespace {
208 
209 const char* const dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?";
210 
211 } // end namespace
212 
213 #endif // TEST_OUTPUT_TEST_H
GetFileReporterOutput
std::string GetFileReporterOutput(int argc, char *argv[])
Definition: benchmark/test/output_test_helper.cc:501
Results::DurationCPUTime
double DurationCPUTime() const
Definition: benchmark/test/output_test.h:116
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
regen-readme.it
it
Definition: regen-readme.py:15
Results::NumThreads
int NumThreads() const
Definition: benchmark/test/output_test_helper.cc:308
TC_NumID
@ TC_NumID
Definition: benchmark/test/output_test.h:48
ResultsCheckFn
std::function< void(Results const &)> ResultsCheckFn
Definition: benchmark/test/output_test.h:85
TestCase::substituted_regex
std::string substituted_regex
Definition: benchmark/test/output_test.h:36
BM_CHECK
#define BM_CHECK(b)
Definition: benchmark/src/check.h:58
Results::GetCounterAs
T GetCounterAs(const char *entry_name) const
Definition: benchmark/test/output_test.h:136
TC_CSVErr
@ TC_CSVErr
Definition: benchmark/test/output_test.h:46
TestCase::regex_str
std::string regex_str
Definition: benchmark/test/output_test.h:34
MR_Next
@ MR_Next
Definition: benchmark/test/output_test.h:26
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
MR_Not
@ MR_Not
Definition: benchmark/test/output_test.h:27
TC_ConsoleErr
@ TC_ConsoleErr
Definition: benchmark/test/output_test.h:42
TC_CSVOut
@ TC_CSVOut
Definition: benchmark/test/output_test.h:45
SubstrCnt
int SubstrCnt(const std::string &haystack, const std::string &pat)
Definition: benchmark/test/output_test_helper.cc:453
TestCase::TestCase
TestCase(std::string re, int rule=MR_Default)
Definition: benchmark/test/output_test_helper.cc:348
TC_JSONOut
@ TC_JSONOut
Definition: benchmark/test/output_test.h:43
T
#define T(upbtypeconst, upbtype, ctype, default_value)
TestCaseID
TestCaseID
Definition: benchmark/test/output_test.h:40
Results::NumIterations
double NumIterations() const
Definition: benchmark/test/output_test_helper.cc:320
SetSubstitutions
int SetSubstitutions(std::initializer_list< std::pair< std::string, std::string >> il)
Definition: benchmark/test/output_test_helper.cc:367
Results::values
std::map< std::string, std::string > values
Definition: benchmark/test/output_test.h:96
generate-asm-lcov.fn
fn
Definition: generate-asm-lcov.py:146
TestCase::regex
std::shared_ptr< benchmark::Regex > regex
Definition: benchmark/test/output_test.h:37
Results::kCpuTime
@ kCpuTime
Definition: benchmark/test/output_test.h:104
Results
Definition: benchmark/test/output_test.h:92
python_utils.jobset.which
def which(filename)
Definition: jobset.py:157
TestCase
Definition: benchmark/test/output_test.h:31
Results::GetAs
T GetAs(const char *entry_name) const
Definition: benchmark/test/output_test.h:144
AddCases
int AddCases(TestCaseID ID, std::initializer_list< TestCase > il)
Definition: benchmark/test/output_test_helper.cc:361
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
AddChecker
size_t AddChecker(const char *bm_name_pattern, ResultsCheckFn fn)
Definition: benchmark/test/output_test_helper.cc:302
TC_ConsoleOut
@ TC_ConsoleOut
Definition: benchmark/test/output_test.h:41
RunOutputTests
void RunOutputTests(int argc, char *argv[])
Definition: benchmark/test/output_test_helper.cc:391
MatchRules
MatchRules
Definition: benchmark/test/output_test.h:24
TC_JSONErr
@ TC_JSONErr
Definition: benchmark/test/output_test.h:44
Results::kRealTime
@ kRealTime
Definition: benchmark/test/output_test.h:104
Results::DurationRealTime
double DurationRealTime() const
Definition: benchmark/test/output_test.h:112
MR_Default
@ MR_Default
Definition: benchmark/test/output_test.h:25
TestCase::match_rule
int match_rule
Definition: benchmark/test/output_test.h:35
Results::name
std::string name
Definition: benchmark/test/output_test.h:94
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
Results::Results
Results(const std::string &n)
Definition: benchmark/test/output_test.h:98
Results::GetTime
double GetTime(BenchmarkTime which) const
Definition: benchmark/test/output_test_helper.cc:324
Results::Get
const std::string * Get(const char *entry_name) const
Definition: benchmark/test/output_test.h:122
Results::BenchmarkTime
BenchmarkTime
Definition: benchmark/test/output_test.h:104


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:36