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 if (context
->ui_ops
->comment
)
53 context
->ui_ops
->comment(context
, context
->last_reason
);
55 context
->last_result
= TORTURE_FAIL
;
58 void _torture_skip_ext(struct torture_context
*context
,
65 context
->last_result
= TORTURE_SKIP
;
66 context
->last_reason
= talloc_vasprintf(context
, fmt
, ap
);
70 struct torture_suite
*torture_suite_create(TALLOC_CTX
*ctx
, const char *name
)
72 struct torture_suite
*suite
= talloc_zero(ctx
, struct torture_suite
);
74 suite
->name
= talloc_strdup(suite
, name
);
75 suite
->testcases
= NULL
;
76 suite
->children
= NULL
;
81 void torture_tcase_set_fixture(struct torture_tcase
*tcase
,
82 BOOL (*setup
) (struct torture_context
*, void **),
83 BOOL (*teardown
) (struct torture_context
*, void *))
86 tcase
->teardown
= teardown
;
89 static bool wrap_test_with_testcase(struct torture_context
*torture_ctx
,
90 struct torture_tcase
*tcase
,
91 struct torture_test
*test
)
93 bool (*fn
) (struct torture_context
*,
94 const void *tcase_data
,
95 const void *test_data
);
99 return fn(torture_ctx
, tcase
->data
, test
->data
);
102 struct torture_test
*torture_tcase_add_test(struct torture_tcase
*tcase
,
104 bool (*run
) (struct torture_context
*,
105 const void *tcase_data
,
106 const void *test_data
),
109 struct torture_test
*test
= talloc(tcase
, struct torture_test
);
111 test
->name
= talloc_strdup(test
, name
);
112 test
->description
= NULL
;
113 test
->run
= wrap_test_with_testcase
;
115 test
->dangerous
= False
;
118 DLIST_ADD_END(tcase
->tests
, test
, struct torture_test
*);
123 struct torture_tcase
*torture_suite_add_tcase(struct torture_suite
*suite
,
126 struct torture_tcase
*tcase
= talloc(suite
, struct torture_tcase
);
128 tcase
->name
= talloc_strdup(tcase
, name
);
129 tcase
->description
= NULL
;
131 tcase
->teardown
= NULL
;
132 tcase
->fixture_persistent
= True
;
135 DLIST_ADD_END(suite
->testcases
, tcase
, struct torture_tcase
*);
140 BOOL
torture_run_suite(struct torture_context
*context
,
141 struct torture_suite
*suite
)
144 struct torture_tcase
*tcase
;
145 struct torture_suite
*tsuite
;
148 if (context
->ui_ops
->suite_start
)
149 context
->ui_ops
->suite_start(context
, suite
);
152 torture_subunit_run_suite(context
, suite
);
154 for (tcase
= suite
->testcases
; tcase
; tcase
= tcase
->next
) {
155 ret
&= torture_run_tcase(context
, tcase
);
158 for (tsuite
= suite
->children
; tsuite
; tsuite
= tsuite
->next
) {
159 ret
&= torture_run_suite(context
, tsuite
);
162 if (context
->ui_ops
->suite_finish
)
163 context
->ui_ops
->suite_finish(context
, suite
);
170 void torture_ui_test_start(struct torture_context
*context
,
171 struct torture_tcase
*tcase
,
172 struct torture_test
*test
)
174 if (context
->ui_ops
->test_start
)
175 context
->ui_ops
->test_start(context
, tcase
, test
);
178 void torture_ui_test_result(struct torture_context
*context
,
179 enum torture_result result
,
182 if (context
->ui_ops
->test_result
)
183 context
->ui_ops
->test_result(context
, result
, comment
);
187 case TORTURE_SKIP
: context
->success
++; break;
188 case TORTURE_FAIL
: context
->failed
++; break;
189 case TORTURE_TODO
: context
->todo
++; break;
190 case TORTURE_OK
: context
->success
++; break;
194 static BOOL
internal_torture_run_test(struct torture_context
*context
,
195 struct torture_tcase
*tcase
,
196 struct torture_test
*test
,
201 if (test
->dangerous
&& !torture_setting_bool(context
, "dangerous", False
)) {
202 _torture_skip_ext(context
,
203 "disabled %s - enable dangerous tests to use", test
->name
);
207 if (!already_setup
&& tcase
->setup
&&
208 !tcase
->setup(context
, &(tcase
->data
)))
211 context
->active_tcase
= tcase
;
212 context
->active_test
= test
;
214 torture_ui_test_start(context
, tcase
, test
);
216 context
->last_reason
= NULL
;
217 context
->last_result
= TORTURE_OK
;
219 ret
= test
->run(context
, tcase
, test
);
221 if (context
->last_reason
== NULL
)
222 context
->last_reason
= talloc_strdup(context
, "...");
223 context
->last_result
= TORTURE_FAIL
;
226 torture_ui_test_result(context
, context
->last_result
, context
->last_reason
);
228 talloc_free(context
->last_reason
);
230 context
->active_test
= NULL
;
231 context
->active_tcase
= NULL
;
233 if (!already_setup
&& tcase
->teardown
&& !tcase
->teardown(context
, tcase
->data
))
239 BOOL
torture_run_tcase(struct torture_context
*context
,
240 struct torture_tcase
*tcase
)
243 struct torture_test
*test
;
247 context
->active_tcase
= tcase
;
248 if (context
->ui_ops
->tcase_start
)
249 context
->ui_ops
->tcase_start(context
, tcase
);
251 if (tcase
->fixture_persistent
&& tcase
->setup
252 && !tcase
->setup(context
, &tcase
->data
)) {
257 for (test
= tcase
->tests
; test
; test
= test
->next
) {
258 ret
&= internal_torture_run_test(context
, tcase
, test
,
259 tcase
->fixture_persistent
);
262 if (tcase
->fixture_persistent
&& tcase
->teardown
&&
263 !tcase
->teardown(context
, tcase
->data
))
267 context
->active_tcase
= NULL
;
269 if (context
->ui_ops
->tcase_finish
)
270 context
->ui_ops
->tcase_finish(context
, tcase
);
277 BOOL
torture_run_test(struct torture_context
*context
,
278 struct torture_tcase
*tcase
,
279 struct torture_test
*test
)
281 return internal_torture_run_test(context
, tcase
, test
, False
);
284 int torture_setting_int(struct torture_context
*test
, const char *name
,
287 return lp_parm_int(-1, "torture", name
, default_value
);
290 bool torture_setting_bool(struct torture_context
*test
, const char *name
,
293 return lp_parm_bool(-1, "torture", name
, default_value
);
296 const char *torture_setting_string(struct torture_context
*test
, const char *name
,
297 const char *default_value
)
299 const char *ret
= lp_parm_string(-1, "torture", name
);
302 return default_value
;
307 static bool wrap_test_with_simple_tcase(struct torture_context
*torture_ctx
,
308 struct torture_tcase
*tcase
,
309 struct torture_test
*test
)
311 bool (*fn
) (struct torture_context
*, const void *tcase_data
);
315 return fn(torture_ctx
, test
->data
);
318 struct torture_tcase
*torture_suite_add_simple_tcase(
319 struct torture_suite
*suite
,
321 bool (*run
) (struct torture_context
*test
, const void *),
324 struct torture_tcase
*tcase
;
325 struct torture_test
*test
;
327 tcase
= torture_suite_add_tcase(suite
, name
);
329 test
= talloc(tcase
, struct torture_test
);
331 test
->name
= talloc_strdup(test
, name
);
332 test
->description
= NULL
;
333 test
->run
= wrap_test_with_simple_tcase
;
336 test
->dangerous
= False
;
338 DLIST_ADD_END(tcase
->tests
, test
, struct torture_test
*);
343 static bool wrap_simple_test(struct torture_context
*torture_ctx
,
344 struct torture_tcase
*tcase
,
345 struct torture_test
*test
)
347 bool (*fn
) (struct torture_context
*);
351 return fn(torture_ctx
);
354 struct torture_tcase
*torture_suite_add_simple_test(
355 struct torture_suite
*suite
,
357 bool (*run
) (struct torture_context
*test
))
359 struct torture_test
*test
;
360 struct torture_tcase
*tcase
;
362 tcase
= torture_suite_add_tcase(suite
, name
);
364 test
= talloc(tcase
, struct torture_test
);
366 test
->name
= talloc_strdup(test
, name
);
367 test
->description
= NULL
;
368 test
->run
= wrap_simple_test
;
370 test
->dangerous
= false;
372 DLIST_ADD_END(tcase
->tests
, test
, struct torture_test
*);
377 BOOL
torture_teardown_free(struct torture_context
*torture
, void *data
)
379 return talloc_free(data
);
383 bool torture_suite_add_suite(struct torture_suite
*suite
,
384 struct torture_suite
*child
)
389 DLIST_ADD_END(suite
->children
, child
, struct torture_suite
*);
391 /* FIXME: Check for duplicates and return false if the
392 * added suite already exists as a child */
398 struct torture_suite
*torture_find_suite(struct torture_suite
*parent
,
401 struct torture_suite
*child
;
403 for (child
= parent
->children
; child
; child
= child
->next
)
404 if (!strcmp(child
->name
, name
))