PageRenderTime 59ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/test/test.cpp

http://github.com/mozy/mordor
C++ | 344 lines | 306 code | 37 blank | 1 comment | 51 complexity | 261e20046dbfe93662abec34628b1d6f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright (c) 2009 - Mozy, Inc.
  2. #include "mordor/predef.h"
  3. #include "test.h"
  4. #include <iostream>
  5. #include <boost/regex.hpp>
  6. #include "mordor/config.h"
  7. #include "mordor/sleep.h"
  8. #include "mordor/timer.h"
  9. #ifdef WINDOWS
  10. #include <windows.h>
  11. #elif defined (LINUX)
  12. #include <fcntl.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #elif defined (OSX)
  16. #include <sys/sysctl.h>
  17. #endif
  18. namespace Mordor {
  19. namespace Test {
  20. static ConfigVar<bool>::ptr g_protect = Config::lookup(
  21. "test.protect", false,
  22. "Protect test while running under a debugger");
  23. static ConfigVar<bool>::ptr g_wait = Config::lookup(
  24. "test.waitfordebugger", false,
  25. "Wait for a debugger to attach before running tests");
  26. TestSuites &allTests()
  27. {
  28. static TestSuites s_allTests;
  29. return s_allTests;
  30. }
  31. void
  32. registerTest(const std::string &suite, const std::string &testName,
  33. TestDg test)
  34. {
  35. allTests()[suite].second[testName] = test;
  36. }
  37. void
  38. registerSuiteInvariant(const std::string &suite, TestDg invariant)
  39. {
  40. MORDOR_ASSERT(allTests()[suite].first == NULL);
  41. allTests()[suite].first = invariant;
  42. }
  43. TimeConstraint::TimeConstraint(unsigned long long us)
  44. : m_end(TimerManager::now() + us)
  45. {}
  46. TimeConstraint::~TimeConstraint()
  47. {
  48. MORDOR_TEST_ASSERT_LESS_THAN_OR_EQUAL(TimerManager::now(), m_end);
  49. }
  50. TakesAtLeast::TakesAtLeast(unsigned long long us)
  51. : m_until(TimerManager::now() + us)
  52. {}
  53. TakesAtLeast::~TakesAtLeast()
  54. {
  55. MORDOR_TEST_ASSERT_GREATER_THAN(TimerManager::now(), m_until);
  56. }
  57. void
  58. assertion(const char *file, int line, const char *function,
  59. const std::string &expr)
  60. {
  61. throw boost::enable_current_exception(Assertion(expr))
  62. << boost::throw_file(file) << boost::throw_line(line)
  63. << boost::throw_function(function)
  64. << errinfo_backtrace(backtrace());
  65. }
  66. static bool
  67. runTest(TestListener *listener, const std::string &suite,
  68. const std::string &testName, TestDg test)
  69. {
  70. if (listener)
  71. listener->testStarted(suite, testName);
  72. bool protect = !isDebuggerAttached();
  73. protect = protect || g_protect->val();
  74. if (protect) {
  75. try {
  76. test();
  77. if (listener)
  78. listener->testComplete(suite, testName);
  79. } catch (const TestSkippedException &) {
  80. if (listener)
  81. listener->testSkipped(suite, testName);
  82. } catch (const Assertion &assertion) {
  83. if (listener)
  84. listener->testAsserted(suite, testName, assertion);
  85. return false;
  86. } catch (...) {
  87. if (listener)
  88. listener->testException(suite, testName);
  89. return false;
  90. }
  91. } else {
  92. try {
  93. test();
  94. if (listener)
  95. listener->testComplete(suite, testName);
  96. } catch (const TestSkippedException &) {
  97. if (listener)
  98. listener->testSkipped(suite, testName);
  99. }
  100. }
  101. return true;
  102. }
  103. static bool
  104. runTests(const TestSuites *suites, TestListener *listener)
  105. {
  106. Assertion::throwOnAssertion = true;
  107. if (g_wait->val()) {
  108. while (!isDebuggerAttached())
  109. sleep(10000ull);
  110. debugBreak();
  111. }
  112. bool result = true;
  113. if (!suites) suites = &allTests();
  114. if (suites) {
  115. for (TestSuites::const_iterator it(suites->begin());
  116. it != suites->end();
  117. ++it) {
  118. for (TestSuite::second_type::const_iterator
  119. it2(it->second.second.begin());
  120. it2 != it->second.second.end();
  121. ++it2) {
  122. if (it->second.first) {
  123. result = result && runTest(listener, it->first,
  124. "<invariant>", it->second.first);
  125. }
  126. result = runTest(listener, it->first, it2->first,
  127. it2->second) && result;
  128. }
  129. if (it->second.first) {
  130. result = runTest(listener, it->first,
  131. "<invariant>", it->second.first) && result;
  132. }
  133. }
  134. }
  135. if (listener)
  136. listener->testsComplete();
  137. return result;
  138. }
  139. TestSuites
  140. testsForArguments(int argc, char **argv)
  141. {
  142. TestSuites tests;
  143. const TestSuites &all = allTests();
  144. for (int i = 0; i < argc; ++i) {
  145. boost::regex regex("^" + std::string(argv[i]) + "$");
  146. for (TestSuites::const_iterator j(all.begin());
  147. j != all.end();
  148. ++j) {
  149. if (boost::regex_match(j->first, regex)) {
  150. tests[j->first] = j->second;
  151. } else {
  152. for (std::map<std::string, TestDg>::const_iterator k(j->second.second.begin());
  153. k != j->second.second.end();
  154. ++k) {
  155. if (boost::regex_match(j->first + "::" + k->first, regex)) {
  156. tests[j->first].first = j->second.first;
  157. tests[j->first].second[k->first] = k->second;
  158. }
  159. }
  160. }
  161. }
  162. }
  163. return tests;
  164. }
  165. bool
  166. runTests()
  167. {
  168. return runTests(&allTests(), NULL);
  169. }
  170. bool
  171. runTests(const TestSuites &suites)
  172. {
  173. return runTests(&suites, NULL);
  174. }
  175. bool
  176. runTests(TestListener &listener)
  177. {
  178. return runTests(&allTests(), &listener);
  179. }
  180. bool
  181. runTests(const TestSuites &suites, TestListener &listener)
  182. {
  183. return runTests(&suites, &listener);
  184. }
  185. template <>
  186. void assertEqual<const char *, const char *>(const char *file,
  187. int line, const char *function, const char *lhs, const char *rhs,
  188. const char *lhsExpr, const char *rhsExpr)
  189. {
  190. if (!(strcmp(lhs, rhs) == 0)) {
  191. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  192. "==");
  193. }
  194. }
  195. template <>
  196. void assertNotEqual<const char *, const char *>(const char *file,
  197. int line, const char *function, const char *lhs, const char *rhs,
  198. const char *lhsExpr, const char *rhsExpr)
  199. {
  200. if (!(strcmp(lhs, rhs) != 0)) {
  201. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  202. "!=");
  203. }
  204. }
  205. template <>
  206. void assertLessThan<const char *, const char *>(const char *file,
  207. int line, const char *function, const char *lhs, const char *rhs,
  208. const char *lhsExpr, const char *rhsExpr)
  209. {
  210. if (!(strcmp(lhs, rhs) < 0)) {
  211. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  212. "<");
  213. }
  214. }
  215. template <>
  216. void assertLessThanOrEqual<const char *, const char *>(const char *file,
  217. int line, const char *function, const char *lhs, const char *rhs,
  218. const char *lhsExpr, const char *rhsExpr)
  219. {
  220. if (!(strcmp(lhs, rhs) <= 0)) {
  221. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  222. "<=");
  223. }
  224. }
  225. template <>
  226. void assertGreaterThan<const char *, const char *>(const char *file,
  227. int line, const char *function, const char *lhs, const char *rhs,
  228. const char *lhsExpr, const char *rhsExpr)
  229. {
  230. if (!(strcmp(lhs, rhs) > 0)) {
  231. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  232. ">");
  233. }
  234. }
  235. template <>
  236. void assertGreaterThanOrEqual<const char *, const char *>(const char *file,
  237. int line, const char *function, const char *lhs, const char *rhs,
  238. const char *lhsExpr, const char *rhsExpr)
  239. {
  240. if (!(strcmp(lhs, rhs) == 0)) {
  241. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  242. ">=");
  243. }
  244. }
  245. #ifdef WINDOWS
  246. template <>
  247. void assertEqual<const wchar_t *, const wchar_t *>(const char *file,
  248. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  249. const char *lhsExpr, const char *rhsExpr)
  250. {
  251. if (!(wcscmp(lhs, rhs) == 0)) {
  252. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  253. "==");
  254. }
  255. }
  256. template <>
  257. void assertNotEqual<const wchar_t *, const wchar_t *>(const char *file,
  258. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  259. const char *lhsExpr, const char *rhsExpr)
  260. {
  261. if (!(wcscmp(lhs, rhs) != 0)) {
  262. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  263. "!=");
  264. }
  265. }
  266. template <>
  267. void assertLessThan<const wchar_t *, const wchar_t *>(const char *file,
  268. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  269. const char *lhsExpr, const char *rhsExpr)
  270. {
  271. if (!(wcscmp(lhs, rhs) < 0)) {
  272. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  273. "<");
  274. }
  275. }
  276. template <>
  277. void assertLessThanOrEqual<const wchar_t *, const wchar_t *>(const char *file,
  278. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  279. const char *lhsExpr, const char *rhsExpr)
  280. {
  281. if (!(wcscmp(lhs, rhs) <= 0)) {
  282. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  283. "<=");
  284. }
  285. }
  286. template <>
  287. void assertGreaterThan<const wchar_t *, const wchar_t *>(const char *file,
  288. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  289. const char *lhsExpr, const char *rhsExpr)
  290. {
  291. if (!(wcscmp(lhs, rhs) > 0)) {
  292. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  293. ">");
  294. }
  295. }
  296. template <>
  297. void assertGreaterThanOrEqual<const wchar_t *, const wchar_t *>(const char *file,
  298. int line, const char *function, const wchar_t *lhs, const wchar_t *rhs,
  299. const char *lhsExpr, const char *rhsExpr)
  300. {
  301. if (!(wcscmp(lhs, rhs) == 0)) {
  302. assertComparison(file, line, function, lhs, rhs, lhsExpr, rhsExpr,
  303. ">=");
  304. }
  305. }
  306. #endif
  307. }}