Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB torture UI functions
4 :
5 : Copyright (C) Jelmer Vernooij 2006
6 :
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 3 of the License, or
10 : (at your option) any later version.
11 :
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.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifndef __TORTURE_UI_H__
22 : #define __TORTURE_UI_H__
23 :
24 : struct torture_test;
25 : struct torture_context;
26 : struct torture_suite;
27 : struct torture_tcase;
28 : struct torture_results;
29 :
30 : enum torture_result {
31 : TORTURE_OK=0,
32 : TORTURE_FAIL=1,
33 : TORTURE_ERROR=2,
34 : TORTURE_SKIP=3
35 : };
36 :
37 : enum torture_progress_whence {
38 : TORTURE_PROGRESS_SET,
39 : TORTURE_PROGRESS_CUR,
40 : TORTURE_PROGRESS_POP,
41 : TORTURE_PROGRESS_PUSH,
42 : };
43 :
44 : /*
45 : * These callbacks should be implemented by any backend that wishes
46 : * to listen to reports from the torture tests.
47 : */
48 : struct torture_ui_ops
49 : {
50 : void (*init) (struct torture_results *);
51 : void (*comment) (struct torture_context *, const char *);
52 : void (*warning) (struct torture_context *, const char *);
53 : void (*suite_start) (struct torture_context *, struct torture_suite *);
54 : void (*suite_finish) (struct torture_context *, struct torture_suite *);
55 : void (*tcase_start) (struct torture_context *, struct torture_tcase *);
56 : void (*tcase_finish) (struct torture_context *, struct torture_tcase *);
57 : void (*test_start) (struct torture_context *,
58 : struct torture_tcase *,
59 : struct torture_test *);
60 : void (*test_result) (struct torture_context *,
61 : enum torture_result, const char *reason);
62 : void (*progress) (struct torture_context *, int offset, enum torture_progress_whence whence);
63 : void (*report_time) (struct torture_context *);
64 : };
65 :
66 : void torture_ui_test_start(struct torture_context *context,
67 : struct torture_tcase *tcase,
68 : struct torture_test *test);
69 :
70 : void torture_ui_test_result(struct torture_context *context,
71 : enum torture_result result,
72 : const char *comment);
73 :
74 : void torture_ui_report_time(struct torture_context *context);
75 :
76 : /*
77 : * Holds information about a specific run of the testsuite.
78 : * The data in this structure should be considered private to
79 : * the torture tests and should only be used directly by the torture
80 : * code and the ui backends.
81 : *
82 : * Torture tests should instead call the torture_*() macros and functions
83 : * specified below.
84 : */
85 :
86 : struct torture_subunit_prefix {
87 : const struct torture_subunit_prefix *parent;
88 : char subunit_prefix[256];
89 : };
90 :
91 : struct torture_context
92 : {
93 : struct torture_results *results;
94 :
95 : struct torture_test *active_test;
96 : struct torture_tcase *active_tcase;
97 : struct torture_subunit_prefix _initial_prefix;
98 : const struct torture_subunit_prefix *active_prefix;
99 :
100 : enum torture_result last_result;
101 : char *last_reason;
102 :
103 : /** Directory used for temporary test data */
104 : const char *outputdir;
105 :
106 : /** Event context */
107 : struct tevent_context *ev;
108 :
109 : /** Loadparm context (will go away in favor of torture_setting_ at some point) */
110 : struct loadparm_context *lp_ctx;
111 :
112 : int conn_index;
113 : };
114 :
115 : struct torture_results
116 : {
117 : const struct torture_ui_ops *ui_ops;
118 : void *ui_data;
119 :
120 : /** Whether tests should avoid writing output to stdout */
121 : bool quiet;
122 :
123 : bool returncode;
124 : };
125 :
126 : /*
127 : * Describes a particular torture test
128 : */
129 : struct torture_test {
130 : /** Short unique name for the test. */
131 : const char *name;
132 :
133 : /** Long description for the test. */
134 : const char *description;
135 :
136 : /** Whether this is a dangerous test
137 : * (can corrupt the remote servers data or bring it down). */
138 : bool dangerous;
139 :
140 : /** Function to call to run this test */
141 : bool (*run) (struct torture_context *torture_ctx,
142 : struct torture_tcase *tcase,
143 : struct torture_test *test);
144 :
145 : struct torture_test *prev, *next;
146 :
147 : /** Pointer to the actual test function. This is run by the
148 : * run() function above. */
149 : void *fn;
150 :
151 : /** Use data for this test */
152 : const void *data;
153 :
154 : struct torture_tcase *tcase;
155 : };
156 :
157 : /*
158 : * Describes a particular test case.
159 : */
160 : struct torture_tcase {
161 : const char *name;
162 : const char *description;
163 : bool (*setup) (struct torture_context *tcase, void **data);
164 : bool (*teardown) (struct torture_context *tcase, void *data);
165 : bool fixture_persistent;
166 : void *data;
167 : struct torture_test *tests;
168 : struct torture_tcase *prev, *next;
169 : const struct torture_suite *suite;
170 : };
171 :
172 : struct torture_suite
173 : {
174 : const char *name;
175 : const char *description;
176 : struct torture_tcase *testcases;
177 : struct torture_suite *children;
178 : const struct torture_suite *parent;
179 :
180 : /* Pointers to siblings of this torture suite */
181 : struct torture_suite *prev, *next;
182 : };
183 :
184 : /** Create a new torture suite */
185 : struct torture_suite *torture_suite_create(TALLOC_CTX *mem_ctx,
186 : const char *name);
187 :
188 : /** Change the setup and teardown functions for a testcase */
189 : void torture_tcase_set_fixture(struct torture_tcase *tcase,
190 : bool (*setup) (struct torture_context *, void **),
191 : bool (*teardown) (struct torture_context *, void *));
192 :
193 : /* Add another test to run for a particular testcase */
194 : struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
195 : const char *name,
196 : bool (*run) (struct torture_context *test,
197 : const void *tcase_data, const void *test_data),
198 : const void *test_data);
199 :
200 : /* Add a testcase to a testsuite */
201 : struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite,
202 : const char *name);
203 :
204 : /* Convenience wrapper that adds a testcase against only one
205 : * test will be run */
206 : struct torture_tcase *torture_suite_add_simple_tcase_const(
207 : struct torture_suite *suite,
208 : const char *name,
209 : bool (*run) (struct torture_context *test,
210 : const void *test_data),
211 : const void *data);
212 :
213 : /* Convenience function that adds a test which only
214 : * gets the test case data */
215 : struct torture_test *torture_tcase_add_simple_test_const(
216 : struct torture_tcase *tcase,
217 : const char *name,
218 : bool (*run) (struct torture_context *test,
219 : const void *tcase_data));
220 :
221 : /* Convenience wrapper that adds a test that doesn't need any
222 : * testcase data */
223 : struct torture_tcase *torture_suite_add_simple_test(
224 : struct torture_suite *suite,
225 : const char *name,
226 : bool (*run) (struct torture_context *test));
227 :
228 : /* Add a child testsuite to an existing testsuite */
229 : bool torture_suite_add_suite(struct torture_suite *suite,
230 : struct torture_suite *child);
231 :
232 : char *torture_subunit_test_name(struct torture_context *ctx,
233 : struct torture_tcase *tcase,
234 : struct torture_test *test);
235 : void torture_subunit_prefix_reset(struct torture_context *ctx,
236 : const char *name);
237 :
238 : /* Run the specified testsuite recursively */
239 : bool torture_run_suite(struct torture_context *context,
240 : struct torture_suite *suite);
241 :
242 : /* Run the specified testsuite recursively, but only the specified
243 : * tests */
244 : bool torture_run_suite_restricted(struct torture_context *context,
245 : struct torture_suite *suite, const char **restricted);
246 :
247 : /* Run the specified testcase */
248 : bool torture_run_tcase(struct torture_context *context,
249 : struct torture_tcase *tcase);
250 :
251 : bool torture_run_tcase_restricted(struct torture_context *context,
252 : struct torture_tcase *tcase, const char **restricted);
253 :
254 : /* Run the specified test */
255 : bool torture_run_test(struct torture_context *context,
256 : struct torture_tcase *tcase,
257 : struct torture_test *test);
258 :
259 : bool torture_run_test_restricted(struct torture_context *context,
260 : struct torture_tcase *tcase,
261 : struct torture_test *test,
262 : const char **restricted);
263 :
264 : void torture_comment(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
265 : void torture_warning(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
266 : void torture_result(struct torture_context *test,
267 : enum torture_result, const char *reason, ...) PRINTF_ATTRIBUTE(3,4);
268 :
269 : #define torture_assert(torture_ctx,expr,cmt) do { \
270 : if (!(expr)) { \
271 : torture_result(torture_ctx, TORTURE_FAIL, __location__": Expression `%s' failed: %s", __STRING(expr), cmt); \
272 : return false; \
273 : } \
274 : } while(0)
275 :
276 : #define torture_assertf(torture_ctx, expr, format, ...) do { \
277 : if (!(expr)) { \
278 : char *_msg = talloc_asprintf(torture_ctx, \
279 : format, \
280 : __VA_ARGS__); \
281 : torture_result(torture_ctx, \
282 : TORTURE_FAIL, \
283 : __location__": Expression `%s' failed: %s", \
284 : __STRING(expr), _msg); \
285 : talloc_free(_msg); \
286 : return false; \
287 : } \
288 : } while(0)
289 :
290 : #define torture_assert_goto(torture_ctx,expr,ret,label,cmt) do { \
291 : if (!(expr)) { \
292 : torture_result(torture_ctx, TORTURE_FAIL, __location__": Expression `%s' failed: %s", __STRING(expr), cmt); \
293 : ret = false; \
294 : goto label; \
295 : } \
296 : } while(0)
297 :
298 : #define torture_assert_werr_equal(torture_ctx, got, expected, cmt) \
299 : do { WERROR __got = got, __expected = expected; \
300 : if (!W_ERROR_EQUAL(__got, __expected)) { \
301 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", win_errstr(__got), win_errstr(__expected), cmt); \
302 : return false; \
303 : } \
304 : } while (0)
305 :
306 : #define torture_assert_ntstatus_equal(torture_ctx,got,expected,cmt) \
307 : do { NTSTATUS __got = got, __expected = expected; \
308 : if (!NT_STATUS_EQUAL(__got, __expected)) { \
309 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", nt_errstr(__got), nt_errstr(__expected), cmt); \
310 : return false; \
311 : }\
312 : } while(0)
313 :
314 : #define torture_assert_ntstatus_equal_goto(torture_ctx,got,expected,ret,label,cmt) \
315 : do { NTSTATUS __got = got, __expected = expected; \
316 : if (!NT_STATUS_EQUAL(__got, __expected)) { \
317 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", nt_errstr(__got), nt_errstr(__expected), cmt); \
318 : ret = false; \
319 : goto label; \
320 : }\
321 : } while(0)
322 :
323 : #define torture_assert_ndr_err_equal(torture_ctx,got,expected,cmt) \
324 : do { enum ndr_err_code __got = got, __expected = expected; \
325 : if (__got != __expected) { \
326 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %d (%s), expected %d (%s): %s", __got, ndr_errstr(__got), __expected, __STRING(expected), cmt); \
327 : return false; \
328 : }\
329 : } while(0)
330 :
331 : #define torture_assert_ndr_err_equal_goto(torture_ctx,got,expected,ret,label,cmt) \
332 : do { enum ndr_err_code __got = got, __expected = expected; \
333 : if (__got != __expected) { \
334 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %d (%s), expected %d (%s): %s", __got, ndr_errstr(__got), __expected, __STRING(expected), cmt); \
335 : ret = false; \
336 : goto label; \
337 : }\
338 : } while(0)
339 :
340 : #define torture_assert_hresult_equal(torture_ctx, got, expected, cmt) \
341 : do { HRESULT __got = got, __expected = expected; \
342 : if (!HRES_IS_EQUAL(__got, __expected)) { \
343 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", hresult_errstr(__got), hresult_errstr(__expected), cmt); \
344 : return false; \
345 : } \
346 : } while (0)
347 :
348 : #define torture_assert_krb5_error_equal(torture_ctx, got, expected, cmt) \
349 : do { krb5_error_code __got = got, __expected = expected; \
350 : if (__got != __expected) { \
351 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %d (%s), expected %d (%s): %s", __got, error_message(__got), __expected, error_message(__expected), cmt); \
352 : return false; \
353 : } \
354 : } while (0)
355 :
356 : #define torture_assert_casestr_equal(torture_ctx,got,expected,cmt) \
357 : do { const char *__got = (got), *__expected = (expected); \
358 : if (!strequal(__got, __expected)) { \
359 : torture_result(torture_ctx, TORTURE_FAIL, \
360 : __location__": "#got" was %s, expected %s: %s", \
361 : __got, __expected == NULL ? "null" : __expected, cmt); \
362 : return false; \
363 : } \
364 : } while(0)
365 :
366 : #define torture_assert_str_equal(torture_ctx,got,expected,cmt)\
367 : do { const char *__got = (got), *__expected = (expected); \
368 : if (strcmp_safe(__got, __expected) != 0) { \
369 : torture_result(torture_ctx, TORTURE_FAIL, \
370 : __location__": "#got" was %s, expected %s: %s", \
371 : __got, __expected == NULL ? "NULL" : __expected, cmt); \
372 : return false; \
373 : } \
374 : } while(0)
375 :
376 : #define torture_assert_strn_equal(torture_ctx,got,expected,len,cmt)\
377 : do { const char *__got = (got), *__expected = (expected); \
378 : if (strncmp(__got, __expected, len) != 0) { \
379 : torture_result(torture_ctx, TORTURE_FAIL, \
380 : __location__": "#got" %s of len %d did not match "#expected" %s: %s", \
381 : __got, (int)len, __expected, cmt); \
382 : return false; \
383 : } \
384 : } while(0)
385 :
386 : #define torture_assert_str_equal_goto(torture_ctx,got,expected,ret,label,cmt)\
387 : do { const char *__got = (got), *__expected = (expected); \
388 : if (strcmp_safe(__got, __expected) != 0) { \
389 : torture_result(torture_ctx, TORTURE_FAIL, \
390 : __location__": "#got" was %s, expected %s: %s", \
391 : __got, __expected, cmt); \
392 : ret = false; \
393 : goto label; \
394 : } \
395 : } while(0)
396 :
397 : #define torture_assert_mem_equal(torture_ctx,got,expected,len,cmt)\
398 : do { const void *__got = (got), *__expected = (expected); \
399 : if (memcmp(__got, __expected, len) != 0) { \
400 : torture_result(torture_ctx, TORTURE_FAIL, \
401 : __location__": "#got" of len %d did not match "#expected": %s", (int)len, cmt); \
402 : return false; \
403 : } \
404 : } while(0)
405 :
406 : #define torture_assert_mem_equal_goto(torture_ctx,got,expected,len,ret,label,cmt) \
407 : do { const void *__got = (got), *__expected = (expected); \
408 : if (memcmp(__got, __expected, len) != 0) { \
409 : torture_result(torture_ctx, TORTURE_FAIL, \
410 : __location__": "#got" of len %d did not match "#expected": %s", (int)len, cmt); \
411 : ret = false; \
412 : goto label; \
413 : } \
414 : } while(0)
415 :
416 : #define torture_assert_mem_not_equal_goto(torture_ctx,got,expected,len,ret,label,cmt) \
417 : do { const void *__got = (got), *__expected = (expected); \
418 : if (memcmp(__got, __expected, len) == 0) { \
419 : torture_result(torture_ctx, TORTURE_FAIL, \
420 : __location__": "#got" of len %d unexpectedly matches "#expected": %s", (int)len, cmt); \
421 : ret = false; \
422 : goto label; \
423 : } \
424 : } while(0)
425 :
426 0 : static inline void torture_dump_data_str_cb(const char *buf, void *private_data)
427 : {
428 0 : char **dump = (char **)private_data;
429 0 : *dump = talloc_strdup_append_buffer(*dump, buf);
430 0 : }
431 :
432 : #define torture_assert_data_blob_equal(torture_ctx,got,expected,cmt)\
433 : do { const DATA_BLOB __got = (got), __expected = (expected); \
434 : if (__got.length != __expected.length) { \
435 : torture_result(torture_ctx, TORTURE_FAIL, \
436 : __location__": "#got".len %d did not match "#expected" len %d: %s", \
437 : (int)__got.length, (int)__expected.length, cmt); \
438 : return false; \
439 : } \
440 : if (memcmp(__got.data, __expected.data, __got.length) != 0) { \
441 : char *__dump = NULL; \
442 : uint8_t __byte_a = 0x00;\
443 : uint8_t __byte_b = 0x00;\
444 : size_t __i;\
445 : for (__i=0; __i < __expected.length; __i++) {\
446 : __byte_a = __expected.data[__i];\
447 : if (__i == __got.length) {\
448 : __byte_b = 0x00;\
449 : break;\
450 : }\
451 : __byte_b = __got.data[__i];\
452 : if (__byte_a != __byte_b) {\
453 : break;\
454 : }\
455 : }\
456 : torture_warning(torture_ctx, "blobs differ at byte 0x%02X (%zu)", (unsigned int)__i, __i);\
457 : torture_warning(torture_ctx, "expected byte[0x%02X] = 0x%02X got byte[0x%02X] = 0x%02X",\
458 : (unsigned int)__i, __byte_a, (unsigned int)__i, __byte_b);\
459 : __dump = talloc_strdup(torture_ctx, ""); \
460 : dump_data_cb(__got.data, __got.length, true, \
461 : torture_dump_data_str_cb, &__dump); \
462 : torture_warning(torture_ctx, "got[0x%02X]: \n%s", \
463 : (unsigned int)__got.length, __dump); \
464 : TALLOC_FREE(__dump); \
465 : __dump = talloc_strdup(torture_ctx, ""); \
466 : dump_data_cb(__expected.data, __expected.length, true, \
467 : torture_dump_data_str_cb, &__dump); \
468 : torture_warning(torture_ctx, "expected[0x%02X]: \n%s", \
469 : (int)__expected.length, __dump); \
470 : TALLOC_FREE(__dump); \
471 : torture_result(torture_ctx, TORTURE_FAIL, \
472 : __location__": "#got" of len %d did not match "#expected": %s", (int)__got.length, cmt); \
473 : return false; \
474 : } \
475 : } while(0)
476 :
477 : #define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\
478 : do { \
479 : char *__got; \
480 : const char *__expected = (expected); \
481 : size_t __size; \
482 : __got = file_load(filename, &__size, 0, torture_ctx); \
483 : if (__got == NULL) { \
484 : torture_result(torture_ctx, TORTURE_FAIL, \
485 : __location__": unable to open %s: %s\n", \
486 : filename, cmt); \
487 : return false; \
488 : } \
489 : \
490 : if (strcmp_safe(__got, __expected) != 0) { \
491 : torture_result(torture_ctx, TORTURE_FAIL, \
492 : __location__": %s contained:\n%sExpected: %s%s\n", \
493 : filename, __got, __expected, cmt); \
494 : talloc_free(__got); \
495 : return false; \
496 : } \
497 : talloc_free(__got); \
498 : } while(0)
499 :
500 : #define torture_assert_file_contains(torture_ctx,filename,expected,cmt)\
501 : do { const char *__got, *__expected = (expected); \
502 : size_t __size; \
503 : __got = file_load(filename, *size, 0, torture_ctx); \
504 : if (strcmp_safe(__got, __expected) != 0) { \
505 : torture_result(torture_ctx, TORTURE_FAIL, \
506 : __location__": %s contained:\n%sExpected: %s%s\n", \
507 : __got, __expected, cmt); \
508 : talloc_free(__got); \
509 : return false; \
510 : } \
511 : talloc_free(__got); \
512 : } while(0)
513 :
514 : #define torture_assert_int_equal(torture_ctx,got,expected,cmt)\
515 : do { int __got = (got), __expected = (expected); \
516 : if (__got != __expected) { \
517 : torture_result(torture_ctx, TORTURE_FAIL, \
518 : __location__": "#got" was %d (0x%X), expected %d (0x%X): %s", \
519 : __got, __got, __expected, __expected, cmt); \
520 : return false; \
521 : } \
522 : } while(0)
523 :
524 : #define torture_assert_int_equal_goto(torture_ctx,got,expected,ret,label,cmt)\
525 : do { int __got = (got), __expected = (expected); \
526 : if (__got != __expected) { \
527 : torture_result(torture_ctx, TORTURE_FAIL, \
528 : __location__": "#got" was %d (0x%X), expected %d (0x%X): %s", \
529 : __got, __got, __expected, __expected, cmt); \
530 : ret = false; \
531 : goto label; \
532 : } \
533 : } while(0)
534 :
535 : #define torture_assert_int_not_equal(torture_ctx,got,not_expected,cmt)\
536 : do { int __got = (got), __not_expected = (not_expected); \
537 : if (__got == __not_expected) { \
538 : torture_result(torture_ctx, TORTURE_FAIL, \
539 : __location__": "#got" was %d (0x%X), expected a different number: %s", \
540 : __got, __got, cmt); \
541 : return false; \
542 : } \
543 : } while(0)
544 :
545 : #define torture_assert_int_not_equal_goto(torture_ctx,got,not_expected,ret,label,cmt)\
546 : do { int __got = (got), __not_expected = (not_expected); \
547 : if (__got == __not_expected) { \
548 : torture_result(torture_ctx, TORTURE_FAIL, \
549 : __location__": "#got" was %d (0x%X), expected a different number: %s", \
550 : __got, __got, cmt); \
551 : ret = false; \
552 : goto label; \
553 : } \
554 : } while(0)
555 :
556 : #define torture_assert_u32_equal(torture_ctx,got,expected,cmt)\
557 : do { uint32_t __got = (got), __expected = (expected); \
558 : if (__got != __expected) { \
559 : torture_result(torture_ctx, TORTURE_FAIL, \
560 : __location__": "#got" was %ju (0x%jX), expected %ju (0x%jX): %s", \
561 : (uintmax_t)__got, (uintmax_t)__got, \
562 : (uintmax_t)__expected, (uintmax_t)__expected, \
563 : cmt); \
564 : return false; \
565 : } \
566 : } while(0)
567 :
568 : #define torture_assert_u32_equal_goto(torture_ctx,got,expected,ret,label,cmt)\
569 : do { uint32_t __got = (got), __expected = (expected); \
570 : if (__got != __expected) { \
571 : torture_result(torture_ctx, TORTURE_FAIL, \
572 : __location__": "#got" was %ju (0x%jX), expected %ju (0x%jX): %s", \
573 : (uintmax_t)__got, (uintmax_t)__got, \
574 : (uintmax_t)__expected, (uintmax_t)__expected, \
575 : cmt); \
576 : ret = false; \
577 : goto label; \
578 : } \
579 : } while(0)
580 :
581 : #define torture_assert_u32_not_equal(torture_ctx,got,not_expected,cmt)\
582 : do { uint32_t __got = (got), __not_expected = (not_expected); \
583 : if (__got == __not_expected) { \
584 : torture_result(torture_ctx, TORTURE_FAIL, \
585 : __location__": "#got" was %ju (0x%jX), expected a different number: %s", \
586 : (uintmax_t)__got, (uintmax_t)__got, \
587 : cmt); \
588 : return false; \
589 : } \
590 : } while(0)
591 :
592 : #define torture_assert_u32_not_equal_goto(torture_ctx,got,not_expected,ret,label,cmt)\
593 : do { uint32_t __got = (got), __not_expected = (not_expected); \
594 : if (__got == __not_expected) { \
595 : torture_result(torture_ctx, TORTURE_FAIL, \
596 : __location__": "#got" was %ju (0x%jX), expected a different number: %s", \
597 : (uintmax_t)__got, (uintmax_t)__got, \
598 : cmt); \
599 : ret = false; \
600 : goto label; \
601 : } \
602 : } while(0)
603 :
604 : #define torture_assert_u64_equal(torture_ctx,got,expected,cmt)\
605 : do { uint64_t __got = (got), __expected = (expected); \
606 : if (__got != __expected) { \
607 : torture_result(torture_ctx, TORTURE_FAIL, \
608 : __location__": "#got" was %llu (0x%llX), expected %llu (0x%llX): %s", \
609 : (unsigned long long)__got, (unsigned long long)__got, \
610 : (unsigned long long)__expected, (unsigned long long)__expected, \
611 : cmt); \
612 : return false; \
613 : } \
614 : } while(0)
615 :
616 : #define torture_assert_u64_equal_goto(torture_ctx,got,expected,ret,label,cmt)\
617 : do { uint64_t __got = (got), __expected = (expected); \
618 : if (__got != __expected) { \
619 : torture_result(torture_ctx, TORTURE_FAIL, \
620 : __location__": "#got" was %llu (0x%llX), expected %llu (0x%llX): %s", \
621 : (unsigned long long)__got, (unsigned long long)__got, \
622 : (unsigned long long)__expected, (unsigned long long)__expected, \
623 : cmt); \
624 : ret = false; \
625 : goto label; \
626 : } \
627 : } while(0)
628 :
629 : #define torture_assert_u64_not_equal(torture_ctx,got,not_expected,cmt)\
630 : do { uint64_t __got = (got), __not_expected = (not_expected); \
631 : if (__got == __not_expected) { \
632 : torture_result(torture_ctx, TORTURE_FAIL, \
633 : __location__": "#got" was %llu (0x%llX), expected a different number: %s", \
634 : (unsigned long long)__got, (unsigned long long)__got, \
635 : cmt); \
636 : return false; \
637 : } \
638 : } while(0)
639 :
640 : #define torture_assert_u64_not_equal_goto(torture_ctx,got,not_expected,ret,label,cmt)\
641 : do { uint64_t __got = (got), __not_expected = (not_expected); \
642 : if (__got == __not_expected) { \
643 : torture_result(torture_ctx, TORTURE_FAIL, \
644 : __location__": "#got" was %llu (0x%llX), expected a different number: %s", \
645 : (unsigned long long)__got, (unsigned long long)__got, \
646 : cmt); \
647 : ret = false; \
648 : goto label; \
649 : } \
650 : } while(0)
651 :
652 : #define torture_assert_errno_equal(torture_ctx,expected,cmt)\
653 : do { int __expected = (expected); \
654 : if (errno != __expected) { \
655 : torture_result(torture_ctx, TORTURE_FAIL, \
656 : __location__": errno was %d (%s), expected %d: %s: %s", \
657 : errno, strerror(errno), __expected, \
658 : strerror(__expected), cmt); \
659 : return false; \
660 : } \
661 : } while(0)
662 :
663 : #define torture_assert_errno_equal_goto(torture_ctx,expected,ret,label,cmt)\
664 : do { int __expected = (expected); \
665 : if (errno != __expected) { \
666 : torture_result(torture_ctx, TORTURE_FAIL, \
667 : __location__": errno was %d (%s), expected %d: %s: %s", \
668 : errno, strerror(errno), __expected, \
669 : strerror(__expected), cmt); \
670 : ret = false; \
671 : goto label; \
672 : } \
673 : } while(0)
674 :
675 : #define torture_assert_guid_equal(torture_ctx,got,expected,cmt)\
676 : do {const struct GUID __got = (got), __expected = (expected); \
677 : if (!GUID_equal(&__got, &__expected)) { \
678 : torture_result(torture_ctx, TORTURE_FAIL, \
679 : __location__": "#got" was %s, expected %s: %s", \
680 : GUID_string(torture_ctx, &__got), GUID_string(torture_ctx, &__expected), cmt); \
681 : return false; \
682 : } \
683 : } while(0)
684 :
685 : #define torture_assert_nttime_equal(torture_ctx,got,expected,cmt) \
686 : do { NTTIME __got = got, __expected = expected; \
687 : if (!nt_time_equal(&__got, &__expected)) { \
688 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", nt_time_string(tctx, __got), nt_time_string(tctx, __expected), cmt); \
689 : return false; \
690 : }\
691 : } while(0)
692 :
693 : #define torture_assert_sid_equal(torture_ctx,got,expected,cmt)\
694 : do {const struct dom_sid *__got = (got), *__expected = (expected); \
695 : if (!dom_sid_equal(__got, __expected)) { \
696 : torture_result(torture_ctx, TORTURE_FAIL, \
697 : __location__": "#got" was %s, expected %s: %s", \
698 : dom_sid_string(torture_ctx, __got), dom_sid_string(torture_ctx, __expected), cmt); \
699 : return false; \
700 : } \
701 : } while(0)
702 :
703 : #define torture_assert_not_null(torture_ctx,got,cmt)\
704 : do {const void *__got = (got); \
705 : if (__got == NULL) { \
706 : torture_result(torture_ctx, TORTURE_FAIL, \
707 : __location__": "#got" was NULL, expected != NULL: %s", \
708 : cmt); \
709 : return false; \
710 : } \
711 : } while(0)
712 :
713 : #define torture_assert_not_null_goto(torture_ctx,got,ret,label,cmt)\
714 : do {const void *__got = (got); \
715 : if (__got == NULL) { \
716 : torture_result(torture_ctx, TORTURE_FAIL, \
717 : __location__": "#got" was NULL, expected != NULL: %s", \
718 : cmt); \
719 : ret = false; \
720 : goto label; \
721 : } \
722 : } while(0)
723 :
724 : #define torture_skip(torture_ctx,cmt) do {\
725 : torture_result(torture_ctx, TORTURE_SKIP, __location__": %s", cmt);\
726 : return true; \
727 : } while(0)
728 : #define torture_skip_goto(torture_ctx,label,cmt) do {\
729 : torture_result(torture_ctx, TORTURE_SKIP, __location__": %s", cmt);\
730 : goto label; \
731 : } while(0)
732 : #define torture_fail(torture_ctx,cmt) do {\
733 : torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
734 : return false; \
735 : } while (0)
736 : #define torture_fail_goto(torture_ctx,label,cmt) do {\
737 : torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
738 : goto label; \
739 : } while (0)
740 :
741 : #define torture_out stderr
742 :
743 : /* Convenience macros */
744 : #define torture_assert_ntstatus_ok(torture_ctx,expr,cmt) \
745 : torture_assert_ntstatus_equal(torture_ctx,expr,NT_STATUS_OK,cmt)
746 :
747 : #define torture_assert_ntstatus_ok_goto(torture_ctx,expr,ret,label,cmt) \
748 : torture_assert_ntstatus_equal_goto(torture_ctx,expr,NT_STATUS_OK,ret,label,cmt)
749 :
750 : #define torture_assert_werr_ok(torture_ctx,expr,cmt) \
751 : torture_assert_werr_equal(torture_ctx,expr,WERR_OK,cmt)
752 :
753 : #define torture_assert_ndr_success(torture_ctx,expr,cmt) \
754 : torture_assert_ndr_err_equal(torture_ctx,expr,NDR_ERR_SUCCESS,cmt)
755 :
756 : #define torture_assert_ndr_success_goto(torture_ctx,expr,ret,label,cmt) \
757 : torture_assert_ndr_err_equal_goto(torture_ctx,expr,NDR_ERR_SUCCESS,ret,label,cmt)
758 :
759 : #define torture_assert_hresult_ok(torture_ctx,expr,cmt) \
760 : torture_assert_hresult_equal(torture_ctx,expr,HRES_ERROR(0), cmt)
761 :
762 : /* Getting settings */
763 : const char *torture_setting_string(struct torture_context *test, \
764 : const char *name,
765 : const char *default_value);
766 :
767 : int torture_setting_int(struct torture_context *test,
768 : const char *name,
769 : int default_value);
770 :
771 : double torture_setting_double(struct torture_context *test,
772 : const char *name,
773 : double default_value);
774 :
775 : bool torture_setting_bool(struct torture_context *test,
776 : const char *name,
777 : bool default_value);
778 :
779 : struct torture_suite *torture_find_suite(struct torture_suite *parent,
780 : const char *name);
781 :
782 : unsigned long torture_setting_ulong(struct torture_context *test,
783 : const char *name,
784 : unsigned long default_value);
785 :
786 : NTSTATUS torture_temp_dir(struct torture_context *tctx,
787 : const char *prefix,
788 : char **tempdir);
789 : NTSTATUS torture_deltree_outputdir(struct torture_context *tctx);
790 :
791 : struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
792 : const char *name,
793 : bool (*run) (struct torture_context *test, void *tcase_data));
794 :
795 :
796 : bool torture_suite_init_tcase(struct torture_suite *suite,
797 : struct torture_tcase *tcase,
798 : const char *name);
799 : int torture_suite_children_count(const struct torture_suite *suite);
800 :
801 : struct torture_context *torture_context_init(struct tevent_context *event_ctx, struct torture_results *results);
802 :
803 : struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops);
804 :
805 : struct torture_context *torture_context_child(struct torture_context *tctx);
806 :
807 : extern const struct torture_ui_ops torture_subunit_ui_ops;
808 : extern const struct torture_ui_ops torture_simple_ui_ops;
809 :
810 : #endif /* __TORTURE_UI_H__ */
|