1b4915e13d75ac1802e40a9cd37906b83fb814ad
[awesomized/libmemcached] / libtest / collection.cc
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
37 #include "libtest/yatlcon.h"
38
39 #include <libtest/common.h>
40
41 // @todo possibly have this code fork off so if it fails nothing goes bad
42 static test_return_t runner_code(libtest::Framework* frame,
43 test_st* run,
44 libtest::Timer& _timer)
45 { // Runner Code
46
47 assert(frame->runner());
48 assert(run->test_fn);
49
50 test_return_t return_code;
51 try
52 {
53 _timer.reset();
54 return_code= frame->runner()->main(run->test_fn, frame->creators_ptr());
55 }
56 // Special case where check for the testing of the exception
57 // system.
58 catch (libtest::fatal &e)
59 {
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
71 _timer.sample();
72
73 return return_code;
74 }
75
76 namespace libtest {
77
78 Collection::Collection(Framework* frame_arg,
79 collection_st* arg) :
80 _name(arg->name),
81 _pre(arg->pre),
82 _post(arg->post),
83 _tests(arg->tests),
84 _frame(frame_arg),
85 _success(0),
86 _skipped(0),
87 _failed(0),
88 _total(0),
89 _formatter(frame_arg->name(), _name)
90 {
91 fatal_assert(arg);
92 }
93
94 test_return_t Collection::exec()
95 {
96 if (test_success(_frame->runner()->setup(_pre, _frame->creators_ptr())))
97 {
98 for (test_st *run= _tests; run->name; run++)
99 {
100 formatter()->push_testcase(run->name);
101 if (_frame->match(run->name))
102 {
103 formatter()->skipped();
104 continue;
105 }
106 _total++;
107
108 test_return_t return_code;
109 try
110 {
111 if (run->requires_flush)
112 {
113 if (test_failed(_frame->runner()->flush(_frame->creators_ptr())))
114 {
115 Error << "frame->runner()->flush(creators_ptr)";
116 _skipped++;
117 formatter()->skipped();
118 continue;
119 }
120 }
121
122 set_alarm();
123
124 try
125 {
126 return_code= runner_code(_frame, run, _timer);
127 }
128 catch (...)
129 {
130 cancel_alarm();
131
132 throw;
133 }
134 libtest::cancel_alarm();
135 }
136 catch (libtest::fatal &e)
137 {
138 stream::cerr(e.file(), e.line(), e.func()) << e.what();
139 _failed++;
140 formatter()->failed();
141 throw;
142 }
143
144 switch (return_code)
145 {
146 case TEST_SUCCESS:
147 _success++;
148 formatter()->success(_timer);
149 break;
150
151 case TEST_FAILURE:
152 _failed++;
153 formatter()->failed();
154 break;
155
156 case TEST_SKIPPED:
157 _skipped++;
158 formatter()->skipped();
159 break;
160
161 default:
162 fatal_message("invalid return code");
163 }
164 #if 0
165 @TODO add code here to allow for a collection to define a method to reset to allow tests to continue.
166 #endif
167 }
168
169 (void) _frame->runner()->teardown(_post, _frame->creators_ptr());
170 }
171
172 if (_failed == 0 and _skipped == 0 and _success)
173 {
174 return TEST_SUCCESS;
175 }
176
177 if (_failed)
178 {
179 return TEST_FAILURE;
180 }
181
182 fatal_assert(_skipped or _success == 0);
183
184 return TEST_SKIPPED;
185 }
186
187 } // namespace libtest
188