From 582d46ec42144bddccddacadd52a0256f58cb453 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Jun 2006 22:06:09 +0000 Subject: r16304: Improve testing UI API. This now allows registering the full test suite tree, looks a bit more like other unit testing API's, fixes some memory responsibility issues, introduces testcases, and removes the need for tests to call torture_ok(). (This used to be commit 0445b1a56a02552f895f400960b9ced39244a144) --- source4/torture/auth/ntlmssp.c | 24 ++-- source4/torture/auth/pac.c | 56 ++------ source4/torture/local/binding_string.c | 48 ++++--- source4/torture/local/event.c | 36 +++--- source4/torture/local/idtree.c | 14 +- source4/torture/local/irpc.c | 99 +++++++------- source4/torture/local/messaging.c | 42 +++--- source4/torture/local/ndr.c | 17 ++- source4/torture/local/registry.c | 40 ++++-- source4/torture/local/resolve.c | 19 ++- source4/torture/rpc/samr.c | 36 ++---- source4/torture/smbtorture.c | 61 +++++---- source4/torture/torture.c | 2 +- source4/torture/ui.c | 229 +++++++++++++++++++++++++-------- source4/torture/ui.h | 100 ++++++++++---- 15 files changed, 499 insertions(+), 324 deletions(-) (limited to 'source4/torture') diff --git a/source4/torture/auth/ntlmssp.c b/source4/torture/auth/ntlmssp.c index 072d9a3b27..5c75a5b028 100644 --- a/source4/torture/auth/ntlmssp.c +++ b/source4/torture/auth/ntlmssp.c @@ -25,18 +25,16 @@ #include "torture/torture.h" #include "torture/ui.h" -BOOL torture_ntlmssp_self_check(struct torture_context *torture) +static BOOL torture_ntlmssp_self_check(struct torture_context *test, + const void *_data) { struct gensec_security *gensec_security; struct gensec_ntlmssp_state *gensec_ntlmssp_state; DATA_BLOB data; DATA_BLOB sig, expected_sig; - NTSTATUS status; - struct torture_test *test = torture_test(torture, "ntlmssp_self_check", - "NTLMSSP Self Check"); torture_assert_ntstatus_ok(test, - gensec_client_start(torture, &gensec_security, NULL), + gensec_client_start(test, &gensec_security, NULL), "gensec client start"); gensec_set_credentials(gensec_security, cmdline_credentials); @@ -73,7 +71,6 @@ BOOL torture_ntlmssp_self_check(struct torture_context *torture) if (sig.length != expected_sig.length) { torture_fail(test, "Wrong sig length: %d != %d", (int)sig.length, (int)expected_sig.length); - talloc_free(test); return False; } @@ -83,7 +80,7 @@ BOOL torture_ntlmssp_self_check(struct torture_context *torture) talloc_free(gensec_security); torture_assert_ntstatus_ok(test, - gensec_client_start(torture, &gensec_security, NULL), + gensec_client_start(test, &gensec_security, NULL), "Failed to start GENSEC for NTLMSSP"); gensec_set_credentials(gensec_security, cmdline_credentials); @@ -120,7 +117,6 @@ BOOL torture_ntlmssp_self_check(struct torture_context *torture) if (sig.length != expected_sig.length) { torture_fail(test, "Wrong sig length: %d != %d", (int)sig.length, (int)expected_sig.length); - talloc_free(test); return False; } @@ -129,8 +125,16 @@ BOOL torture_ntlmssp_self_check(struct torture_context *torture) "data mismatch"); talloc_free(gensec_security); - torture_ok(test); - talloc_free(test); return True; } + +BOOL torture_ntlmssp(struct torture_context *torture) +{ + struct torture_suite *suite = torture_suite_create(torture, "AUTH-NTLMSSP"); + + torture_suite_add_simple_tcase(suite, "NTLMSSP self check", + torture_ntlmssp_self_check, NULL); + + return torture_run_suite(torture, suite); +} diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c index 313e0f0d3d..316a67acb0 100644 --- a/source4/torture/auth/pac.c +++ b/source4/torture/auth/pac.c @@ -31,7 +31,8 @@ #include "torture/torture.h" #include "torture/ui.h" -static BOOL torture_pac_self_check(struct torture_context *torture) +static BOOL torture_pac_self_check(struct torture_context *test, + const void *_data) { NTSTATUS nt_status; DATA_BLOB tmp_blob; @@ -52,9 +53,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) struct auth_serversupplied_info *server_info; struct auth_serversupplied_info *server_info_out; - struct torture_test *test = torture_test(torture, "pac-selfcheck", - "PAC Selfcheck"); - krb5_principal client_principal; time_t logon_time = time(NULL); @@ -73,7 +71,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, test)); - talloc_free(test); return False; } @@ -88,7 +85,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -100,7 +96,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) &server_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); - talloc_free(test); return False; } @@ -112,7 +107,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) &server_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &krbtgt_keyblock); - talloc_free(test); return False; } @@ -136,7 +130,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); - talloc_free(test); return False; } @@ -162,7 +155,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) krb5_free_principal(smb_krb5_context->krb5_context, client_principal); - talloc_free(test); return False; } @@ -188,7 +180,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) krb5_free_principal(smb_krb5_context->krb5_context, client_principal); - talloc_free(test); return False; } @@ -209,7 +200,6 @@ static BOOL torture_pac_self_check(struct torture_context *torture) "(self test) PAC decoding (make server info) failed: %s", nt_errstr(nt_status)); - talloc_free(test); return False; } @@ -219,12 +209,9 @@ static BOOL torture_pac_self_check(struct torture_context *torture) "(self test) PAC Decode resulted in *different* domain SID: %s != %s", dom_sid_string(test, server_info->account_sid), dom_sid_string(test, server_info_out->account_sid)); - talloc_free(test); return False; } - torture_ok(test); - talloc_free(test); return True; } @@ -276,11 +263,10 @@ static const uint8_t saved_pac[] = { }; /* Check with a known 'well formed' PAC, from my test server */ -static BOOL torture_pac_saved_check(struct torture_context *torture) +static BOOL torture_pac_saved_check(struct torture_context *test, + const void *_data) { NTSTATUS nt_status; - struct torture_test *test = torture_test(torture, "pac-saved-check", - "PAC saved check"); DATA_BLOB tmp_blob, validate_blob; struct PAC_DATA *pac_data, pac_data2; struct PAC_LOGON_INFO *logon_info; @@ -322,14 +308,12 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krbtgt_bytes = smbpasswd_gethexpwd(test, pac_kdc_key); if (!krbtgt_bytes) { torture_fail(test, "(saved test) Could not interpret krbtgt key"); - talloc_free(test); return False; } krbsrv_bytes = smbpasswd_gethexpwd(test, pac_member_key); if (!krbsrv_bytes) { torture_fail(test, "(saved test) Could not interpret krbsrv key"); - talloc_free(test); return False; } @@ -343,7 +327,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, test)); - talloc_free(test); return False; } @@ -359,7 +342,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -397,7 +379,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -418,7 +399,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); - talloc_free(test); return False; } @@ -441,7 +421,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) "(saved test) PAC decoding (for logon info) failed: %s", nt_errstr(nt_status)); - talloc_free(test); return False; } @@ -461,7 +440,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) "(saved test) PAC decoding (make server info) failed: %s", nt_errstr(nt_status)); - talloc_free(test); return False; } @@ -479,7 +457,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) "(saved test) PAC Decode resulted in *different* domain SID: %s != %s", "S-1-5-21-3048156945-3961193616-3706469200-1005", dom_sid_string(test, server_info_out->account_sid)); - talloc_free(test); return False; } @@ -498,7 +475,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(test, "(saved test) PAC push failed"); - talloc_free(test); return False; } @@ -518,7 +494,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) torture_fail(test, "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]", (unsigned)tmp_blob.length, (unsigned)validate_blob.length); - talloc_free(test); return False; } @@ -535,7 +510,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) DEBUG(0, ("validate_blob:\n")); dump_data(0, validate_blob.data, validate_blob.length); - talloc_free(test); return False; } @@ -555,7 +529,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krb5_free_principal(smb_krb5_context->krb5_context, client_principal); torture_fail(test, "(saved test) regnerated PAC create failed"); - talloc_free(test); return False; } @@ -582,7 +555,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) torture_fail(test, "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]", (unsigned)tmp_blob.length, (unsigned)validate_blob.length); - talloc_free(test); return False; } @@ -607,7 +579,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) DEBUG(0, ("validate_blob:\n")); dump_data(0, validate_blob.data, validate_blob.length); - talloc_free(test); return False; } @@ -627,7 +598,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); - talloc_free(test); return False; } @@ -644,7 +614,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -662,7 +631,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -683,7 +651,6 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) &krbtgt_keyblock); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - talloc_free(test); return False; } @@ -692,15 +659,18 @@ static BOOL torture_pac_saved_check(struct torture_context *torture) krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); - torture_ok(test); - talloc_free(test); return True; } BOOL torture_pac(struct torture_context *torture) { - BOOL ret = True; - ret &= torture_pac_self_check(torture); - ret &= torture_pac_saved_check(torture); - return ret; + struct torture_suite *suite = torture_suite_create(torture, "AUTH-PAC"); + + torture_suite_add_simple_tcase(suite, "self check", + torture_pac_self_check, NULL); + + torture_suite_add_simple_tcase(suite, "saved check", + torture_pac_saved_check, NULL); + + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/binding_string.c b/source4/torture/local/binding_string.c index 4405bf0256..a7b6cd14b4 100644 --- a/source4/torture/local/binding_string.c +++ b/source4/torture/local/binding_string.c @@ -26,38 +26,37 @@ #include "torture/torture.h" #include "torture/ui.h" -static BOOL test_BindingString(struct torture_context *torture, const char *binding) +static BOOL test_BindingString(struct torture_context *torture, + const void *_binding) { + const char *binding = _binding; struct dcerpc_binding *b, *b2; const char *s, *s2; struct epm_tower tower; - NTSTATUS status; - struct torture_test *test = torture_test(torture, binding, binding); /* Parse */ - torture_assert_ntstatus_ok(test, - dcerpc_parse_binding(test, binding, &b), + torture_assert_ntstatus_ok(torture, + dcerpc_parse_binding(torture, binding, &b), "Error parsing binding string"); - s = dcerpc_binding_string(test, b); + s = dcerpc_binding_string(torture, b); if (!s) { - torture_fail(test, "Error converting binding back to string"); - talloc_free(test); + torture_fail(torture, "Error converting binding back to string"); return False; } - torture_assert_casestr_equal(test, binding, s, + torture_assert_casestr_equal(torture, binding, s, "Mismatch while comparing original and regenerated binding strings"); /* Generate protocol towers */ - torture_assert_ntstatus_ok(test, - dcerpc_binding_build_tower(test, b, &tower), + torture_assert_ntstatus_ok(torture, + dcerpc_binding_build_tower(torture, b, &tower), "Error generating protocol tower"); /* Convert back to binding and then back to string and compare */ - torture_assert_ntstatus_ok(test, - dcerpc_binding_from_tower(test, &tower, &b2), + torture_assert_ntstatus_ok(torture, + dcerpc_binding_from_tower(torture, &tower, &b2), "Error generating binding from tower for original binding"); /* Compare to a stripped down version of the binding string because @@ -66,29 +65,24 @@ static BOOL test_BindingString(struct torture_context *torture, const char *bind b->flags = 0; - s = dcerpc_binding_string(test, b); + s = dcerpc_binding_string(torture, b); if (!s) { - torture_fail(test, "Error converting binding back to string for (stripped down)"); - talloc_free(test); + torture_fail(torture, "Error converting binding back to string for (stripped down)"); return False; } - s2 = dcerpc_binding_string(test, b2); + s2 = dcerpc_binding_string(torture, b2); if (!s) { - torture_fail(test, "Error converting binding back to string"); - talloc_free(test); + torture_fail(torture, "Error converting binding back to string"); return False; } if (is_ipaddress(b->host) && strcasecmp(s, s2) != 0) { - torture_fail(test, "Mismatch while comparing original and from protocol tower generated binding strings: '%s' <> '%s'\n", s, s2); - talloc_free(test); + torture_fail(torture, "Mismatch while comparing original and from protocol tower generated binding strings: '%s' <> '%s'\n", s, s2); return False; } - torture_ok(test); - talloc_free(test); return True; } @@ -119,12 +113,14 @@ static const char *test_strings[] = { BOOL torture_local_binding_string(struct torture_context *torture) { - BOOL ret = True; int i; + struct torture_suite *suite = torture_suite_create(torture, + "LOCAL-BINDING"); for (i = 0; i < ARRAY_SIZE(test_strings); i++) { - ret &= test_BindingString(torture, test_strings[i]); + torture_suite_add_simple_tcase(suite, test_strings[i], + test_BindingString, test_strings[i]); } - return ret; + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/event.c b/source4/torture/local/event.c index 79f5413595..d886519220 100644 --- a/source4/torture/local/event.c +++ b/source4/torture/local/event.c @@ -34,7 +34,7 @@ static int write_fd, read_fd; static struct fd_event *fde; static int te_count; static int fde_count; -static struct torture_test *test; +static struct torture_context *test; static void fde_handler(struct event_context *ev_ctx, struct fd_event *f, uint16_t flags, void *private) @@ -75,11 +75,17 @@ static void timed_handler(struct event_context *ev_ctx, struct timed_event *te, event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(0,500), timed_handler, private); } -static BOOL test_event_context(struct torture_context *torture, struct event_context *ev_ctx, const char *comment) +static BOOL test_event_context(struct torture_context *torture, const void *_data) { + struct event_context *ev_ctx; int fd[2] = { -1, -1 }; + BOOL try_epoll = (BOOL)_data; + + ev_ctx = event_context_init_ops(torture, + event_standard_get_ops(), + &try_epoll); - test = torture_test(torture, comment, comment); + test = torture; /* reset globals */ write_fd = -1; @@ -101,30 +107,24 @@ static BOOL test_event_context(struct torture_context *torture, struct event_con close(read_fd); close(write_fd); + + talloc_free(ev_ctx); - torture_ok(test); - talloc_free(test); return True; } BOOL torture_local_event(struct torture_context *torture) { - struct event_context *ev_ctx; - BOOL try_epoll; BOOL retv = True; + struct torture_suite *suite = torture_suite_create(torture, "LOCAL-EVENT"); - try_epoll = False; - ev_ctx = event_context_init_ops(torture, event_standard_get_ops(), - &try_epoll); - retv &= test_event_context(torture, ev_ctx, "standard with select"); - talloc_free(ev_ctx); + torture_suite_add_simple_tcase(suite, "standard with select", + test_event_context, + (void *)False); - try_epoll = True; - ev_ctx = event_context_init_ops(torture, event_standard_get_ops(), - &try_epoll); - retv &= test_event_context(torture, ev_ctx, - "standard try epool (or select)"); - talloc_free(ev_ctx); + torture_suite_add_simple_tcase(suite, "standard try epoll (or select)", + test_event_context, + (void *)True); return retv; } diff --git a/source4/torture/local/idtree.c b/source4/torture/local/idtree.c index 8d776219db..a81eddedc3 100644 --- a/source4/torture/local/idtree.c +++ b/source4/torture/local/idtree.c @@ -24,7 +24,8 @@ #include "torture/torture.h" #include "torture/ui.h" -BOOL torture_local_idtree(struct torture_context *torture) +static BOOL torture_local_idtree_simple(struct torture_context *test, + const void *_data) { struct idr_context *idr; int i; @@ -32,7 +33,6 @@ BOOL torture_local_idtree(struct torture_context *torture) int *present; extern int torture_numops; int n = torture_numops; - struct torture_test *test = torture_test(torture, "idtree", "idtree"); idr = idr_init(test); @@ -90,7 +90,13 @@ BOOL torture_local_idtree(struct torture_context *torture) torture_comment(test, "cleaned up"); - talloc_free(test); + return True; +} - return torture_result(torture); +BOOL torture_local_idtree(struct torture_context *torture) +{ + struct torture_suite *suite = torture_suite_create(torture, "LOCAL-IDTREE"); + torture_suite_add_simple_tcase(suite, "idtree", torture_local_idtree_simple, + NULL); + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/irpc.c b/source4/torture/local/irpc.c index 5fbf76beb2..b90f91d19b 100644 --- a/source4/torture/local/irpc.c +++ b/source4/torture/local/irpc.c @@ -31,6 +31,12 @@ const uint32_t MSG_ID1 = 1, MSG_ID2 = 2; static BOOL test_debug; +struct irpc_test_data +{ + struct messaging_context *msg_ctx1, *msg_ctx2; + struct event_context *ev; +}; + /* serve up AddOne over the irpc system */ @@ -75,22 +81,19 @@ static NTSTATUS irpc_EchoData(struct irpc_message *irpc, struct echo_EchoData *r /* test a addone call over the internal messaging system */ -static BOOL test_addone(struct torture_test *parent_test, - struct messaging_context *msg_ctx1, - struct messaging_context *msg_ctx2, - uint32_t value) +static BOOL test_addone(struct torture_context *test, const void *_data, + const void *_value) { struct echo_AddOne r; NTSTATUS status; - - struct torture_test *test = torture_subtest(parent_test, "test_addone", - "test_addone"); + const struct irpc_test_data *data = _data; + uint32_t value = (uint32_t)value; /* make the call */ r.in.in_data = value; test_debug = True; - status = IRPC_CALL(msg_ctx1, MSG_ID2, rpcecho, ECHO_ADDONE, &r, test); + status = IRPC_CALL(data->msg_ctx1, MSG_ID2, rpcecho, ECHO_ADDONE, &r, test); test_debug = False; torture_assert_ntstatus_ok(test, status, "AddOne failed"); @@ -107,21 +110,19 @@ static BOOL test_addone(struct torture_test *parent_test, /* test a echodata call over the internal messaging system */ -static BOOL test_echodata(struct torture_test *parent_test, - struct messaging_context *msg_ctx1, - struct messaging_context *msg_ctx2) +static BOOL test_echodata(struct torture_context *test, + const void *_data, const void *_data2) { struct echo_EchoData r; NTSTATUS status; - - struct torture_test *test = torture_subtest(parent_test, "test_echodata", - "test_echodata"); + const struct irpc_test_data *data = _data; /* make the call */ r.in.in_data = (unsigned char *)talloc_strdup(test, "0123456789"); r.in.len = strlen((char *)r.in.in_data); - status = IRPC_CALL(msg_ctx1, MSG_ID2, rpcecho, ECHO_ECHODATA, &r, test); + status = IRPC_CALL(data->msg_ctx1, MSG_ID2, rpcecho, ECHO_ECHODATA, &r, + test); torture_assert_ntstatus_ok(test, status, "EchoData failed"); /* check the answer */ @@ -159,20 +160,17 @@ static void irpc_callback(struct irpc_request *irpc) /* test echo speed */ -static BOOL test_speed(struct torture_test *parent_test, - struct messaging_context *msg_ctx1, - struct messaging_context *msg_ctx2, - struct event_context *ev) +static BOOL test_speed(struct torture_context *test, + const void *_data, + const void *_data2) { int ping_count = 0; int pong_count = 0; + const struct irpc_test_data *data = _data; struct timeval tv; struct echo_AddOne r; int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); - struct torture_test *test = torture_subtest(parent_test, "test_speed", - "test_speed"); - tv = timeval_current(); r.in.in_data = 0; @@ -181,7 +179,8 @@ static BOOL test_speed(struct torture_test *parent_test, while (timeval_elapsed(&tv) < timelimit) { struct irpc_request *irpc; - irpc = IRPC_CALL_SEND(msg_ctx1, MSG_ID2, rpcecho, ECHO_ADDONE, &r, test); + irpc = IRPC_CALL_SEND(data->msg_ctx1, MSG_ID2, rpcecho, ECHO_ADDONE, + &r, test); torture_assert(test, irpc != NULL, "AddOne send failed"); irpc->async.fn = irpc_callback; @@ -190,14 +189,14 @@ static BOOL test_speed(struct torture_test *parent_test, ping_count++; while (ping_count > pong_count + 20) { - event_loop_once(ev); + event_loop_once(data->ev); } } torture_comment(test, "waiting for %d remaining replies (done %d)", ping_count - pong_count, pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { - event_loop_once(ev); + event_loop_once(data->ev); } if (ping_count != pong_count) { @@ -212,39 +211,49 @@ static BOOL test_speed(struct torture_test *parent_test, } -BOOL torture_local_irpc(struct torture_context *torture) +static BOOL irpc_setup(struct torture_context *test, void **_data) { - struct torture_test *test = torture_test(torture, "torture_local_irpc", ""); - struct messaging_context *msg_ctx1, *msg_ctx2; - struct event_context *ev; + struct irpc_test_data *data; + + *_data = data = talloc(test, struct irpc_test_data); lp_set_cmdline("lock dir", "lockdir.tmp"); - ev = event_context_init(test); + data->ev = event_context_init(test); torture_assert(test, - msg_ctx1 = messaging_init(test, MSG_ID1, ev), + data->msg_ctx1 = messaging_init(test, MSG_ID1, data->ev), "Failed to init first messaging context"); torture_assert(test, - msg_ctx2 = messaging_init(test, MSG_ID2, ev), + data->msg_ctx2 = messaging_init(test, MSG_ID2, data->ev), "Failed to init second messaging context"); /* register the server side function */ - IRPC_REGISTER(msg_ctx1, rpcecho, ECHO_ADDONE, irpc_AddOne, NULL); - IRPC_REGISTER(msg_ctx2, rpcecho, ECHO_ADDONE, irpc_AddOne, NULL); + IRPC_REGISTER(data->msg_ctx1, rpcecho, ECHO_ADDONE, irpc_AddOne, NULL); + IRPC_REGISTER(data->msg_ctx2, rpcecho, ECHO_ADDONE, irpc_AddOne, NULL); - IRPC_REGISTER(msg_ctx1, rpcecho, ECHO_ECHODATA, irpc_EchoData, NULL); - IRPC_REGISTER(msg_ctx2, rpcecho, ECHO_ECHODATA, irpc_EchoData, NULL); + IRPC_REGISTER(data->msg_ctx1, rpcecho, ECHO_ECHODATA, irpc_EchoData, NULL); + IRPC_REGISTER(data->msg_ctx2, rpcecho, ECHO_ECHODATA, irpc_EchoData, NULL); - test_addone(test, msg_ctx1, msg_ctx2, 0); - test_addone(test, msg_ctx1, msg_ctx2, 0x7FFFFFFE); - test_addone(test, msg_ctx1, msg_ctx2, 0xFFFFFFFE); - test_addone(test, msg_ctx1, msg_ctx2, 0xFFFFFFFF); - test_addone(test, msg_ctx1, msg_ctx2, random() & 0xFFFFFFFF); - test_echodata(test, msg_ctx1, msg_ctx2); - test_speed(test, msg_ctx1, msg_ctx2, ev); + return True; +} - talloc_free(test); +BOOL torture_local_irpc(struct torture_context *torture) +{ + struct torture_suite *suite = torture_suite_create(torture, "LOCAL-IRPC"); + struct torture_tcase *tcase = torture_suite_add_tcase(suite, "irpc"); + int i; + uint32_t values[] = {0, 0x7FFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, + random() & 0xFFFFFFFF}; + + tcase->setup = irpc_setup; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + torture_tcase_add_test(tcase, "addone", test_addone, (void *)values[i]); + } + + torture_tcase_add_test(tcase, "echodata", test_echodata, NULL); + torture_tcase_add_test(tcase, "speed", test_speed, NULL); - return torture_result(torture); + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/messaging.c b/source4/torture/local/messaging.c index 572ace0448..38d3056f6e 100644 --- a/source4/torture/local/messaging.c +++ b/source4/torture/local/messaging.c @@ -56,7 +56,7 @@ static void exit_message(struct messaging_context *msg, void *private, /* test ping speed */ -static void test_ping_speed(struct torture_context *torture) +static BOOL test_ping_speed(struct torture_context *torture, const void *_data) { struct event_context *ev; struct messaging_context *msg_client_ctx; @@ -66,36 +66,33 @@ static void test_ping_speed(struct torture_context *torture) struct timeval tv; int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); uint32_t msg_ping, msg_exit; - struct torture_test *test = torture_test(torture, "ping_speed", "ping speed"); lp_set_cmdline("lock dir", "lockdir.tmp"); - ev = event_context_init(test); + ev = event_context_init(torture); - msg_server_ctx = messaging_init(test, 1, ev); + msg_server_ctx = messaging_init(torture, 1, ev); if (!msg_server_ctx) { - torture_fail(test, "Failed to init ping messaging context"); - talloc_free(test); - return; + torture_fail(torture, "Failed to init ping messaging context"); + return False; } messaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping); - messaging_register_tmp(msg_server_ctx, test, exit_message, &msg_exit); + messaging_register_tmp(msg_server_ctx, torture, exit_message, &msg_exit); - msg_client_ctx = messaging_init(test, 2, ev); + msg_client_ctx = messaging_init(torture, 2, ev); if (!msg_client_ctx) { - torture_fail(test, "msg_client_ctx messaging_init() failed"); - talloc_free(test); - return; + torture_fail(torture, "msg_client_ctx messaging_init() failed"); + return False; } messaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong); tv = timeval_current(); - torture_comment(test, "Sending pings for %d seconds", timelimit); + torture_comment(torture, "Sending pings for %d seconds", timelimit); while (timeval_elapsed(&tv) < timelimit) { DATA_BLOB data; NTSTATUS status1, status2; @@ -107,13 +104,13 @@ static void test_ping_speed(struct torture_context *torture) status2 = messaging_send(msg_client_ctx, 1, msg_ping, NULL); if (!NT_STATUS_IS_OK(status1)) { - torture_fail(test, "msg1 failed - %s", nt_errstr(status1)); + torture_fail(torture, "msg1 failed - %s", nt_errstr(status1)); } else { ping_count++; } if (!NT_STATUS_IS_OK(status2)) { - torture_fail(test, "msg2 failed - %s", nt_errstr(status2)); + torture_fail(torture, "msg2 failed - %s", nt_errstr(status2)); } else { ping_count++; } @@ -123,31 +120,34 @@ static void test_ping_speed(struct torture_context *torture) } } - torture_comment(test, "waiting for %d remaining replies (done %d)", + torture_comment(torture, "waiting for %d remaining replies (done %d)", ping_count - pong_count, pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { event_loop_once(ev); } - torture_comment(test, "sending exit"); + torture_comment(torture, "sending exit"); messaging_send(msg_client_ctx, 1, msg_exit, NULL); if (ping_count != pong_count) { - torture_fail(test, "ping test failed! received %d, sent %d", + torture_fail(torture, "ping test failed! received %d, sent %d", pong_count, ping_count); } - torture_comment(test, "ping rate of %.0f messages/sec", + torture_comment(torture, "ping rate of %.0f messages/sec", (ping_count+pong_count)/timeval_elapsed(&tv)); talloc_free(msg_client_ctx); talloc_free(msg_server_ctx); talloc_free(ev); + + return True; } BOOL torture_local_messaging(struct torture_context *torture) { - test_ping_speed(torture); - return torture_result(torture); + struct torture_suite *s = torture_suite_create(torture, "LOCAL-MESSAGING"); + torture_suite_add_simple_tcase(s, "ping_speed", test_ping_speed, NULL); + return torture_run_suite(torture, s); } diff --git a/source4/torture/local/ndr.c b/source4/torture/local/ndr.c index 9950531a26..4f743b5229 100644 --- a/source4/torture/local/ndr.c +++ b/source4/torture/local/ndr.c @@ -24,12 +24,11 @@ #include "torture/ui.h" #include "librpc/ndr/libndr.h" -static BOOL test_check_string_terminator(struct torture_context *torture) +static BOOL test_check_string_terminator(struct torture_context *test, + const void *_data) { struct ndr_pull *ndr; DATA_BLOB blob; - struct torture_test *test = torture_test(torture, "string_terminator", - "string terminator"); /* Simple test */ blob = strhex_to_data_blob("0000"); @@ -45,7 +44,6 @@ static BOOL test_check_string_terminator(struct torture_context *torture) if (NT_STATUS_IS_OK(ndr_check_string_terminator(ndr, 1, 3))) { torture_fail(test, "check_string_terminator checked beyond string boundaries"); - talloc_free(test); return False; } @@ -68,21 +66,22 @@ static BOOL test_check_string_terminator(struct torture_context *torture) if (NT_STATUS_IS_OK(ndr_check_string_terminator(ndr, 2, 1))) { torture_fail(test, "check_string_terminator erroneously reported terminator"); - talloc_free(test); return False; } torture_assert (test, ndr->offset == 0, "check_string_terminator did not reset offset"); - talloc_free(test); - return True; } BOOL torture_local_ndr(struct torture_context *torture) { - test_check_string_terminator(torture); + struct torture_suite *suite = torture_suite_create(torture, "LOCAL-NDR"); + + torture_suite_add_simple_tcase(suite, "string terminator", + test_check_string_terminator, + NULL); - return torture_result(torture); + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/registry.c b/source4/torture/local/registry.c index 49f019ba7a..4c8d773a44 100644 --- a/source4/torture/local/registry.c +++ b/source4/torture/local/registry.c @@ -26,19 +26,32 @@ #include "torture/torture.h" #include "torture/ui.h" -static bool test_hive(struct torture_context *parent_ctx, const char *backend, const char *location) +const static struct test_backend_settings { + const char *name; + const char *location; +} backends[] = { + { "nt4", "TEST.DAT" }, + { "ldb", "test.ldb" }, + { "gconf", "." }, + { "dir", "." }, + { NULL, NULL } +}; + +static BOOL test_hive(struct torture_context *ctx, const void *_backend) { WERROR error; struct registry_key *root, *subkey; uint32_t count; - struct torture_test *ctx = torture_test(parent_ctx, "test_hive", backend); - - if (!reg_has_backend(backend)) { - torture_skip(ctx, "Backend '%s' support not compiled in", backend); + const struct test_backend_settings *backend = _backend; + + if (!reg_has_backend(backend->name)) { + torture_skip(ctx, "Backend '%s' support not compiled in", + backend->name); return True; } - error = reg_open_hive(ctx, backend, location, NULL, cmdline_credentials, &root); + error = reg_open_hive(ctx, backend->name, + backend->location, NULL, cmdline_credentials, &root); torture_assert_werr_ok(ctx, error, "reg_open_hive()"); /* This is a new backend. There should be no subkeys and no @@ -61,21 +74,20 @@ static bool test_hive(struct torture_context *parent_ctx, const char *backend, c talloc_free(root); - torture_ok(ctx); - return True; } BOOL torture_registry(struct torture_context *torture) { - BOOL ret = True; + struct torture_suite *suite = torture_suite_create(torture, + "LOCAL-REGISTRY"); + int i; registry_init(); - ret &= test_hive(torture, "nt4", "TEST.DAT"); - ret &= test_hive(torture, "ldb", "test.ldb"); - ret &= test_hive(torture, "gconf", "."); - ret &= test_hive(torture, "dir", "."); + for (i = 0; backends[i].name; i++) { + torture_suite_add_simple_tcase(suite, backends[i].name, test_hive, &backends[i]); + } - return ret; + return torture_run_suite(torture, suite); } diff --git a/source4/torture/local/resolve.c b/source4/torture/local/resolve.c index 29606f4966..da83b45341 100644 --- a/source4/torture/local/resolve.c +++ b/source4/torture/local/resolve.c @@ -26,11 +26,9 @@ #include "torture/torture.h" #include "torture/ui.h" -static BOOL test_async_resolve(struct torture_context *torture) +static BOOL test_async_resolve(struct torture_context *test, const void *_data) { struct nbt_name n; - struct torture_test *test = torture_test(torture, "async_resolve", - "asynchronous resolve"); struct event_context *ev; int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); const char *host = lp_parm_string(-1, "torture", "host"); @@ -56,21 +54,18 @@ static BOOL test_async_resolve(struct torture_context *torture) torture_comment(test, "async rate of %.1f resolves/sec", count/timeval_elapsed(&tv)); - talloc_free(test); return True; } /* test resolution using sync method */ -static BOOL test_sync_resolve(struct torture_context *torture) +static BOOL test_sync_resolve(struct torture_context *test, const void *_data) { int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); struct timeval tv = timeval_current(); int count = 0; const char *host = lp_parm_string(-1, "torture", "host"); - struct torture_test *test = torture_test(torture, "sync resolve", - "synchronous resolve"); torture_comment(test, "Testing sync resolve of localhost for %d seconds", timelimit); @@ -82,15 +77,17 @@ static BOOL test_sync_resolve(struct torture_context *torture) torture_comment(test, "sync rate of %.1f resolves/sec", count/timeval_elapsed(&tv)); - talloc_free(test); return True; } BOOL torture_local_resolve(struct torture_context *torture) { - test_async_resolve(torture); - test_sync_resolve(torture); + struct torture_suite *suite = torture_suite_create(torture, + "LOCAL-RESOLVE"); - return torture_result(torture); + torture_suite_add_simple_tcase(suite, "async", test_async_resolve, NULL); + torture_suite_add_simple_tcase(suite, "sync", test_sync_resolve, NULL); + + return torture_run_suite(torture, suite); } diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 6e21ff595f..57e50009b4 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -3368,45 +3368,27 @@ static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, BOOL torture_rpc_samr(struct torture_context *torture) { - NTSTATUS status; - struct dcerpc_pipe *p; - TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct dcerpc_pipe *p; BOOL ret = True; struct policy_handle handle; - mem_ctx = talloc_init("torture_rpc_samr"); - - status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr); + status = torture_rpc_connection(torture, &p, &dcerpc_table_samr); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); return False; } - if (!test_Connect(p, mem_ctx, &handle)) { - ret = False; - } + ret &= test_Connect(p, torture, &handle); - if (!test_QuerySecurity(p, mem_ctx, &handle)) { - ret = False; - } - - if (!test_EnumDomains(p, mem_ctx, &handle)) { - ret = False; - } + ret &= test_QuerySecurity(p, torture, &handle); - if (!test_SetDsrmPassword(p, mem_ctx, &handle)) { - ret = False; - } + ret &= test_EnumDomains(p, torture, &handle); - if (!test_Shutdown(p, mem_ctx, &handle)) { - ret = False; - } + ret &= test_SetDsrmPassword(p, torture, &handle); - if (!test_samr_handle_Close(p, mem_ctx, &handle)) { - ret = False; - } + ret &= test_Shutdown(p, torture, &handle); - talloc_free(mem_ctx); + ret &= test_samr_handle_Close(p, torture, &handle); return ret; } diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index c2c76d25c3..bdd7f0ed84 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -233,12 +233,22 @@ static void max_runtime_handler(int sig) exit(1); } -static void simple_test_start (struct torture_test *test) +static void simple_tcase_start (struct torture_context *ctx, + struct torture_tcase *tcase, + struct torture_test *test) { - printf("Testing %s...\n", test->name); + printf("Testing %s...\n", tcase->name); } -static void simple_test_result (struct torture_test *test, enum torture_result res, const char *reason) +static void simple_test_start (struct torture_context *ctx, + struct torture_tcase *tcase, + struct torture_test *test) +{ + printf("Testing %s/%s...\n", tcase->name, test->name); +} + +static void simple_test_result (struct torture_context *context, + enum torture_result res, const char *reason) { switch (res) { case TORTURE_OK: @@ -246,19 +256,19 @@ static void simple_test_result (struct torture_test *test, enum torture_result r printf("OK: %s\n", reason); break; case TORTURE_FAIL: - printf("ERROR: %s - %s\n", test->name, reason); + printf("ERROR: %s - %s\n", context->active_test->name, reason); break; case TORTURE_TODO: - printf("TODO: %s - %s\n", test->name, reason); + printf("TODO: %s - %s\n", context->active_test->name, reason); break; case TORTURE_SKIP: - printf("SKIP: %s - %s\n", test->name, reason); + printf("SKIP: %s - %s\n", context->active_test->name, reason); break; } } -static void simple_comment (struct torture_test *test, const char *comment) +static void simple_comment (struct torture_context *test, const char *comment) { printf("# %s\n", comment); } @@ -266,34 +276,38 @@ static void simple_comment (struct torture_test *test, const char *comment) const static struct torture_ui_ops std_ui_ops = { .comment = simple_comment, .test_start = simple_test_start, + .tcase_start = simple_tcase_start, .test_result = simple_test_result }; -static void subunit_test_start (struct torture_test *test) +static void subunit_test_start (struct torture_context *ctx, + struct torture_tcase *tcase, + struct torture_test *test) { printf("test: %s\n", test->name); } -static void subunit_test_result (struct torture_test *test, enum torture_result res, const char *reason) +static void subunit_test_result (struct torture_context *context, + enum torture_result res, const char *reason) { switch (res) { case TORTURE_OK: - printf("success: %s\n", test->name); + printf("success: %s\n", context->active_test->name); break; case TORTURE_FAIL: - printf("failure: %s [ %s ]\n", test->name, reason); + printf("failure: %s [ %s ]\n", context->active_test->name, reason); break; case TORTURE_TODO: - printf("todo: %s\n", test->name); + printf("todo: %s\n", context->active_test->name); break; case TORTURE_SKIP: - printf("skip: %s\n", test->name); + printf("skip: %s\n", context->active_test->name); break; } } -static void subunit_comment (struct torture_test *test, const char *comment) +static void subunit_comment (struct torture_context *test, const char *comment) { printf("# %s\n", comment); } @@ -304,29 +318,32 @@ const static struct torture_ui_ops subunit_ui_ops = { .test_result = subunit_test_result }; -static void harness_test_start (struct torture_test *test) +static void harness_test_start (struct torture_context *ctx, + struct torture_tcase *tcase, + struct torture_test *test) { } -static void harness_test_result (struct torture_test *test, enum torture_result res, const char *reason) +static void harness_test_result (struct torture_context *context, + enum torture_result res, const char *reason) { switch (res) { case TORTURE_OK: - printf("ok %s - %s\n", test->name, reason); + printf("ok %s - %s\n", context->active_test->name, reason); break; case TORTURE_FAIL: - printf("not ok %s - %s\n", test->name, reason); + printf("not ok %s - %s\n", context->active_test->name, reason); break; case TORTURE_TODO: - printf("todo %s - %s\n", test->name, reason); + printf("todo %s - %s\n", context->active_test->name, reason); break; case TORTURE_SKIP: - printf("skip %s - %s\n", test->name, reason); + printf("skip %s - %s\n", context->active_test->name, reason); break; } } -static void harness_comment (struct torture_test *test, const char *comment) +static void harness_comment (struct torture_context *test, const char *comment) { printf("# %s\n", comment); } @@ -350,7 +367,7 @@ const static struct torture_ui_ops harness_ui_ops = { struct torture_context *torture; char **argv_new; poptContext pc; - static char *ui_ops_name = "simple"; + static const char *ui_ops_name = "simple"; enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC}; diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 66f37d51f5..6080b8cb82 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -637,7 +637,7 @@ static struct { {"SCAN-EAMAX", torture_max_eas, 0}, /* local (no server) testers */ - {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0}, + {"LOCAL-NTLMSSP", torture_ntlmssp, 0}, {"LOCAL-ICONV", torture_local_iconv, 0}, {"LOCAL-TALLOC", torture_local_talloc, 0}, {"LOCAL-MESSAGING", torture_local_messaging, 0}, diff --git a/source4/torture/ui.c b/source4/torture/ui.c index 62f8bacb65..5315640717 100644 --- a/source4/torture/ui.c +++ b/source4/torture/ui.c @@ -21,93 +21,220 @@ #include "includes.h" #include "torture/ui.h" +#include "dlinklist.h" -static int test_destructor(void *_test) +void torture_comment(struct torture_context *context, const char *comment, ...) _PRINTF_ATTRIBUTE(2,3) { - struct torture_test *test = _test; + va_list ap; + char *tmp; + va_start(ap, comment); + tmp = talloc_vasprintf(context, comment, ap); + + context->ui_ops->comment(context, tmp); + + talloc_free(tmp); +} - if (test->result == TORTURE_OK) - torture_ok(test); - return 0; +void torture_ok(struct torture_context *context) +{ + context->ui_ops->test_result(context, TORTURE_OK, NULL); + context->success++; } +void torture_fail(struct torture_context *context, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3) +{ + va_list ap; + char *reason; + va_start(ap, fmt); + reason = talloc_vasprintf(context, fmt, ap); + va_end(ap); + context->ui_ops->test_result(context, TORTURE_FAIL, reason); + talloc_free(reason); -struct torture_test *torture_test(struct torture_context *ctx, const char *name, const char *description) + context->failed++; +} + +void torture_skip(struct torture_context *context, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3) { - struct torture_test *test = talloc(ctx, struct torture_test); + va_list ap; + char *reason; + va_start(ap, fmt); + reason = talloc_vasprintf(context, fmt, ap); + va_end(ap); + context->ui_ops->test_result(context, TORTURE_SKIP, reason); + talloc_free(reason); + context->skipped++; +} - test->name = talloc_strdup(test, name); - test->description = talloc_strdup(test, description); - test->context = ctx; +void torture_register_suite(struct torture_suite *suite) +{ + /* FIXME */ +} - ctx->ui_ops->test_start(test); +struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name) +{ + struct torture_suite *suite = talloc(ctx, struct torture_suite); - talloc_set_destructor(test, test_destructor); + suite->name = talloc_strdup(suite, name); + suite->testcases = NULL; - return test; + return suite; +} + +void torture_tcase_set_fixture(struct torture_tcase *tcase, + BOOL (*setup) (struct torture_context *, void **), + BOOL (*teardown) (struct torture_context *, void *)) +{ + tcase->setup = setup; + tcase->teardown = teardown; } -struct torture_test *torture_subtest(struct torture_test *parent, const char *name, const char *description) +struct torture_test *torture_tcase_add_test(struct torture_tcase *tcase, + const char *name, + BOOL (*run) (struct torture_context *, + const void *tcase_data, + const void *test_data), + const void *data) { - struct torture_test *test = talloc(parent, struct torture_test); + struct torture_test *test = talloc(tcase, struct torture_test); test->name = talloc_strdup(test, name); - test->description = talloc_strdup(test, description); - test->context = parent->context; + test->description = NULL; + test->run = run; + test->data = data; - test->context->ui_ops->test_start(test); + DLIST_ADD(tcase->tests, test); - talloc_set_destructor(test, test_destructor); - return test; } -void torture_comment(struct torture_test *test, const char *comment, ...) _PRINTF_ATTRIBUTE(2,3) +struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite, + const char *name) { - va_list ap; - char *tmp; - va_start(ap, comment); - tmp = talloc_vasprintf(test, comment, ap); - - test->context->ui_ops->comment(test, tmp); + struct torture_tcase *tcase = talloc(suite, struct torture_tcase); + + tcase->name = talloc_strdup(tcase, name); + tcase->description = NULL; + tcase->setup = NULL; + tcase->teardown = NULL; + tcase->fixture_persistent = True; + tcase->tests = NULL; + + DLIST_ADD(suite->testcases, tcase); + + return tcase; +} + +BOOL torture_run_suite(struct torture_context *context, + struct torture_suite *suite) +{ + BOOL ret = True; + struct torture_tcase *tcase; + + for (tcase = suite->testcases; tcase; tcase = tcase->next) { + ret &= torture_run_tcase(context, tcase); + } - talloc_free(tmp); + return ret; } +BOOL torture_run_tcase(struct torture_context *context, + struct torture_tcase *tcase) +{ + BOOL ret = True; + void *data = NULL; + struct torture_test *test; + + context->active_tcase = tcase; + if (context->ui_ops->tcase_start) + context->ui_ops->tcase_start(context, tcase); + + if (tcase->fixture_persistent && tcase->setup + && !tcase->setup(context, &data)) + return False; + + for (test = tcase->tests; test; test = test->next) { + if (tcase->fixture_persistent) { + context->active_test = test; + context->ui_ops->test_start(context, tcase, test); + ret &= test->run(context, (tcase->setup?data:tcase->data), + test->data); + } else + ret &= torture_run_test(context, tcase, test); -void torture_ok(struct torture_test *test) + } + context->active_test = NULL; + + if (tcase->fixture_persistent && tcase->teardown && + !tcase->teardown(context, data)) + return False; + + context->active_tcase = NULL; + + return ret; +} + +BOOL torture_run_test(struct torture_context *context, + struct torture_tcase *tcase, + struct torture_test *test) { - test->context->ui_ops->test_result(test, TORTURE_OK, NULL); - test->context->success++; + BOOL ret; + void *data = NULL; + + if (tcase->setup && !tcase->setup(context, &data)) + return False; + + context->active_tcase = tcase; + context->active_test = test; + context->ui_ops->test_start(context, tcase, test); + ret = test->run(context, tcase->setup?data:tcase->data, test->data); + context->active_test = NULL; + context->active_tcase = NULL; + + if (tcase->teardown && !tcase->teardown(context, data)) + return False; + + return ret; } -void torture_fail(struct torture_test *test, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3) +const char *torture_setting(struct torture_context *test, const char *name, + const char *default_value) { - va_list ap; - char *reason; - va_start(ap, fmt); - reason = talloc_vasprintf(test, fmt, ap); - va_end(ap); - test->context->ui_ops->test_result(test, TORTURE_FAIL, reason); - talloc_free(reason); + const char *ret = lp_parm_string(-1, "torture", name); - test->context->failed++; + if (ret == NULL) + return default_value; + + return ret; } -BOOL torture_result(struct torture_context *torture) +static BOOL simple_tcase_helper(struct torture_context *test, + const void *tcase_data, + const void *test_data) { - return (torture->failed == 0); + BOOL (*run) (struct torture_context *, const void *) = test_data; + + return run(test, tcase_data); } -void torture_skip(struct torture_test *test, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3) +struct torture_tcase *torture_suite_add_simple_tcase( + struct torture_suite *suite, + const char *name, + BOOL (*run) (struct torture_context *test, const void *), + const void *data) { - va_list ap; - char *reason; - va_start(ap, fmt); - reason = talloc_vasprintf(test, fmt, ap); - va_end(ap); - test->context->ui_ops->test_result(test, TORTURE_SKIP, reason); - talloc_free(reason); - test->context->skipped++; + struct torture_tcase *tcase; + + tcase = torture_suite_add_tcase(suite, name); + tcase->data = data; + + torture_tcase_add_test(tcase, "Test", simple_tcase_helper, run); + + return tcase; +} + +BOOL torture_teardown_free(struct torture_context *torture, void *data) +{ + return talloc_free(data); } diff --git a/source4/torture/ui.h b/source4/torture/ui.h index 9c19d99f1c..ccd50095a5 100644 --- a/source4/torture/ui.h +++ b/source4/torture/ui.h @@ -19,7 +19,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __TORTURE_UI_H__ +#define __TORTURE_UI_H__ + struct torture_test; +struct torture_context; +struct torture_tcase; enum torture_result { TORTURE_OK=0, @@ -30,35 +35,82 @@ enum torture_result { struct torture_ui_ops { - void (*comment) (struct torture_test *, const char *); - void (*test_start) (struct torture_test *); - void (*test_result) (struct torture_test *, enum torture_result, + void (*comment) (struct torture_context *, const char *); + void (*tcase_start) (struct torture_context *, struct torture_tcase *); + void (*tcase_finish) (struct torture_context *, struct torture_tcase *); + void (*test_start) (struct torture_context *, + struct torture_tcase *, + struct torture_test *); + void (*test_result) (struct torture_context *, enum torture_result, const char *reason); }; -struct torture_test -{ - char *name; - char *description; - - void *ui_data; - - enum torture_result result; - - struct torture_context *context; -}; - struct torture_context { const struct torture_ui_ops *ui_ops; void *ui_data; + struct torture_test *active_test; + struct torture_tcase *active_tcase; + int skipped; int todo; int success; int failed; }; +struct torture_suite +{ + const char *name; + const char *description; + struct torture_tcase { + const char *name; + const char *description; + BOOL (*setup) (struct torture_context *tcase, void **data); + BOOL (*teardown) (struct torture_context *tcase, void *data); + BOOL fixture_persistent; + const void *data; + struct torture_test { + const char *name; + const char *description; + const void *data; + BOOL (*run) (struct torture_context *test, + const void *tcase_data, + const void *test_data); + struct torture_test *prev, *next; + } *tests; + struct torture_tcase *prev, *next; + } *testcases; +}; + +void torture_register_suite(struct torture_suite *suite); +struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name); +void torture_tcase_set_fixture(struct torture_tcase *tcase, + BOOL (*setup) (struct torture_context *, void **), + BOOL (*teardown) (struct torture_context *, void *)); +struct torture_test *torture_tcase_add_test(struct torture_tcase *tcase, + const char *name, + BOOL (*run) (struct torture_context *test, const void *tcase_data, + const void *test_data), + const void *test_data); +struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite, + const char *name); +struct torture_tcase *torture_suite_add_simple_tcase( + struct torture_suite *suite, + const char *name, + BOOL (*run) (struct torture_context *test, const void *test_data), + const void *data); + +BOOL torture_run_suite(struct torture_context *context, + struct torture_suite *suite); + +BOOL torture_run_tcase(struct torture_context *context, + struct torture_tcase *tcase); + +BOOL torture_run_test(struct torture_context *context, + struct torture_tcase *tcase, + struct torture_test *test); + #define torture_assert(ctx,expr,string) \ if (!(expr)) { \ torture_fail(ctx, "%s:%d (%s): %s", __FILE__, __LINE__, string, \ @@ -103,10 +155,14 @@ struct torture_context #define torture_assert_werr_ok(ctx,expr,string) \ torture_assert_werr_equal(ctx,expr,WERR_OK,string) -struct torture_test *torture_test(struct torture_context *ctx, const char *name, const char *description); -struct torture_test *torture_subtest(struct torture_test *parent, const char *name, const char *description); -void torture_comment(struct torture_test *test, const char *comment, ...) _PRINTF_ATTRIBUTE(2,3); -void torture_ok(struct torture_test *test); -void torture_fail(struct torture_test *test, const char *reason, ...) _PRINTF_ATTRIBUTE(2,3); -void torture_skip(struct torture_test *test, const char *reason, ...) _PRINTF_ATTRIBUTE(2,3); -BOOL torture_result(struct torture_context *torture); +void torture_comment(struct torture_context *test, const char *comment, ...) _PRINTF_ATTRIBUTE(2,3); +void torture_ok(struct torture_context *test); +void torture_fail(struct torture_context *test, const char *reason, ...) _PRINTF_ATTRIBUTE(2,3); +void torture_skip(struct torture_context *test, const char *reason, ...) _PRINTF_ATTRIBUTE(2,3); +const char *torture_setting(struct torture_context *test, const char *name, + const char *default_value); + +/* Helper function commonly used */ +BOOL torture_teardown_free(struct torture_context *torture, void *data); + +#endif /* __TORTURE_UI_H__ */ -- cgit