Testing.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright (c) 2013-2017 Josh Blum
  2. // 2020 Nicholas Corgan
  3. // SPDX-License-Identifier: BSL-1.0
  4. #include <Pothos/Testing.hpp>
  5. #include <Poco/Logger.h>
  6. #include <Poco/Path.h>
  7. #include <Poco/Format.h>
  8. #include <mutex>
  9. #include <vector>
  10. #include <cassert>
  11. static std::mutex &getTestMutex(void)
  12. {
  13. static std::mutex mutex;
  14. return mutex;
  15. }
  16. Pothos::TestingBase::TestingBase(void)
  17. {
  18. return;
  19. }
  20. Pothos::TestingBase::~TestingBase(void)
  21. {
  22. return;
  23. }
  24. /*!
  25. * The special report exception thrown by report on errors
  26. * so that the test handler will know its an intentional exit.
  27. */
  28. struct TestingReportError : Pothos::Exception
  29. {
  30. TestingReportError(const std::string &what):
  31. Pothos::Exception(what)
  32. {
  33. return;
  34. }
  35. };
  36. static Pothos::TestingBase *testInProgress = nullptr;
  37. static int lastLine = 0;
  38. static std::string lastFile;
  39. Pothos::TestingBase &Pothos::TestingBase::current(void)
  40. {
  41. assert(testInProgress != nullptr);
  42. return *testInProgress;
  43. }
  44. void Pothos::TestingBase::runTests(void)
  45. {
  46. std::lock_guard<std::mutex> lock(getTestMutex());
  47. testInProgress = this;
  48. POTHOS_EXCEPTION_TRY
  49. {
  50. lastLine = -1;
  51. lastFile = "";
  52. this->runTestsImpl();
  53. }
  54. POTHOS_EXCEPTION_CATCH(const Exception &ex)
  55. {
  56. try
  57. {
  58. const TestingReportError &reportError = dynamic_cast<const TestingReportError &>(ex);
  59. throw reportError;
  60. }
  61. catch (const std::bad_cast &)
  62. {
  63. //unknown, report a new error
  64. }
  65. this->report("Unexpected error after last checkpoint", "runTests()", ex.displayText(), lastLine, lastFile);
  66. }
  67. testInProgress = nullptr;
  68. }
  69. void Pothos::TestingBase::report(
  70. const std::string &message,
  71. const std::string &/*statement*/,
  72. const std::string &error,
  73. const int line,
  74. const std::string &file)
  75. {
  76. //cache line and file to report possible location of unexpected errors
  77. lastLine = line;
  78. lastFile = file;
  79. //format an informational message
  80. std::string testMessage = Poco::format(
  81. "%s:%d\n %s", Poco::Path(file).getFileName(), line, message);
  82. if (error.empty())
  83. {
  84. poco_debug(Poco::Logger::get("Pothos.Testing"), testMessage);
  85. }
  86. else
  87. {
  88. testMessage += "\n " + error;
  89. poco_debug(Poco::Logger::get("Pothos.Testing"), testMessage);
  90. throw TestingReportError("Pothos::Testing " + testMessage);
  91. }
  92. }
  93. //
  94. // Not all macros are used within PothosCore's testing, so we'll add
  95. // specific tests for each one to make sure they compile and work as
  96. // expected.
  97. //
  98. POTHOS_TEST_BLOCK("/testing/tests", test_asserts)
  99. {
  100. std::vector<int> vec;
  101. POTHOS_TEST_TRUE(vec.empty());
  102. vec.emplace_back(0);
  103. POTHOS_TEST_FALSE(vec.empty());
  104. }
  105. POTHOS_TEST_BLOCK("/testing/tests", test_scalar_comparison)
  106. {
  107. constexpr int intVal1 = 0;
  108. constexpr int intVal2 = 0;
  109. constexpr int intVal3 = 1;
  110. POTHOS_TEST_EQUAL(intVal1, intVal2);
  111. POTHOS_TEST_NOT_EQUAL(intVal1, intVal3);
  112. POTHOS_TEST_LE(intVal1, intVal2);
  113. POTHOS_TEST_LT(intVal1, intVal3);
  114. POTHOS_TEST_GE(intVal2, intVal1);
  115. POTHOS_TEST_GT(intVal3, intVal1);
  116. constexpr float epsilon = 1e-3;
  117. constexpr float floatVal1 = 0.0;
  118. constexpr float floatVal2 = (floatVal1 + (epsilon / 2.0f));
  119. constexpr float floatVal3 = (floatVal1 - (epsilon * 2.0f));
  120. POTHOS_TEST_CLOSE(floatVal1, floatVal2, epsilon);
  121. POTHOS_TEST_NOT_CLOSE(floatVal1, floatVal3, epsilon);
  122. }
  123. POTHOS_TEST_BLOCK("/testing/tests", test_vector_comparison)
  124. {
  125. const std::vector<int> intVec1 = {0,1,2,3,4};
  126. const std::vector<int> intVec2 = {0,1,2,3,4};
  127. const std::vector<int> intVec3 = {0,1,2,3,4,5};
  128. const std::vector<int> intVec4 = {0,1,2,3,5};
  129. POTHOS_TEST_EQUALV(intVec1, intVec2);
  130. POTHOS_TEST_NOT_EQUALV(intVec1, intVec3);
  131. POTHOS_TEST_NOT_EQUALV(intVec1, intVec4);
  132. constexpr float epsilon = 1e-3;
  133. const std::vector<float> floatVec1 = {0,1,2,3,4};
  134. const std::vector<float> floatVec2 = {0,1,(2+(epsilon/2.0f)),3,4};
  135. const std::vector<float> floatVec3 = {0,1,2,3,4,5};
  136. const std::vector<float> floatVec4 = {0,1,2,3,(4+(epsilon*2.0f))};
  137. POTHOS_TEST_CLOSEV(floatVec1, floatVec2, epsilon);
  138. POTHOS_TEST_NOT_CLOSEV(floatVec1, floatVec3, epsilon);
  139. POTHOS_TEST_NOT_CLOSEV(floatVec1, floatVec4, epsilon);
  140. }
  141. POTHOS_TEST_BLOCK("/testing/tests", test_array_comparison)
  142. {
  143. constexpr size_t arrSize = 5;
  144. int intArr1[arrSize] = {0,1,2,3,4};
  145. int intArr2[arrSize] = {0,1,2,3,4};
  146. int intArr3[arrSize] = {0,1,2,3,5};
  147. POTHOS_TEST_EQUALA(intArr1, intArr2, arrSize);
  148. POTHOS_TEST_NOT_EQUALA(intArr1, intArr3, arrSize);
  149. constexpr float epsilon = 1e-3;
  150. float floatArr1[arrSize] = {0,1,2,3,4};
  151. float floatArr2[arrSize] = {0,1,(2+(epsilon/2.0f)),3,4};
  152. float floatArr3[arrSize] = {0,1,2,3,(4+(epsilon*2.0f))};
  153. POTHOS_TEST_CLOSEA(floatArr1, floatArr2, epsilon, arrSize);
  154. POTHOS_TEST_NOT_CLOSEA(floatArr1, floatArr3, epsilon, arrSize);
  155. }