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