tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_dispatch.c (5984B)


      1 /* Copyright (c) 2018-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 #define DISPATCH_NEW_PRIVATE
      5 #define DISPATCH_PRIVATE
      6 
      7 #include "test/test.h"
      8 
      9 #include "lib/dispatch/dispatch.h"
     10 #include "lib/dispatch/dispatch_cfg.h"
     11 #include "lib/dispatch/dispatch_st.h"
     12 #include "lib/dispatch/msgtypes.h"
     13 
     14 #include "lib/log/escape.h"
     15 #include "lib/malloc/malloc.h"
     16 #include "lib/string/printf.h"
     17 
     18 #include <stdio.h>
     19 #include <string.h>
     20 
     21 static dispatch_t *dispatcher_in_use=NULL;
     22 
     23 static void
     24 test_dispatch_max_in_u16_sl(void *arg)
     25 {
     26  (void)arg;
     27  smartlist_t *sl = smartlist_new();
     28  uint16_t nums[] = { 10, 20, 30 };
     29  tt_int_op(-1, OP_EQ, max_in_u16_sl(sl, -1));
     30 
     31  smartlist_add(sl, NULL);
     32  tt_int_op(-1, OP_EQ, max_in_u16_sl(sl, -1));
     33 
     34  smartlist_add(sl, &nums[1]);
     35  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
     36 
     37  smartlist_add(sl, &nums[0]);
     38  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
     39 
     40  smartlist_add(sl, NULL);
     41  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
     42 
     43  smartlist_add(sl, &nums[2]);
     44  tt_int_op(30, OP_EQ, max_in_u16_sl(sl, -1));
     45 
     46 done:
     47  smartlist_free(sl);
     48 }
     49 
     50 /* Construct an empty dispatch_t. */
     51 static void
     52 test_dispatch_empty(void *arg)
     53 {
     54  (void)arg;
     55 
     56  dispatch_t *d=NULL;
     57  dispatch_cfg_t *cfg=NULL;
     58 
     59  cfg = dcfg_new();
     60  d = dispatch_new(cfg);
     61  tt_assert(d);
     62 
     63 done:
     64  dispatch_free(d);
     65  dcfg_free(cfg);
     66 }
     67 
     68 static int total_recv1_simple = 0;
     69 static int total_recv2_simple = 0;
     70 
     71 static void
     72 simple_recv1(const msg_t *m)
     73 {
     74  total_recv1_simple += m->aux_data__.u64;
     75 }
     76 
     77 static char *recv2_received = NULL;
     78 
     79 static void
     80 simple_recv2(const msg_t *m)
     81 {
     82  tor_free(recv2_received);
     83  recv2_received = dispatch_fmt_msg_data(dispatcher_in_use, m);
     84 
     85  total_recv2_simple += m->aux_data__.u64*10;
     86 }
     87 
     88 /* Construct a dispatch_t with two messages, make sure that they both get
     89 * delivered. */
     90 static void
     91 test_dispatch_simple(void *arg)
     92 {
     93  (void)arg;
     94 
     95  dispatch_t *d=NULL;
     96  dispatch_cfg_t *cfg=NULL;
     97  int r;
     98 
     99  cfg = dcfg_new();
    100  r = dcfg_msg_set_type(cfg,0,0);
    101  r += dcfg_msg_set_chan(cfg,0,0);
    102  r += dcfg_add_recv(cfg,0,1,simple_recv1);
    103  r += dcfg_msg_set_type(cfg,1,0);
    104  r += dcfg_msg_set_chan(cfg,1,0);
    105  r += dcfg_add_recv(cfg,1,1,simple_recv2);
    106  r += dcfg_add_recv(cfg,1,1,simple_recv2); /* second copy */
    107  tt_int_op(r, OP_EQ, 0);
    108 
    109  d = dispatch_new(cfg);
    110  tt_assert(d);
    111  dispatcher_in_use = d;
    112 
    113  msg_aux_data_t data = {.u64 = 7};
    114  r = dispatch_send(d, 99, 0, 0, 0, data);
    115  tt_int_op(r, OP_EQ, 0);
    116  tt_int_op(total_recv1_simple, OP_EQ, 0);
    117 
    118  r = dispatch_flush(d, 0, INT_MAX);
    119  tt_int_op(r, OP_EQ, 0);
    120  tt_int_op(total_recv1_simple, OP_EQ, 7);
    121  tt_int_op(total_recv2_simple, OP_EQ, 0);
    122 
    123  total_recv1_simple = 0;
    124  r = dispatch_send(d, 99, 0, 1, 0, data);
    125  tt_int_op(r, OP_EQ, 0);
    126  r = dispatch_flush(d, 0, INT_MAX);
    127  tt_int_op(total_recv1_simple, OP_EQ, 0);
    128  tt_int_op(total_recv2_simple, OP_EQ, 140);
    129 
    130  tt_str_op(recv2_received, OP_EQ, "<>"); // no format function was set.
    131 
    132 done:
    133  dispatch_free(d);
    134  dcfg_free(cfg);
    135  tor_free(recv2_received);
    136 }
    137 
    138 /* Construct a dispatch_t with a message and no receiver; make sure that it
    139 * gets dropped properly. */
    140 static void
    141 test_dispatch_no_recipient(void *arg)
    142 {
    143  (void)arg;
    144 
    145  dispatch_t *d=NULL;
    146  dispatch_cfg_t *cfg=NULL;
    147  int r;
    148 
    149  cfg = dcfg_new();
    150  r = dcfg_msg_set_type(cfg,0,0);
    151  r += dcfg_msg_set_chan(cfg,0,0);
    152  tt_int_op(r, OP_EQ, 0);
    153 
    154  d = dispatch_new(cfg);
    155  tt_assert(d);
    156  dispatcher_in_use = d;
    157 
    158  msg_aux_data_t data = { .u64 = 7};
    159  r = dispatch_send(d, 99, 0, 0, 0, data);
    160  tt_int_op(r, OP_EQ, 0);
    161 
    162  r = dispatch_flush(d, 0, INT_MAX);
    163  tt_int_op(r, OP_EQ, 0);
    164 
    165 done:
    166  dispatch_free(d);
    167  dcfg_free(cfg);
    168 }
    169 
    170 struct coord_t { int x; int y; };
    171 static void
    172 free_coord(msg_aux_data_t d)
    173 {
    174  tor_free(d.ptr);
    175 }
    176 static char *
    177 fmt_coord(msg_aux_data_t d)
    178 {
    179  char *v;
    180  struct coord_t *c = d.ptr;
    181  tor_asprintf(&v, "[%d, %d]", c->x, c->y);
    182  return v;
    183 }
    184 static dispatch_typefns_t coord_fns = {
    185  .fmt_fn = fmt_coord,
    186  .free_fn = free_coord,
    187 };
    188 static void
    189 alert_run_immediate(dispatch_t *d, channel_id_t ch, void *arg)
    190 {
    191  (void)arg;
    192  dispatch_flush(d, ch, INT_MAX);
    193 }
    194 
    195 static char *received_data=NULL;
    196 
    197 static void
    198 recv_typed_data(const msg_t *m)
    199 {
    200  tor_free(received_data);
    201  received_data = dispatch_fmt_msg_data(dispatcher_in_use, m);
    202 }
    203 
    204 static void
    205 test_dispatch_with_types(void *arg)
    206 {
    207  (void)arg;
    208 
    209  dispatch_t *d=NULL;
    210  dispatch_cfg_t *cfg=NULL;
    211  int r;
    212 
    213  cfg = dcfg_new();
    214  r = dcfg_msg_set_type(cfg,5,3);
    215  r += dcfg_msg_set_chan(cfg,5,2);
    216  r += dcfg_add_recv(cfg,5,0,recv_typed_data);
    217  r += dcfg_type_set_fns(cfg,3,&coord_fns);
    218  tt_int_op(r, OP_EQ, 0);
    219 
    220  d = dispatch_new(cfg);
    221  tt_assert(d);
    222  dispatcher_in_use = d;
    223 
    224  /* Make this message get run immediately. */
    225  r = dispatch_set_alert_fn(d, 2, alert_run_immediate, NULL);
    226  tt_int_op(r, OP_EQ, 0);
    227 
    228  struct coord_t *xy = tor_malloc(sizeof(*xy));
    229  xy->x = 13;
    230  xy->y = 37;
    231  msg_aux_data_t data = {.ptr = xy};
    232  r = dispatch_send(d, 99/*sender*/, 2/*channel*/, 5/*msg*/, 3/*type*/, data);
    233  tt_int_op(r, OP_EQ, 0);
    234  tt_str_op(received_data, OP_EQ, "[13, 37]");
    235 
    236 done:
    237  dispatch_free(d);
    238  dcfg_free(cfg);
    239  tor_free(received_data);
    240  dispatcher_in_use = NULL;
    241 }
    242 
    243 static void
    244 test_dispatch_bad_type_setup(void *arg)
    245 {
    246  (void)arg;
    247  static dispatch_typefns_t fns;
    248  dispatch_cfg_t *cfg = dcfg_new();
    249 
    250  tt_int_op(0, OP_EQ, dcfg_type_set_fns(cfg, 7, &coord_fns));
    251 
    252  fns = coord_fns;
    253  fns.fmt_fn = NULL;
    254  tt_int_op(-1, OP_EQ, dcfg_type_set_fns(cfg, 7, &fns));
    255 
    256  fns = coord_fns;
    257  fns.free_fn = NULL;
    258  tt_int_op(-1, OP_EQ, dcfg_type_set_fns(cfg, 7, &fns));
    259 
    260  fns = coord_fns;
    261  tt_int_op(0, OP_EQ, dcfg_type_set_fns(cfg, 7, &fns));
    262 
    263 done:
    264  dcfg_free(cfg);
    265 }
    266 
    267 #define T(name)                                                 \
    268  { #name, test_dispatch_ ## name, TT_FORK, NULL, NULL }
    269 
    270 struct testcase_t dispatch_tests[] = {
    271  T(max_in_u16_sl),
    272  T(empty),
    273  T(simple),
    274  T(no_recipient),
    275  T(with_types),
    276  T(bad_type_setup),
    277  END_OF_TESTCASES
    278 };