summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2006-10-16 20:05:19 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:21:13 -0500
commit52e3f69a36b6ba6a589a8f768fbee77ee06b281c (patch)
tree4f77d34f1c12b2fb77f672ed2d989f7ad88d7ca6 /source4
parent3478bf1c238eaa82d9383f18dcb7d802aed06cd0 (diff)
downloadsamba-52e3f69a36b6ba6a589a8f768fbee77ee06b281c.tar.gz
samba-52e3f69a36b6ba6a589a8f768fbee77ee06b281c.tar.bz2
samba-52e3f69a36b6ba6a589a8f768fbee77ee06b281c.zip
r19343: Add support for external scripts/binaries that write results using the
'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)
Diffstat (limited to 'source4')
-rw-r--r--source4/build/smb_build/makefile.pm19
-rw-r--r--source4/dynconfig.c3
-rw-r--r--source4/dynconfig.h1
-rw-r--r--source4/dynconfig.mk1
-rw-r--r--source4/lib/talloc/config.mk4
-rw-r--r--source4/lib/talloc/testsuite.c436
-rw-r--r--source4/main.mk12
-rwxr-xr-xsource4/script/tests/mktestsetup.sh3
-rw-r--r--source4/torture/config.mk3
-rw-r--r--source4/torture/local/config.mk1
-rw-r--r--source4/torture/local/local.c5
-rw-r--r--source4/torture/smbtorture.c27
-rw-r--r--source4/torture/subunit.c239
-rw-r--r--source4/torture/ui.c48
-rw-r--r--source4/torture/ui.h9
15 files changed, 589 insertions, 222 deletions
diff --git a/source4/build/smb_build/makefile.pm b/source4/build/smb_build/makefile.pm
index 97cfd7770f..0d448773a6 100644
--- a/source4/build/smb_build/makefile.pm
+++ b/source4/build/smb_build/makefile.pm
@@ -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");
diff --git a/source4/dynconfig.c b/source4/dynconfig.c
index 41728af57d..5b1074382c 100644
--- a/source4/dynconfig.c
+++ b/source4/dynconfig.c
@@ -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;
diff --git a/source4/dynconfig.h b/source4/dynconfig.h
index b1a7fff191..312283c5fb 100644
--- a/source4/dynconfig.h
+++ b/source4/dynconfig.h
@@ -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;
diff --git a/source4/dynconfig.mk b/source4/dynconfig.mk
index 2743bc2b29..180333693d 100644
--- a/source4/dynconfig.mk
+++ b/source4/dynconfig.mk
@@ -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
diff --git a/source4/lib/talloc/config.mk b/source4/lib/talloc/config.mk
index 3a8a22aa57..19059ca4dc 100644
--- a/source4/lib/talloc/config.mk
+++ b/source4/lib/talloc/config.mk
@@ -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
diff --git a/source4/lib/talloc/testsuite.c b/source4/lib/talloc/testsuite.c
index f2e61157e4..14222c75af 100644
--- a/source4/lib/talloc/testsuite.c
+++ b/source4/lib/talloc/testsuite.c
@@ -27,17 +27,6 @@
#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
diff --git a/source4/main.mk b/source4/main.mk
index 7151ebb70b..42c471da80 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -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)*
diff --git a/source4/script/tests/mktestsetup.sh b/source4/script/tests/mktestsetup.sh
index 2d3422efc5..9a8c2677be 100755
--- a/source4/script/tests/mktestsetup.sh
+++ b/source4/script/tests/mktestsetup.sh
@@ -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
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 32205c5566..1edaa69447 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -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
diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk
index 682fb55416..a997732c29 100644
--- a/source4/torture/local/config.mk
+++ b/source4/torture/local/config.mk
@@ -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 \
diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c
index 42fe94bc92..2408971199 100644
--- a/source4/torture/local/local.c
+++ b/source4/torture/local/local.c
@@ -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);
diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c
index 4c2cfa5524..3d7a75f8cf 100644
--- a/source4/torture/smbtorture.c
+++ b/source4/torture/smbtorture.c
@@ -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
index 0000000000..72e39101e2
--- /dev/null
+++ b/source4/torture/subunit.c
@@ -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;
+}
diff --git a/source4/torture/ui.c b/source4/torture/ui.c
index c105f4ec9d..32b632a3e8 100644
--- a/source4/torture/ui.c
+++ b/source4/torture/ui.c
@@ -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;
diff --git a/source4/torture/ui.h b/source4/torture/ui.h
index 36457e6a84..b4e3585031 100644
--- a/source4/torture/ui.h
+++ b/source4/torture/ui.h
@@ -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;