diff options
author | Volker Lendecke <vl@samba.org> | 2017-05-25 10:48:15 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2017-06-15 13:19:15 +0200 |
commit | 2c200dd00d8a3969e5dbbdb0598b5073fd3cf65e (patch) | |
tree | 18c4dd3eee0f379a2ef6c581496123bc9743b754 /source3 | |
parent | d19e7709d9b6666f53ccfec47a86f0f0cab70925 (diff) | |
download | samba-2c200dd00d8a3969e5dbbdb0598b5073fd3cf65e.tar.gz |
torture3: Test heuristic cleanup
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rwxr-xr-x | source3/selftest/tests.py | 1 | ||||
-rw-r--r-- | source3/torture/proto.h | 1 | ||||
-rw-r--r-- | source3/torture/test_g_lock.c | 142 | ||||
-rw-r--r-- | source3/torture/torture.c | 1 |
4 files changed, 145 insertions, 0 deletions
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 8a8a62d1fb6..965ad7eee3e 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -152,6 +152,7 @@ local_tests = [ "LOCAL-G-LOCK2", "LOCAL-G-LOCK3", "LOCAL-G-LOCK4", + "LOCAL-G-LOCK5", "LOCAL-hex_encode_buf", "LOCAL-remove_duplicate_addrs2"] diff --git a/source3/torture/proto.h b/source3/torture/proto.h index c945d92038c..6d5ca7747e1 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -128,5 +128,6 @@ bool run_g_lock1(int dummy); bool run_g_lock2(int dummy); bool run_g_lock3(int dummy); bool run_g_lock4(int dummy); +bool run_g_lock5(int dummy); #endif /* __TORTURE_H__ */ diff --git a/source3/torture/test_g_lock.c b/source3/torture/test_g_lock.c index 98fd01312f8..ca373123e11 100644 --- a/source3/torture/test_g_lock.c +++ b/source3/torture/test_g_lock.c @@ -500,3 +500,145 @@ fail: TALLOC_FREE(ev); return ret; } + +struct lock5_parser_state { + size_t num_locks; +}; + +static void lock5_parser(const struct g_lock_rec *locks, + size_t num_locks, + const uint8_t *data, + size_t datalen, + void *private_data) +{ + struct lock5_parser_state *state = private_data; + state->num_locks = num_locks; +} + +/* + * Test heuristic cleanup + */ + +bool run_g_lock5(int dummy) +{ + struct tevent_context *ev = NULL; + struct messaging_context *msg = NULL; + struct g_lock_ctx *ctx = NULL; + const char *lockname = "lock5"; + pid_t child; + int exit_pipe[2], ready_pipe[2]; + NTSTATUS status; + size_t i, nprocs; + int ret; + bool ok; + ssize_t nread; + char c; + + nprocs = 5; + + if ((pipe(exit_pipe) != 0) || (pipe(ready_pipe) != 0)) { + perror("pipe failed"); + return false; + } + + ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx); + if (!ok) { + fprintf(stderr, "get_g_lock_ctx failed"); + return false; + } + + for (i=0; i<nprocs; i++) { + + child = fork(); + + if (child == -1) { + perror("fork failed"); + return false; + } + + if (child == 0) { + TALLOC_FREE(ctx); + TALLOC_FREE(msg); + TALLOC_FREE(ev); + + close(ready_pipe[0]); + close(exit_pipe[1]); + + ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx); + if (!ok) { + fprintf(stderr, "get_g_lock_ctx failed"); + exit(1); + } + status = g_lock_lock(ctx, lockname, G_LOCK_READ, + (struct timeval) { .tv_sec = 1 }); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, + "child g_lock_lock failed %s\n", + nt_errstr(status)); + exit(1); + } + close(ready_pipe[1]); + nread = sys_read(exit_pipe[0], &c, sizeof(c)); + if (nread != 0) { + fprintf(stderr, "sys_read returned %zu (%s)\n", + nread, strerror(errno)); + exit(1); + } + exit(0); + } + } + + close(ready_pipe[1]); + + nread = sys_read(ready_pipe[0], &c, sizeof(c)); + if (nread != 0) { + fprintf(stderr, "sys_read returned %zu (%s)\n", + nread, strerror(errno)); + return false; + } + + close(exit_pipe[1]); + + for (i=0; i<nprocs; i++) { + int child_status; + ret = waitpid(-1, &child_status, 0); + if (ret == -1) { + perror("waitpid failed"); + return false; + } + } + + for (i=0; i<nprocs; i++) { + struct lock5_parser_state state; + + status = g_lock_dump(ctx, lockname, lock5_parser, &state); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "g_lock_dump returned %s\n", + nt_errstr(status)); + return false; + } + + if (state.num_locks != (nprocs - i)) { + fprintf(stderr, "nlocks=%zu, expected %zu\n", + state.num_locks, (nprocs-i)); + return false; + } + + status = g_lock_lock(ctx, lockname, G_LOCK_READ, + (struct timeval) { .tv_sec = 1 }); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "g_lock_lock failed %s\n", + nt_errstr(status)); + return false; + } + status = g_lock_unlock(ctx, lockname); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "g_lock_unlock failed %s\n", + nt_errstr(status)); + return false; + } + } + + + return true; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 81d180e5a36..2d4b62de860 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -11481,6 +11481,7 @@ static struct { { "LOCAL-G-LOCK2", run_g_lock2, 0 }, { "LOCAL-G-LOCK3", run_g_lock3, 0 }, { "LOCAL-G-LOCK4", run_g_lock4, 0 }, + { "LOCAL-G-LOCK5", run_g_lock5, 0 }, { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 }, { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 }, {NULL, NULL, 0}}; |