2 Unix SMB/CIFS implementation.
3 SMB torture UI functions
5 Copyright (C) Jelmer Vernooij 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "torture/ui.h"
24 #include "torture/torture.h"
25 #include "lib/util/dlinklist.h"
27 void torture_comment(struct torture_context *context,
28 const char *comment, ...)
33 if (!context->ui_ops->comment)
36 va_start(ap, comment);
37 tmp = talloc_vasprintf(context, comment, ap);
39 context->ui_ops->comment(context, tmp);
44 void _torture_fail_ext(struct torture_context *context,
50 context->last_reason = talloc_vasprintf(context, fmt, ap);
51 /* make sure the reason for the failure is displayed */
52 context->ui_ops->comment(context, context->last_reason);
54 context->last_result = TORTURE_FAIL;
57 void _torture_skip_ext(struct torture_context *context,
64 context->last_result = TORTURE_SKIP;
65 context->last_reason = talloc_vasprintf(context, fmt, ap);
69 struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name)
71 struct torture_suite *suite = talloc_zero(ctx, struct torture_suite);
73 suite->name = talloc_strdup(suite, name);
74 suite->testcases = NULL;
75 suite->children = NULL;
80 void torture_tcase_set_fixture(struct torture_tcase *tcase,
81 BOOL (*setup) (struct torture_context *, void **),
82 BOOL (*teardown) (struct torture_context *, void *))
85 tcase->teardown = teardown;
88 static bool wrap_test_with_testcase(struct torture_context *torture_ctx,
89 struct torture_tcase *tcase,
90 struct torture_test *test)
92 bool (*fn) (struct torture_context *,
93 const void *tcase_data,
94 const void *test_data);
98 return fn(torture_ctx, tcase->data, test->data);
101 struct torture_test *torture_tcase_add_test(struct torture_tcase *tcase,
103 bool (*run) (struct torture_context *,
104 const void *tcase_data,
105 const void *test_data),
108 struct torture_test *test = talloc(tcase, struct torture_test);
110 test->name = talloc_strdup(test, name);
111 test->description = NULL;
112 test->run = wrap_test_with_testcase;
114 test->dangerous = False;
117 DLIST_ADD_END(tcase->tests, test, struct torture_test *);
122 struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite,
125 struct torture_tcase *tcase = talloc(suite, struct torture_tcase);
127 tcase->name = talloc_strdup(tcase, name);
128 tcase->description = NULL;
130 tcase->teardown = NULL;
131 tcase->fixture_persistent = True;
134 DLIST_ADD_END(suite->testcases, tcase, struct torture_tcase *);
139 BOOL torture_run_suite(struct torture_context *context,
140 struct torture_suite *suite)
143 struct torture_tcase *tcase;
144 struct torture_suite *tsuite;
147 if (context->ui_ops->suite_start)
148 context->ui_ops->suite_start(context, suite);
151 torture_subunit_run_suite(context, suite);
153 for (tcase = suite->testcases; tcase; tcase = tcase->next) {
154 ret &= torture_run_tcase(context, tcase);
157 for (tsuite = suite->children; tsuite; tsuite = tsuite->next) {
158 ret &= torture_run_suite(context, tsuite);
161 if (context->ui_ops->suite_finish)
162 context->ui_ops->suite_finish(context, suite);
169 void torture_ui_test_start(struct torture_context *context,
170 struct torture_tcase *tcase,
171 struct torture_test *test)
173 if (context->ui_ops->test_start)
174 context->ui_ops->test_start(context, tcase, test);
177 void torture_ui_test_result(struct torture_context *context,
178 enum torture_result result,
181 if (context->ui_ops->test_result)
182 context->ui_ops->test_result(context, result, comment);
186 case TORTURE_SKIP: context->success++; break;
187 case TORTURE_FAIL: context->failed++; break;
188 case TORTURE_TODO: context->todo++; break;
189 case TORTURE_OK: context->success++; break;
193 static BOOL internal_torture_run_test(struct torture_context *context,
194 struct torture_tcase *tcase,
195 struct torture_test *test,
200 if (test->dangerous && !torture_setting_bool(context, "dangerous", False)) {
201 _torture_skip_ext(context,
202 "disabled %s - enable dangerous tests to use", test->name);
206 if (!already_setup && tcase->setup &&
207 !tcase->setup(context, &(tcase->data)))
210 context->active_tcase = tcase;
211 context->active_test = test;
213 torture_ui_test_start(context, tcase, test);
215 context->last_reason = NULL;
216 context->last_result = TORTURE_OK;
218 ret = test->run(context, tcase, test);
220 if (context->last_reason == NULL)
221 context->last_reason = talloc_strdup(context, "...");
222 context->last_result = TORTURE_FAIL;
225 torture_ui_test_result(context, context->last_result, context->last_reason);
227 talloc_free(context->last_reason);
229 context->active_test = NULL;
230 context->active_tcase = NULL;
232 if (!already_setup && tcase->teardown && !tcase->teardown(context, tcase->data))
238 BOOL torture_run_tcase(struct torture_context *context,
239 struct torture_tcase *tcase)
242 struct torture_test *test;
246 context->active_tcase = tcase;
247 if (context->ui_ops->tcase_start)
248 context->ui_ops->tcase_start(context, tcase);
250 if (tcase->fixture_persistent && tcase->setup
251 && !tcase->setup(context, &tcase->data)) {
256 for (test = tcase->tests; test; test = test->next) {
257 ret &= internal_torture_run_test(context, tcase, test,
258 tcase->fixture_persistent);
261 if (tcase->fixture_persistent && tcase->teardown &&
262 !tcase->teardown(context, tcase->data))
266 context->active_tcase = NULL;
268 if (context->ui_ops->tcase_finish)
269 context->ui_ops->tcase_finish(context, tcase);
276 BOOL torture_run_test(struct torture_context *context,
277 struct torture_tcase *tcase,
278 struct torture_test *test)
280 return internal_torture_run_test(context, tcase, test, False);
283 int torture_setting_int(struct torture_context *test, const char *name,
286 return lp_parm_int(-1, "torture", name, default_value);
289 bool torture_setting_bool(struct torture_context *test, const char *name,
292 return lp_parm_bool(-1, "torture", name, default_value);
295 const char *torture_setting_string(struct torture_context *test, const char *name,
296 const char *default_value)
298 const char *ret = lp_parm_string(-1, "torture", name);
301 return default_value;
306 static bool wrap_test_with_simple_tcase(struct torture_context *torture_ctx,
307 struct torture_tcase *tcase,
308 struct torture_test *test)
310 bool (*fn) (struct torture_context *, const void *tcase_data);
314 return fn(torture_ctx, test->data);
317 struct torture_tcase *torture_suite_add_simple_tcase(
318 struct torture_suite *suite,
320 bool (*run) (struct torture_context *test, const void *),
323 struct torture_tcase *tcase;
324 struct torture_test *test;
326 tcase = torture_suite_add_tcase(suite, name);
328 test = talloc(tcase, struct torture_test);
330 test->name = talloc_strdup(test, name);
331 test->description = NULL;
332 test->run = wrap_test_with_simple_tcase;
335 test->dangerous = False;
337 DLIST_ADD_END(tcase->tests, test, struct torture_test *);
342 static bool wrap_simple_test(struct torture_context *torture_ctx,
343 struct torture_tcase *tcase,
344 struct torture_test *test)
346 bool (*fn) (struct torture_context *);
350 return fn(torture_ctx);
353 struct torture_tcase *torture_suite_add_simple_test(
354 struct torture_suite *suite,
356 bool (*run) (struct torture_context *test))
358 struct torture_test *test;
359 struct torture_tcase *tcase;
361 tcase = torture_suite_add_tcase(suite, name);
363 test = talloc(tcase, struct torture_test);
365 test->name = talloc_strdup(test, name);
366 test->description = NULL;
367 test->run = wrap_simple_test;
369 test->dangerous = false;
371 DLIST_ADD_END(tcase->tests, test, struct torture_test *);
376 BOOL torture_teardown_free(struct torture_context *torture, void *data)
378 return talloc_free(data);
382 bool torture_suite_add_suite(struct torture_suite *suite,
383 struct torture_suite *child)
388 DLIST_ADD_END(suite->children, child, struct torture_suite *);
390 /* FIXME: Check for duplicates and return false if the
391 * added suite already exists as a child */
397 struct torture_suite *torture_find_suite(struct torture_suite *parent,
400 struct torture_suite *child;
402 for (child = parent->children; child; child = child->next)
403 if (!strcmp(child->name, name))