summaryrefslogtreecommitdiff
path: root/source4/lib/messaging/tests
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-07-10 16:21:55 +0200
committerJeremy Allison <jra@samba.org>2018-07-10 20:31:13 +0200
commit0503bbab958754bc8ba32da8578602927ebf25c0 (patch)
treef85b52a30fffd0daba714c4f0e4afe4e20ddc417 /source4/lib/messaging/tests
parentd08efa7f90e97f1f797d09f7519076646110cb45 (diff)
downloadsamba-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.c221
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;
}