Chebyshev
Unit testing for scientific software
Loading...
Searching...
No Matches
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#include <memory>
13#include <iomanip>
14
15#include "./core/common.h"
16#include "./core/random.h"
17#include "./core/output.h"
19
20
21namespace chebyshev {
22
23
24// To err is human; to forgive, divine.
25
26
34namespace err {
35
36
39 struct err_settings {
40
42 std::string moduleName = "unknown";
43
45 bool outputToFile = true;
46
48 std::vector<std::string> outputFiles {};
49
52 std::vector<std::string> assertOutputFiles {};
53
55 std::vector<std::string> assertColumns = {
56 "name", "evaluated", "failed", "description"
57 };
58
61 std::vector<std::string> errnoOutputFiles {};
62
64 std::vector<std::string> errnoColumns = {
65 "name", "evaluated", "expectedFlags", "failed"
66 };
67
70 std::vector<std::string> exceptionOutputFiles {};
71
73 std::vector<std::string> exceptionColumns = {
74 "name", "thrown", "correctType", "failed"
75 };
76
80 std::map<std::string, bool> pickedChecks {};
81
83 bool quiet = false;
84
85 };
86
87
91 private:
92
94 std::map<std::string, std::vector<assert_result>> assertResults {};
95
97 std::map<std::string, std::vector<errno_result>> errnoResults {};
98
100 std::map<std::string, std::vector<exception_result>> exceptionResults {};
101
103 bool wasTerminated {false};
104
105 public:
106
109
112 std::shared_ptr<output::output_context> output;
113
116 std::shared_ptr<random::random_context> random;
117
118
125 inline void setup(
126 const std::string& moduleName,
127 int argc = 0, const char** argv = nullptr) {
128
129 // Initialize other modules
131 output = std::make_shared<output::output_context>();
132 random = std::make_shared<random::random_context>();
133
134 if(argc && argv)
135 for (int i = 1; i < argc; ++i)
136 settings.pickedChecks[argv[i]] = true;
137
138 output->info("Starting error checking on the " + moduleName + " module ...");
139
140 settings.moduleName = moduleName;
141 wasTerminated = false;
142 }
143
144
149 inline void terminate(bool exit = false) {
150
151 unsigned int failedChecks = 0;
152 unsigned int totalChecks = 0;
153
154 for (const auto& pair : assertResults) {
155 for (const auto& testCase : pair.second) {
156 totalChecks++;
157 failedChecks += testCase.failed ? 1 : 0;
158 }
159 }
160
161 for (const auto& pair : errnoResults) {
162 for (const auto& testCase : pair.second) {
163 totalChecks++;
164 failedChecks += testCase.failed ? 1 : 0;
165 }
166 }
167
168 for (const auto& pair : exceptionResults) {
169 for (const auto& testCase : pair.second) {
170 totalChecks++;
171 failedChecks += testCase.failed ? 1 : 0;
172 }
173 }
174
175 // Ensure that an output file is specified
177 !output->settings.outputFiles.size() &&
178 !settings.assertOutputFiles.size() &&
179 !settings.errnoOutputFiles.size() &&
181 !settings.outputFiles.size()) {
182
183 settings.outputFiles = { settings.moduleName + "_results" };
184 }
185
186 std::vector<std::string> outputFiles;
187
188 // Print assert results
189 outputFiles = settings.outputFiles;
190 outputFiles.insert(
191 outputFiles.end(),
194 );
195
196
197 output->print_results(
198 assertResults,
200 outputFiles
201 );
202
203 // Print errno checking results
204 outputFiles = settings.outputFiles;
205 outputFiles.insert(
206 outputFiles.end(),
209 );
210
211
212 output->print_results(
213 errnoResults,
215 outputFiles
216 );
217
218 // Print exception checking results
219 outputFiles = settings.outputFiles;
220 outputFiles.insert(
221 outputFiles.end(),
224 );
225
226
227 output->print_results(
228 exceptionResults,
230 outputFiles
231 );
232
233 // Print overall checks results
234 double percent = totalChecks > 0 ? (failedChecks / (double) totalChecks) * 100 : 0.0;
235 output->info("Finished error checking on the " + settings.moduleName + " module ...");
236 output->info(
237 std::to_string(totalChecks) + " total checks, " + std::to_string(failedChecks) +
238 " failed (" + std::to_string(percent).substr(0, 4) + "%)"
239 );
240
241 if (totalChecks == 0)
242 output->warn("No checks were executed!");
243
244 if(exit) {
245 output->terminate();
246 std::exit(failedChecks);
247 }
248
249 wasTerminated = true;
250 }
251
252
255 std::string moduleName,
256 int argc = 0,
257 const char** argv = nullptr) {
258
259 setup(moduleName, argc, argv);
260 }
261
262
265 if (!wasTerminated)
266 terminate();
267 }
268
269
275 inline void assert(
276 const std::string& name,
277 bool exp,
278 std::string description = "",
279 bool quiet = false) {
280
281 output->debug("Checking assertion: " + name);
282
284 res.name = name;
285 res.evaluated = exp;
286 res.failed = !exp;
287 res.description = description;
288 res.quiet = quiet;
289
290 assertResults[name].push_back(res);
291 }
292
293
300 template<typename Function, typename InputType>
301 inline void errno_value(
302 const std::string& name,
303 Function f,
304 InputType x,
305 int expected_errno,
306 bool quiet = false) {
307
308 output->debug("Checking errno value for: " + name);
309
310 errno_result res {};
311 errno = 0;
312
313 try {
314 volatile auto r = f(x);
315 r = *(&r);
316 } catch(...) {}
317
318 res.name = name;
319 res.evaluated = errno;
320 res.expectedFlags = { expected_errno };
321 res.failed = (errno != expected_errno);
322 res.quiet = quiet;
323
324 errnoResults[name].push_back(res);
325 }
326
327
334 template<typename Function, typename InputType>
335 inline void errno_value(
336 const std::string& name, Function f,
337 std::function<InputType()> generator,
338 int expected_errno,
339 bool quiet = false) {
340
341 errno_value(name, f, generator(), expected_errno, quiet);
342 }
343
344
353 template<typename Function, typename InputType>
354 inline void errno_flags(
355 const std::string& name,
356 Function f,
357 InputType x,
358 std::vector<int>& expected_flags,
359 bool quiet = false) {
360
361 output->debug("Checking errno flags for: " + name);
362
363 errno_result res {};
364 errno = 0;
365
366 try {
367 volatile auto r = f(x);
368 r = *(&r);
369 } catch(...) {}
370
371 res.name = name;
372 res.evaluated = errno;
373 res.expectedFlags = expected_flags;
374 res.quiet = quiet;
375
376 res.failed = false;
377 for (int flag : expected_flags)
378 if(!(errno & flag))
379 res.failed = true;
380
381 errnoResults[name].push_back(res);
382 }
383
384
393 template<typename Function, typename InputType>
395 const std::string& name, Function f,
396 std::function<InputType()> generator,
397 std::vector<int>& expected_flags,
398 bool quiet = false) {
399
400 errno_flags(name, f, generator(), expected_flags, quiet);
401 }
402
403
410 template<typename Function, typename InputType>
411 inline void throws(
412 const std::string& name,
413 Function f,
414 InputType x,
415 bool quiet = false) {
416
417 output->debug("Checking exception for: " + name);
418
420 bool thrown = false;
421
422 try {
423 volatile auto r = f(x);
424 r = *(&r);
425 } catch(...) {
426 thrown = true;
427 }
428
429 res.name = name;
430 res.thrown = thrown;
431 res.failed = !thrown;
432 res.correctType = true;
433 res.quiet = quiet;
434
435 exceptionResults[name].push_back(res);
436 }
437
438
445 template<typename Function, typename InputType>
446 inline void throws(
447 const std::string& name, Function f,
448 std::function<InputType()> generator,
449 bool quiet = false) {
450
451 throws(name, f, generator(), quiet);
452 }
453
454
461 template <
462 typename ExceptionType,
463 typename Function,
464 typename InputType
465 >
466 inline void throws(
467 const std::string& name,
468 Function f,
469 InputType x,
470 bool quiet = false) {
471
472 output->debug("Checking exception for: " + name);
473
475 bool thrown = false;
476 bool correctType = false;
477
478 try {
479 volatile auto r = f(x);
480 r = *(&r);
481 } catch(ExceptionType& exc) {
482
483 correctType = true;
484 thrown = true;
485
486 } catch(...) {
487 thrown = true;
488 }
489
490 res.name = name;
491 res.thrown = thrown;
492 res.failed = !(thrown && correctType);
493 res.correctType = correctType;
494 res.quiet = quiet;
495
496 exceptionResults[name].push_back(res);
497 }
498
499
507 template <
508 typename ExceptionType,
509 typename Function,
510 typename InputType
511 >
512 inline void throws(
513 const std::string& name, Function f,
514 std::function<InputType()> generator,
515 bool quiet = false) {
516
517 throws(name, f, generator(), quiet);
518 }
519
520
522 inline std::vector<assert_result> get_assertion(const std::string& name) {
523 return assertResults[name];
524 }
525
526
528 inline assert_result get_assertion(const std::string& name, unsigned int i) {
529 return assertResults[name].at(i);
530 }
531
532
534 inline std::vector<errno_result> get_errno(const std::string& name) {
535 return errnoResults[name];
536 }
537
538
540 inline errno_result get_errno(const std::string& name, unsigned int i) {
541 return errnoResults[name].at(i);
542 }
543
544
546 inline std::vector<exception_result> get_exception(const std::string& name) {
547 return exceptionResults[name];
548 }
549
550
552 inline exception_result get_exception(const std::string& name, unsigned int i) {
553 return exceptionResults[name].at(i);
554 }
555
556 };
557
558
564 err_context make_context(const std::string& moduleName,
565 int argc = 0, const char** argv = nullptr) {
566
567 return err_context(moduleName, argc, argv);
568 }
569
570}}
571
572#endif
Error checking context, for assertions and exception checking.
Definition err.h:90
void errno_value(const std::string &name, Function f, InputType x, int expected_errno, bool quiet=false)
Check errno value after function call.
Definition err.h:301
void errno_flags(const std::string &name, Function f, InputType x, std::vector< int > &expected_flags, bool quiet=false)
Check the value of errno after a function call, comparing to multiple expected flags which should all...
Definition err.h:354
std::vector< errno_result > get_errno(const std::string &name)
Get the results of errno checking by name or label.
Definition err.h:534
err_context(std::string moduleName, int argc=0, const char **argv=nullptr)
Setup the error checking module.
Definition err.h:254
~err_context()
Terminate the error checking module.
Definition err.h:264
void setup(const std::string &moduleName, int argc=0, const char **argv=nullptr)
Setup error checking module.
Definition err.h:125
std::shared_ptr< random::random_context > random
Random module settings for the context, dynamically allocated and possibly shared between multiple co...
Definition err.h:116
std::vector< assert_result > get_assertion(const std::string &name)
Get the results of an assertion by name or label.
Definition err.h:522
errno_result get_errno(const std::string &name, unsigned int i)
Get a single result of errno checking by label and index.
Definition err.h:540
assert_result get_assertion(const std::string &name, unsigned int i)
Get a single result of an assertion by label and index.
Definition err.h:528
std::vector< exception_result > get_exception(const std::string &name)
Get the results of exception checking by name or label.
Definition err.h:546
void errno_flags(const std::string &name, Function f, std::function< InputType()> generator, std::vector< int > &expected_flags, bool quiet=false)
Check the value of errno after a function call, comparing to multiple expected flags which should all...
Definition err.h:394
err_settings settings
Settings for the benchmark context.
Definition err.h:108
std::shared_ptr< output::output_context > output
Output module settings for the context, dynamically allocated and possibly shared between multiple co...
Definition err.h:112
exception_result get_exception(const std::string &name, unsigned int i)
Get a single result of exception checking by label and index.
Definition err.h:552
void errno_value(const std::string &name, Function f, std::function< InputType()> generator, int expected_errno, bool quiet=false)
Check errno value after function call.
Definition err.h:335
void terminate(bool exit=false)
Terminate the error testing environment.
Definition err.h:149
void assert(const std::string &name, bool exp, std::string description="", bool quiet=false)
Assert that an expression is true.
Definition err.h:275
Common definitions for the framework.
Structures for the error checking module.
err_context make_context(const std::string &moduleName, int argc=0, const char **argv=nullptr)
Construct an error checking context with the given parameters.
Definition err.h:564
General namespace of the framework.
Definition benchmark.h:22
constexpr FloatType get_nan()
Get a quiet NaN of the specified floating point type.
Definition common.h:65
The output module, with formatting capabilities.
The pseudorandom number generation and sampling module.
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
Settings of the error testing module, used in err_context.
Definition err.h:39
std::vector< std::string > outputFiles
The files to write all error checking results to.
Definition err.h:48
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:52
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:70
std::vector< std::string > assertColumns
Default columns to print for assertions.
Definition err.h:55
std::vector< std::string > exceptionColumns
Default columns to print for exception checks.
Definition err.h:73
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:80
std::string moduleName
Name of the module being tested.
Definition err.h:42
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:61
std::vector< std::string > errnoColumns
Default columns to print for errno checks.
Definition err.h:64
bool quiet
Whether to print to standard output.
Definition err.h:83
bool outputToFile
Whether to print to an output file.
Definition err.h:45
Result of errno checking of a function.
Definition err_structures.h:42
Result of exception checking of a function.
Definition err_structures.h:63