OpENerTests.cpp 3.4 KB

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