collection.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
  2. *
  3. * Data Differential YATL (i.e. libtest) library
  4. *
  5. * Copyright (C) 2012 Data Differential, http://datadifferential.com/
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * * Redistributions in binary form must reproduce the above
  15. * copyright notice, this list of conditions and the following disclaimer
  16. * in the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * * The names of its contributors may not be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  26. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  28. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  29. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  33. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. */
  36. #include "libtest/yatlcon.h"
  37. #include <libtest/common.h>
  38. #include <algorithm>
  39. // @todo possibly have this code fork off so if it fails nothing goes bad
  40. static test_return_t runner_code(libtest::Framework* frame,
  41. const struct test_st* run,
  42. libtest::Timer& _timer)
  43. { // Runner Code
  44. assert(frame->runner());
  45. assert(run->test_fn);
  46. test_return_t return_code;
  47. try
  48. {
  49. _timer.reset();
  50. assert(frame);
  51. assert(frame->runner());
  52. assert(run->test_fn);
  53. return_code= frame->runner()->main(run->test_fn, frame->creators_ptr());
  54. }
  55. // Special case where check for the testing of the exception
  56. // system.
  57. catch (const libtest::fatal& e)
  58. {
  59. alarm(0);
  60. if (libtest::fatal::is_disabled())
  61. {
  62. libtest::fatal::increment_disabled_counter();
  63. return_code= TEST_SUCCESS;
  64. }
  65. else
  66. {
  67. throw;
  68. }
  69. }
  70. catch (...)
  71. {
  72. alarm(0);
  73. throw;
  74. }
  75. _timer.sample();
  76. return return_code;
  77. }
  78. namespace libtest {
  79. Collection::Collection(Framework* frame_,
  80. collection_st* tests_) :
  81. _name(tests_->name),
  82. _ret(TEST_SKIPPED),
  83. _pre(tests_->pre),
  84. _post(tests_->post),
  85. _tests(tests_->tests),
  86. _frame(frame_),
  87. _success(0),
  88. _skipped(0),
  89. _failed(0),
  90. _formatter(frame_->formatter())
  91. {
  92. fatal_assert(tests_);
  93. for (const test_st *run= _tests; run->name; run++)
  94. {
  95. push_testcase(run);
  96. }
  97. case_iter= _testcases.begin();
  98. }
  99. Collection::~Collection()
  100. {
  101. std::for_each(_testcases.begin(), _testcases.end(), DeleteFromVector());
  102. _testcases.clear();
  103. std::for_each(_formatter.begin(), _formatter.end(), DeleteFromVector());
  104. _formatter.clear();
  105. }
  106. void Collection::push_testcase(const test_st* test_)
  107. {
  108. TestCase* _current_testcase= new TestCase(test_);
  109. _testcases.push_back(_current_testcase);
  110. }
  111. void Collection::format()
  112. {
  113. for (Formatters::iterator format_iter= _formatter.begin();
  114. format_iter != _formatter.end();
  115. ++format_iter)
  116. {
  117. (*format_iter)->report((*case_iter), std::distance(_testcases.begin(), case_iter));
  118. }
  119. }
  120. void Collection::plan()
  121. {
  122. for (Formatters::iterator format_iter= _formatter.begin();
  123. format_iter != _formatter.end();
  124. ++format_iter)
  125. {
  126. (*format_iter)->plan(this);
  127. }
  128. }
  129. void Collection::complete()
  130. {
  131. for (Formatters::iterator format_iter= _formatter.begin();
  132. format_iter != _formatter.end();
  133. ++format_iter)
  134. {
  135. (*format_iter)->complete();
  136. }
  137. }
  138. void Collection::succeess()
  139. {
  140. _success++;
  141. (*case_iter)->success(_timer);
  142. format();
  143. }
  144. void Collection::skip()
  145. {
  146. _skipped++;
  147. (*case_iter)->skipped();
  148. format();
  149. }
  150. void Collection::fail()
  151. {
  152. _failed++;
  153. (*case_iter)->failed();
  154. format();
  155. }
  156. test_return_t Collection::exec()
  157. {
  158. // Write out any headers required by formatting.
  159. plan();
  160. if (test_success(_frame->runner()->setup(_pre, _frame->creators_ptr())))
  161. {
  162. for (; case_iter != _testcases.end();
  163. ++case_iter)
  164. {
  165. if (_frame->match((*case_iter)->name()))
  166. {
  167. skip();
  168. continue;
  169. }
  170. test_return_t return_code;
  171. try
  172. {
  173. if ((*case_iter)->requires_flush())
  174. {
  175. if (test_failed(_frame->runner()->flush(_frame->creators_ptr())))
  176. {
  177. Error << "frame->runner()->flush(creators_ptr)";
  178. skip();
  179. continue;
  180. }
  181. }
  182. set_alarm();
  183. try
  184. {
  185. return_code= runner_code(_frame, (*case_iter)->test(), _timer);
  186. }
  187. catch (...)
  188. {
  189. cancel_alarm();
  190. throw;
  191. }
  192. libtest::cancel_alarm();
  193. }
  194. catch (const libtest::fatal& e)
  195. {
  196. stream::cerr(e.file(), e.line(), e.func()) << e.what();
  197. fail();
  198. throw;
  199. }
  200. switch (return_code)
  201. {
  202. case TEST_SUCCESS:
  203. succeess();
  204. break;
  205. case TEST_FAILURE:
  206. fail();
  207. break;
  208. case TEST_SKIPPED:
  209. skip();
  210. break;
  211. default:
  212. FATAL("invalid return code");
  213. }
  214. #if 0
  215. @TODO add code here to allow for a collection to define a method to reset to allow tests to continue.
  216. #endif
  217. }
  218. (void) _frame->runner()->teardown(_post, _frame->creators_ptr());
  219. }
  220. if (_failed == 0 and _skipped == 0 and _success)
  221. {
  222. _ret= TEST_SUCCESS;
  223. }
  224. else if (_failed)
  225. {
  226. _ret= TEST_FAILURE;
  227. }
  228. // Complete any headers required by formatting.
  229. complete();
  230. return _ret;
  231. }
  232. } // namespace libtest