OpENerTests.cpp 3.1 KB

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