LCOV - code coverage report
Current view: top level - source4/lib/messaging/tests - messaging.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 241 277 87.0 %
Date: 2021-09-23 10:06:22 Functions: 12 13 92.3 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    local test for messaging code
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "lib/events/events.h"
      24             : #include "lib/messaging/irpc.h"
      25             : #include "torture/torture.h"
      26             : #include "cluster/cluster.h"
      27             : #include "param/param.h"
      28             : #include "torture/local/proto.h"
      29             : #include "system/select.h"
      30             : #include "system/filesys.h"
      31             : 
      32             : #include <gnutls/gnutls.h>
      33             : #include <gnutls/crypto.h>
      34             : 
      35             : static uint32_t msg_pong;
      36             : 
      37        7318 : static void ping_message(struct imessaging_context *msg,
      38             :                          void *private_data,
      39             :                          uint32_t msg_type,
      40             :                          struct server_id src,
      41             :                          size_t num_fds,
      42             :                          int *fds,
      43             :                          DATA_BLOB *data)
      44             : {
      45             :         NTSTATUS status;
      46             : 
      47        7318 :         if (num_fds != 0) {
      48           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
      49           0 :                 return;
      50             :         }
      51             : 
      52        7318 :         status = imessaging_send(msg, src, msg_pong, data);
      53        7318 :         if (!NT_STATUS_IS_OK(status)) {
      54           0 :                 printf("pong failed - %s\n", nt_errstr(status));
      55             :         }
      56             : }
      57             : 
      58        7318 : static void pong_message(struct imessaging_context *msg,
      59             :                          void *private_data,
      60             :                          uint32_t msg_type,
      61             :                          struct server_id src,
      62             :                          size_t num_fds,
      63             :                          int *fds,
      64             :                          DATA_BLOB *data)
      65             : {
      66        7318 :         int *count = (int *)private_data;
      67             : 
      68        7318 :         if (num_fds != 0) {
      69           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
      70           0 :                 return;
      71             :         }
      72             : 
      73        7318 :         (*count)++;
      74             : }
      75             : 
      76           0 : static void exit_message(struct imessaging_context *msg,
      77             :                          void *private_data,
      78             :                          uint32_t msg_type,
      79             :                          struct server_id src,
      80             :                          size_t num_fds,
      81             :                          int *fds,
      82             :                          DATA_BLOB *data)
      83             : {
      84           0 :         if (num_fds != 0) {
      85           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
      86           0 :                 return;
      87             :         }
      88             : 
      89           0 :         talloc_free(private_data);
      90           0 :         exit(0);
      91             : }
      92             : 
      93             : /*
      94             :   test ping speed
      95             : */
      96           1 : static bool test_ping_speed(struct torture_context *tctx)
      97             : {
      98             :         struct tevent_context *ev;
      99             :         struct imessaging_context *msg_client_ctx;
     100             :         struct imessaging_context *msg_server_ctx;
     101           1 :         int ping_count = 0;
     102           1 :         int pong_count = 0;
     103             :         struct timeval tv;
     104           1 :         int timelimit = torture_setting_int(tctx, "timelimit", 10);
     105             :         uint32_t msg_ping, msg_exit;
     106             : 
     107           1 :         lpcfg_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
     108             : 
     109           1 :         ev = tctx->ev;
     110             : 
     111           1 :         msg_server_ctx = imessaging_init(tctx,
     112             :                                          tctx->lp_ctx, cluster_id(0, 1),
     113             :                                          ev);
     114             :         
     115           1 :         torture_assert(tctx, msg_server_ctx != NULL, "Failed to init ping messaging context");
     116             :                 
     117           1 :         imessaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping);
     118           1 :         imessaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit);
     119             : 
     120           1 :         msg_client_ctx = imessaging_init(tctx,
     121             :                                          tctx->lp_ctx,
     122             :                                          cluster_id(0, 2),
     123             :                                          ev);
     124             : 
     125           1 :         torture_assert(tctx, msg_client_ctx != NULL, 
     126             :                        "msg_client_ctx imessaging_init() failed");
     127             : 
     128           1 :         imessaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong);
     129             : 
     130           1 :         tv = timeval_current();
     131             : 
     132           1 :         torture_comment(tctx, "Sending pings for %d seconds\n", timelimit);
     133           1 :         while (timeval_elapsed(&tv) < timelimit) {
     134             :                 DATA_BLOB data;
     135             :                 NTSTATUS status1, status2;
     136             : 
     137        3659 :                 data.data = discard_const_p(uint8_t, "testing");
     138        3659 :                 data.length = strlen((const char *)data.data);
     139             : 
     140        3659 :                 status1 = imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, &data);
     141        3659 :                 status2 = imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, NULL);
     142             : 
     143        3659 :                 torture_assert_ntstatus_ok(tctx, status1, "msg1 failed");
     144        3659 :                 ping_count++;
     145             : 
     146        3659 :                 torture_assert_ntstatus_ok(tctx, status2, "msg2 failed");
     147        3659 :                 ping_count++;
     148             : 
     149       65691 :                 while (ping_count > pong_count + 20) {
     150       58373 :                         tevent_loop_once(ev);
     151             :                 }
     152             :         }
     153             : 
     154           1 :         torture_comment(tctx, "waiting for %d remaining replies (done %d)\n", 
     155             :                ping_count - pong_count, pong_count);
     156         107 :         while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
     157         105 :                 tevent_loop_once(ev);
     158             :         }
     159             : 
     160           1 :         torture_comment(tctx, "sending exit\n");
     161           1 :         imessaging_send(msg_client_ctx, cluster_id(0, 1), msg_exit, NULL);
     162             : 
     163           1 :         torture_assert_int_equal(tctx, ping_count, pong_count, "ping test failed");
     164             : 
     165           2 :         torture_comment(tctx, "ping rate of %.0f messages/sec\n", 
     166           2 :                (ping_count+pong_count)/timeval_elapsed(&tv));
     167             : 
     168           1 :         talloc_free(msg_client_ctx);
     169           1 :         talloc_free(msg_server_ctx);
     170             : 
     171           1 :         return true;
     172             : }
     173             : 
     174           1 : static bool test_messaging_overflow(struct torture_context *tctx)
     175             : {
     176             :         struct imessaging_context *msg_ctx;
     177             :         ssize_t nwritten, nread;
     178             :         pid_t child;
     179           1 :         char c = 0;
     180             :         int up_pipe[2], down_pipe[2];
     181             :         int i, ret, child_status;
     182             : 
     183           1 :         ret = pipe(up_pipe);
     184           1 :         torture_assert(tctx, ret == 0, "pipe failed");
     185           1 :         ret = pipe(down_pipe);
     186           1 :         torture_assert(tctx, ret == 0, "pipe failed");
     187             : 
     188           1 :         child = fork();
     189           2 :         if (child < 0) {
     190           0 :                 torture_fail(tctx, "fork failed");
     191             :         }
     192             : 
     193           2 :         if (child == 0) {
     194           1 :                 ret = tevent_re_initialise(tctx->ev);
     195           1 :                 torture_assert(tctx, ret == 0, "tevent_re_initialise failed");
     196             : 
     197           2 :                 msg_ctx = imessaging_init(tctx, tctx->lp_ctx,
     198           1 :                                           cluster_id(getpid(), 0),
     199             :                                           tctx->ev);
     200           1 :                 torture_assert(tctx, msg_ctx != NULL,
     201             :                                "imessaging_init failed");
     202             : 
     203             :                 do {
     204           1 :                         nwritten = write(up_pipe[1], &c, 1);
     205           1 :                 } while ((nwritten == -1) && (errno == EINTR));
     206             : 
     207           1 :                 ret = close(down_pipe[1]);
     208           1 :                 torture_assert(tctx, ret == 0, "close failed");
     209             : 
     210             :                 do {
     211           2 :                         nread = read(down_pipe[0], &c, 1);
     212           1 :                 } while ((nread == -1) && (errno == EINTR));
     213             : 
     214           1 :                 exit(0);
     215             :         }
     216             : 
     217             :         do {
     218           2 :                 nread = read(up_pipe[0], &c, 1);
     219           1 :         } while ((nread == -1) && (errno == EINTR));
     220             : 
     221           1 :         msg_ctx = imessaging_init(tctx, tctx->lp_ctx, cluster_id(getpid(), 0),
     222             :                                   tctx->ev);
     223           1 :         torture_assert(tctx, msg_ctx != NULL, "imessaging_init failed");
     224             : 
     225        1000 :         for (i=0; i<1000; i++) {
     226             :                 NTSTATUS status;
     227        1000 :                 status = imessaging_send(msg_ctx, cluster_id(child, 0),
     228             :                                          MSG_PING, NULL);
     229        1000 :                 torture_assert_ntstatus_ok(tctx, status,
     230             :                                            "imessaging_send failed");
     231             :         }
     232             : 
     233           1 :         tevent_loop_once(tctx->ev);
     234             : 
     235           1 :         talloc_free(msg_ctx);
     236             : 
     237           1 :         ret = close(down_pipe[1]);
     238           1 :         torture_assert(tctx, ret == 0, "close failed");
     239             : 
     240           1 :         ret = waitpid(child, &child_status, 0);
     241           1 :         torture_assert(tctx, ret == child, "wrong child exited");
     242           1 :         torture_assert(tctx, child_status == 0, "child failed");
     243             : 
     244           1 :         poll(NULL, 0, 500);
     245             : 
     246           1 :         return true;
     247             : }
     248             : 
     249             : struct overflow_parent_child {
     250             :         gnutls_hash_hd_t md5_hash_hnd;
     251             :         bool done;
     252             : };
     253             : 
     254        1001 : static void overflow_md5_child_handler(struct imessaging_context *msg,
     255             :                                        void *private_data,
     256             :                                        uint32_t msg_type,
     257             :                                        struct server_id server_id,
     258             :                                        size_t num_fds,
     259             :                                        int *fds,
     260             :                                        DATA_BLOB *data)
     261             : {
     262        1001 :         struct overflow_parent_child *state = private_data;
     263             : 
     264        1001 :         if (num_fds != 0) {
     265           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     266           0 :                 return;
     267             :         }
     268             : 
     269        1001 :         if (data->length == 0) {
     270           1 :                 state->done = true;
     271           1 :                 return;
     272             :         }
     273             : 
     274        1000 :         gnutls_hash(state->md5_hash_hnd, data->data, data->length);
     275             : }
     276             : 
     277             : struct overflow_child_parent {
     278             :         uint8_t final[16];
     279             :         bool done;
     280             : };
     281             : 
     282           1 : static void overflow_md5_parent_handler(struct imessaging_context *msg_ctx,
     283             :                                         void *private_data,
     284             :                                         uint32_t msg_type,
     285             :                                         struct server_id server_id,
     286             :                                         size_t num_fds,
     287             :                                         int *fds,
     288             :                                         DATA_BLOB *data)
     289             : {
     290           1 :         struct overflow_child_parent *state = private_data;
     291             : 
     292           1 :         if (num_fds != 0) {
     293           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     294           0 :                 return;
     295             :         }
     296             : 
     297           1 :         if (data->length != sizeof(state->final)) {
     298           0 :                 memset(state->final, 0, sizeof(state->final));
     299           0 :                 state->done = true;
     300           0 :                 return;
     301             :         }
     302           2 :         memcpy(state->final, data->data, 16);
     303           1 :         state->done = true;
     304             : }
     305             : 
     306           1 : static bool test_messaging_overflow_check(struct torture_context *tctx)
     307             : {
     308             :         struct imessaging_context *msg_ctx;
     309             :         ssize_t nwritten, nread;
     310             :         pid_t child;
     311           1 :         char c = 0;
     312             :         int up_pipe[2], down_pipe[2];
     313             :         int i, ret, child_status;
     314             :         gnutls_hash_hd_t hash_hnd;
     315             :         uint8_t final[16];
     316           1 :         struct overflow_child_parent child_msg = { .done = false };
     317             :         NTSTATUS status;
     318             : 
     319           1 :         ret = pipe(up_pipe);
     320           1 :         torture_assert(tctx, ret == 0, "pipe failed");
     321           1 :         ret = pipe(down_pipe);
     322           1 :         torture_assert(tctx, ret == 0, "pipe failed");
     323             : 
     324           1 :         child = fork();
     325           2 :         if (child < 0) {
     326           0 :                 torture_fail(tctx, "fork failed");
     327             :         }
     328             : 
     329           2 :         if (child == 0) {
     330           1 :                 struct overflow_parent_child child_state = { .done = false };
     331           1 :                 DATA_BLOB retblob = { .data = final, .length = sizeof(final) };
     332             : 
     333           1 :                 ret = tevent_re_initialise(tctx->ev);
     334           1 :                 torture_assert(tctx, ret == 0, "tevent_re_initialise failed");
     335             : 
     336           1 :                 gnutls_hash_init(&child_state.md5_hash_hnd, GNUTLS_DIG_MD5);
     337             : 
     338           2 :                 msg_ctx = imessaging_init(tctx, tctx->lp_ctx,
     339           1 :                                           cluster_id(getpid(), 0),
     340             :                                           tctx->ev);
     341           1 :                 torture_assert(tctx, msg_ctx != NULL,
     342             :                                "imessaging_init failed");
     343             : 
     344           1 :                 status = imessaging_register(msg_ctx, &child_state,
     345             :                                              MSG_TMP_BASE-1,
     346             :                                              overflow_md5_child_handler);
     347           1 :                 torture_assert(tctx, NT_STATUS_IS_OK(status),
     348             :                                "imessaging_register failed");
     349             : 
     350             :                 do {
     351           1 :                         nwritten = write(up_pipe[1], &c, 1);
     352           1 :                 } while ((nwritten == -1) && (errno == EINTR));
     353             : 
     354           1 :                 ret = close(down_pipe[1]);
     355           1 :                 torture_assert(tctx, ret == 0, "close failed");
     356             : 
     357             :                 do {
     358           2 :                         nread = read(down_pipe[0], &c, 1);
     359           1 :                 } while ((nread == -1) && (errno == EINTR));
     360             : 
     361        1002 :                 while (!child_state.done) {
     362        1001 :                         tevent_loop_once(tctx->ev);
     363             :                 }
     364             : 
     365           1 :                 gnutls_hash_deinit(child_state.md5_hash_hnd, final);
     366             : 
     367           1 :                 status = imessaging_send(msg_ctx,
     368           1 :                                          cluster_id(getppid(), 0),
     369             :                                          MSG_TMP_BASE-2,
     370             :                                          &retblob);
     371           1 :                 torture_assert(tctx, NT_STATUS_IS_OK(status),
     372             :                                "imessaging_send failed");
     373             : 
     374           1 :                 exit(0);
     375             :         }
     376             : 
     377             :         do {
     378           2 :                 nread = read(up_pipe[0], &c, 1);
     379           1 :         } while ((nread == -1) && (errno == EINTR));
     380             : 
     381           1 :         msg_ctx = imessaging_init(tctx, tctx->lp_ctx, cluster_id(getpid(), 0),
     382             :                                   tctx->ev);
     383           1 :         torture_assert(tctx, msg_ctx != NULL, "imessaging_init failed");
     384             : 
     385           1 :         status = imessaging_register(msg_ctx,
     386             :                                      &child_msg,
     387             :                                      MSG_TMP_BASE-2,
     388             :                                      overflow_md5_parent_handler);
     389           1 :         torture_assert(tctx,
     390             :                        NT_STATUS_IS_OK(status),
     391             :                        "imessaging_register failed");
     392             : 
     393           1 :         gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
     394             : 
     395        1001 :         for (i=0; i<1000; i++) {
     396        1000 :                 size_t len = ((random() % 100) + 1);
     397        1000 :                 uint8_t buf[len];
     398        1000 :                 DATA_BLOB blob = { .data = buf, .length = len };
     399             : 
     400        1000 :                 generate_random_buffer(buf, len);
     401             : 
     402        1000 :                 gnutls_hash(hash_hnd, buf, len);
     403             : 
     404        1000 :                 status = imessaging_send(msg_ctx, cluster_id(child, 0),
     405             :                                          MSG_TMP_BASE-1, &blob);
     406        1000 :                 torture_assert_ntstatus_ok(tctx, status,
     407             :                                            "imessaging_send failed");
     408             :         }
     409             : 
     410           1 :         status = imessaging_send(msg_ctx, cluster_id(child, 0),
     411             :                                  MSG_TMP_BASE-1, NULL);
     412           1 :         torture_assert_ntstatus_ok(tctx, status,
     413             :                                    "imessaging_send failed");
     414             : 
     415           1 :         gnutls_hash_deinit(hash_hnd, final);
     416             : 
     417             :         do {
     418           1 :                 nwritten = write(down_pipe[1], &c, 1);
     419           1 :         } while ((nwritten == -1) && (errno == EINTR));
     420             : 
     421        2972 :         while (!child_msg.done) {
     422        2971 :                 tevent_loop_once(tctx->ev);
     423             :         }
     424             : 
     425           1 :         ret = close(down_pipe[1]);
     426           1 :         torture_assert(tctx, ret == 0, "close failed");
     427             : 
     428           1 :         talloc_free(msg_ctx);
     429             : 
     430           1 :         ret = waitpid(child, &child_status, 0);
     431           1 :         torture_assert(tctx, ret == child, "wrong child exited");
     432           1 :         torture_assert(tctx, child_status == 0, "child failed");
     433             : 
     434           1 :         if (memcmp(final, child_msg.final, 16) != 0) {
     435           0 :                 dump_data_file(final, 16, false, stderr);
     436           0 :                 dump_data_file(child_msg.final, 16, false, stderr);
     437           0 :                 fflush(stderr);
     438           0 :                 torture_fail(tctx, "checksum comparison failed");
     439             :         }
     440             : 
     441           0 :         return true;
     442             : }
     443             : 
     444             : struct test_multi_ctx {
     445             :         struct torture_context *tctx;
     446             :         struct imessaging_context *server_ctx;
     447             :         struct imessaging_context *client_ctx[4];
     448             :         size_t num_missing;
     449             :         bool got_server;
     450             :         bool got_client_0_1;
     451             :         bool got_client_2_3;
     452             :         bool ok;
     453             : };
     454             : 
     455           1 : static void multi_ctx_server_handler(struct imessaging_context *msg,
     456             :                                      void *private_data,
     457             :                                      uint32_t msg_type,
     458             :                                      struct server_id server_id,
     459             :                                      size_t num_fds,
     460             :                                      int *fds,
     461             :                                      DATA_BLOB *data)
     462             : {
     463           1 :         struct test_multi_ctx *state = private_data;
     464           1 :         char *str = NULL;
     465             : 
     466           1 :         if (num_fds != 0) {
     467           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     468           0 :                 return;
     469             :         }
     470             : 
     471           1 :         torture_assert_goto(state->tctx, state->num_missing >= 1,
     472             :                             state->ok, fail,
     473             :                             "num_missing should be at least 1.");
     474           1 :         state->num_missing -= 1;
     475             : 
     476           1 :         torture_assert_goto(state->tctx, !state->got_server,
     477             :                             state->ok, fail,
     478             :                             "already got server.");
     479           1 :         state->got_server = true;
     480             : 
     481             :         /*
     482             :          * We free the context itself and most likely reuse
     483             :          * the memory immediately.
     484             :          */
     485           1 :         TALLOC_FREE(state->server_ctx);
     486           1 :         str = generate_random_str(state->tctx, 128);
     487           1 :         torture_assert_goto(state->tctx, str != NULL,
     488             :                             state->ok, fail,
     489             :                             "generate_random_str()");
     490             : 
     491           2 : fail:
     492           0 :         return;
     493             : }
     494             : 
     495           1 : static void multi_ctx_client_0_1_handler(struct imessaging_context *msg,
     496             :                                          void *private_data,
     497             :                                          uint32_t msg_type,
     498             :                                          struct server_id server_id,
     499             :                                          size_t num_fds,
     500             :                                          int *fds,
     501             :                                          DATA_BLOB *data)
     502             : {
     503           1 :         struct test_multi_ctx *state = private_data;
     504           1 :         char *str = NULL;
     505             : 
     506           1 :         if (num_fds != 0) {
     507           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     508           0 :                 return;
     509             :         }
     510             : 
     511           1 :         torture_assert_goto(state->tctx, state->num_missing >= 2,
     512             :                             state->ok, fail,
     513             :                             "num_missing should be at least 2.");
     514           1 :         state->num_missing -= 2;
     515             : 
     516           1 :         torture_assert_goto(state->tctx, !state->got_client_0_1,
     517             :                             state->ok, fail,
     518             :                             "already got client_0_1.");
     519           1 :         state->got_client_0_1 = true;
     520             : 
     521             :         /*
     522             :          * We free two contexts and most likely reuse
     523             :          * the memory immediately.
     524             :          */
     525           1 :         TALLOC_FREE(state->client_ctx[0]);
     526           1 :         str = generate_random_str(state->tctx, 128);
     527           1 :         torture_assert_goto(state->tctx, str != NULL,
     528             :                             state->ok, fail,
     529             :                             "generate_random_str()");
     530           1 :         TALLOC_FREE(state->client_ctx[1]);
     531           1 :         str = generate_random_str(state->tctx, 128);
     532           1 :         torture_assert_goto(state->tctx, str != NULL,
     533             :                             state->ok, fail,
     534             :                             "generate_random_str()");
     535             : 
     536           2 : fail:
     537           0 :         return;
     538             : }
     539             : 
     540           1 : static void multi_ctx_client_2_3_handler(struct imessaging_context *msg,
     541             :                                          void *private_data,
     542             :                                          uint32_t msg_type,
     543             :                                          struct server_id server_id,
     544             :                                          size_t num_fds,
     545             :                                          int *fds,
     546             :                                          DATA_BLOB *data)
     547             : {
     548           1 :         struct test_multi_ctx *state = private_data;
     549           1 :         char *str = NULL;
     550             : 
     551           1 :         if (num_fds != 0) {
     552           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     553           0 :                 return;
     554             :         }
     555             : 
     556           1 :         torture_assert_goto(state->tctx, state->num_missing >= 2,
     557             :                             state->ok, fail,
     558             :                             "num_missing should be at least 2.");
     559           1 :         state->num_missing -= 2;
     560             : 
     561           1 :         torture_assert_goto(state->tctx, !state->got_client_2_3,
     562             :                             state->ok, fail,
     563             :                             "already got client_2_3.");
     564           1 :         state->got_client_2_3 = true;
     565             : 
     566             :         /*
     567             :          * We free two contexts and most likely reuse
     568             :          * the memory immediately.
     569             :          */
     570           1 :         TALLOC_FREE(state->client_ctx[2]);
     571           1 :         str = generate_random_str(state->tctx, 128);
     572           1 :         torture_assert_goto(state->tctx, str != NULL,
     573             :                             state->ok, fail,
     574             :                             "generate_random_str()");
     575           1 :         TALLOC_FREE(state->client_ctx[3]);
     576           1 :         str = generate_random_str(state->tctx, 128);
     577           1 :         torture_assert_goto(state->tctx, str != NULL,
     578             :                             state->ok, fail,
     579             :                             "generate_random_str()");
     580             : 
     581           2 : fail:
     582           0 :         return;
     583             : }
     584             : 
     585           1 : static bool test_multi_ctx(struct torture_context *tctx)
     586             : {
     587           1 :         struct test_multi_ctx state = {
     588             :                 .tctx = tctx,
     589             :                 .ok = true,
     590             :         };
     591             :         struct timeval tv;
     592             :         NTSTATUS status;
     593             : 
     594           1 :         lpcfg_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");
     595             : 
     596             :         /*
     597             :          * We use cluster_id(0, 0) as that gets for
     598             :          * all task ids.
     599             :          */
     600           1 :         state.server_ctx = imessaging_init(tctx,
     601             :                                            tctx->lp_ctx,
     602             :                                            cluster_id(0, 0),
     603             :                                            tctx->ev);
     604           1 :         torture_assert(tctx, state.server_ctx != NULL,
     605             :                        "Failed to init messaging context");
     606             : 
     607           1 :         status = imessaging_register(state.server_ctx, &state,
     608             :                                      MSG_TMP_BASE-1,
     609             :                                      multi_ctx_server_handler);
     610           1 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed");
     611             : 
     612           1 :         state.client_ctx[0] = imessaging_init(tctx,
     613             :                                               tctx->lp_ctx,
     614             :                                               cluster_id(0, 0),
     615             :                                               tctx->ev);
     616           1 :         torture_assert(tctx, state.client_ctx[0] != NULL,
     617             :                        "msg_client_ctx imessaging_init() failed");
     618           1 :         status = imessaging_register(state.client_ctx[0], &state,
     619             :                                      MSG_TMP_BASE-1,
     620             :                                      multi_ctx_client_0_1_handler);
     621           1 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed");
     622           1 :         state.client_ctx[1] = imessaging_init(tctx,
     623             :                                               tctx->lp_ctx,
     624             :                                               cluster_id(0, 0),
     625             :                                               tctx->ev);
     626           1 :         torture_assert(tctx, state.client_ctx[1] != NULL,
     627             :                        "msg_client_ctx imessaging_init() failed");
     628           1 :         status = imessaging_register(state.client_ctx[1], &state,
     629             :                                      MSG_TMP_BASE-1,
     630             :                                      multi_ctx_client_0_1_handler);
     631           1 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed");
     632           1 :         state.client_ctx[2] = imessaging_init(tctx,
     633             :                                               tctx->lp_ctx,
     634             :                                               cluster_id(0, 0),
     635             :                                               tctx->ev);
     636           1 :         torture_assert(tctx, state.client_ctx[2] != NULL,
     637             :                        "msg_client_ctx imessaging_init() failed");
     638           1 :         status = imessaging_register(state.client_ctx[2], &state,
     639             :                                      MSG_TMP_BASE-1,
     640             :                                      multi_ctx_client_2_3_handler);
     641           1 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed");
     642           1 :         state.client_ctx[3] = imessaging_init(tctx,
     643             :                                               tctx->lp_ctx,
     644             :                                               cluster_id(0, 0),
     645             :                                               tctx->ev);
     646           1 :         torture_assert(tctx, state.client_ctx[3] != NULL,
     647             :                        "msg_client_ctx imessaging_init() failed");
     648           1 :         status = imessaging_register(state.client_ctx[3], &state,
     649             :                                      MSG_TMP_BASE-1,
     650             :                                      multi_ctx_client_2_3_handler);
     651           1 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "imessaging_register failed");
     652             : 
     653             :         /*
     654             :          * Send one message that need to arrive on 3 ( 5 - 2 ) handlers.
     655             :          */
     656           1 :         state.num_missing = 5;
     657             : 
     658           1 :         status = imessaging_send(state.server_ctx,
     659             :                                  cluster_id(0, 0),
     660             :                                  MSG_TMP_BASE-1, NULL);
     661           1 :         torture_assert_ntstatus_ok(tctx, status, "msg failed");
     662             : 
     663           1 :         tv = timeval_current();
     664           1 :         while (timeval_elapsed(&tv) < 30 && state.num_missing > 0 && state.ok) {
     665             :                 int ret;
     666             : 
     667           1 :                 ret = tevent_loop_once(tctx->ev);
     668           1 :                 torture_assert_int_equal(tctx, ret, 0, "tevent_loop_once()");
     669             :         }
     670             : 
     671           1 :         if (!state.ok) {
     672           0 :                 return false;
     673             :         }
     674             : 
     675           1 :         torture_assert_int_equal(tctx, state.num_missing, 0,
     676             :                                  "wrong message count");
     677             : 
     678           1 :         torture_assert(tctx, state.got_client_0_1, "got_client_0_1");
     679           1 :         torture_assert(tctx, state.got_client_2_3, "got_client_2_3");
     680           1 :         torture_assert(tctx, state.got_server, "got_server");
     681             : 
     682           0 :         return true;
     683             : }
     684             : 
     685        2355 : struct torture_suite *torture_local_messaging(TALLOC_CTX *mem_ctx)
     686             : {
     687        2355 :         struct torture_suite *s = torture_suite_create(mem_ctx, "messaging");
     688        2355 :         torture_suite_add_simple_test(s, "overflow", test_messaging_overflow);
     689        2355 :         torture_suite_add_simple_test(s, "overflow_check",
     690             :                                       test_messaging_overflow_check);
     691        2355 :         torture_suite_add_simple_test(s, "ping_speed", test_ping_speed);
     692        2355 :         torture_suite_add_simple_test(s, "multi_ctx", test_multi_ctx);
     693        2355 :         return s;
     694             : }

Generated by: LCOV version 1.13