diff options
author | Stefan Metzmacher <metze@samba.org> | 2018-07-10 16:21:55 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2018-07-10 20:31:13 +0200 |
commit | 0503bbab958754bc8ba32da8578602927ebf25c0 (patch) | |
tree | f85b52a30fffd0daba714c4f0e4afe4e20ddc417 /source4/lib/messaging/tests | |
parent | d08efa7f90e97f1f797d09f7519076646110cb45 (diff) | |
download | samba-0503bbab958754bc8ba32da8578602927ebf25c0.tar.gz |
s4:messaging: add local.messaging.multi_ctx.multi_ctx test
This tests the usage of multiple imessaging_contexts in one process
and also freeing two of them during a message handler.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13514
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4/lib/messaging/tests')
-rw-r--r-- | source4/lib/messaging/tests/messaging.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/source4/lib/messaging/tests/messaging.c b/source4/lib/messaging/tests/messaging.c index ba589788288..80c8583c21e 100644 --- a/source4/lib/messaging/tests/messaging.c +++ b/source4/lib/messaging/tests/messaging.c @@ -393,6 +393,226 @@ static bool test_messaging_overflow_check(struct torture_context *tctx) return true; } +struct test_multi_ctx { + struct torture_context *tctx; + struct imessaging_context *server_ctx; + struct imessaging_context *client_ctx[4]; + size_t num_missing; + bool got_server; + bool got_client_0_1; + bool got_client_2_3; + bool ok; +}; + +static void multi_ctx_server_handler(struct imessaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct test_multi_ctx *state = private_data; + char *str = NULL; + + torture_assert_goto(state->tctx, state->num_missing >= 1, + state->ok, fail, + "num_missing should be at least 1."); + state->num_missing -= 1; + + torture_assert_goto(state->tctx, !state->got_server, + state->ok, fail, + "already got server."); + state->got_server = true; + + /* + * We free the context itself and most likely reuse + * the memory immediately. + */ + TALLOC_FREE(state->server_ctx); + str = generate_random_str(state->tctx, 128); + torture_assert_goto(state->tctx, str != NULL, + state->ok, fail, + "generate_random_str()"); + +fail: + return; +} + +static void multi_ctx_client_0_1_handler(struct imessaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct test_multi_ctx *state = private_data; + char *str = NULL; + + torture_assert_goto(state->tctx, state->num_missing >= 2, + state->ok, fail, + "num_missing should be at least 2."); + state->num_missing -= 2; + + torture_assert_goto(state->tctx, !state->got_client_0_1, + state->ok, fail, + "already got client_0_1."); + state->got_client_0_1 = true; + + /* + * We free two contexts and most likely reuse + * the memory immediately. + */ + TALLOC_FREE(state->client_ctx[0]); + str = generate_random_str(state->tctx, 128); + torture_assert_goto(state->tctx, str != NULL, + state->ok, fail, + "generate_random_str()"); + TALLOC_FREE(state->client_ctx[1]); + str = generate_random_str(state->tctx, 128); + torture_assert_goto(state->tctx, str != NULL, + state->ok, fail, + "generate_random_str()"); + +fail: + return; +} + +static void multi_ctx_client_2_3_handler(struct imessaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct test_multi_ctx *state = private_data; + char *str = NULL; + + torture_assert_goto(state->tctx, state->num_missing >= 2, + state->ok, fail, + "num_missing should be at least 2."); + state->num_missing -= 2; + + torture_assert_goto(state->tctx, !state->got_client_2_3, + state->ok, fail, + "already got client_2_3."); + state->got_client_2_3 = true; + + /* + * We free two contexts and most likely reuse + * the memory immediately. + */ + TALLOC_FREE(state->client_ctx[2]); + str = generate_random_str(state->tctx, 128); + torture_assert_goto(state->tctx, str != NULL, + state->ok, fail, + "generate_random_str()"); + TALLOC_FREE(state->client_ctx[3]); + str = generate_random_str(state->tctx, 128); + torture_assert_goto(state->tctx, str != NULL, + state->ok, fail, + "generate_random_str()"); + +fail: + return; +} + +static bool test_multi_ctx(struct torture_context *tctx) +{ + struct test_multi_ctx state = { + .tctx = tctx, + .ok = true, + }; + struct timeval tv; + NTSTATUS status; + + lpcfg_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp"); + + /* + * We use cluster_id(0, 0) as that gets for + * all task ids. + */ + state.server_ctx = imessaging_init(tctx, + tctx->lp_ctx, + cluster_id(0, 0), + tctx->ev); + torture_assert(tctx, state.server_ctx != NULL, + "Failed to init messaging context"); + + status = imessaging_register(state.server_ctx, &state, + MSG_TMP_BASE-1, + multi_ctx_server_handler); + torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed"); + + state.client_ctx[0] = imessaging_init(tctx, + tctx->lp_ctx, + cluster_id(0, 0), + tctx->ev); + torture_assert(tctx, state.client_ctx[0] != NULL, + "msg_client_ctx imessaging_init() failed"); + status = imessaging_register(state.client_ctx[0], &state, + MSG_TMP_BASE-1, + multi_ctx_client_0_1_handler); + torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed"); + state.client_ctx[1] = imessaging_init(tctx, + tctx->lp_ctx, + cluster_id(0, 0), + tctx->ev); + torture_assert(tctx, state.client_ctx[1] != NULL, + "msg_client_ctx imessaging_init() failed"); + status = imessaging_register(state.client_ctx[1], &state, + MSG_TMP_BASE-1, + multi_ctx_client_0_1_handler); + torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed"); + state.client_ctx[2] = imessaging_init(tctx, + tctx->lp_ctx, + cluster_id(0, 0), + tctx->ev); + torture_assert(tctx, state.client_ctx[2] != NULL, + "msg_client_ctx imessaging_init() failed"); + status = imessaging_register(state.client_ctx[2], &state, + MSG_TMP_BASE-1, + multi_ctx_client_2_3_handler); + torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed"); + state.client_ctx[3] = imessaging_init(tctx, + tctx->lp_ctx, + cluster_id(0, 0), + tctx->ev); + torture_assert(tctx, state.client_ctx[3] != NULL, + "msg_client_ctx imessaging_init() failed"); + status = imessaging_register(state.client_ctx[3], &state, + MSG_TMP_BASE-1, + multi_ctx_client_2_3_handler); + torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed"); + + /* + * Send one message that need to arrive on 3 ( 5 - 2 ) handlers. + */ + state.num_missing = 5; + + status = imessaging_send(state.server_ctx, + cluster_id(0, 0), + MSG_TMP_BASE-1, NULL); + torture_assert_ntstatus_ok(tctx, status, "msg failed"); + + tv = timeval_current(); + while (timeval_elapsed(&tv) < 30 && state.num_missing > 0 && state.ok) { + int ret; + + ret = tevent_loop_once(tctx->ev); + torture_assert_int_equal(tctx, ret, 0, "tevent_loop_once()"); + } + + if (!state.ok) { + return false; + } + + torture_assert_int_equal(tctx, state.num_missing, 0, + "wrong message count"); + + torture_assert(tctx, state.got_client_0_1, "got_client_0_1"); + torture_assert(tctx, state.got_client_2_3, "got_client_2_3"); + torture_assert(tctx, state.got_server, "got_server"); + + return true; +} + struct torture_suite *torture_local_messaging(TALLOC_CTX *mem_ctx) { struct torture_suite *s = torture_suite_create(mem_ctx, "messaging"); @@ -400,5 +620,6 @@ struct torture_suite *torture_local_messaging(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(s, "overflow_check", test_messaging_overflow_check); torture_suite_add_simple_test(s, "ping_speed", test_ping_speed); + torture_suite_add_simple_test(s, "multi_ctx", test_multi_ctx); return s; } |