LCOV - code coverage report
Current view: top level - lib/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 293 366 80.1 %
Date: 2024-06-13 04:01:37 Functions: 36 46 78.3 %

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

Generated by: LCOV version 1.13