root/lib/torture/torture.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. torture_comment

   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 /* 
  38  * These callbacks should be implemented by any backend that wishes 
  39  * to listen to reports from the torture tests.
  40  */
  41 struct torture_ui_ops
  42 {
  43         void (*init) (struct torture_results *);
  44         void (*comment) (struct torture_context *, const char *);
  45         void (*warning) (struct torture_context *, const char *);
  46         void (*suite_start) (struct torture_context *, struct torture_suite *);
  47         void (*suite_finish) (struct torture_context *, struct torture_suite *);
  48         void (*tcase_start) (struct torture_context *, struct torture_tcase *); 
  49         void (*tcase_finish) (struct torture_context *, struct torture_tcase *);
  50         void (*test_start) (struct torture_context *, 
  51                                                 struct torture_tcase *,
  52                                                 struct torture_test *);
  53         void (*test_result) (struct torture_context *, 
  54                                                  enum torture_result, const char *reason);
  55 };
  56 
  57 void torture_ui_test_start(struct torture_context *context,
  58                                                            struct torture_tcase *tcase,
  59                                                            struct torture_test *test);
  60 
  61 void torture_ui_test_result(struct torture_context *context,
  62                                                                 enum torture_result result,
  63                                                                 const char *comment);
  64 
  65 /*
  66  * Holds information about a specific run of the testsuite. 
  67  * The data in this structure should be considered private to 
  68  * the torture tests and should only be used directly by the torture 
  69  * code and the ui backends.
  70  *
  71  * Torture tests should instead call the torture_*() macros and functions 
  72  * specified below.
  73  */
  74 
  75 struct torture_context
  76 {
  77         struct torture_results *results;
  78 
  79         char *active_testname;
  80         struct torture_test *active_test;
  81         struct torture_tcase *active_tcase;
  82 
  83         enum torture_result last_result;
  84         char *last_reason;
  85 
  86         /** Directory used for temporary test data */
  87         const char *outputdir;
  88         
  89         /** Indentation level */
  90         int level;
  91 
  92         /** Event context */
  93         struct tevent_context *ev;
  94 
  95         /** Loadparm context (will go away in favor of torture_setting_ at some point) */
  96         struct loadparm_context *lp_ctx;
  97 };
  98 
  99 struct torture_results
 100 {
 101         const struct torture_ui_ops *ui_ops;
 102         void *ui_data;
 103 
 104         /** Whether tests should avoid writing output to stdout */
 105         bool quiet;
 106 
 107         bool returncode;
 108 };
 109 
 110 /* 
 111  * Describes a particular torture test
 112  */
 113 struct torture_test {
 114         /** Short unique name for the test. */
 115         const char *name;
 116 
 117         /** Long description for the test. */
 118         const char *description;
 119 
 120         /** Whether this is a dangerous test 
 121          * (can corrupt the remote servers data or bring it down). */
 122         bool dangerous;
 123 
 124         /** Function to call to run this test */
 125         bool (*run) (struct torture_context *torture_ctx, 
 126                                  struct torture_tcase *tcase,
 127                                  struct torture_test *test);
 128 
 129         struct torture_test *prev, *next;
 130 
 131         /** Pointer to the actual test function. This is run by the 
 132           * run() function above. */
 133         void *fn;
 134 
 135         /** Use data for this test */
 136         const void *data;
 137 };
 138 
 139 /* 
 140  * Describes a particular test case.
 141  */
 142 struct torture_tcase {
 143     const char *name;
 144         const char *description;
 145         bool (*setup) (struct torture_context *tcase, void **data);
 146         bool (*teardown) (struct torture_context *tcase, void *data); 
 147         bool fixture_persistent;
 148         void *data;
 149         struct torture_test *tests;
 150         struct torture_tcase *prev, *next;
 151 };
 152 
 153 struct torture_suite
 154 {
 155         const char *name;
 156         const char *description;
 157         struct torture_tcase *testcases;
 158         struct torture_suite *children;
 159 
 160         /* Pointers to siblings of this torture suite */
 161         struct torture_suite *prev, *next;
 162 };
 163 
 164 /** Create a new torture suite */
 165 struct torture_suite *torture_suite_create(TALLOC_CTX *mem_ctx,
 166                 const char *name);
 167 
 168 /** Change the setup and teardown functions for a testcase */
 169 void torture_tcase_set_fixture(struct torture_tcase *tcase,
 170                 bool (*setup) (struct torture_context *, void **),
 171                 bool (*teardown) (struct torture_context *, void *));
 172 
 173 /* Add another test to run for a particular testcase */
 174 struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
 175                 const char *name,
 176                 bool (*run) (struct torture_context *test,
 177                         const void *tcase_data, const void *test_data),
 178                 const void *test_data);
 179 
 180 /* Add a testcase to a testsuite */
 181 struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite,
 182                                                          const char *name);
 183 
 184 /* Convenience wrapper that adds a testcase against only one
 185  * test will be run */
 186 struct torture_tcase *torture_suite_add_simple_tcase_const(
 187                 struct torture_suite *suite,
 188                 const char *name,
 189                 bool (*run) (struct torture_context *test,
 190                         const void *test_data),
 191                 const void *data);
 192 
 193 /* Convenience function that adds a test which only
 194  * gets the test case data */
 195 struct torture_test *torture_tcase_add_simple_test_const(
 196                 struct torture_tcase *tcase,
 197                 const char *name,
 198                 bool (*run) (struct torture_context *test,
 199                         const void *tcase_data));
 200 
 201 /* Convenience wrapper that adds a test that doesn't need any
 202  * testcase data */
 203 struct torture_tcase *torture_suite_add_simple_test(
 204                 struct torture_suite *suite,
 205                 const char *name,
 206                 bool (*run) (struct torture_context *test));
 207 
 208 /* Add a child testsuite to an existing testsuite */
 209 bool torture_suite_add_suite(struct torture_suite *suite,
 210                 struct torture_suite *child);
 211 
 212 /* Run the specified testsuite recursively */
 213 bool torture_run_suite(struct torture_context *context,
 214                                            struct torture_suite *suite);
 215 
 216 /* Run the specified testcase */
 217 bool torture_run_tcase(struct torture_context *context,
 218                                            struct torture_tcase *tcase);
 219 
 220 /* Run the specified test */
 221 bool torture_run_test(struct torture_context *context,
 222                                           struct torture_tcase *tcase,
 223                                           struct torture_test *test);
 224 
 225 void torture_comment(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
     /* [<][>][^][v][top][bottom][index][help] */
 226 void torture_warning(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
 227 void torture_result(struct torture_context *test,
 228                         enum torture_result, const char *reason, ...) PRINTF_ATTRIBUTE(3,4);
 229 
 230 #define torture_assert(torture_ctx,expr,cmt) \
 231         if (!(expr)) { \
 232                 torture_result(torture_ctx, TORTURE_FAIL, __location__": Expression `%s' failed: %s", __STRING(expr), cmt); \
 233                 return false; \
 234         }
 235 
 236 #define torture_assert_werr_equal(torture_ctx, got, expected, cmt) \
 237         do { WERROR __got = got, __expected = expected; \
 238         if (!W_ERROR_EQUAL(__got, __expected)) { \
 239                 torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", win_errstr(__got), win_errstr(__expected), cmt); \
 240                 return false; \
 241         } \
 242         } while (0)
 243 
 244 #define torture_assert_ntstatus_equal(torture_ctx,got,expected,cmt) \
 245         do { NTSTATUS __got = got, __expected = expected; \
 246         if (!NT_STATUS_EQUAL(__got, __expected)) { \
 247                 torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", nt_errstr(__got), nt_errstr(__expected), cmt); \
 248                 return false; \
 249         }\
 250         } while(0)
 251 
 252 #define torture_assert_ndr_err_equal(torture_ctx,got,expected,cmt) \
 253         do { enum ndr_err_code __got = got, __expected = expected; \
 254         if (__got != __expected) { \
 255                 torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %d, expected %d (%s): %s", __got, __expected, __STRING(expected), cmt); \
 256                 return false; \
 257         }\
 258         } while(0)
 259 
 260 #define torture_assert_casestr_equal(torture_ctx,got,expected,cmt) \
 261         do { const char *__got = (got), *__expected = (expected); \
 262         if (!strequal(__got, __expected)) { \
 263                 torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", __got, __expected, cmt); \
 264                 return false; \
 265         } \
 266         } while(0)
 267 
 268 #define torture_assert_str_equal(torture_ctx,got,expected,cmt)\
 269         do { const char *__got = (got), *__expected = (expected); \
 270         if (strcmp_safe(__got, __expected) != 0) { \
 271                 torture_result(torture_ctx, TORTURE_FAIL, \
 272                                            __location__": "#got" was %s, expected %s: %s", \
 273                                            __got, __expected, cmt); \
 274                 return false; \
 275         } \
 276         } while(0)
 277 
 278 #define torture_assert_mem_equal(torture_ctx,got,expected,len,cmt)\
 279         do { const void *__got = (got), *__expected = (expected); \
 280         if (memcmp(__got, __expected, len) != 0) { \
 281                 torture_result(torture_ctx, TORTURE_FAIL, \
 282                                __location__": "#got" of len %d did not match"#expected": %s", (int)len, cmt); \
 283                 return false; \
 284         } \
 285         } while(0)
 286 
 287 #define torture_assert_data_blob_equal(torture_ctx,got,expected,cmt)\
 288         do { const DATA_BLOB __got = (got), __expected = (expected); \
 289         if (__got.length != __expected.length) { \
 290                 torture_result(torture_ctx, TORTURE_FAIL, \
 291                                __location__": "#got".len %d did not match "#expected" len %d: %s", \
 292                                (int)__got.length, (int)__expected.length, cmt); \
 293                 return false; \
 294         } \
 295         if (memcmp(__got.data, __expected.data, __got.length) != 0) { \
 296                 torture_result(torture_ctx, TORTURE_FAIL, \
 297                                __location__": "#got" of len %d did not match"#expected": %s", (int)__got.length, cmt); \
 298                 return false; \
 299         } \
 300         } while(0)
 301 
 302 #define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\
 303         do { \
 304         char *__got; \
 305         const char *__expected = (expected); \
 306         size_t __size; \
 307         __got = file_load(filename, &__size, 0, torture_ctx); \
 308         if (__got == NULL) { \
 309                 torture_result(torture_ctx, TORTURE_FAIL, \
 310                                __location__": unable to open %s: %s\n", \
 311                                filename, cmt); \
 312                 return false; \
 313         } \
 314         \
 315         if (strcmp_safe(__got, __expected) != 0) { \
 316                 torture_result(torture_ctx, TORTURE_FAIL, \
 317                         __location__": %s contained:\n%sExpected: %s%s\n", \
 318                         filename, __got, __expected, cmt); \
 319                 talloc_free(__got); \
 320                 return false; \
 321         } \
 322         talloc_free(__got); \
 323         } while(0)
 324 
 325 #define torture_assert_file_contains(torture_ctx,filename,expected,cmt)\
 326         do { const char *__got, *__expected = (expected); \
 327         size_t __size; \
 328         __got = file_load(filename, *size, 0, torture_ctx); \
 329         if (strcmp_safe(__got, __expected) != 0) { \
 330                 torture_result(torture_ctx, TORTURE_FAIL, \
 331                                            __location__": %s contained:\n%sExpected: %s%s\n", \
 332                                            __got, __expected, cmt); \
 333                 talloc_free(__got); \
 334                 return false; \
 335         } \
 336         talloc_free(__got); \
 337         } while(0)
 338 
 339 #define torture_assert_int_equal(torture_ctx,got,expected,cmt)\
 340         do { int __got = (got), __expected = (expected); \
 341         if (__got != __expected) { \
 342                 torture_result(torture_ctx, TORTURE_FAIL, \
 343                         __location__": "#got" was %d, expected %d: %s", \
 344                         __got, __expected, cmt); \
 345                 return false; \
 346         } \
 347         } while(0)
 348 
 349 #define torture_assert_u64_equal(torture_ctx,got,expected,cmt)\
 350         do { uint64_t __got = (got), __expected = (expected); \
 351         if (__got != __expected) { \
 352                 torture_result(torture_ctx, TORTURE_FAIL, \
 353                         __location__": "#got" was %llu, expected %llu: %s", \
 354                         (unsigned long long)__got, (unsigned long long)__expected, cmt); \
 355                 return false; \
 356         } \
 357         } while(0)
 358 
 359 #define torture_assert_errno_equal(torture_ctx,expected,cmt)\
 360         do { int __expected = (expected); \
 361         if (errno != __expected) { \
 362                 torture_result(torture_ctx, TORTURE_FAIL, \
 363                         __location__": errno was %d (%s), expected %d: %s: %s", \
 364                                            errno, strerror(errno), __expected, \
 365                                            strerror(__expected), cmt); \
 366                 return false; \
 367         } \
 368         } while(0)
 369 
 370 
 371 
 372 #define torture_skip(torture_ctx,cmt) do {\
 373                 torture_result(torture_ctx, TORTURE_SKIP, __location__": %s", cmt);\
 374                 return true; \
 375         } while(0)
 376 #define torture_fail(torture_ctx,cmt) do {\
 377                 torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
 378                 return false; \
 379         } while (0)
 380 #define torture_fail_goto(torture_ctx,label,cmt) do {\
 381                 torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
 382                 goto label; \
 383         } while (0)
 384 
 385 #define torture_out stderr
 386 
 387 /* Convenience macros */
 388 #define torture_assert_ntstatus_ok(torture_ctx,expr,cmt) \
 389                 torture_assert_ntstatus_equal(torture_ctx,expr,NT_STATUS_OK,cmt)
 390 
 391 #define torture_assert_werr_ok(torture_ctx,expr,cmt) \
 392                 torture_assert_werr_equal(torture_ctx,expr,WERR_OK,cmt)
 393 
 394 #define torture_assert_ndr_success(torture_ctx,expr,cmt) \
 395                 torture_assert_ndr_err_equal(torture_ctx,expr,NDR_ERR_SUCCESS,cmt)
 396 
 397 /* Getting settings */
 398 const char *torture_setting_string(struct torture_context *test, \
 399                                                                    const char *name, 
 400                                                                    const char *default_value);
 401 
 402 int torture_setting_int(struct torture_context *test, 
 403                                                 const char *name, 
 404                                                 int default_value);
 405 
 406 double torture_setting_double(struct torture_context *test, 
 407                                                 const char *name, 
 408                                                 double default_value);
 409 
 410 bool torture_setting_bool(struct torture_context *test, 
 411                                                   const char *name, 
 412                                                   bool default_value);
 413 
 414 struct torture_suite *torture_find_suite(struct torture_suite *parent, 
 415                                                                                  const char *name);
 416 
 417 NTSTATUS torture_temp_dir(struct torture_context *tctx, 
 418                                    const char *prefix, 
 419                                    char **tempdir);
 420 
 421 struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
 422                 const char *name,
 423                 bool (*run) (struct torture_context *test, void *tcase_data));
 424 
 425 
 426 bool torture_suite_init_tcase(struct torture_suite *suite, 
 427                               struct torture_tcase *tcase, 
 428                               const char *name);
 429 
 430 struct torture_context *torture_context_init(struct tevent_context *event_ctx, struct torture_results *results);
 431 
 432 struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops);
 433 
 434 struct torture_context *torture_context_child(struct torture_context *tctx);
 435 
 436 extern const struct torture_ui_ops torture_subunit_ui_ops;
 437 
 438 #endif /* __TORTURE_UI_H__ */

/* [<][>][^][v][top][bottom][index][help] */