s4:torture/smb2: add --option="torture:looplimit=150000" to smb2.bench.echo
authorStefan Metzmacher <metze@samba.org>
Fri, 28 Apr 2023 08:02:39 +0000 (08:02 +0000)
committerStefan Metzmacher <metze@samba.org>
Thu, 1 Jun 2023 07:20:31 +0000 (07:20 +0000)
Also see the commit message of 23988f19e7cc2823d6c0c0f40af0195d0a3b81bf
for other examples...

This test calls SMB2_Echo in a loop per connection.

time smbtorture //127.0.0.1/m -Uroot%test smb2.bench.echo \
        --option="torture:timelimit=600" \
        --option="torture:looplimit=150000" \
        --option="torture:nprocs=1" \
        --option="torture:qdepth=1"

This is a very useful test to show how many requests are possible
at the raw SMB2 layer.

In order to do profiling and being able to compare the
profiles between runs, it is important to produce the
exact same load in each run, which is not possible
with the typical --option="torture:timelimit=600".

E.g. when the server runs under 'valgrind --tool=callgrind bin/smbd'
I typically run without "torture:looplimit" first in order to
see, which rate is possible per second, then I'll add a
"torture:looplimit" in order to run about half of the timelimit.
Then the looplimit should run for some time, but finish
before the timelimit.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source4/torture/smb2/bench.c

index 2793b50fb4c1597f3ff8afff97735ef623f639b2..5d9e84e67063e2a1401db553a7302c3deab872bf 100644 (file)
@@ -140,6 +140,7 @@ struct test_smb2_bench_echo_state {
        struct test_smb2_bench_echo_conn *conns;
        size_t num_loops;
        struct test_smb2_bench_echo_loop *loops;
+       size_t pending_loops;
        struct timeval starttime;
        int timecount;
        int timelimit;
@@ -166,6 +167,8 @@ struct test_smb2_bench_echo_loop {
        struct timeval starttime;
        uint64_t num_started;
        uint64_t num_finished;
+       uint64_t total_finished;
+       uint64_t max_finished;
        double total_latency;
        double min_latency;
        double max_latency;
@@ -200,7 +203,7 @@ static void test_smb2_bench_echo_loop_do(
                                      loop->conn->tree->session->transport->conn,
                                      1000);
        torture_assert_goto(state->tctx, loop->req != NULL,
-                           state->ok, asserted, "smb2_create_send");
+                           state->ok, asserted, "smb2cli_echo_send");
 
        tevent_req_set_callback(loop->req,
                                test_smb2_bench_echo_loop_done,
@@ -233,6 +236,7 @@ static void test_smb2_bench_echo_loop_done(struct tevent_req *req)
        }
 
        loop->num_finished += 1;
+       loop->total_finished += 1;
        loop->total_latency += latency;
 
        if (latency < loop->min_latency) {
@@ -243,6 +247,15 @@ static void test_smb2_bench_echo_loop_done(struct tevent_req *req)
                loop->max_latency = latency;
        }
 
+       if (loop->total_finished >= loop->max_finished) {
+               if (state->pending_loops > 0) {
+                       state->pending_loops -= 1;
+               }
+               if (state->pending_loops == 0) {
+                       goto asserted;
+               }
+       }
+
        TALLOC_FREE(frame);
        test_smb2_bench_echo_loop_do(loop);
        return;
@@ -355,6 +368,7 @@ static bool test_smb2_bench_echo(struct torture_context *tctx,
        int torture_qdepth = torture_setting_int(tctx, "qdepth", 1);
        size_t i;
        size_t li = 0;
+       int looplimit = torture_setting_int(tctx, "looplimit", -1);
        int timelimit = torture_setting_int(tctx, "timelimit", 10);
        struct tevent_timer *te = NULL;
        uint32_t timeout_msec;
@@ -418,6 +432,11 @@ static bool test_smb2_bench_echo(struct torture_context *tctx,
                        struct test_smb2_bench_echo_loop *loop = &state->loops[li];
 
                        loop->idx = li++;
+                       if (looplimit != -1) {
+                               loop->max_finished = looplimit;
+                       } else {
+                               loop->max_finished = UINT64_MAX;
+                       }
                        loop->state = state;
                        loop->conn = &state->conns[i];
                        loop->im = tevent_create_immediate(state->loops);
@@ -436,6 +455,7 @@ static bool test_smb2_bench_echo(struct torture_context *tctx,
        torture_comment(tctx, "Running for %d seconds\n", state->timelimit);
 
        state->starttime = timeval_current();
+       state->pending_loops = state->num_loops;
 
        te = tevent_add_timer(tctx->ev,
                              state,
@@ -932,8 +952,8 @@ struct torture_suite *torture_smb2_bench_init(TALLOC_CTX *ctx)
        struct torture_suite *suite = torture_suite_create(ctx, "bench");
 
        torture_suite_add_1smb2_test(suite, "oplock1", test_smb2_bench_oplock);
-       torture_suite_add_1smb2_test(suite, "path-contention-shared", test_smb2_bench_path_contention_shared);
        torture_suite_add_1smb2_test(suite, "echo", test_smb2_bench_echo);
+       torture_suite_add_1smb2_test(suite, "path-contention-shared", test_smb2_bench_path_contention_shared);
 
        suite->description = talloc_strdup(suite, "SMB2-BENCH tests");