talloc: use the system pytalloc-util for python3 as well
[sfrench/samba-autobuild/.git] / lib / torture / torture.c
index d6f893eb0fc20c62feb63e2500c4979bee8c2ee7..40807d92a62151c22e688df12de16377e34a3ed6 100644 (file)
@@ -23,6 +23,7 @@
 #include "../lib/util/dlinklist.h"
 #include "param/param.h"
 #include "system/filesys.h"
+#include "system/dir.h"
 
 
 struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops)
@@ -75,7 +76,7 @@ struct torture_context *torture_context_child(struct torture_context *parent)
 }
 
 /**
- create a temporary directory.
+ create a temporary directory under the output dir
 */
 _PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx,
                                   const char *prefix, char **tempdir)
@@ -87,12 +88,79 @@ _PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx,
        NT_STATUS_HAVE_NO_MEMORY(*tempdir);
 
        if (mkdtemp(*tempdir) == NULL) {
-               return map_nt_error_from_unix(errno);
+               return map_nt_error_from_unix_common(errno);
        }
 
        return NT_STATUS_OK;
 }
 
+static int local_deltree(const char *path)
+{
+       int ret = 0;
+       struct dirent *dirent;
+       DIR *dir = opendir(path);
+       if (!dir) {
+               char *error = talloc_asprintf(NULL, "Could not open directory %s", path);
+               perror(error);
+               talloc_free(error);
+               return -1;
+       }
+       while ((dirent = readdir(dir))) {
+               char *name;
+               if ((strcmp(dirent->d_name, ".") == 0) || (strcmp(dirent->d_name, "..") == 0)) {
+                       continue;
+               }
+               name = talloc_asprintf(NULL, "%s/%s", path,
+                                      dirent->d_name);
+               if (name == NULL) {
+                       closedir(dir);
+                       return -1;
+               }
+               DEBUG(0, ("About to remove %s\n", name));
+               ret = remove(name);
+               if (ret == 0) {
+                       talloc_free(name);
+                       continue;
+               }
+
+               if (errno == ENOTEMPTY) {
+                       ret = local_deltree(name);
+                       if (ret == 0) {
+                               ret = remove(name);
+                       }
+               }
+               talloc_free(name);
+               if (ret != 0) {
+                       char *error = talloc_asprintf(NULL, "Could not remove %s", path);
+                       perror(error);
+                       talloc_free(error);
+                       break;
+               }
+       }
+       closedir(dir);
+       rmdir(path);
+       return ret;
+}
+
+_PUBLIC_ NTSTATUS torture_deltree_outputdir(struct torture_context *tctx)
+{
+       if (tctx->outputdir == NULL) {
+               return NT_STATUS_OK;
+       }
+       if ((strcmp(tctx->outputdir, "/") == 0)
+           || (strcmp(tctx->outputdir, "") == 0)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (local_deltree(tctx->outputdir) == -1) {
+               if (errno != 0) {
+                       return map_nt_error_from_unix_common(errno);
+               }
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       return NT_STATUS_OK;
+}
+
 /**
  * Comment on the status/progress of a test
  */
@@ -209,7 +277,7 @@ struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
        test->dangerous = false;
        test->data = data;
 
-       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+       DLIST_ADD_END(tcase->tests, test);
 
        return test;
 }
@@ -228,7 +296,7 @@ bool torture_suite_init_tcase(struct torture_suite *suite,
        tcase->fixture_persistent = true;
        tcase->tests = NULL;
 
-       DLIST_ADD_END(suite->testcases, tcase, struct torture_tcase *);
+       DLIST_ADD_END(suite->testcases, tcase);
 
        return true;
 }
@@ -277,7 +345,6 @@ bool torture_run_suite_restricted(struct torture_context *context,
        bool ret = true;
        struct torture_tcase *tcase;
        struct torture_suite *tsuite;
-       char *old_testname;
 
        if (context->results->ui_ops->suite_start)
                context->results->ui_ops->suite_start(context, suite);
@@ -333,20 +400,19 @@ static bool test_needs_running(const char *name, const char **restricted)
        return false;
 }
 
-static bool internal_torture_run_test(struct torture_context *context, 
+static bool internal_torture_run_test(struct torture_context *context,
                                          struct torture_tcase *tcase,
                                          struct torture_test *test,
                                          bool already_setup,
                                          const char **restricted)
 {
        bool success;
-       char *old_testname = NULL;
        char *subunit_testname = NULL;
 
-       if (tcase == NULL || strcmp(test->name, tcase->name) != 0) { 
+       if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
                subunit_testname = talloc_asprintf(context, "%s.%s", tcase->name, test->name);
        } else {
-               subunit_testname = test->name;
+               subunit_testname = talloc_strdup(context, test->name);
        }
 
        if (!test_needs_running(subunit_testname, restricted))
@@ -360,39 +426,41 @@ static bool internal_torture_run_test(struct torture_context *context,
        context->last_reason = NULL;
        context->last_result = TORTURE_OK;
 
-       if (!already_setup && tcase->setup && 
-               !tcase->setup(context, &(tcase->data))) {
-               if (context->last_reason == NULL)
+       if (!already_setup && tcase->setup &&
+           !tcase->setup(context, &(tcase->data))) {
+               if (context->last_reason == NULL)
                        context->last_reason = talloc_strdup(context, "Setup failure");
                context->last_result = TORTURE_ERROR;
                success = false;
-       } else if (test->dangerous && 
-           !torture_setting_bool(context, "dangerous", false)) {
-           context->last_result = TORTURE_SKIP;
-           context->last_reason = talloc_asprintf(context, 
-               "disabled %s - enable dangerous tests to use", test->name);
-           success = true;
+       } else if (test->dangerous &&
+                  !torture_setting_bool(context, "dangerous", false)) {
+               context->last_result = TORTURE_SKIP;
+               context->last_reason = talloc_asprintf(context,
+               "disabled %s - enable dangerous tests to use", test->name);
+               success = true;
        } else {
-           success = test->run(context, tcase, test);
+               success = test->run(context, tcase, test);
 
-           if (!success && context->last_result == TORTURE_OK) {
-                   if (context->last_reason == NULL)
-                           context->last_reason = talloc_strdup(context, "Unknown error/failure");
-                   context->last_result = TORTURE_ERROR;
-           }
+               if (!success && context->last_result == TORTURE_OK) {
+                       if (context->last_reason == NULL)
+                               context->last_reason = talloc_strdup(context,
+                                       "Unknown error/failure. Missing torture_fail() or torture_assert_*() call?");
+                       context->last_result = TORTURE_ERROR;
+               }
        }
 
        if (!already_setup && tcase->teardown && !tcase->teardown(context, tcase->data)) {
-               if (context->last_reason == NULL)
-                   context->last_reason = talloc_strdup(context, "Setup failure");
-               context->last_result = TORTURE_ERROR;
+               if (context->last_reason == NULL)
+                       context->last_reason = talloc_strdup(context, "Setup failure");
+               context->last_result = TORTURE_ERROR;
                success = false;
        }
 
-       torture_ui_test_result(context, context->last_result, 
+       torture_ui_test_result(context, context->last_result,
                               context->last_reason);
-       
+
        talloc_free(context->last_reason);
+       context->last_reason = NULL;
 
        context->active_test = NULL;
        context->active_tcase = NULL;
@@ -410,7 +478,6 @@ bool torture_run_tcase_restricted(struct torture_context *context,
                       struct torture_tcase *tcase, const char **restricted)
 {
        bool ret = true;
-       char *old_testname;
        struct torture_test *test;
        bool setup_succeeded = true;
        const char * setup_reason = "Setup failed";
@@ -550,7 +617,7 @@ struct torture_tcase *torture_suite_add_simple_tcase_const(
        test->data = data;
        test->dangerous = false;
 
-       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+       DLIST_ADD_END(tcase->tests, test);
 
        return tcase;
 }
@@ -584,7 +651,7 @@ struct torture_tcase *torture_suite_add_simple_test(
        test->fn = run;
        test->dangerous = false;
 
-       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+       DLIST_ADD_END(tcase->tests, test);
 
        return tcase;
 }
@@ -598,7 +665,7 @@ bool torture_suite_add_suite(struct torture_suite *suite,
        if (child == NULL)
                return false;
 
-       DLIST_ADD_END(suite->children, child, struct torture_suite *);
+       DLIST_ADD_END(suite->children, child);
 
        /* FIXME: Check for duplicates and return false if the 
         * added suite already exists as a child */
@@ -649,7 +716,7 @@ struct torture_test *torture_tcase_add_simple_test_const(
        test->data = NULL;
        test->dangerous = false;
 
-       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+       DLIST_ADD_END(tcase->tests, test);
 
        return test;
 }
@@ -680,7 +747,13 @@ struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
        test->data = NULL;
        test->dangerous = false;
 
-       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+       DLIST_ADD_END(tcase->tests, test);
 
        return test;
 }
+
+void torture_ui_report_time(struct torture_context *context)
+{
+       if (context->results->ui_ops->report_time)
+               context->results->ui_ops->report_time(context);
+}