LCOV - code coverage report
Current view: top level - lib/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 333 398 83.7 %
Date: 2024-02-28 12:06:22 Functions: 38 46 82.6 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture UI functions
       4             : 
       5             :    Copyright (C) Jelmer Vernooij 2006-2008
       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             : #include "source4/include/includes.h"
      22             : #include "../torture/torture.h"
      23             : #include "../lib/util/dlinklist.h"
      24             : #include "param/param.h"
      25             : #include "system/filesys.h"
      26             : #include "system/dir.h"
      27             : 
      28             : 
      29        2296 : struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops)
      30             : {
      31        2296 :         struct torture_results *results = talloc_zero(mem_ctx, struct torture_results);
      32             : 
      33        2296 :         results->ui_ops = ui_ops;
      34        2296 :         results->returncode = true;
      35             : 
      36        2296 :         if (ui_ops->init)
      37           0 :                 ui_ops->init(results);
      38             : 
      39        2296 :         return results;
      40             : }
      41             : 
      42             : /**
      43             :  * Initialize a torture context
      44             :  */
      45        2296 : struct torture_context *torture_context_init(struct tevent_context *event_ctx, 
      46             :                                                                                          struct torture_results *results)
      47             : {
      48        2296 :         struct torture_context *torture = talloc_zero(event_ctx, 
      49             :                                                       struct torture_context);
      50             : 
      51        2296 :         if (torture == NULL)
      52           0 :                 return NULL;
      53             : 
      54        2296 :         torture->ev = event_ctx;
      55        2296 :         torture->results = talloc_reference(torture, results);
      56             : 
      57             :         /*
      58             :          * We start with an empty subunit prefix
      59             :          */
      60        2296 :         torture_subunit_prefix_reset(torture, NULL);
      61             : 
      62        2296 :         return torture;
      63             : }
      64             : 
      65             : /**
      66             :  * Create a sub torture context
      67             :  */
      68           0 : struct torture_context *torture_context_child(struct torture_context *parent)
      69             : {
      70           0 :         struct torture_context *subtorture = talloc_zero(parent, struct torture_context);
      71             : 
      72           0 :         if (subtorture == NULL)
      73           0 :                 return NULL;
      74             : 
      75           0 :         subtorture->ev = talloc_reference(subtorture, parent->ev);
      76           0 :         subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx);
      77           0 :         subtorture->outputdir = talloc_reference(subtorture, parent->outputdir);
      78           0 :         subtorture->results = talloc_reference(subtorture, parent->results);
      79             : 
      80           0 :         return subtorture;
      81             : }
      82             : 
      83             : /**
      84             :  create a temporary directory under the output dir
      85             : */
      86          14 : _PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx,
      87             :                                    const char *prefix, char **tempdir)
      88             : {
      89          14 :         SMB_ASSERT(tctx->outputdir != NULL);
      90             : 
      91          14 :         *tempdir = talloc_asprintf(tctx, "%s/%s.XXXXXX", tctx->outputdir,
      92             :                                    prefix);
      93          14 :         NT_STATUS_HAVE_NO_MEMORY(*tempdir);
      94             : 
      95          14 :         if (mkdtemp(*tempdir) == NULL) {
      96           0 :                 return map_nt_error_from_unix_common(errno);
      97             :         }
      98             : 
      99          14 :         return NT_STATUS_OK;
     100             : }
     101             : 
     102        2319 : static int local_deltree(const char *path)
     103             : {
     104        2319 :         int ret = 0;
     105         126 :         struct dirent *dirent;
     106        2319 :         DIR *dir = opendir(path);
     107        2319 :         if (!dir) {
     108           0 :                 char *error = talloc_asprintf(NULL, "Could not open directory %s", path);
     109           0 :                 perror(error);
     110           0 :                 talloc_free(error);
     111           0 :                 return -1;
     112             :         }
     113        6940 :         while ((dirent = readdir(dir))) {
     114         260 :                 char *name;
     115        4644 :                 if ((strcmp(dirent->d_name, ".") == 0) || (strcmp(dirent->d_name, "..") == 0)) {
     116        4607 :                         continue;
     117             :                 }
     118          37 :                 name = talloc_asprintf(NULL, "%s/%s", path,
     119          20 :                                        dirent->d_name);
     120          37 :                 if (name == NULL) {
     121           0 :                         closedir(dir);
     122           0 :                         return -1;
     123             :                 }
     124          37 :                 DEBUG(0, ("About to remove %s\n", name));
     125          37 :                 ret = remove(name);
     126          37 :                 if (ret == 0) {
     127          14 :                         talloc_free(name);
     128          14 :                         continue;
     129             :                 }
     130             : 
     131          23 :                 if (errno == ENOTEMPTY) {
     132          23 :                         ret = local_deltree(name);
     133          23 :                         if (ret == 0) {
     134           8 :                                 ret = remove(name);
     135             :                         }
     136             :                 }
     137          23 :                 talloc_free(name);
     138          23 :                 if (ret != 0) {
     139          23 :                         char *error = talloc_asprintf(NULL, "Could not remove %s", path);
     140          23 :                         perror(error);
     141          23 :                         talloc_free(error);
     142          23 :                         break;
     143             :                 }
     144             :         }
     145        2319 :         closedir(dir);
     146        2319 :         rmdir(path);
     147        2319 :         return ret;
     148             : }
     149             : 
     150        2296 : _PUBLIC_ NTSTATUS torture_deltree_outputdir(struct torture_context *tctx)
     151             : {
     152        2296 :         if (tctx->outputdir == NULL) {
     153           0 :                 return NT_STATUS_OK;
     154             :         }
     155        2296 :         if ((strcmp(tctx->outputdir, "/") == 0)
     156        2296 :             || (strcmp(tctx->outputdir, "") == 0)) {
     157           0 :                 return NT_STATUS_INVALID_PARAMETER;
     158             :         }
     159             : 
     160        2296 :         if (local_deltree(tctx->outputdir) == -1) {
     161           8 :                 if (errno != 0) {
     162           8 :                         return map_nt_error_from_unix_common(errno);
     163             :                 }
     164           0 :                 return NT_STATUS_UNSUCCESSFUL;
     165             :         }
     166        2288 :         return NT_STATUS_OK;
     167             : }
     168             : 
     169             : /**
     170             :  * Comment on the status/progress of a test
     171             :  */
     172      192216 : void torture_comment(struct torture_context *context, const char *comment, ...)
     173             : {
     174        5408 :         va_list ap;
     175        5408 :         char *tmp;
     176             : 
     177      192216 :         if (!context->results->ui_ops->comment)
     178           0 :                 return;
     179             : 
     180      192216 :         va_start(ap, comment);
     181      192216 :         tmp = talloc_vasprintf(context, comment, ap);
     182      192216 :         va_end(ap);
     183             : 
     184      192216 :         context->results->ui_ops->comment(context, tmp);
     185             : 
     186      192216 :         talloc_free(tmp);
     187             : }
     188             : 
     189             : /**
     190             :  * Print a warning about the current test
     191             :  */
     192        8940 : void torture_warning(struct torture_context *context, const char *comment, ...)
     193             : {
     194          11 :         va_list ap;
     195          11 :         char *tmp;
     196             : 
     197        8940 :         if (!context->results->ui_ops->warning)
     198           0 :                 return;
     199             : 
     200        8940 :         va_start(ap, comment);
     201        8940 :         tmp = talloc_vasprintf(context, comment, ap);
     202        8940 :         va_end(ap);
     203             : 
     204        8940 :         context->results->ui_ops->warning(context, tmp);
     205             : 
     206        8940 :         talloc_free(tmp);
     207             : }
     208             : 
     209             : /**
     210             :  * Store the result of a torture test.
     211             :  */
     212        9389 : void torture_result(struct torture_context *context, 
     213             :                     enum torture_result result, const char *fmt, ...)
     214             : {
     215             :         /* Of the two outcomes, keep that with the higher priority. */
     216        9389 :         if (result >= context->last_result) {
     217         125 :                 va_list ap;
     218             : 
     219        9344 :                 va_start(ap, fmt);
     220             : 
     221        9344 :                 if (context->last_reason) {
     222        3581 :                         torture_warning(context, "%s", context->last_reason);
     223        3581 :                         talloc_free(context->last_reason);
     224             :                 }
     225             : 
     226        9344 :                 context->last_result = result;
     227        9344 :                 context->last_reason = talloc_vasprintf(context, fmt, ap);
     228             : 
     229        9344 :                 va_end(ap);
     230             :         }
     231        9389 : }
     232             : 
     233             : /**
     234             :  * Create a new torture suite
     235             :  */
     236     1730478 : struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name)
     237             : {
     238     1730478 :         struct torture_suite *suite = talloc_zero(ctx, struct torture_suite);
     239             : 
     240     1730478 :         suite->name = talloc_strdup(suite, name);
     241     1730478 :         suite->testcases = NULL;
     242     1730478 :         suite->children = NULL;
     243             : 
     244     1730478 :         return suite;
     245             : }
     246             : 
     247             : /**
     248             :  * Set the setup() and teardown() functions for a testcase.
     249             :  */
     250       99918 : void torture_tcase_set_fixture(struct torture_tcase *tcase, 
     251             :                 bool (*setup) (struct torture_context *, void **),
     252             :                 bool (*teardown) (struct torture_context *, void *))
     253             : {
     254       99918 :         tcase->setup = setup;
     255       99918 :         tcase->teardown = teardown;
     256       99918 : }
     257             : 
     258          13 : static bool wrap_test_with_testcase_const(struct torture_context *torture_ctx,
     259             :                                     struct torture_tcase *tcase,
     260             :                                     struct torture_test *test)
     261             : {
     262          13 :         bool (*fn) (struct torture_context *,
     263             :                     const void *tcase_data,
     264             :                     const void *test_data);
     265             : 
     266          13 :         fn = test->fn;
     267             : 
     268          13 :         return fn(torture_ctx, tcase->data, test->data);
     269             : }
     270             : 
     271             : /**
     272             :  * Add a test that uses const data to a testcase
     273             :  */
     274       30927 : struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
     275             :                 const char *name,
     276             :                 bool (*run) (struct torture_context *, const void *tcase_data,
     277             :                         const void *test_data),
     278             :                 const void *data)
     279             : {
     280       30927 :         struct torture_test *test = talloc(tcase, struct torture_test);
     281             : 
     282       30927 :         test->name = talloc_strdup(test, name);
     283       30927 :         test->description = NULL;
     284       30927 :         test->run = wrap_test_with_testcase_const;
     285       30927 :         test->fn = run;
     286       30927 :         test->dangerous = false;
     287       30927 :         test->data = data;
     288             : 
     289       30927 :         DLIST_ADD_END(tcase->tests, test);
     290             : 
     291       30927 :         return test;
     292             : }
     293             : 
     294             : /**
     295             :  * Add a new testcase
     296             :  */
     297     5068044 : bool torture_suite_init_tcase(struct torture_suite *suite, 
     298             :                               struct torture_tcase *tcase, 
     299             :                               const char *name)
     300             : {
     301     5068044 :         tcase->name = talloc_strdup(tcase, name);
     302     5068044 :         tcase->description = NULL;
     303     5068044 :         tcase->setup = NULL;
     304     5068044 :         tcase->teardown = NULL;
     305     5068044 :         tcase->fixture_persistent = true;
     306     5068044 :         tcase->tests = NULL;
     307             : 
     308     5068044 :         DLIST_ADD_END(suite->testcases, tcase);
     309     5068044 :         tcase->suite = suite;
     310             : 
     311     5068044 :         return true;
     312             : }
     313             : 
     314             : 
     315     4939176 : struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite, 
     316             :                                                          const char *name)
     317             : {
     318     4939176 :         struct torture_tcase *tcase = talloc(suite, struct torture_tcase);
     319             : 
     320     4939176 :         if (!torture_suite_init_tcase(suite, tcase, name))
     321           0 :                 return NULL;
     322             : 
     323     4643426 :         return tcase;
     324             : }
     325             : 
     326       58261 : char *torture_subunit_test_name(struct torture_context *ctx,
     327             :                                 struct torture_tcase *tcase,
     328             :                                 struct torture_test *test)
     329             : {
     330       58261 :         if (!strcmp(tcase->name, test->name)) {
     331       39180 :                 return talloc_asprintf(ctx, "%s%s",
     332       39180 :                                 ctx->active_prefix->subunit_prefix,
     333             :                                 test->name);
     334             :         } else {
     335       19081 :                 return talloc_asprintf(ctx, "%s%s.%s",
     336       19081 :                                 ctx->active_prefix->subunit_prefix,
     337             :                                 tcase->name, test->name);
     338             :         }
     339             : }
     340             : 
     341        2304 : void torture_subunit_prefix_reset(struct torture_context *ctx,
     342             :                                   const char *name)
     343             : {
     344        2304 :         struct torture_subunit_prefix *prefix = &ctx->_initial_prefix;
     345             : 
     346        2304 :         ZERO_STRUCTP(prefix);
     347             : 
     348        2304 :         if (name != NULL) {
     349           4 :                 int ret;
     350             : 
     351           4 :                 ret = snprintf(prefix->subunit_prefix,
     352             :                                sizeof(prefix->subunit_prefix),
     353             :                                "%s.", name);
     354           4 :                 if (ret < 0) {
     355           0 :                         abort();
     356             :                 }
     357             :         }
     358             : 
     359        2304 :         ctx->active_prefix = prefix;
     360        2304 : }
     361             : 
     362        5600 : static void torture_subunit_prefix_push(struct torture_context *ctx,
     363             :                                         struct torture_subunit_prefix *prefix,
     364             :                                         const char *name)
     365             : {
     366        5600 :         *prefix = (struct torture_subunit_prefix) {
     367        5600 :                 .parent = ctx->active_prefix,
     368             :         };
     369             : 
     370        5600 :         if (ctx->active_prefix->parent != NULL ||
     371        1384 :             ctx->active_prefix->subunit_prefix[0] != '\0') {
     372             :                 /*
     373             :                  * We need a new component for the prefix.
     374             :                  */
     375          89 :                 int ret;
     376             : 
     377        4219 :                 ret = snprintf(prefix->subunit_prefix,
     378             :                                sizeof(prefix->subunit_prefix),
     379             :                                "%s%s.",
     380        4219 :                                ctx->active_prefix->subunit_prefix,
     381             :                                name);
     382        4219 :                 if (ret < 0) {
     383           0 :                         abort();
     384             :                 }
     385             :         }
     386             : 
     387        5600 :         ctx->active_prefix = prefix;
     388        5600 : }
     389             : 
     390        5600 : static void torture_subunit_prefix_pop(struct torture_context *ctx)
     391             : {
     392        5600 :         ctx->active_prefix = ctx->active_prefix->parent;
     393        5434 : }
     394             : 
     395        5600 : int torture_suite_children_count(const struct torture_suite *suite)
     396             : {
     397        5600 :         int ret = 0;
     398         166 :         struct torture_tcase *tcase;
     399         166 :         struct torture_test *test;
     400         166 :         struct torture_suite *tsuite;
     401       19074 :         for (tcase = suite->testcases; tcase; tcase = tcase->next) {
     402       31686 :                 for (test = tcase->tests; test; test = test->next) {
     403       18212 :                         ret++;
     404             :                 }
     405             :         }
     406        9816 :         for (tsuite = suite->children; tsuite; tsuite = tsuite->next) {
     407        4216 :                 ret ++;
     408             :         }
     409        5600 :         return ret;
     410             : }
     411             : 
     412             : /**
     413             :  * Run a torture test suite.
     414             :  */
     415           0 : bool torture_run_suite(struct torture_context *context, 
     416             :                        struct torture_suite *suite)
     417             : {
     418           0 :         return torture_run_suite_restricted(context, suite, NULL);
     419             : }
     420             : 
     421        5600 : bool torture_run_suite_restricted(struct torture_context *context, 
     422             :                        struct torture_suite *suite, const char **restricted)
     423             : {
     424         166 :         struct torture_subunit_prefix _prefix_stack;
     425        5600 :         bool ret = true;
     426         166 :         struct torture_tcase *tcase;
     427         166 :         struct torture_suite *tsuite;
     428             : 
     429        5600 :         torture_subunit_prefix_push(context, &_prefix_stack, suite->name);
     430             : 
     431        5600 :         if (context->results->ui_ops->suite_start)
     432        5600 :                 context->results->ui_ops->suite_start(context, suite);
     433             : 
     434             :         /* FIXME: Adjust torture_suite_children_count if restricted != NULL */
     435        5600 :         context->results->ui_ops->progress(context,
     436             :                 torture_suite_children_count(suite), TORTURE_PROGRESS_SET);
     437             : 
     438       19074 :         for (tcase = suite->testcases; tcase; tcase = tcase->next) {
     439       13474 :                 ret &= torture_run_tcase_restricted(context, tcase, restricted);
     440             :         }
     441             : 
     442        9816 :         for (tsuite = suite->children; tsuite; tsuite = tsuite->next) {
     443        4216 :                 context->results->ui_ops->progress(context, 0, TORTURE_PROGRESS_PUSH);
     444        4216 :                 ret &= torture_run_suite_restricted(context, tsuite, restricted);
     445        4216 :                 context->results->ui_ops->progress(context, 0, TORTURE_PROGRESS_POP);
     446             :         }
     447             : 
     448        5600 :         if (context->results->ui_ops->suite_finish)
     449           0 :                 context->results->ui_ops->suite_finish(context, suite);
     450             : 
     451        5600 :         torture_subunit_prefix_pop(context);
     452             : 
     453        5600 :         return ret;
     454             : }
     455             : 
     456       19445 : void torture_ui_test_start(struct torture_context *context, 
     457             :                            struct torture_tcase *tcase, 
     458             :                            struct torture_test *test)
     459             : {
     460       19445 :         if (context->results->ui_ops->test_start)
     461       19445 :                 context->results->ui_ops->test_start(context, tcase, test);
     462       19445 : }
     463             : 
     464       19445 : void torture_ui_test_result(struct torture_context *context, 
     465             :                             enum torture_result result,
     466             :                             const char *comment)
     467             : {
     468       19445 :         if (context->results->ui_ops->test_result)
     469       19445 :                 context->results->ui_ops->test_result(context, result, comment);
     470             : 
     471       19445 :         if (result == TORTURE_ERROR || result == TORTURE_FAIL)
     472        1819 :                 context->results->returncode = false;
     473       19445 : }
     474             : 
     475       19371 : static bool test_needs_running(const char *name, const char **restricted)
     476             : {
     477        1446 :         int i;
     478       19371 :         if (restricted == NULL)
     479       17925 :                 return true;
     480           0 :         for (i = 0; restricted[i]; i++) {
     481           0 :                 if (!strcmp(name, restricted[i]))
     482           0 :                         return true;
     483             :         }
     484           0 :         return false;
     485             : }
     486             : 
     487       19371 : static bool internal_torture_run_test(struct torture_context *context,
     488             :                                           struct torture_tcase *tcase,
     489             :                                           struct torture_test *test,
     490             :                                           bool already_setup,
     491             :                                           const char **restricted)
     492             : {
     493        1446 :         bool success;
     494       19371 :         char *subunit_testname = torture_subunit_test_name(context, tcase, test);
     495             : 
     496       19371 :         if (!test_needs_running(subunit_testname, restricted))
     497           0 :                 return true;
     498             : 
     499       19371 :         context->active_tcase = tcase;
     500       19371 :         context->active_test = test;
     501             : 
     502       19371 :         torture_ui_test_start(context, tcase, test);
     503             : 
     504       19371 :         context->last_reason = NULL;
     505       19371 :         context->last_result = TORTURE_OK;
     506             : 
     507       19371 :         if (!already_setup && tcase->setup &&
     508           0 :             !tcase->setup(context, &(tcase->data))) {
     509           0 :                 if (context->last_reason == NULL)
     510           0 :                         context->last_reason = talloc_strdup(context, "Setup failure");
     511           0 :                 context->last_result = TORTURE_ERROR;
     512           0 :                 success = false;
     513       19374 :         } else if (test->dangerous &&
     514         237 :                    !torture_setting_bool(context, "dangerous", false)) {
     515         237 :                 context->last_result = TORTURE_SKIP;
     516         237 :                 context->last_reason = talloc_asprintf(context,
     517             :                 "disabled %s - enable dangerous tests to use", test->name);
     518         237 :                 success = true;
     519             :         } else {
     520       19134 :                 success = test->run(context, tcase, test);
     521             : 
     522       19134 :                 if (!success && context->last_result == TORTURE_OK) {
     523           0 :                         if (context->last_reason == NULL)
     524           0 :                                 context->last_reason = talloc_strdup(context,
     525             :                                         "Unknown error/failure. Missing torture_fail() or torture_assert_*() call?");
     526           0 :                         context->last_result = TORTURE_ERROR;
     527             :                 }
     528             :         }
     529             : 
     530       19371 :         if (!already_setup && tcase->teardown && !tcase->teardown(context, tcase->data)) {
     531           0 :                 if (context->last_reason == NULL)
     532           0 :                         context->last_reason = talloc_strdup(context, "Setup failure");
     533           0 :                 context->last_result = TORTURE_ERROR;
     534           0 :                 success = false;
     535             :         }
     536             : 
     537       19371 :         torture_ui_test_result(context, context->last_result,
     538       19371 :                                context->last_reason);
     539             : 
     540       19371 :         talloc_free(context->last_reason);
     541       19371 :         context->last_reason = NULL;
     542             : 
     543       19371 :         context->active_test = NULL;
     544       19371 :         context->active_tcase = NULL;
     545             : 
     546       19371 :         return success;
     547             : }
     548             : 
     549           0 : bool torture_run_tcase(struct torture_context *context,
     550             :                        struct torture_tcase *tcase)
     551             : {
     552           0 :         return torture_run_tcase_restricted(context, tcase, NULL);
     553             : }
     554             : 
     555       14564 : bool torture_run_tcase_restricted(struct torture_context *context,
     556             :                        struct torture_tcase *tcase, const char **restricted)
     557             : {
     558       14564 :         bool ret = true;
     559        1197 :         struct torture_test *test;
     560       14564 :         bool setup_succeeded = true;
     561       14564 :         const char * setup_reason = "Setup failed";
     562             : 
     563       14564 :         context->active_tcase = tcase;
     564       14564 :         if (context->results->ui_ops->tcase_start) 
     565           0 :                 context->results->ui_ops->tcase_start(context, tcase);
     566             : 
     567       14564 :         if (tcase->fixture_persistent && tcase->setup) {
     568         998 :                 setup_succeeded = tcase->setup(context, &tcase->data);
     569             :         }
     570             : 
     571       13395 :         if (!setup_succeeded) {
     572             :                 /* Uh-oh. The setup failed, so we can't run any of the tests
     573             :                  * in this testcase. The subunit format doesn't specify what
     574             :                  * to do here, so we keep the failure reason, and manually
     575             :                  * use it to fail every test.
     576             :                  */
     577           9 :                 if (context->last_reason != NULL) {
     578           9 :                         setup_reason = talloc_asprintf(context,
     579             :                                 "Setup failed: %s", context->last_reason);
     580             :                 }
     581             :         }
     582             : 
     583       34009 :         for (test = tcase->tests; test; test = test->next) {
     584       19445 :                 if (setup_succeeded) {
     585       19371 :                         ret &= internal_torture_run_test(context, tcase, test,
     586       19371 :                                         tcase->fixture_persistent, restricted);
     587             :                 } else {
     588          74 :                         context->active_tcase = tcase;
     589          74 :                         context->active_test = test;
     590          74 :                         torture_ui_test_start(context, tcase, test);
     591          74 :                         torture_ui_test_result(context, TORTURE_FAIL, setup_reason);
     592             :                 }
     593             :         }
     594             : 
     595       14586 :         if (setup_succeeded && tcase->fixture_persistent && tcase->teardown &&
     596         983 :                 !tcase->teardown(context, tcase->data)) {
     597           8 :                 ret = false;
     598             :         }
     599             : 
     600       14564 :         context->active_tcase = NULL;
     601       14564 :         context->active_test = NULL;
     602             : 
     603       14564 :         if (context->results->ui_ops->tcase_finish)
     604           0 :                 context->results->ui_ops->tcase_finish(context, tcase);
     605             : 
     606       14564 :         return (!setup_succeeded) ? false : ret;
     607             : }
     608             : 
     609           0 : bool torture_run_test(struct torture_context *context, 
     610             :                                           struct torture_tcase *tcase,
     611             :                                           struct torture_test *test)
     612             : {
     613           0 :         return internal_torture_run_test(context, tcase, test, false, NULL);
     614             : }
     615             : 
     616           0 : bool torture_run_test_restricted(struct torture_context *context, 
     617             :                                           struct torture_tcase *tcase,
     618             :                                           struct torture_test *test,
     619             :                                           const char **restricted)
     620             : {
     621           0 :         return internal_torture_run_test(context, tcase, test, false, restricted);
     622             : }
     623             : 
     624         126 : int torture_setting_int(struct torture_context *test, const char *name, 
     625             :                                                         int default_value)
     626             : {
     627         126 :         return lpcfg_parm_int(test->lp_ctx, NULL, "torture", name, default_value);
     628             : }
     629             : 
     630           0 : unsigned long torture_setting_ulong(struct torture_context *test,
     631             :                                     const char *name,
     632             :                                     unsigned long default_value)
     633             : {
     634           0 :         return lpcfg_parm_ulong(test->lp_ctx, NULL, "torture", name,
     635             :                              default_value);
     636             : }
     637             : 
     638           0 : double torture_setting_double(struct torture_context *test, const char *name, 
     639             :                                                         double default_value)
     640             : {
     641           0 :         return lpcfg_parm_double(test->lp_ctx, NULL, "torture", name, default_value);
     642             : }
     643             : 
     644      123069 : bool torture_setting_bool(struct torture_context *test, const char *name, 
     645             :                                                         bool default_value)
     646             : {
     647      123069 :         return lpcfg_parm_bool(test->lp_ctx, NULL, "torture", name, default_value);
     648             : }
     649             : 
     650       44156 : const char *torture_setting_string(struct torture_context *test, 
     651             :                                    const char *name, 
     652             :                                    const char *default_value)
     653             : {
     654        1220 :         const char *ret;
     655             : 
     656       44156 :         SMB_ASSERT(test != NULL);
     657       44156 :         SMB_ASSERT(test->lp_ctx != NULL);
     658             :         
     659       44156 :         ret = lpcfg_parm_string(test->lp_ctx, NULL, "torture", name);
     660             : 
     661       44156 :         if (ret == NULL)
     662       15059 :                 return default_value;
     663             : 
     664       28149 :         return ret;
     665             : }
     666             : 
     667        6537 : static bool wrap_test_with_simple_tcase_const (
     668             :                 struct torture_context *torture_ctx,
     669             :                 struct torture_tcase *tcase,
     670             :                 struct torture_test *test)
     671             : {
     672         122 :         bool (*fn) (struct torture_context *, const void *tcase_data);
     673             : 
     674        6537 :         fn = test->fn;
     675             : 
     676        6537 :         return fn(torture_ctx, test->data);
     677             : }
     678             : 
     679      920169 : struct torture_tcase *torture_suite_add_simple_tcase_const(
     680             :                 struct torture_suite *suite, const char *name,
     681             :                 bool (*run) (struct torture_context *test, const void *),
     682             :                 const void *data)
     683             : {
     684       83375 :         struct torture_tcase *tcase;
     685       83375 :         struct torture_test *test;
     686             : 
     687      920169 :         tcase = torture_suite_add_tcase(suite, name);
     688             : 
     689      920169 :         test = talloc(tcase, struct torture_test);
     690             : 
     691      920169 :         test->name = talloc_strdup(test, name);
     692      920169 :         test->description = NULL;
     693      920169 :         test->run = wrap_test_with_simple_tcase_const;
     694      920169 :         test->fn = run;
     695      920169 :         test->data = data;
     696      920169 :         test->dangerous = false;
     697             : 
     698      920169 :         DLIST_ADD_END(tcase->tests, test);
     699      920169 :         test->tcase = tcase;
     700             : 
     701      920169 :         return tcase;
     702             : }
     703             : 
     704        1379 : static bool wrap_simple_test(struct torture_context *torture_ctx,
     705             :                              struct torture_tcase *tcase,
     706             :                              struct torture_test *test)
     707             : {
     708         332 :         bool (*fn) (struct torture_context *);
     709             : 
     710        1379 :         fn = test->fn;
     711             : 
     712        1379 :         return fn(torture_ctx);
     713             : }
     714             : 
     715     1130901 : struct torture_tcase *torture_suite_add_simple_test(
     716             :                                         struct torture_suite *suite, 
     717             :                                         const char *name,
     718             :                                         bool (*run) (struct torture_context *test))
     719             : {
     720       60625 :         struct torture_test *test; 
     721       60625 :         struct torture_tcase *tcase;
     722             :         
     723     1130901 :         tcase = torture_suite_add_tcase(suite, name);
     724             : 
     725     1130901 :         test = talloc(tcase, struct torture_test);
     726             : 
     727     1130901 :         test->name = talloc_strdup(test, name);
     728     1130901 :         test->description = NULL;
     729     1130901 :         test->run = wrap_simple_test;
     730     1130901 :         test->fn = run;
     731     1130901 :         test->dangerous = false;
     732             : 
     733     1130901 :         DLIST_ADD_END(tcase->tests, test);
     734             : 
     735     1130901 :         return tcase;
     736             : }
     737             : 
     738             : /**
     739             :  * Add a child testsuite to a testsuite.
     740             :  */
     741     1180131 : bool torture_suite_add_suite(struct torture_suite *suite, 
     742             :                              struct torture_suite *child)
     743             : {
     744     1180131 :         if (child == NULL)
     745           0 :                 return false;
     746             : 
     747     1180131 :         DLIST_ADD_END(suite->children, child);
     748     1180131 :         child->parent = suite;
     749             : 
     750             :         /* FIXME: Check for duplicates and return false if the 
     751             :          * added suite already exists as a child */
     752             : 
     753     1180131 :         return true;
     754             : }
     755             : 
     756             : /**
     757             :  * Find the child testsuite with the specified name.
     758             :  */
     759           0 : struct torture_suite *torture_find_suite(struct torture_suite *parent, 
     760             :                                          const char *name)
     761             : {
     762           0 :         struct torture_suite *child;
     763             : 
     764           0 :         for (child = parent->children; child; child = child->next) 
     765           0 :                 if (!strcmp(child->name, name))
     766           0 :                         return child;
     767             : 
     768           0 :         return NULL;
     769             : }
     770             : 
     771          20 : static bool wrap_test_with_simple_test_const(struct torture_context *torture_ctx,
     772             :                                        struct torture_tcase *tcase,
     773             :                                        struct torture_test *test)
     774             : {
     775          20 :         bool (*fn) (struct torture_context *, const void *tcase_data);
     776             : 
     777          20 :         fn = test->fn;
     778             : 
     779          20 :         return fn(torture_ctx, tcase->data);
     780             : }
     781             : 
     782       47580 : struct torture_test *torture_tcase_add_simple_test_const(
     783             :                 struct torture_tcase *tcase,
     784             :                 const char *name,
     785             :                 bool (*run) (struct torture_context *test,
     786             :                         const void *tcase_data))
     787             : {
     788        2500 :         struct torture_test *test;
     789             : 
     790       47580 :         test = talloc(tcase, struct torture_test);
     791             : 
     792       47580 :         test->name = talloc_strdup(test, name);
     793       47580 :         test->description = NULL;
     794       47580 :         test->run = wrap_test_with_simple_test_const;
     795       47580 :         test->fn = run;
     796       47580 :         test->data = NULL;
     797       47580 :         test->dangerous = false;
     798             : 
     799       47580 :         DLIST_ADD_END(tcase->tests, test);
     800             : 
     801       47580 :         return test;
     802             : }
     803             : 
     804         440 : static bool wrap_test_with_simple_test(struct torture_context *torture_ctx,
     805             :                                        struct torture_tcase *tcase,
     806             :                                        struct torture_test *test)
     807             : {
     808          55 :         bool (*fn) (struct torture_context *, void *tcase_data);
     809             : 
     810         440 :         fn = test->fn;
     811             : 
     812         440 :         return fn(torture_ctx, tcase->data);
     813             : }
     814             : 
     815      618540 : struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
     816             :                 const char *name,
     817             :                 bool (*run) (struct torture_context *test, void *tcase_data))
     818             : {
     819       32500 :         struct torture_test *test;
     820             : 
     821      618540 :         test = talloc(tcase, struct torture_test);
     822             : 
     823      618540 :         test->name = talloc_strdup(test, name);
     824      618540 :         test->description = NULL;
     825      618540 :         test->run = wrap_test_with_simple_test;
     826      618540 :         test->fn = run;
     827      618540 :         test->data = NULL;
     828      618540 :         test->dangerous = false;
     829             : 
     830      618540 :         DLIST_ADD_END(tcase->tests, test);
     831             : 
     832      618540 :         return test;
     833             : }
     834             : 
     835        2304 : void torture_ui_report_time(struct torture_context *context)
     836             : {
     837        2304 :         if (context->results->ui_ops->report_time)
     838        2304 :                 context->results->ui_ops->report_time(context);
     839        2304 : }

Generated by: LCOV version 1.14