JayBeams  0.1
Another project to have fun coding.
microbenchmark_group_main.hpp
Go to the documentation of this file.
1 #ifndef jb_testing_microbenchmark_group_main_hpp
2 #define jb_testing_microbenchmark_group_main_hpp
3 
5 #include <jb/log.hpp>
6 
7 #include <functional>
8 #include <iostream>
9 #include <map>
10 #include <stdexcept>
11 #include <string>
12 
13 namespace jb {
14 namespace testing {
15 
16 namespace detail {
18 } // namespace detail
19 
20 /**
21  * Define a representation for a group of microbenchmarks.
22  *
23  * Each microbenchmark is encapsulated in a (type erased)
24  * std::function, which typically creates an instance of
25  * jb::testing::microbenchmark and runs it. The keys into the group
26  * are the names of the testcases.
27  *
28  * @tparam config the configuration class for the group of
29  * microbenchmarks.
30  */
31 template <typename config>
33  std::map<std::string, std::function<void(config const& cfg)>>;
34 
35 /**
36  * Implement the main() function for a multi-testcase benchmark.
37  *
38  * A common idiom in complex benchmarks is to create multiple
39  * testcases that exercise different implementations, different
40  * template instantiations, or otherwise vary the test in a
41  * non-trivial way.
42  *
43  * In such cases the main() function follows a well understood
44  * pattern:
45  * - Initialize the benchmark configuration.
46  * - Find which testcase is requested.
47  * - Call a function for that testcase.
48  *
49  * This class refactors that pattern into a static function.
50  *
51  * @tparam config the configuration object used by the benchmark. We
52  * expect that it has at least two configuration attributes:
53  * - log: of type jb::log::config
54  * - microbenchmark: of type jb::testing::microbenchmark_config
55  *
56  * @return the exit status for the program
57  * @param argc the number of arguments in @a argv
58  * @param argv the command-line arguments
59  * @param testcases a group of microbenchmarks, executes the one
60  * selected via the --microbenchmark.test-case command-line
61  * argument.
62  * @throws nothing, all exceptions are captured and printed to
63  * stderr before the program exits.
64  */
65 template <typename config>
67  int argc, char* argv[], microbenchmark_group<config> const& testcases) try {
68  // Create a default instance of the configuration ...
69  config cfg;
70  // ... parse the command-line arguments ...
71  cfg.process_cmdline(argc, argv);
72  // initialize the logging framework ...
73  jb::log::init(cfg.log());
74  // ... get the microbenchmark configuration ..
75  jb::testing::microbenchmark_config const& bmcfg = cfg.microbenchmark();
76  // ... print out the test parameters ...
77  if (bmcfg.verbose()) {
78  JB_LOG(info) << "Configuration for test\n" << cfg << "\n";
79  }
80  // ... find out if the requested test case is in the list of known
81  // test cases ...
82  auto testcase = testcases.find(bmcfg.test_case());
83  // ... if not, print a usage message and terminate the test ...
84  if (testcase == testcases.end()) {
85  std::ostringstream os;
86  os << "Unknown test case (" << bmcfg.test_case() << ")\n";
87  os << " --microbenchmark.test-case must be one of:";
88  for (auto const& i : testcases) {
89  os << " " << i.first << "\n";
90  }
91  throw jb::usage(os.str(), 1);
92  }
93  // ... run the test that was configured ...
94  testcase->second(cfg);
95  // ... exit with a success status ...
96  return 0;
97 } catch (...) {
99 }
100 
101 /**
102  * Overload microbenchmark_group_main for jb::testing::microbenchmark_config.
103  *
104  * A common idiom in complex benchmarks is to create multiple
105  * testcases that exercise different implementations, different
106  * template instantiations, or otherwise vary the test in a
107  * non-trivial way.
108  *
109  * In such cases the main() function follows a well understood
110  * pattern:
111  * - Initialize the benchmark configuration.
112  * - Find which testcase is requested.
113  * - Call a function for that testcase.
114  *
115  * @return the exit status for the program
116  * @param argc the number of arguments in @a argv
117  * @param argv the command-line arguments
118  * @param testcases a group of microbenchmarks, executes the one
119  * selected via the --microbenchmark.test-case command-line
120  * argument.
121  * @throws nothing, all exceptions are captured and printed to
122  * stderr before the program exits.
123  */
125  int argc, char* argv[],
127 
128 } // namespace testing
129 } // namespace jb
130 
131 #endif // jb_testing_microbenchmark_group_main_hpp
int microbenchmark_group_main(int argc, char *argv[], microbenchmark_group< microbenchmark_config > const &testcases)
Overload microbenchmark_group_main for jb::testing::microbenchmark_config.
std::map< std::string, std::function< void(config const &cfg)> > microbenchmark_group
Define a representation for a group of microbenchmarks.
void init(config const &cfg)
Initialize the logging functions using the configuration provided.
Definition: log.cpp:190
A simple class to communicate the result of parsing the options.
Definition: usage.hpp:11
#define JB_LOG(lvl)
Definition: log.hpp:70
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7