diff options
author | Volker Lendecke <vl@samba.org> | 2014-04-29 14:25:14 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2014-04-30 14:52:08 +0200 |
commit | 54118d24a712172c6d54b213c70c926148fd61ff (patch) | |
tree | cd7200ff98dff0d070457c5d79f1cb1f58af21c7 /source3/torture | |
parent | d0590eec7e12f2a5ddb9f76365d5547cc3c668c1 (diff) | |
download | samba-54118d24a712172c6d54b213c70c926148fd61ff.tar.gz |
torture3: Add local-messaging-read1
This covers deleting and re-adding a request in a callback
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/torture')
-rw-r--r-- | source3/torture/proto.h | 1 | ||||
-rw-r--r-- | source3/torture/test_messaging_read.c | 144 | ||||
-rw-r--r-- | source3/torture/torture.c | 1 |
3 files changed, 146 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>. +*/ + +#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}, |