OpENerTests.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <setjmp.h>
  2. #include <stdexcept>
  3. #include <stdio.h>
  4. #include "OpENerTests.h"
  5. #include "CppUTest/TestRegistry.h"
  6. extern "C" {
  7. #include "endianconv.h"
  8. }
  9. /*
  10. * Stores the location in the unit test function where execution should jump
  11. * to upon a failed assertion.
  12. */
  13. jmp_buf assert_jump;
  14. /*
  15. * This pointer is used to indicate if an assertion is expected in the code
  16. * being tested. A non-NULL value means an assertion is expected, and the
  17. * resulting longjmp() target has been stored in the assert_jmp variable.
  18. * The actual address stored here is meaningless, aside from being NULL or not;
  19. * this pointer is never dereferenced. A pointer is used instead of a boolean
  20. * so the SetPointerPlugin can automatically reset it after every test.
  21. */
  22. jmp_buf *assert_jump_enabled;
  23. int main(int argc,
  24. char **argv) {
  25. /* These checks are here to make sure assertions outside test runs don't crash */
  26. CHECK(true);
  27. LONGS_EQUAL(1, 1);
  28. DetermineEndianess();
  29. /*
  30. * Enable the Cpputest SetPointerPlugin to automatically reset the
  31. * assert_jump_enabled pointer after each test.
  32. */
  33. SetPointerPlugin assert_restore("AssertJumpRestore");
  34. TestRegistry::getCurrentRegistry()->installPlugin(&assert_restore);
  35. return CommandLineTestRunner::RunAllTests(argc, argv);
  36. }
  37. /*
  38. * This is the function called by the OPENER_ASSERT macro if the assertion
  39. * condition fails. It will interrupt the code under test in one of two ways
  40. * depending on if an assertion is expected from the CHECK_ASSERT test macro.
  41. *
  42. * Arguments:
  43. *
  44. * file - Path to the source file where the assertion failed.
  45. * line - Line number identifying the failed assertion.
  46. */
  47. extern "C" void test_assert_fail(const char *const file,
  48. const unsigned int line) {
  49. /*
  50. * Throw an exception with the assertion location if an assertion is not
  51. * expected. Unfortunately, this will stop all further tests and does not
  52. * identify the test that failed.
  53. */
  54. if (assert_jump_enabled == NULL) {
  55. const char format[] = "Assertion failure: %s:%d";
  56. char dummy;
  57. /* Determine how long the exception message would be. */
  58. int len_no_null = snprintf(&dummy, 1, format, file, line);
  59. if (len_no_null > 0) {
  60. /*
  61. * Allocate memory for the exception message, including the NULL
  62. * terminator. This memory is not freed because the forthcoming
  63. * exception terminates everything anyway.
  64. */
  65. const size_t len_with_null = len_no_null + 1;
  66. char *msg = (char *)malloc(len_with_null);
  67. if (msg != NULL) {
  68. len_no_null = snprintf(msg, len_with_null, format, file, line);
  69. if (len_no_null > 0) {
  70. throw std::runtime_error(msg);
  71. }
  72. }
  73. }
  74. /* Throw a generic exception if string generation fails. */
  75. throw std::runtime_error("Assertion failure.");
  76. }
  77. /*
  78. * Execute the jump back to the unit test function if an assertion was
  79. * expected.
  80. */
  81. else {
  82. longjmp(assert_jump, 0);
  83. }
  84. }