Chebyshev
Unit testing for scientific software
err.h
Go to the documentation of this file.
1 
5 
6 #ifndef CHEBYSHEV_ERR_H
7 #define CHEBYSHEV_ERR_H
8 
9 #include <vector>
10 #include <cstdlib>
11 #include <iostream>
12 
13 #include "./core/common.h"
14 #include "./core/random.h"
15 #include "./err/err_structures.h"
16 
17 
18 namespace chebyshev {
19 
20 
21  // To err is human; to forgive, divine.
22 
23 
31  namespace err {
32 
33 
36  struct err_settings {
37 
39  std::string moduleName = "unknown";
40 
42  bool outputToFile = true;
43 
45  std::vector<std::string> outputFiles {};
46 
49  std::vector<std::string> assertOutputFiles {};
50 
52  std::vector<std::string> assertColumns = {
53  "name", "evaluated", "failed", "description"
54  };
55 
58  std::vector<std::string> errnoOutputFiles {};
59 
61  std::vector<std::string> errnoColumns = {
62  "name", "evaluated", "expectedFlags", "failed"
63  };
64 
67  std::vector<std::string> exceptionOutputFiles {};
68 
70  std::vector<std::string> exceptionColumns = {
71  "name", "thrown", "correctType", "failed"
72  };
73 
77  std::map<std::string, bool> pickedChecks {};
78 
80  bool quiet = false;
81 
82  } settings;
83 
84 
86  struct err_results {
87 
88  // Total number of checks
89  unsigned int totalChecks = 0;
90 
92  unsigned int failedChecks = 0;
93 
95  std::map<std::string, std::vector<assert_result>> assertResults {};
96 
98  std::map<std::string, std::vector<errno_result>> errnoResults {};
99 
101  std::map<std::string, std::vector<exception_result>> exceptionResults {};
102 
103  } results;
104 
105 
112  inline void setup(
113  const std::string& moduleName, int argc = 0, const char** argv = nullptr) {
114 
115  if(argc && argv)
116  for (int i = 1; i < argc; ++i)
117  settings.pickedChecks[argv[i]] = true;
118 
119  std::cout << "Starting error checking on "
120  << moduleName << " ..." << std::endl;
121 
122  settings.moduleName = moduleName;
123  results.failedChecks = 0;
124  results.totalChecks = 0;
125 
126  random::setup();
127  output::setup();
128  }
129 
130 
135  inline void terminate(bool exit = true) {
136 
137  output::settings.quiet = settings.quiet;
138 
139  // Output to file is true but no specific files are specified, add default output file.
140  if( settings.outputToFile &&
141  !output::settings.outputFiles.size() &&
142  !settings.assertOutputFiles.size() &&
143  !settings.errnoOutputFiles.size() &&
144  !settings.exceptionOutputFiles.size() &&
145  !settings.outputFiles.size()) {
146 
147  settings.outputFiles = { settings.moduleName + "_results" };
148  }
149 
150  std::vector<std::string> outputFiles;
151 
152  // Print assert results
153  outputFiles = settings.outputFiles;
154  outputFiles.insert(outputFiles.end(), settings.assertOutputFiles.begin(), settings.assertOutputFiles.end());
155 
156 
157  output::print_results(results.assertResults, settings.assertColumns, outputFiles);
158 
159  // Print errno checking results
160  outputFiles = settings.outputFiles;
161  outputFiles.insert(outputFiles.end(), settings.errnoOutputFiles.begin(), settings.errnoOutputFiles.end());
162 
163 
164  output::print_results(results.errnoResults, settings.errnoColumns, outputFiles);
165 
166  // Print exception checking results
167  outputFiles = settings.outputFiles;
168  outputFiles.insert(outputFiles.end(), settings.exceptionOutputFiles.begin(), settings.exceptionOutputFiles.end());
169 
170 
171  output::print_results(results.exceptionResults, settings.exceptionColumns, outputFiles);
172 
173  std::cout << "Finished error checking " << settings.moduleName << " ...\n";
174  std::cout << results.totalChecks
175  << " total checks, "
176  << results.failedChecks << " failed (" << std::setprecision(3)
177  << (results.failedChecks / (double) results.totalChecks * 100.0)
178  << "%)" << std::endl;
179 
180  // Discard previous results
181  results = err_results();
182 
183  if(exit) {
185  std::exit(results.failedChecks);
186  }
187  }
188 
189 
195  inline void assert(
196  const std::string& name,
197  bool exp,
198  std::string description = "",
199  bool quiet = false) {
200 
201  assert_result res {};
202 
203  res.name = name;
204  res.evaluated = exp;
205  res.failed = !exp;
206  res.description = description;
207  res.quiet = quiet;
208 
209  results.totalChecks++;
210 
211  if(!exp)
212  results.failedChecks++;
213 
214  results.assertResults[name].push_back(res);
215  }
216 
217 
224  template<typename Function, typename InputType>
225  inline void check_errno(
226  const std::string& name,
227  Function f,
228  InputType x,
229  int expected_errno,
230  bool quiet = false) {
231 
232  errno_result res {};
233  errno = 0;
234 
235  try {
236  volatile auto r = f(x);
237  r = *(&r);
238  } catch(...) {}
239 
240  res.name = name;
241  res.evaluated = errno;
242  res.expectedFlags = { expected_errno };
243  res.failed = (errno != expected_errno);
244  res.quiet = quiet;
245 
246  results.totalChecks++;
247 
248  if(res.failed)
249  results.failedChecks++;
250 
251  results.errnoResults[name].push_back(res);
252  }
253 
254 
262  template<typename Function, typename InputType>
263  inline void check_errno(
264  const std::string& name, Function f,
265  std::function<InputType()> generator,
266  int expected_errno,
267  bool quiet = false) {
268 
269  check_errno(name, f, generator(), expected_errno, quiet);
270  }
271 
272 
279  template<typename Function, typename InputType>
280  inline void check_errno(
281  const std::string& name,
282  Function f,
283  InputType x,
284  std::vector<int>& expected_flags,
285  bool quiet = false) {
286 
287 
288  errno_result res {};
289  errno = 0;
290 
291  try {
292  volatile auto r = f(x);
293  r = *(&r);
294  } catch(...) {}
295 
296  res.name = name;
297  res.evaluated = errno;
298  res.expectedFlags = expected_flags;
299  res.quiet = quiet;
300 
301  res.failed = false;
302  for (int flag : expected_flags)
303  if(!(errno & flag))
304  res.failed = true;
305 
306  results.totalChecks++;
307 
308  if(res.failed)
309  results.failedChecks++;
310 
311  results.errnoResults[name].push_back(res);
312  }
313 
314 
322  template<typename Function, typename InputType>
324  const std::string& name, Function f,
325  std::function<InputType()> generator,
326  std::vector<int>& expected_flags,
327  bool quiet = false) {
328 
329  check_errno(name, f, generator(), expected_flags, quiet);
330  }
331 
332 
338  template<typename Function, typename InputType>
339  inline void check_exception(
340  const std::string& name,
341  Function f,
342  InputType x,
343  bool quiet = false) {
344 
345  exception_result res {};
346  bool thrown = false;
347 
348  try {
349  volatile auto r = f(x);
350  r = *(&r);
351  } catch(...) {
352  thrown = true;
353  }
354 
355  res.name = name;
356  res.thrown = thrown;
357  res.failed = !thrown;
358  res.correctType = true;
359  res.quiet = quiet;
360 
361  results.totalChecks++;
362  if(!thrown)
363  results.failedChecks++;
364 
365  results.exceptionResults[name].push_back(res);
366  }
367 
368 
375  template<typename Function, typename InputType>
376  inline void check_exception(
377  const std::string& name, Function f,
378  std::function<InputType()> generator,
379  bool quiet = false) {
380 
381  check_exception(name, f, generator(), quiet);
382  }
383 
384 
391  template<typename ExceptionType, typename Function, typename InputType>
392  inline void check_exception(
393  const std::string& name,
394  Function f,
395  InputType x,
396  bool quiet = false) {
397 
398  exception_result res {};
399  bool thrown = false;
400  bool correctType = false;
401 
402  try {
403  volatile auto r = f(x);
404  r = *(&r);
405  } catch(ExceptionType& exc) {
406 
407  correctType = true;
408  thrown = true;
409 
410  } catch(...) {
411  thrown = true;
412  }
413 
414  res.name = name;
415  res.thrown = thrown;
416  res.failed = !(thrown && correctType);
417  res.correctType = correctType;
418  res.quiet = quiet;
419 
420  results.totalChecks++;
421  if(!thrown)
422  results.failedChecks++;
423 
424  results.exceptionResults[name].push_back(res);
425  }
426 
427 
435  template<typename ExceptionType, typename Function, typename InputType>
436  inline void check_exception(
437  const std::string& name, Function f,
438  std::function<InputType()> generator,
439  bool quiet = false) {
440 
441  check_exception(name, f, generator(), quiet);
442  }
443  }
444 }
445 
446 #endif
Common definitions for the framework.
Structures for the error checking module.
void setup(const std::string &moduleName, int argc=0, const char **argv=nullptr)
Setup error checking module.
Definition: err.h:112
void check_errno(const std::string &name, Function f, InputType x, int expected_errno, bool quiet=false)
Check errno value after function call.
Definition: err.h:225
void check_exception(const std::string &name, Function f, InputType x, bool quiet=false)
Check that an exception is thrown during a function call.
Definition: err.h:339
void terminate(bool exit=true)
Terminate the error testing environment.
Definition: err.h:135
void assert(const std::string &name, bool exp, std::string description="", bool quiet=false)
Assert that an expression is true.
Definition: err.h:195
void print_results(const std::map< std::string, std::vector< ResultType >> &results, const std::vector< std::string > &fields, const std::vector< std::string > &filenames)
Print the test results to standard output and output files with their given formats,...
Definition: output.h:871
void setup()
Setup printing to the output stream with default options.
Definition: output.h:503
void terminate()
Terminate the output module by closing all output files and resetting its settings.
Definition: output.h:562
std::string string(size_t length)
Generate a random string made of human-readable ASCII characters.
Definition: random.h:84
void setup(uint64_t seed=0)
Initialize the random module.
Definition: random.h:31
General namespace of the framework.
Definition: benchmark_structures.h:16
The pseudorandom number generation and sampling module.
std::string moduleName
Name of the module currently being benchmarked.
Definition: benchmark.h:38
bool outputToFile
Whether to output results to a file.
Definition: benchmark.h:47
std::vector< std::string > outputFiles
The files to write all benchmark results to.
Definition: benchmark.h:50
bool quiet
Whether to print benchmark results to standard output.
Definition: benchmark.h:35
Result of assertion checking of a function.
Definition: err_structures.h:21
std::string name
Identifying name of the function or test case.
Definition: err_structures.h:24
error checking
Definition: err.h:86
std::map< std::string, std::vector< errno_result > > errnoResults
Results of checking errno.
Definition: err.h:98
unsigned int failedChecks
Number of failed checks.
Definition: err.h:92
std::map< std::string, std::vector< exception_result > > exceptionResults
Results of exception testing.
Definition: err.h:101
std::map< std::string, std::vector< assert_result > > assertResults
Results of checking assertions.
Definition: err.h:95
Global settings of the error testing module.
Definition: err.h:36
std::vector< std::string > outputFiles
The files to write all error checking results to.
Definition: err.h:45
std::vector< std::string > assertOutputFiles
The files to write assertion results results to (if empty, all results are output to a generic file).
Definition: err.h:49
std::vector< std::string > exceptionOutputFiles
The files to write exception results results to (if empty, all results are output to a generic file).
Definition: err.h:67
std::vector< std::string > assertColumns
Default columns to print for assertions.
Definition: err.h:52
std::vector< std::string > exceptionColumns
Default columns to print for exception checks.
Definition: err.h:70
std::map< std::string, bool > pickedChecks
Target checks marked for execution, can be picked by passing test case names by command line.
Definition: err.h:77
std::string moduleName
Name of the module being tested.
Definition: err.h:39
std::vector< std::string > errnoOutputFiles
The files to write errno checking results to (if empty, all results are output to a generic file).
Definition: err.h:58
std::vector< std::string > errnoColumns
Default columns to print for errno checks.
Definition: err.h:61
bool quiet
Whether to print to standard output.
Definition: err.h:80
bool outputToFile
Whether to print to an output file.
Definition: err.h:42
Result of errno checking of a function.
Definition: err_structures.h:42
Result of exception checking of a function.
Definition: err_structures.h:63