r19343: Add support for external scripts/binaries that write results using the
authorJelmer Vernooij <jelmer@samba.org>
Mon, 16 Oct 2006 20:05:19 +0000 (20:05 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:21:13 +0000 (14:21 -0500)
'subunit' protocol. This allows us to easily plug EJS scripts or binaries that
can't depend on -ltorture into smbtorture. The protocol is very simple:

- write "comments" to stderr

Example output on stdout:
test: foo
success: foo
test: bar
success: bar
test: blah
failure: blah [
dummy.c:30: Expression 1 != 2 failed!
]
test: blie
skip: blie [
Iconv support not built in
]

I've already converted the talloc testsuite.
(This used to be commit e1742c14a247fabba969f8698108e73997d3f420)

15 files changed:
source4/build/smb_build/makefile.pm
source4/dynconfig.c
source4/dynconfig.h
source4/dynconfig.mk
source4/lib/talloc/config.mk
source4/lib/talloc/testsuite.c
source4/main.mk
source4/script/tests/mktestsetup.sh
source4/torture/config.mk
source4/torture/local/config.mk
source4/torture/local/local.c
source4/torture/smbtorture.c
source4/torture/subunit.c [new file with mode: 0644]
source4/torture/ui.c
source4/torture/ui.h

index 97cfd7770f04da5b980a88e313eaeaf3a21e351e..0d448773a658758429d88a96c289d28397a21a9a 100644 (file)
@@ -22,6 +22,7 @@ sub new($$$)
        $self->{manpages} = [];
        $self->{sbin_progs} = [];
        $self->{bin_progs} = [];
+       $self->{torture_progs} = [];
        $self->{static_libs} = [];
        $self->{shared_libs} = [];
        $self->{installable_shared_libs} = [];
@@ -79,6 +80,7 @@ BASEDIR = $self->{config}->{prefix}
 BINDIR = $self->{config}->{bindir}
 SBINDIR = $self->{config}->{sbindir}
 LIBDIR = $self->{config}->{libdir}
+TORTUREDIR = $self->{config}->{libdir}/torture
 MODULESDIR = $self->{config}->{modulesdir}
 INCLUDEDIR = $self->{config}->{includedir}
 CONFIGDIR = $self->{config}->{sysconfdir}
@@ -364,11 +366,18 @@ sub Binary($$)
        my ($self,$ctx) = @_;
 
        my $installdir;
+       my $localdir;
+
+       if (defined($ctx->{INSTALLDIR}) && $ctx->{INSTALLDIR} eq "TORTUREDIR") {
+               $localdir = "bin/torture";
+       } else {
+               $localdir = "bin";
+       }
        
        if ($self->{duplicate_build}) {
                $installdir = "bin/install";
        } else {
-               $installdir = "bin";
+               $installdir = $localdir;
        }
 
        push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_FULL_OBJ_LIST)");
@@ -378,9 +387,12 @@ sub Binary($$)
                push (@{$self->{sbin_progs}}, "$installdir/$ctx->{BINARY}");
        } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
                push (@{$self->{bin_progs}}, "$installdir/$ctx->{BINARY}");
+       } elsif ($ctx->{INSTALLDIR} eq "TORTUREDIR") {
+               push (@{$self->{torture_progs}}, "$installdir/$ctx->{BINARY}");
        }
 
-       push (@{$self->{binaries}}, "bin/$ctx->{BINARY}");
+
+       push (@{$self->{binaries}}, "$localdir/$ctx->{BINARY}");
 
        $self->_prepare_list($ctx, "OBJ_LIST");
        $self->_prepare_list($ctx, "FULL_OBJ_LIST");
@@ -390,7 +402,7 @@ sub Binary($$)
        if ($self->{duplicate_build}) {
        $self->output(<< "__EOD__"
 #
-bin/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_FULL_OBJ_LIST) 
+$localdir/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_FULL_OBJ_LIST) 
        \@echo Linking \$\@
        \@\$(LD) \$(LDFLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \$(INSTALL_LINK_FLAGS) \\
                \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) 
@@ -511,6 +523,7 @@ sub write($$)
        $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
        $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
        $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
+       $self->output("TORTURE_PROGS = " . array2oneperline($self->{torture_progs}) . "\n");
        $self->output("BINARIES = " . array2oneperline($self->{binaries}) . "\n");
        $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
        $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
index 41728af57de542656ab8e1f7738f438bdf2d000e..5b1074382cfc691ac5ec78a7e6ce6937bfa48afe 100644 (file)
@@ -88,3 +88,6 @@ _PUBLIC_ const char *dyn_JSDIR = JSDIR;
 
 /** Where to find the winbindd socket */
 _PUBLIC_ const char *dyn_WINBINDD_SOCKET_DIR = WINBINDD_SOCKET_DIR;
+
+/** Directory with subunit torture tests */
+_PUBLIC_ const char *dyn_TORTUREDIR = TORTUREDIR;
index b1a7fff191a01f5a8c6880069011d6d71c37fc98..312283c5fb05af1bbb8cc0e706ae3ab7c3cf4b45 100644 (file)
@@ -40,3 +40,4 @@ extern const char *dyn_SWATDIR;
 extern const char *dyn_JSDIR;
 extern const char *dyn_SETUPDIR;
 extern const char *dyn_WINBINDD_SOCKET_DIR;
+extern const char *dyn_TORTUREDIR;
index 2743bc2b296912f8c804a91c35283b7763d7c22b..180333693d00f3d428fc6c8e953130dd2f898612 100644 (file)
@@ -10,6 +10,7 @@ PATH_FLAGS = -DCONFIGFILE=\"$(CONFIGFILE)\" \
         -DCONFIGDIR=\"$(CONFIGDIR)\" -DNCALRPCDIR=\"$(NCALRPCDIR)\" \
         -DSWATDIR=\"$(SWATDIR)\" -DPRIVATE_DIR=\"$(PRIVATEDIR)\" \
         -DMODULESDIR=\"$(MODULESDIR)\" -DJSDIR=\"$(JSDIR)\" \
+        -DTORTUREDIR=\"$(TORTUREDIR)\" \
         -DSETUPDIR=\"$(SETUPDIR)\" -DWINBINDD_SOCKET_DIR=\"$(WINBINDD_SOCKET_DIR)\"
 
 dynconfig.o: dynconfig.c Makefile
index 3a8a22aa572a4b7d005eeca53726bc1277c30cbc..19059ca4dcad059edbcceff55cbfc1145a800681 100644 (file)
@@ -12,3 +12,7 @@ DESCRIPTION = A hierarchical pool based memory system with destructors
 # End LIBRARY LIBTALLOC
 ################################################
 
+[BINARY::LOCAL-TALLOC]
+OBJ_FILES = testsuite.o
+PRIVATE_DEPENDENCIES = LIBTALLOC
+INSTALLDIR = TORTUREDIR
index f2e61157e4f5d21fe363183c3f6153a1f3c10f32..14222c75af5416d66525381c7de370cc74d2f3fb 100644 (file)
 #include "replace.h"
 #include "system/time.h"
 #include "talloc.h"
-#ifdef _SAMBA_BUILD_
-#include "includes.h"
-#include "torture/ui.h"
-#else
-#define torture_comment printf
-#define torture_assert(tctx, expr, str) if (!(expr)) { printf str; return false; }
-#define torture_suite_add_simple_tcase(suite,name,fn) \
-       ret &= printf("TESTING %s\n", name), fn();
-#define torture_out stdout
-
-struct torture_suite;
 
 static struct timeval timeval_current(void)
 {
@@ -52,7 +41,18 @@ static double timeval_elapsed(struct timeval *tv)
        return (tv2.tv_sec - tv->tv_sec) + 
               (tv2.tv_usec - tv->tv_usec)*1.0e-6;
 }
-#endif /* _SAMBA_BUILD_ */
+
+#define torture_assert(expr, str) if (!(expr)) { \
+       printf("failure: xx [\n%s: Expression %s failed: %s\n]\n", \
+               __location__, #expr, str); \
+       return false; \
+}
+
+#define torture_assert_str_equal(arg1, arg2, desc) if (strcmp(arg1, arg2)) { \
+       printf("failure: xx [\n%s: Expected %s, got %s: %s\n]\n", \
+                  __location__, arg1, arg2, desc); \
+       return false; \
+}
 
 #if _SAMBA_BUILD_==3
 #ifdef malloc
@@ -65,10 +65,10 @@ static double timeval_elapsed(struct timeval *tv)
 
 #define CHECK_SIZE(ptr, tsize) do { \
        if (talloc_total_size(ptr) != (tsize)) { \
-               torture_comment(tctx, talloc_asprintf(tctx, "failed: wrong '%s' tree size: got %u  expected %u\n", \
+               fprintf(stderr, "failed: wrong '%s' tree size: got %u  expected %u\n", \
                       #ptr, \
                       (unsigned)talloc_total_size(ptr), \
-                      (unsigned)tsize)); \
+                      (unsigned)tsize); \
                talloc_report_full(ptr, stdout); \
                return false; \
        } \
@@ -76,10 +76,10 @@ static double timeval_elapsed(struct timeval *tv)
 
 #define CHECK_BLOCKS(ptr, tblocks) do { \
        if (talloc_total_blocks(ptr) != (tblocks)) { \
-               torture_comment(tctx, talloc_asprintf(tctx, "failed: wrong '%s' tree blocks: got %u  expected %u\n", \
+               fprintf(stderr, "failed: wrong '%s' tree blocks: got %u  expected %u\n", \
                       #ptr, \
                       (unsigned)talloc_total_blocks(ptr), \
-                      (unsigned)tblocks)); \
+                      (unsigned)tblocks); \
                talloc_report_full(ptr, stdout); \
                return false; \
        } \
@@ -87,10 +87,10 @@ static double timeval_elapsed(struct timeval *tv)
 
 #define CHECK_PARENT(ptr, parent) do { \
        if (talloc_parent(ptr) != (parent)) { \
-               torture_comment(tctx, talloc_asprintf(tctx, "failed: '%s' has wrong parent: got %p  expected %p\n", \
+               fprintf(stderr, "failed: '%s' has wrong parent: got %p  expected %p\n", \
                       #ptr, \
                       talloc_parent(ptr), \
-                      (parent))); \
+                      (parent)); \
                talloc_report_full(ptr, stdout); \
                talloc_report_full(parent, stdout); \
                talloc_report_full(NULL, stdout); \
@@ -102,10 +102,12 @@ static double timeval_elapsed(struct timeval *tv)
 /*
   test references 
 */
-static bool test_ref1(struct torture_context *tctx)
+static bool test_ref1(void)
 {
        void *root, *p1, *p2, *ref, *r1;
 
+       printf("test: SINGLE REFERENCE FREE\n");
+
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "p1");
        p2 = talloc_named_const(p1, 1, "p2");
@@ -115,31 +117,31 @@ static bool test_ref1(struct torture_context *tctx)
 
        r1 = talloc_named_const(root, 1, "r1"); 
        ref = talloc_reference(r1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 2);
 
-       torture_comment(tctx, "Freeing p2\n");
+       fprintf(stderr, "Freeing p2\n");
        talloc_free(p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p1\n");
+       fprintf(stderr, "Freeing p1\n");
        talloc_free(p1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing r1\n");
+       fprintf(stderr, "Freeing r1\n");
        talloc_free(r1);
-       talloc_report_full(NULL, torture_out);
+       talloc_report_full(NULL, stderr);
 
-       torture_comment(tctx, "Testing NULL\n");
+       fprintf(stderr, "Testing NULL\n");
        if (talloc_reference(root, NULL)) {
                return false;
        }
@@ -149,16 +151,18 @@ static bool test_ref1(struct torture_context *tctx)
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+       printf("success: SINGLE REFERENCE FREE\n");
        return true;
 }
 
 /*
   test references 
 */
-static bool test_ref2(struct torture_context *tctx)
+static bool test_ref2(void)
 {
        void *root, *p1, *p2, *ref, *r1;
 
+       printf("test: DOUBLE REFERENCE FREE\n");
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "p1");
        talloc_named_const(p1, 1, "x1");
@@ -168,85 +172,92 @@ static bool test_ref2(struct torture_context *tctx)
 
        r1 = talloc_named_const(root, 1, "r1"); 
        ref = talloc_reference(r1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 2);
 
-       torture_comment(tctx, "Freeing ref\n");
+       fprintf(stderr, "Freeing ref\n");
        talloc_free(ref);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p2\n");
+       fprintf(stderr, "Freeing p2\n");
        talloc_free(p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 4);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p1\n");
+       fprintf(stderr, "Freeing p1\n");
        talloc_free(p1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing r1\n");
+       fprintf(stderr, "Freeing r1\n");
        talloc_free(r1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+       printf("success: DOUBLE REFERENCE FREE\n");
        return true;
 }
 
 /*
   test references 
 */
-static bool test_ref3(struct torture_context *tctx)
+static bool test_ref3(void)
 {
        void *root, *p1, *p2, *ref, *r1;
 
+       printf("test: PARENT REFERENCE FREE\n");
+
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "p1");
        p2 = talloc_named_const(root, 1, "p2");
        r1 = talloc_named_const(p1, 1, "r1");
        ref = talloc_reference(p2, r1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 2);
        CHECK_BLOCKS(p2, 2);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p1\n");
+       fprintf(stderr, "Freeing p1\n");
        talloc_free(p1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p2, 2);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p2\n");
+       fprintf(stderr, "Freeing p2\n");
        talloc_free(p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+
+       printf("success: PARENT REFERENCE FREE\n");
        return true;
 }
 
 /*
   test references 
 */
-static bool test_ref4(struct torture_context *tctx)
+static bool test_ref4(void)
 {
        void *root, *p1, *p2, *ref, *r1;
 
+       printf("test: REFERRER REFERENCE FREE\n");
+
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "p1");
        talloc_named_const(p1, 1, "x1");
@@ -256,32 +267,34 @@ static bool test_ref4(struct torture_context *tctx)
 
        r1 = talloc_named_const(root, 1, "r1"); 
        ref = talloc_reference(r1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 2);
 
-       torture_comment(tctx, "Freeing r1\n");
+       fprintf(stderr, "Freeing r1\n");
        talloc_free(r1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 5);
        CHECK_BLOCKS(p2, 1);
 
-       torture_comment(tctx, "Freeing p2\n");
+       fprintf(stderr, "Freeing p2\n");
        talloc_free(p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 4);
 
-       torture_comment(tctx, "Freeing p1\n");
+       fprintf(stderr, "Freeing p1\n");
        talloc_free(p1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+
+       printf("success: REFERRER REFERENCE FREE\n");
        return true;
 }
 
@@ -289,10 +302,12 @@ static bool test_ref4(struct torture_context *tctx)
 /*
   test references 
 */
-static bool test_unlink1(struct torture_context *tctx)
+static bool test_unlink1(void)
 {
        void *root, *p1, *p2, *ref, *r1;
 
+       printf("test: UNLINK\n");
+
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "p1");
        talloc_named_const(p1, 1, "x1");
@@ -302,27 +317,29 @@ static bool test_unlink1(struct torture_context *tctx)
 
        r1 = talloc_named_const(p1, 1, "r1");   
        ref = talloc_reference(r1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 7);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 2);
 
-       torture_comment(tctx, "Unreferencing r1\n");
+       fprintf(stderr, "Unreferencing r1\n");
        talloc_unlink(r1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_BLOCKS(p1, 6);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(r1, 1);
 
-       torture_comment(tctx, "Freeing p1\n");
+       fprintf(stderr, "Freeing p1\n");
        talloc_free(p1);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
 
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+
+       printf("success: UNLINK\n");
        return true;
 }
 
@@ -334,17 +351,19 @@ static int fail_destructor(void *ptr)
 /*
   miscellaneous tests to try to get a higher test coverage percentage
 */
-static bool test_misc(struct torture_context *tctx)
+static bool test_misc(void)
 {
        void *root, *p1;
        char *p2;
        double *d;
        const char *name;
 
+       printf("test: MISCELLANEOUS\n");
+
        root = talloc_new(NULL);
 
        p1 = talloc_size(root, 0x7fffffff);
-       torture_assert(tctx, !p1, "failed: large talloc allowed\n");
+       torture_assert(!p1, "failed: large talloc allowed\n");
 
        p1 = talloc_strdup(root, "foo");
        talloc_increase_ref_count(p1);
@@ -359,65 +378,65 @@ static bool test_misc(struct torture_context *tctx)
        CHECK_BLOCKS(p1, 1);
        CHECK_BLOCKS(root, 2);
        p2 = talloc_strdup(p1, "foo");
-       torture_assert(tctx, talloc_unlink(root, p2) == -1,
+       torture_assert(talloc_unlink(root, p2) == -1,
                                   "failed: talloc_unlink() of non-reference context should return -1\n");
-       torture_assert(tctx, talloc_unlink(p1, p2) == 0,
+       torture_assert(talloc_unlink(p1, p2) == 0,
                "failed: talloc_unlink() of parent should succeed\n");
        talloc_free(p1);
        CHECK_BLOCKS(p1, 1);
        CHECK_BLOCKS(root, 2);
 
        name = talloc_set_name(p1, "my name is %s", "foo");
-       torture_assert_str_equal(tctx, talloc_get_name(p1), "my name is foo",
+       torture_assert_str_equal(talloc_get_name(p1), "my name is foo",
                "failed: wrong name after talloc_set_name(my name is foo)");
        CHECK_BLOCKS(p1, 2);
        CHECK_BLOCKS(root, 3);
 
        talloc_set_name_const(p1, NULL);
-       torture_assert_str_equal (tctx, talloc_get_name(p1), "UNNAMED",
+       torture_assert_str_equal (talloc_get_name(p1), "UNNAMED",
                "failed: wrong name after talloc_set_name(NULL)");
        CHECK_BLOCKS(p1, 2);
        CHECK_BLOCKS(root, 3);
        
 
-       torture_assert(tctx, talloc_free(NULL) == -1, 
+       torture_assert(talloc_free(NULL) == -1, 
                                   "talloc_free(NULL) should give -1\n");
 
        talloc_set_destructor(p1, fail_destructor);
-       torture_assert(tctx, talloc_free(p1) == -1, 
+       torture_assert(talloc_free(p1) == -1, 
                "Failed destructor should cause talloc_free to fail\n");
        talloc_set_destructor(p1, NULL);
 
-       talloc_report(root, torture_out);
+       talloc_report(root, stderr);
 
 
        p2 = (char *)talloc_zero_size(p1, 20);
-       torture_assert(tctx, p2[19] == 0, "Failed to give zero memory\n");
+       torture_assert(p2[19] == 0, "Failed to give zero memory\n");
        talloc_free(p2);
 
-       torture_assert(tctx, talloc_strdup(root, NULL) == NULL,
+       torture_assert(talloc_strdup(root, NULL) == NULL,
                "failed: strdup on NULL should give NULL\n");
 
        p2 = talloc_strndup(p1, "foo", 2);
-       torture_assert(tctx, strcmp("fo", p2) == 0, "failed: strndup doesn't work\n");
+       torture_assert(strcmp("fo", p2) == 0, "failed: strndup doesn't work\n");
        p2 = talloc_asprintf_append(p2, "o%c", 'd');
-       torture_assert(tctx, strcmp("food", p2) == 0, 
+       torture_assert(strcmp("food", p2) == 0, 
                                   "failed: talloc_asprintf_append doesn't work\n");
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(p1, 3);
 
        p2 = talloc_asprintf_append(NULL, "hello %s", "world");
-       torture_assert(tctx, strcmp("hello world", p2) == 0,
+       torture_assert(strcmp("hello world", p2) == 0,
                "failed: talloc_asprintf_append doesn't work\n");
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(p1, 3);
        talloc_free(p2);
 
        d = talloc_array(p1, double, 0x20000000);
-       torture_assert(tctx, !d, "failed: integer overflow not detected\n");
+       torture_assert(!d, "failed: integer overflow not detected\n");
 
        d = talloc_realloc(p1, d, double, 0x20000000);
-       torture_assert(tctx, !d, "failed: integer overflow not detected\n");
+       torture_assert(!d, "failed: integer overflow not detected\n");
 
        talloc_free(p1);
        CHECK_BLOCKS(root, 1);
@@ -429,7 +448,7 @@ static bool test_misc(struct torture_context *tctx)
 
        p1 = talloc_init("%d bytes", 200);
        p2 = talloc_asprintf(p1, "my test '%s'", "string");
-       torture_assert_str_equal(tctx, p2, "my test 'string'",
+       torture_assert_str_equal(p2, "my test 'string'",
                "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
        CHECK_BLOCKS(p1, 3);
        CHECK_SIZE(p2, 17);
@@ -439,9 +458,9 @@ static bool test_misc(struct torture_context *tctx)
        p1 = talloc_named_const(root, 10, "p1");
        p2 = (char *)talloc_named_const(root, 20, "p2");
        (void)talloc_reference(p1, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
        talloc_unlink(root, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(p1, 2);
        CHECK_BLOCKS(root, 3);
@@ -451,9 +470,9 @@ static bool test_misc(struct torture_context *tctx)
        p1 = talloc_named_const(root, 10, "p1");
        p2 = (char *)talloc_named_const(root, 20, "p2");
        (void)talloc_reference(NULL, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
        talloc_unlink(root, p2);
-       talloc_report_full(root, torture_out);
+       talloc_report_full(root, stderr);
        CHECK_BLOCKS(p2, 1);
        CHECK_BLOCKS(p1, 1);
        CHECK_BLOCKS(root, 2);
@@ -462,11 +481,11 @@ static bool test_misc(struct torture_context *tctx)
 
        /* Test that talloc_unlink is a no-op */
 
-       torture_assert(tctx, talloc_unlink(root, NULL) == -1,
+       torture_assert(talloc_unlink(root, NULL) == -1,
                "failed: talloc_unlink(root, NULL) == -1\n");
 
-       talloc_report(root, torture_out);
-       talloc_report(NULL, torture_out);
+       talloc_report(root, stderr);
+       talloc_report(NULL, stderr);
 
        CHECK_SIZE(root, 0);
 
@@ -476,6 +495,9 @@ static bool test_misc(struct torture_context *tctx)
 
        talloc_enable_leak_report();
        talloc_enable_leak_report_full();
+
+       printf("success: MISCELLANEOUS\n");
+
        return true;
 }
 
@@ -483,10 +505,12 @@ static bool test_misc(struct torture_context *tctx)
 /*
   test realloc
 */
-static bool test_realloc(struct torture_context *tctx)
+static bool test_realloc(void)
 {
        void *root, *p1, *p2;
 
+       printf("test: REALLOC\n");
+
        root = talloc_new(NULL);
 
        p1 = talloc_size(root, 10);
@@ -511,7 +535,7 @@ static bool test_realloc(struct torture_context *tctx)
        CHECK_SIZE(p1, 60);
 
        talloc_increase_ref_count(p2);
-       torture_assert(tctx, talloc_realloc_size(NULL, p2, 5) == NULL,
+       torture_assert(talloc_realloc_size(NULL, p2, 5) == NULL,
                "failed: talloc_realloc() on a referenced pointer should fail\n");
        CHECK_BLOCKS(p1, 4);
 
@@ -519,7 +543,7 @@ static bool test_realloc(struct torture_context *tctx)
        talloc_realloc_size(NULL, p2, 0);
        CHECK_BLOCKS(p1, 3);
 
-       torture_assert(tctx, talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
+       torture_assert(talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
                "failed: oversize talloc should fail\n");
 
        talloc_realloc_size(NULL, p1, 0);
@@ -528,13 +552,16 @@ static bool test_realloc(struct torture_context *tctx)
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+
+       printf("success: REALLOC\n");
+
        return true;
 }
 
 /*
   test realloc with a child
 */
-static bool test_realloc_child(struct torture_context *tctx)
+static bool test_realloc_child(void)
 {
        void *root;
        struct el2 {
@@ -545,6 +572,8 @@ static bool test_realloc_child(struct torture_context *tctx)
                struct el2 **list, **list2, **list3;
        } *el1;
 
+       printf("test: REALLOC WITH CHILD\n");
+
        root = talloc_new(NULL);
 
        el1 = talloc(root, struct el1);
@@ -569,13 +598,15 @@ static bool test_realloc_child(struct torture_context *tctx)
        el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
 
        talloc_free(root);
+
+       printf("success: REALLOC WITH CHILD\n");
        return true;
 }
 
 /*
   test type checking
 */
-static bool test_type(struct torture_context *tctx)
+static bool test_type(void)
 {
        void *root;
        struct el1 {
@@ -586,31 +617,37 @@ static bool test_type(struct torture_context *tctx)
        };
        struct el1 *el1;
 
+       printf("test: talloc type checking\n");
+
        root = talloc_new(NULL);
 
        el1 = talloc(root, struct el1);
 
        el1->count = 1;
 
-       torture_assert(tctx, talloc_get_type(el1, struct el1) == el1,
+       torture_assert(talloc_get_type(el1, struct el1) == el1,
                "type check failed on el1\n");
-       torture_assert(tctx, talloc_get_type(el1, struct el2) == NULL,
+       torture_assert(talloc_get_type(el1, struct el2) == NULL,
                "type check failed on el1 with el2\n");
        talloc_set_type(el1, struct el2);
-       torture_assert(tctx, talloc_get_type(el1, struct el2) == (struct el2 *)el1,
+       torture_assert(talloc_get_type(el1, struct el2) == (struct el2 *)el1,
                "type set failed on el1 with el2\n");
 
        talloc_free(root);
+
+       printf("success: talloc type checking\n");
        return true;
 }
 
 /*
   test steal
 */
-static bool test_steal(struct torture_context *tctx)
+static bool test_steal(void)
 {
        void *root, *p1, *p2;
 
+       printf("test: STEAL\n");
+
        root = talloc_new(NULL);
 
        p1 = talloc_array(root, char, 10);
@@ -620,10 +657,10 @@ static bool test_steal(struct torture_context *tctx)
        CHECK_SIZE(p1, 10);
        CHECK_SIZE(root, 30);
 
-       torture_assert(tctx, talloc_steal(p1, NULL) == NULL,
+       torture_assert(talloc_steal(p1, NULL) == NULL,
                "failed: stealing NULL should give NULL\n");
 
-       torture_assert(tctx, talloc_steal(p1, p1) == p1,
+       torture_assert(talloc_steal(p1, p1) == p1,
                "failed: stealing to ourselves is a nop\n");
        CHECK_BLOCKS(root, 3);
        CHECK_SIZE(root, 30);
@@ -646,16 +683,18 @@ static bool test_steal(struct torture_context *tctx)
        talloc_free(root);
 
        p1 = talloc_size(NULL, 3);
-       talloc_report_full(NULL, torture_out);
+       talloc_report_full(NULL, stderr);
        CHECK_SIZE(NULL, 3);
        talloc_free(p1);
+
+       printf("success: STEAL\n");
        return true;
 }
 
 /*
   test move
 */
-static bool test_move(struct torture_context *tctx)
+static bool test_move(void)
 {
        void *root;
        struct t_move {
@@ -663,6 +702,8 @@ static bool test_move(struct torture_context *tctx)
                int *x;
        } *t1, *t2;
 
+       printf("test: MOVE\n");
+
        root = talloc_new(NULL);
 
        t1 = talloc(root, struct t_move);
@@ -673,22 +714,26 @@ static bool test_move(struct torture_context *tctx)
 
        t2->p = talloc_move(t2, &t1->p);
        t2->x = talloc_move(t2, &t1->x);
-       torture_assert(tctx, t1->p == NULL && t1->x == NULL &&
+       torture_assert(t1->p == NULL && t1->x == NULL &&
            strcmp(t2->p, "foo") == 0 && *t2->x == 42,
                "talloc move failed");
 
        talloc_free(root);
 
+       printf("success: MOVE\n");
+
        return true;
 }
 
 /*
   test talloc_realloc_fn
 */
-static bool test_realloc_fn(struct torture_context *tctx)
+static bool test_realloc_fn(void)
 {
        void *root, *p1;
 
+       printf("test: talloc_realloc_fn\n");
+
        root = talloc_new(NULL);
 
        p1 = talloc_realloc_fn(root, NULL, 10);
@@ -702,14 +747,18 @@ static bool test_realloc_fn(struct torture_context *tctx)
        CHECK_SIZE(root, 0);
 
        talloc_free(root);
+
+       printf("success: talloc_realloc_fn\n");
        return true;
 }
 
 
-static bool test_unref_reparent(struct torture_context *tctx)
+static bool test_unref_reparent(void)
 {
        void *root, *p1, *p2, *c1;
 
+       printf("test: UNREFERENCE AFTER PARENT FREED\n");
+
        root = talloc_named_const(NULL, 0, "root");
        p1 = talloc_named_const(root, 1, "orig parent");
        p2 = talloc_named_const(root, 1, "parent by reference");
@@ -729,18 +778,22 @@ static bool test_unref_reparent(struct torture_context *tctx)
 
        talloc_free(p2);
        talloc_free(root);
+
+       printf("success: UNREFERENCE AFTER PARENT FREED\n");
        return true;
 }
 
 /*
   measure the speed of talloc versus malloc
 */
-static bool test_speed(struct torture_context *tctx)
+static bool test_speed(void)
 {
        void *ctx = talloc_new(NULL);
        unsigned count;
        struct timeval tv;
 
+       printf("test: TALLOC VS MALLOC SPEED\n");
+
        tv = timeval_current();
        count = 0;
        do {
@@ -752,7 +805,7 @@ static bool test_speed(struct torture_context *tctx)
                count += 3;
        } while (timeval_elapsed(&tv) < 5.0);
 
-       torture_comment(tctx, talloc_asprintf(tctx, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv)));
+       fprintf(stderr, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
 
        talloc_free(ctx);
 
@@ -769,27 +822,34 @@ static bool test_speed(struct torture_context *tctx)
                count += 3;
        } while (timeval_elapsed(&tv) < 5.0);
 
-       torture_comment(tctx, talloc_asprintf(tctx, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv)));
+       fprintf(stderr, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
+
+       printf("success: TALLOC VS MALLOC SPEED\n");
+
        return true;
 }
 
-static bool test_lifeless(struct torture_context *tctx)
+static bool test_lifeless(void)
 {
        void *top = talloc_new(NULL);
        char *parent, *child; 
        void *child_owner = talloc_new(NULL);
 
+       printf("test: TALLOC_UNLINK LOOP\n");
+
        parent = talloc_strdup(top, "parent");
        child = talloc_strdup(parent, "child");  
        (void)talloc_reference(child, parent);
        (void)talloc_reference(child_owner, child); 
-       talloc_report_full(top, torture_out);
+       talloc_report_full(top, stderr);
        talloc_unlink(top, parent);
        talloc_free(child);
-       talloc_report_full(top, torture_out);
+       talloc_report_full(top, stderr);
        talloc_free(top);
        talloc_free(child_owner);
        talloc_free(child);
+
+       printf("success: TALLOC_UNLINK LOOP\n");
        return true;
 }
 
@@ -801,7 +861,7 @@ static int test_loop_destructor(char *ptr)
        return 0;
 }
 
-static bool test_loop(struct torture_context *tctx)
+static bool test_loop(void)
 {
        void *top = talloc_new(NULL);
        char *parent;
@@ -809,21 +869,25 @@ static bool test_loop(struct torture_context *tctx)
                char *req2, *req3;
        } *req1;
 
+       printf("test: TALLOC LOOP DESTRUCTION\n");
+
        parent = talloc_strdup(top, "parent");
        req1 = talloc(parent, struct req1);
        req1->req2 = talloc_strdup(req1, "req2");  
        talloc_set_destructor(req1->req2, test_loop_destructor);
        req1->req3 = talloc_strdup(req1, "req3");
        (void)talloc_reference(req1->req3, req1);
-       talloc_report_full(top, torture_out);
+       talloc_report_full(top, stderr);
        talloc_free(parent);
-       talloc_report_full(top, torture_out);
-       talloc_report_full(NULL, torture_out);
+       talloc_report_full(top, stderr);
+       talloc_report_full(NULL, stderr);
        talloc_free(top);
 
-       torture_assert(tctx, loop_destructor_count == 1, 
+       torture_assert(loop_destructor_count == 1, 
                                   "FAILED TO FIRE LOOP DESTRUCTOR\n");
        loop_destructor_count = 0;
+
+       printf("success: TALLOC LOOP DESTRUCTION\n");
        return true;
 }
 
@@ -832,13 +896,15 @@ static int fail_destructor_str(char *ptr)
        return -1;
 }
 
-static bool test_free_parent_deny_child(struct torture_context *tctx)
+static bool test_free_parent_deny_child(void)
 {
        void *top = talloc_new(NULL);
        char *level1;
        char *level2;
        char *level3;
 
+       printf("test: TALLOC FREE PARENT DENY CHILD\n");
+
        level1 = talloc_strdup(top, "level1");
        level2 = talloc_strdup(level1, "level2");
        level3 = talloc_strdup(level2, "level3");
@@ -850,10 +916,12 @@ static bool test_free_parent_deny_child(struct torture_context *tctx)
        CHECK_PARENT(level3, top);
 
        talloc_free(top);
+
+       printf("success: TALLOC FREE PARENT DENY CHILD\n");
        return true;
 }
 
-static bool test_talloc_ptrtype(struct torture_context *tctx)
+static bool test_talloc_ptrtype(void)
 {
        void *top = talloc_new(NULL);
        struct struct1 {
@@ -865,131 +933,123 @@ static bool test_talloc_ptrtype(struct torture_context *tctx)
        const char *location3;
        const char *location4;
 
+       printf("test: TALLOC PTRTYPE\n");
+
        s1 = talloc_ptrtype(top, s1);location1 = __location__;
 
-       torture_assert(tctx, talloc_get_size(s1) == sizeof(struct struct1),
-                                  talloc_asprintf(tctx, 
-                                  "talloc_ptrtype() allocated the wrong size %lu "
-                          "(should be %lu)\n", (unsigned long)talloc_get_size(s1),
-                          (unsigned long)sizeof(struct struct1)));
+       if (talloc_get_size(s1) != sizeof(struct struct1)) {
+               printf("failure: TALLOC PTRTYPE [\n"
+                 "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n"
+                 "]\n", (unsigned long)talloc_get_size(s1),
+                          (unsigned long)sizeof(struct struct1));
+               return false;
+       }
 
-       torture_assert(tctx, strcmp(location1, talloc_get_name(s1)) == 0,
-                                  talloc_asprintf(tctx, 
-               "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n",
-                       talloc_get_name(s1), location1));
+       if (strcmp(location1, talloc_get_name(s1)) != 0) {
+               printf("failure: TALLOC PTRTYPE [\n"
+                 "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
+                       talloc_get_name(s1), location1);
+               return false;
+       }
 
        s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
 
-       torture_assert(tctx, talloc_get_size(s2) == (sizeof(struct struct1) * 10),
-                                  talloc_asprintf(tctx, 
-               "talloc_array_ptrtype() allocated the wrong size "
-                      "%lu (should be %lu)\n",
+       if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {
+               printf("failure: TALLOC PTRTYPE [\n"
+                          "talloc_array_ptrtype() allocated the wrong size "
+                      "%lu (should be %lu)\n]\n",
                        (unsigned long)talloc_get_size(s2),
-                   (unsigned long)(sizeof(struct struct1)*10)));
+                   (unsigned long)(sizeof(struct struct1)*10));
+               return false;
+       }
 
-       torture_assert(tctx, strcmp(location2, talloc_get_name(s2)) == 0,
-                                  talloc_asprintf(tctx, 
-               "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n",
-                       talloc_get_name(s2), location2));
+       if (strcmp(location2, talloc_get_name(s2)) != 0) {
+               printf("failure: TALLOC PTRTYPE [\n"
+               "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
+                       talloc_get_name(s2), location2);
+               return false;
+       }
 
        s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
 
-       torture_assert(tctx, talloc_get_size(s3) == (sizeof(struct struct1 *) * 10),
-                                  talloc_asprintf(tctx, 
-                       "talloc_array_ptrtype() allocated the wrong size "
-                      "%lu (should be %lu)\n",
+       if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {
+               printf("failure: TALLOC PTRTYPE [\n"
+                          "talloc_array_ptrtype() allocated the wrong size "
+                      "%lu (should be %lu)\n]\n",
                           (unsigned long)talloc_get_size(s3),
-                      (unsigned long)(sizeof(struct struct1 *)*10)));
+                      (unsigned long)(sizeof(struct struct1 *)*10));
+               return false;
+       }
 
-       torture_assert_str_equal(tctx, location3, talloc_get_name(s3),
+       torture_assert_str_equal(location3, talloc_get_name(s3),
                "talloc_array_ptrtype() sets the wrong name");
 
        s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
 
-       torture_assert(tctx, talloc_get_size(s4) == (sizeof(struct struct1 **) * 10),
-                                  talloc_asprintf(tctx, 
+       if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {
+               printf("failure: TALLOC PTRTYPE [\n"
                      "talloc_array_ptrtype() allocated the wrong size "
-                      "%lu (should be %lu)\n",
+                      "%lu (should be %lu)\n]\n",
                           (unsigned long)talloc_get_size(s4),
-                      (unsigned long)(sizeof(struct struct1 **)*10)));
+                      (unsigned long)(sizeof(struct struct1 **)*10));
+               return false;
+       }
 
-       torture_assert_str_equal(tctx, location4, talloc_get_name(s4),
+       torture_assert_str_equal(location4, talloc_get_name(s4),
                "talloc_array_ptrtype() sets the wrong name");
 
        talloc_free(top);
+
+       printf("success: TALLOC PTRTYPE\n");
        return true;
 }
 
-static bool test_autofree(struct torture_context *tctx)
+static bool test_autofree(void)
 {
-#if _SAMBA_BUILD_>=4
-       /* 
-        * we can't run this inside smbtorture in samba4
-        * as smbtorture uses talloc_autofree_context()
-        */
-       torture_skip(tctx, 
-               "SKIPPING TALLOC AUTOFREE CONTEXT (not supported from smbtorture)");
-#else
        void *p;
+       printf("test: TALLOC AUTOFREE CONTEXT\n");
 
        p = talloc_autofree_context();
        talloc_free(p);
 
        p = talloc_autofree_context();
        talloc_free(p);
-#endif
+
+       printf("success: TALLOC AUTOFREE CONTEXT\n");
        return true;
 }
 
-bool torture_local_talloc(struct torture_suite *tsuite) 
+int main(void)
 {
        bool ret = true;
 
        talloc_disable_null_tracking();
        talloc_enable_null_tracking();
 
-       torture_suite_add_simple_test(tsuite, "SINGLE REFERENCE FREE", test_ref1);
-       torture_suite_add_simple_test(tsuite, "DOUBLE REFERENCE FREE", test_ref2);
-       torture_suite_add_simple_test(tsuite, "PARENT REFERENCE FREE", test_ref3);
-       torture_suite_add_simple_test(tsuite, "REFERRER REFERENCE FREE", test_ref4);
-       torture_suite_add_simple_test(tsuite, "UNLINK", test_unlink1); 
-       torture_suite_add_simple_test(tsuite, "MISCELLANEOUS", test_misc);
-       torture_suite_add_simple_test(tsuite, "REALLOC", test_realloc);
-       torture_suite_add_simple_test(tsuite, "REALLOC WITH CHILD", 
-                                                                  test_realloc_child);
-       torture_suite_add_simple_test(tsuite, "STEAL", test_steal); 
-       torture_suite_add_simple_test(tsuite, "MOVE", test_move); 
-       torture_suite_add_simple_test(tsuite, "UNREFERENCE AFTER PARENT FREED", 
-                                                                 test_unref_reparent);
-       torture_suite_add_simple_test(tsuite, "talloc_realloc_fn", 
-                                                                 test_realloc_fn); 
-       torture_suite_add_simple_test(tsuite, "talloc type checking", test_type);
-       torture_suite_add_simple_test(tsuite, "TALLOC_UNLINK LOOP", test_lifeless); 
-       torture_suite_add_simple_test(tsuite, "TALLOC LOOP DESTRUCTION", test_loop);
-       torture_suite_add_simple_test(tsuite, "TALLOC FREE PARENT DENY CHILD", 
-                                                                 test_free_parent_deny_child); 
-       torture_suite_add_simple_test(tsuite, "TALLOC PTRTYPE", 
-                                                                 test_talloc_ptrtype);
+       ret &= test_ref1();
+       ret &= test_ref2();
+       ret &= test_ref3();
+       ret &= test_ref4();
+       ret &= test_unlink1(); 
+       ret &= test_misc();
+       ret &= test_realloc();
+       ret &= test_realloc_child(); 
+       ret &= test_steal(); 
+       ret &= test_move(); 
+       ret &= test_unref_reparent();
+       ret &= test_realloc_fn(); 
+       ret &= test_type();
+       ret &= test_lifeless(); 
+       ret &= test_loop();
+       ret &= test_free_parent_deny_child(); 
+       ret &= test_talloc_ptrtype();
 
        if (ret) {
-               torture_suite_add_simple_test(tsuite, "TALLOC VS MALLOC SPEED", 
-                                                                         test_speed);
+               ret &= test_speed();
        }
-       torture_suite_add_simple_test(tsuite, "TALLOC AUTOFREE CONTEXT",
-                                                                 test_autofree);
+       ret &= test_autofree();
 
-       return ret;
-}
-
-
-
-#if _SAMBA_BUILD_<4
- int main(void)
-{
-       if (!torture_local_talloc(NULL)) {
-               printf("ERROR: TESTSUITE FAILED\n");
+       if (!ret)
                return -1;
-       }
        return 0;
 }
-#endif
index 7151ebb70b0e22b6df88d0e13db32912e50d8d83..42c471da80e56a705af5fdb0fe6e03ccea5643c3 100644 (file)
@@ -61,6 +61,7 @@ showlayout:
        @echo '  jsdir:       $(JSDIR)'
        @echo '  swatdir:     $(SWATDIR)'
        @echo '  mandir:      $(MANDIR)'
+       @echo '  torturedir:  $(TORTUREDIR)'
        @echo '  datadir:     $(DATADIR)'
        @echo '  winbindd_socket_dir:  $(WINBINDD_SOCKET_DIR)'
 
@@ -105,6 +106,7 @@ installdirs:
                $(DESTDIR)$(BASEDIR) \
                $(DESTDIR)$(BINDIR) \
                $(DESTDIR)$(SBINDIR) \
+               $(DESTDIR)$(TORTUREDIR) \
                $(DESTDIR)$(LIBDIR) \
                $(DESTDIR)$(MODULESDIR) \
                $(DESTDIR)$(MANDIR) \
@@ -134,6 +136,13 @@ installbin: $(SBIN_PROGS) $(BIN_PROGS) installdirs
                $(DESTDIR)$(LIBDIR) \
                $(DESTDIR)$(VARDIR) \
                $(BIN_PROGS)
+       @$(SHELL) $(srcdir)/script/installbin.sh \
+               $(INSTALLPERMS) \
+               $(DESTDIR)$(BASEDIR) \
+               $(DESTDIR)$(TORTUREDIR) \
+               $(DESTDIR)$(LIBDIR) \
+               $(DESTDIR)$(VARDIR) \
+               $(TORTURE_PROGS)
 
 installlib: $(INSTALLABLE_SHARED_LIBS) $(STATIC_LIBS) installdirs
        @$(SHELL) $(srcdir)/script/installlib.sh $(DESTDIR)$(LIBDIR) "$(SHLIBEXT)" $(INSTALLABLE_SHARED_LIBS) 
@@ -166,6 +175,7 @@ uninstallmisc:
 uninstallbin:
        @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(SBIN_PROGS)
        @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(BIN_PROGS)
+       @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(TORTUREDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(TORTURE_PROGS)
 
 uninstalllib:
        @$(SHELL) $(srcdir)/script/uninstalllib.sh $(DESTDIR)$(LIBDIR) $(SHARED_LIBS)
@@ -242,7 +252,7 @@ clean:: clean_pch
        @echo Removing hostcc objects
        @-find . -name '*.ho' -exec rm -f '{}' \;
        @echo Removing binaries
-       @-rm -f $(BIN_PROGS) $(SBIN_PROGS) $(BINARIES)
+       @-rm -f $(BIN_PROGS) $(SBIN_PROGS) $(BINARIES) $(TORTURE_PROGS)
        @echo Removing libraries
        @-rm -f $(STATIC_LIBRARIES) $(SHARED_LIBRARIES)
        @-rm -f bin/*.$(SHLIBEXT)*
index 2d3422efc533581b3046c5d6a92399df9421be63..9a8c2677beef725825d843abc436908a9b5d5a57 100755 (executable)
@@ -105,8 +105,9 @@ cat >$CONFFILE<<EOF
        server max protocol = SMB2
        notify:inotify = false
        ldb:nosync = true
+       torture:subunitdir = $SRCDIR/bin/torture
 
-system:anonymous = true
+       system:anonymous = true
 
 [tmp]
        path = $TMPDIR
index 32205c55661b520a607f273c201c357f8f1c9708..1edaa694475f71c6ace09cb06608e167ad7fdca6 100644 (file)
@@ -6,7 +6,8 @@ VERSION = 0.0.1
 PUBLIC_HEADERS = torture.h
 PUBLIC_PROTO_HEADER = proto.h
 OBJ_FILES = \
-               torture.o 
+               torture.o \
+               subunit.o
 PUBLIC_DEPENDENCIES = \
                LIBSAMBA-CONFIG \
                LIBSAMBA-UTIL
index 682fb5541651482b3d562cdbf48671984725438e..a997732c29a3b26f679b3086f46b13bb46b434a5 100644 (file)
@@ -7,7 +7,6 @@ PRIVATE_PROTO_HEADER = \
                proto.h
 OBJ_FILES = \
                iconv.o \
-               ../../lib/talloc/testsuite.o \
                ../../lib/replace/test/testsuite.o \
                ../../lib/replace/test/os2_delete.o \
                ../../lib/crypto/md4test.o \
index 42fe94bc92269a8bb00e2b7a2aea03c2777ca3e2..240897119967676e5f515767d7ad6c1010a984d6 100644 (file)
@@ -52,12 +52,7 @@ NTSTATUS torture_local_init(void)
        struct torture_suite *suite = torture_suite_create(
                                                                                talloc_autofree_context(),
                                                                                "LOCAL");
-       struct torture_suite *talloc_suite = torture_suite_create(
-                                                                                               talloc_autofree_context(),
-                                                                                               "TALLOC");
 
-       torture_local_talloc(talloc_suite);
-       torture_suite_add_suite(suite, talloc_suite);
        torture_suite_add_simple_test(suite, "REPLACE", torture_local_replace);
        torture_suite_add_simple_test(suite, "CRYPTO-SHA1", 
                                                                  torture_local_crypto_sha1);
index 4c2cfa5524b8d84e0752bd644ecfab91cf2917f5..3d7a75f8cf50741b440fd66c0e80bc02120168d9 100644 (file)
@@ -27,6 +27,7 @@
 #include "libcli/libcli.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/events/events.h"
+#include "dynconfig.h"
 
 #include "torture/torture.h"
 #include "build.h"
@@ -326,25 +327,27 @@ static void subunit_test_result (struct torture_context *context,
 {
        switch (res) {
        case TORTURE_OK:
-               printf("success: %s\n", context->active_test->name);
+               printf("success: %s", context->active_test->name);
                break;
        case TORTURE_FAIL:
-               printf("failure: %s [ %s ]\n", context->active_test->name, reason);
+               printf("failure: %s", context->active_test->name);
                break;
        case TORTURE_TODO:
-               printf("todo: %s\n", context->active_test->name);
+               printf("todo: %s", context->active_test->name);
                break;
        case TORTURE_SKIP:
-               printf("skip: %s\n", context->active_test->name);
+               printf("skip: %s", context->active_test->name);
                break;
        }
+       if (reason)
+               printf(" [ %s ]", reason);
+       printf("\n");
 }
 
 static void subunit_comment (struct torture_context *test, 
                                                         const char *comment)
 {
-       /* FIXME Add # sign before each line */
-       printf("%s", comment);
+       fprintf(stderr, "%s", comment);
 }
 
 const static struct torture_ui_ops subunit_ui_ops = {
@@ -438,6 +441,7 @@ const static struct torture_ui_ops quiet_ui_ops = {
        char **argv_new;
        poptContext pc;
        static const char *target = "other";
+       const char **subunit_dir;
        static const char *ui_ops_name = "simple";
        enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
              OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC};
@@ -525,6 +529,17 @@ const static struct torture_ui_ops quiet_ui_ops = {
        }
 
        torture_init();
+
+       subunit_dir = lp_parm_string_list(-1, "torture", "subunitdir", ":");
+       if (subunit_dir == NULL) 
+               torture_subunit_load_testsuites(dyn_TORTUREDIR);
+       else {
+               for (i = 0; subunit_dir[i]; i++)
+                       torture_subunit_load_testsuites(subunit_dir[i]);
+       }
+
+
+
        ldb_global_init();
 
        if (torture_seed == 0) {
diff --git a/source4/torture/subunit.c b/source4/torture/subunit.c
new file mode 100644 (file)
index 0000000..72e3910
--- /dev/null
@@ -0,0 +1,239 @@
+/* 
+   Unix SMB/CIFS implementation.
+   Run subunit tests
+   Copyright (C) Jelmer Vernooij 2006
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/dir.h"
+#include "system/network.h"
+#include "system/filesys.h"
+#include "torture/ui.h"
+#include "torture/proto.h"
+
+NTSTATUS torture_register_subunit_testsuite(const char *path)
+{
+       struct torture_suite *suite = talloc_zero(talloc_autofree_context(), 
+                                                                                         struct torture_suite);
+
+       suite->path = talloc_strdup(suite, path);
+       suite->name = talloc_strdup(suite, strrchr(path, '/')?strrchr(path, '/')+1:
+                                                                          path);
+       suite->description = talloc_asprintf(suite, "Subunit test %s", suite->name);
+
+       return torture_register_suite(suite);
+}
+
+int torture_subunit_load_testsuites(const char *directory)
+{
+       DIR *dir;
+       struct dirent *entry;
+       char *filename;
+       int success = 0;
+
+       dir = opendir(directory);
+       if (dir == NULL)
+               return -1;
+
+       while((entry = readdir(dir))) {
+               if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name))
+                       continue;
+
+               filename = talloc_asprintf(NULL, "%s/%s", directory, entry->d_name);
+       
+               if (NT_STATUS_IS_OK(torture_register_subunit_testsuite(filename))) {
+                       success++;
+               }
+
+               talloc_free(filename);
+       }
+
+       closedir(dir);
+
+       return success;
+}
+
+static pid_t piped_child(char* const command[], int *f_in)
+{
+       pid_t pid;
+       int sock[2];
+
+       if (socketpair(PF_UNIX, SOCK_STREAM, AF_LOCAL, sock) == -1) {
+               DEBUG(0, ("socketpair: %s", strerror(errno)));
+               return -1;
+       }
+
+       *f_in = sock[0];
+
+       fcntl(sock[0], F_SETFL, O_NONBLOCK);
+
+       pid = fork();
+
+       if (pid == -1) {
+               DEBUG(0, ("fork: %s", strerror(errno)));
+               return -1;
+       }
+
+       if (pid == 0) {
+               close(0);
+               close(1);
+               close(2);
+               close(sock[0]);
+
+               dup2(sock[1], 0);
+               dup2(sock[1], 1);
+               execvp(command[0], command);
+               exit(-1);
+       }
+
+       close(sock[1]);
+
+       return pid;
+}
+
+enum subunit_field { SUBUNIT_TEST, SUBUNIT_SUCCESS, SUBUNIT_FAILURE, 
+                                        SUBUNIT_SKIP };
+
+static void run_subunit_message(struct torture_context *context,
+                                                               enum subunit_field field, 
+                                                               const char *name, 
+                                                               const char *comment)
+{
+       struct torture_test test;
+
+       ZERO_STRUCT(test);
+       test.name = name;
+
+       switch (field) {
+       case SUBUNIT_TEST:
+               torture_ui_test_start(context, NULL, &test);
+               break;
+       case SUBUNIT_FAILURE:
+               context->active_test = &test;
+               torture_ui_test_result(context, TORTURE_FAIL, comment);
+               context->active_test = NULL;
+               break;
+       case SUBUNIT_SUCCESS:
+               context->active_test = &test;
+               torture_ui_test_result(context, TORTURE_OK, comment);
+               context->active_test = NULL;
+               break;
+       case SUBUNIT_SKIP:
+               context->active_test = &test;
+               torture_ui_test_result(context, TORTURE_SKIP, comment);
+               context->active_test = NULL;
+               break;
+       }
+}
+
+bool torture_subunit_run_suite(struct torture_context *context, 
+                                          struct torture_suite *suite)
+{
+       static char *command[2];
+       int fd;
+       pid_t pid;
+       size_t size;
+       char *p, *q;
+       char *comment = NULL;
+       char *name = NULL;
+       enum subunit_field lastfield;
+       int status;
+       char buffer[4096];
+       size_t offset = 0;
+
+       command[0] = talloc_strdup(context, suite->path);
+       command[1] = NULL;
+
+       pid = piped_child(command, &fd);
+       if (pid == -1)
+               return false;
+
+       if (waitpid(pid, &status, 0) == -1) {
+               torture_comment(context, "waitpid(%d) failed\n", pid);
+               return false;
+       }
+
+       if (WEXITSTATUS(status) != 0) {
+               torture_comment(context, "failed with status %d\n", WEXITSTATUS(status));
+               return false;
+       }
+
+       while ((size = read(fd, buffer+offset, sizeof(buffer-offset) > 0))) {
+               char *eol;
+               buffer[offset+size] = '\0';
+
+               for (p = buffer; p; p = eol+1) {
+                       eol = strchr(p, '\n');
+                       if (eol == NULL) 
+                               break;
+
+                       *eol = '\0';
+
+                       if (comment != NULL && strcmp(p, "]") == 0) {
+                               run_subunit_message(context, lastfield, name, comment);
+                               talloc_free(name); name = NULL;
+                               talloc_free(comment); comment = NULL;
+                       } else if (comment != NULL) {
+                               comment = talloc_append_string(context, comment, p);
+                       } else {
+                               q = strchr(p, ':');
+                               if (q == NULL) {
+                                       torture_comment(context, "Invalid line `%s'\n", p);
+                                       continue;
+                               }
+
+                               *q = '\0';
+                               if (!strcmp(p, "test")) {
+                                       lastfield = SUBUNIT_TEST;
+                               } else if (!strcmp(p, "failure")) {
+                                       lastfield = SUBUNIT_FAILURE;
+                               } else if (!strcmp(p, "success")) {
+                                       lastfield = SUBUNIT_SUCCESS;
+                               } else if (!strcmp(p, "skip")) {
+                                       lastfield = SUBUNIT_SKIP;
+                               } else {
+                                       torture_comment(context, "Invalid subunit field `%s'\n", p);
+                                       continue;
+                               }
+
+                               p = q+1;
+
+                               name = talloc_strdup(context, p+1);
+
+                               q = strrchr(p, '[');
+                               if (q != NULL) {
+                                       *q = '\0';
+                                       comment = talloc_strdup(context, "");
+                               } else {
+                                       run_subunit_message(context, lastfield, name, NULL);
+                                       talloc_free(name);
+                                       name = NULL;
+                               }
+                       }
+               }
+
+               offset += size-(p-buffer);
+               memcpy(buffer, p, offset);
+       }
+
+       if (name != NULL) {
+               torture_comment(context, "Interrupted during %s\n", name);
+               return false;
+       }
+
+       return true;
+}
index c105f4ec9d3c68564caa1d72518a16da1d43e450..32b632a3e80c22032218300558edb320c4e3525c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 #include "torture/ui.h"
+#include "torture/torture.h"
 #include "lib/util/dlinklist.h"
 
 void torture_comment(struct torture_context *context, 
@@ -67,7 +68,7 @@ void _torture_skip_ext(struct torture_context *context,
 
 struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name)
 {
-       struct torture_suite *suite = talloc(ctx, struct torture_suite);
+       struct torture_suite *suite = talloc_zero(ctx, struct torture_suite);
 
        suite->name = talloc_strdup(suite, name);
        suite->testcases = NULL;
@@ -146,6 +147,9 @@ BOOL torture_run_suite(struct torture_context *context,
        if (context->ui_ops->suite_start)
                context->ui_ops->suite_start(context, suite);
 
+       if (suite->path)
+               torture_subunit_run_suite(context, suite);
+
        for (tcase = suite->testcases; tcase; tcase = tcase->next) {
                ret &= torture_run_tcase(context, tcase);
        }
@@ -162,6 +166,30 @@ BOOL torture_run_suite(struct torture_context *context,
        return ret;
 }
 
+void torture_ui_test_start(struct torture_context *context,
+                                                          struct torture_tcase *tcase,
+                                                          struct torture_test *test)
+{
+       if (context->ui_ops->test_start)
+               context->ui_ops->test_start(context, tcase, test);
+}
+
+void torture_ui_test_result(struct torture_context *context,
+                                                               enum torture_result result,
+                                                               const char *comment)
+{
+       if (context->ui_ops->test_result)
+               context->ui_ops->test_result(context, result, comment);
+
+
+       switch (result) {
+               case TORTURE_SKIP: context->success++; break;
+               case TORTURE_FAIL: context->failed++; break;
+               case TORTURE_TODO: context->todo++; break;
+               case TORTURE_OK: context->success++; break;
+       }
+}
+
 static BOOL internal_torture_run_test(struct torture_context *context, 
                                          struct torture_tcase *tcase,
                                          struct torture_test *test,
@@ -182,8 +210,7 @@ static BOOL internal_torture_run_test(struct torture_context *context,
        context->active_tcase = tcase;
        context->active_test = test;
 
-       if (context->ui_ops->test_start)
-               context->ui_ops->test_start(context, tcase, test);
+       torture_ui_test_start(context, tcase, test);
 
        context->last_reason = NULL;
        context->last_result = TORTURE_OK;
@@ -195,19 +222,8 @@ static BOOL internal_torture_run_test(struct torture_context *context,
                context->last_result = TORTURE_FAIL;
        }
 
-       if (context->ui_ops->test_result)
-               context->ui_ops->test_result(context, 
-                                                                        context->last_result, 
-                                                                        context->last_reason);
-
-
-       switch (context->last_result) {
-               case TORTURE_SKIP: context->success++; break;
-               case TORTURE_FAIL: context->failed++; break;
-               case TORTURE_TODO: context->todo++; break;
-               case TORTURE_OK: context->success++; break;
-       }
-
+       torture_ui_test_result(context, context->last_result, context->last_reason);
+       
        talloc_free(context->last_reason);
 
        context->active_test = NULL;
index 36457e6a84d9545a49a7c1c64ae110eda085b5c0..b4e3585031851e05bb4b4f2e7785b845cca44069 100644 (file)
@@ -52,6 +52,14 @@ struct torture_ui_ops
                                                 enum torture_result, const char *reason);
 };
 
+void torture_ui_test_start(struct torture_context *context,
+                                                          struct torture_tcase *tcase,
+                                                          struct torture_test *test);
+
+void torture_ui_test_result(struct torture_context *context,
+                                                               enum torture_result result,
+                                                               const char *comment);
+
 /*
  * Holds information about a specific run of the testsuite. 
  * The data in this structure should be considered private to 
@@ -121,6 +129,7 @@ struct torture_tcase {
 struct torture_suite
 {
        const char *name;
+       const char *path; /* Used by subunit tests only */
        const char *description;
        struct torture_tcase *testcases;
        struct torture_suite *children;