From 54118d24a712172c6d54b213c70c926148fd61ff Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2014 14:25:14 +0200 Subject: [PATCH] torture3: Add local-messaging-read1 This covers deleting and re-adding a request in a callback Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/selftest/tests.py | 1 + source3/torture/proto.h | 1 + source3/torture/test_messaging_read.c | 144 ++++++++++++++++++++++++++++++++++ source3/torture/torture.c | 1 + source3/wscript_build | 1 + 5 files changed, 148 insertions(+) create mode 100644 source3/torture/test_messaging_read.c diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 4357ed93913..7200329d3a0 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -102,6 +102,7 @@ local_tests = [ "LOCAL-CONVERT-STRING", "LOCAL-CONV-AUTH-INFO", "LOCAL-IDMAP-TDB-COMMON", + "LOCAL-MESSAGING-READ1", "LOCAL-hex_encode_buf", "LOCAL-sprintf_append", "LOCAL-remove_duplicate_addrs2"] diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 3673d98def3..f23efa184b2 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -113,5 +113,6 @@ bool run_idmap_tdb_common_test(int dummy); bool run_local_dbwrap_ctdb(int dummy); bool run_qpathinfo_bufsize(int dummy); bool run_bench_pthreadpool(int dummy); +bool run_messaging_read1(int dummy); #endif /* __TORTURE_H__ */ diff --git a/source3/torture/test_messaging_read.c b/source3/torture/test_messaging_read.c new file mode 100644 index 00000000000..6c8cdba724d --- /dev/null +++ b/source3/torture/test_messaging_read.c @@ -0,0 +1,144 @@ +/* + Unix SMB/CIFS implementation. + Test for a messaging_read bug + Copyright (C) Volker Lendecke 2014 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "torture/proto.h" +#include "lib/util/tevent_unix.h" +#include "messages.h" + +struct msg_count_state { + struct tevent_context *ev; + struct messaging_context *msg_ctx; + uint32_t msg_type; + unsigned *count; +}; + +static void msg_count_done(struct tevent_req *subreq); + +static struct tevent_req *msg_count_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct messaging_context *msg_ctx, + uint32_t msg_type, + unsigned *count) +{ + struct tevent_req *req, *subreq; + struct msg_count_state *state; + + req = tevent_req_create(mem_ctx, &state, struct msg_count_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->msg_ctx = msg_ctx; + state->msg_type = msg_type; + state->count = count; + + subreq = messaging_read_send(state, state->ev, state->msg_ctx, + state->msg_type); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, msg_count_done, req); + return req; +} + +static void msg_count_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct msg_count_state *state = tevent_req_data( + req, struct msg_count_state); + int ret; + + ret = messaging_read_recv(subreq, NULL, NULL); + TALLOC_FREE(subreq); + if (tevent_req_error(req, ret)) { + return; + } + *state->count += 1; + + subreq = messaging_read_send(state, state->ev, state->msg_ctx, + state->msg_type); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, msg_count_done, req); +} + +bool run_messaging_read1(int dummy) +{ + struct tevent_context *ev = NULL; + struct messaging_context *msg_ctx = NULL; + struct tevent_req *req1 = NULL; + unsigned count1 = 0; + struct tevent_req *req2 = NULL; + unsigned count2 = 0; + NTSTATUS status; + bool retval = false; + + ev = samba_tevent_context_init(talloc_tos()); + if (ev == NULL) { + fprintf(stderr, "tevent_context_init failed\n"); + goto fail; + } + msg_ctx = messaging_init(ev, ev); + if (msg_ctx == NULL) { + fprintf(stderr, "messaging_init failed\n"); + goto fail; + } + + req1 = msg_count_send(ev, ev, msg_ctx, MSG_SMB_NOTIFY, &count1); + if (req1 == NULL) { + fprintf(stderr, "msg_count_send failed\n"); + goto fail; + } + req2 = msg_count_send(ev, ev, msg_ctx, MSG_SMB_NOTIFY, &count2); + if (req1 == NULL) { + fprintf(stderr, "msg_count_send failed\n"); + goto fail; + } + status = messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx), + MSG_SMB_NOTIFY, NULL, 0); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "messaging_send_buf failed: %s\n", + nt_errstr(status)); + goto fail; + } + + if (tevent_loop_once(ev) != 0) { + fprintf(stderr, "tevent_loop_once failed\n"); + goto fail; + } + + printf("%u/%u\n", count1, count2); + + if ((count1 != 1) || (count2 != 1)){ + fprintf(stderr, "Got %u/%u msgs, expected 1 each\n", + count1, count2); + goto fail; + } + + retval = true; +fail: + TALLOC_FREE(req1); + TALLOC_FREE(req2); + TALLOC_FREE(msg_ctx); + TALLOC_FREE(ev); + return retval; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 61e9338d3d6..5d75bbfd29b 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -9574,6 +9574,7 @@ static struct { { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0}, { "LOCAL-CTDB-CONN", run_ctdb_conn, 0}, { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 }, + { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 }, { "LOCAL-BASE64", run_local_base64, 0}, { "LOCAL-RBTREE", run_local_rbtree, 0}, { "LOCAL-MEMCACHE", run_local_memcache, 0}, diff --git a/source3/wscript_build b/source3/wscript_build index e9c2f91adf1..f13aa630e8f 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1256,6 +1256,7 @@ bld.SAMBA3_BINARY('smbtorture' + bld.env.suffix3, torture/test_idmap_tdb_common.c torture/test_dbwrap_ctdb.c torture/test_buffersize.c + torture/test_messaging_read.c torture/t_strappend.c torture/bench_pthreadpool.c torture/wbc_async.c''', -- 2.11.4.GIT