tor

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

test_containers.c (43900B)


      1 /* Copyright (c) 2001-2004, Roger Dingledine.
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 #include "orconfig.h"
      7 #include "core/or/or.h"
      8 #include "lib/crypt_ops/crypto_rand.h"
      9 #include "feature/dircommon/fp_pair.h"
     10 #include "test/test.h"
     11 
     12 #include "lib/container/bitarray.h"
     13 #include "lib/container/order.h"
     14 #include "lib/crypt_ops/digestset.h"
     15 
     16 /** Helper: return a tristate based on comparing the strings in *<b>a</b> and
     17 * *<b>b</b>. */
     18 static int
     19 compare_strs_(const void **a, const void **b)
     20 {
     21  const char *s1 = *a, *s2 = *b;
     22  return strcmp(s1, s2);
     23 }
     24 
     25 /** Helper: return a tristate based on comparing the strings in <b>a</b> and
     26 * *<b>b</b>. */
     27 static int
     28 compare_strs_for_bsearch_(const void *a, const void **b)
     29 {
     30  const char *s1 = a, *s2 = *b;
     31  return strcmp(s1, s2);
     32 }
     33 
     34 /** Helper: return a tristate based on comparing the strings in *<b>a</b> and
     35 * *<b>b</b>, excluding a's first character, and ignoring case. */
     36 static int
     37 cmp_without_first_(const void *a, const void **b)
     38 {
     39  const char *s1 = a, *s2 = *b;
     40  return strcasecmp(s1+1, s2);
     41 }
     42 
     43 /** Run unit tests for basic dynamic-sized array functionality. */
     44 static void
     45 test_container_smartlist_basic(void *arg)
     46 {
     47  smartlist_t *sl;
     48  char *v0 = tor_strdup("v0");
     49  char *v1 = tor_strdup("v1");
     50  char *v2 = tor_strdup("v2");
     51  char *v3 = tor_strdup("v3");
     52  char *v4 = tor_strdup("v4");
     53  char *v22 = tor_strdup("v22");
     54  char *v99 = tor_strdup("v99");
     55  char *v555 = tor_strdup("v555");
     56 
     57  /* XXXX test sort_digests, uniq_strings, uniq_digests */
     58 
     59  /* Test smartlist add, del_keeporder, insert, get. */
     60  (void)arg;
     61  sl = smartlist_new();
     62  smartlist_add(sl, v1);
     63  smartlist_add(sl, v2);
     64  smartlist_add(sl, v3);
     65  smartlist_add(sl, v4);
     66  smartlist_del_keeporder(sl, 1);
     67  smartlist_insert(sl, 1, v22);
     68  smartlist_insert(sl, 0, v0);
     69  smartlist_insert(sl, 5, v555);
     70  tt_ptr_op(v0,OP_EQ,   smartlist_get(sl,0));
     71  tt_ptr_op(v1,OP_EQ,   smartlist_get(sl,1));
     72  tt_ptr_op(v22,OP_EQ,  smartlist_get(sl,2));
     73  tt_ptr_op(v3,OP_EQ,   smartlist_get(sl,3));
     74  tt_ptr_op(v4,OP_EQ,   smartlist_get(sl,4));
     75  tt_ptr_op(v555,OP_EQ, smartlist_get(sl,5));
     76  /* Try deleting in the middle. */
     77  smartlist_del(sl, 1);
     78  tt_ptr_op(v555,OP_EQ, smartlist_get(sl, 1));
     79  /* Try deleting at the end. */
     80  smartlist_del(sl, 4);
     81  tt_int_op(4,OP_EQ, smartlist_len(sl));
     82 
     83  /* test isin. */
     84  tt_assert(smartlist_contains(sl, v3));
     85  tt_assert(!smartlist_contains(sl, v99));
     86 
     87 done:
     88  smartlist_free(sl);
     89  tor_free(v0);
     90  tor_free(v1);
     91  tor_free(v2);
     92  tor_free(v3);
     93  tor_free(v4);
     94  tor_free(v22);
     95  tor_free(v99);
     96  tor_free(v555);
     97 }
     98 
     99 /** Test SMARTLIST_FOREACH_REVERSE_BEGIN loop macro */
    100 static void
    101 test_container_smartlist_foreach_reverse(void *arg)
    102 {
    103  smartlist_t *sl = smartlist_new();
    104  int i;
    105 
    106  (void) arg;
    107 
    108  /* Add integers to smartlist in increasing order */
    109  for (i=0;i<100;i++) {
    110    smartlist_add(sl, (void*)(uintptr_t)i);
    111  }
    112 
    113  /* Pop them out in reverse and test their value */
    114  SMARTLIST_FOREACH_REVERSE_BEGIN(sl, void*, k) {
    115    i--;
    116    tt_ptr_op(k, OP_EQ, (void*)(uintptr_t)i);
    117  } SMARTLIST_FOREACH_END(k);
    118 
    119 done:
    120  smartlist_free(sl);
    121 }
    122 
    123 /** Run unit tests for smartlist-of-strings functionality. */
    124 static void
    125 test_container_smartlist_strings(void *arg)
    126 {
    127  smartlist_t *sl = smartlist_new();
    128  char *cp=NULL, *cp_alloc=NULL;
    129  size_t sz;
    130 
    131  /* Test split and join */
    132  (void)arg;
    133  tt_int_op(0,OP_EQ, smartlist_len(sl));
    134  smartlist_split_string(sl, "abc", ":", 0, 0);
    135  tt_int_op(1,OP_EQ, smartlist_len(sl));
    136  tt_str_op("abc",OP_EQ, smartlist_get(sl, 0));
    137  smartlist_split_string(sl, "a::bc::", "::", 0, 0);
    138  tt_int_op(4,OP_EQ, smartlist_len(sl));
    139  tt_str_op("a",OP_EQ, smartlist_get(sl, 1));
    140  tt_str_op("bc",OP_EQ, smartlist_get(sl, 2));
    141  tt_str_op("",OP_EQ, smartlist_get(sl, 3));
    142  cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
    143  tt_str_op(cp_alloc,OP_EQ, "abcabc");
    144  tor_free(cp_alloc);
    145  cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
    146  tt_str_op(cp_alloc,OP_EQ, "abc!a!bc!");
    147  tor_free(cp_alloc);
    148  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
    149  tt_str_op(cp_alloc,OP_EQ, "abcXYaXYbcXY");
    150  tor_free(cp_alloc);
    151  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
    152  tt_str_op(cp_alloc,OP_EQ, "abcXYaXYbcXYXY");
    153  tor_free(cp_alloc);
    154  cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
    155  tt_str_op(cp_alloc,OP_EQ, "abcabc");
    156  tor_free(cp_alloc);
    157 
    158  smartlist_split_string(sl, "/def/  /ghijk", "/", 0, 0);
    159  tt_int_op(8,OP_EQ, smartlist_len(sl));
    160  tt_str_op("",OP_EQ, smartlist_get(sl, 4));
    161  tt_str_op("def",OP_EQ, smartlist_get(sl, 5));
    162  tt_str_op("  ",OP_EQ, smartlist_get(sl, 6));
    163  tt_str_op("ghijk",OP_EQ, smartlist_get(sl, 7));
    164  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    165  smartlist_clear(sl);
    166 
    167  smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
    168  tt_int_op(3,OP_EQ, smartlist_len(sl));
    169  tt_str_op("a",OP_EQ, smartlist_get(sl,0));
    170  tt_str_op("bbd",OP_EQ, smartlist_get(sl,1));
    171  tt_str_op("cdef",OP_EQ, smartlist_get(sl,2));
    172  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
    173                         SPLIT_SKIP_SPACE, 0);
    174  tt_int_op(8,OP_EQ, smartlist_len(sl));
    175  tt_str_op("z",OP_EQ, smartlist_get(sl,3));
    176  tt_str_op("zhasd",OP_EQ, smartlist_get(sl,4));
    177  tt_str_op("",OP_EQ, smartlist_get(sl,5));
    178  tt_str_op("bnud",OP_EQ, smartlist_get(sl,6));
    179  tt_str_op("",OP_EQ, smartlist_get(sl,7));
    180 
    181  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    182  smartlist_clear(sl);
    183 
    184  smartlist_split_string(sl, " ab\tc \td ef  ", NULL,
    185                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
    186  tt_int_op(4,OP_EQ, smartlist_len(sl));
    187  tt_str_op("ab",OP_EQ, smartlist_get(sl,0));
    188  tt_str_op("c",OP_EQ, smartlist_get(sl,1));
    189  tt_str_op("d",OP_EQ, smartlist_get(sl,2));
    190  tt_str_op("ef",OP_EQ, smartlist_get(sl,3));
    191  smartlist_split_string(sl, "ghi\tj", NULL,
    192                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
    193  tt_int_op(6,OP_EQ, smartlist_len(sl));
    194  tt_str_op("ghi",OP_EQ, smartlist_get(sl,4));
    195  tt_str_op("j",OP_EQ, smartlist_get(sl,5));
    196 
    197  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    198  smartlist_clear(sl);
    199 
    200  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
    201  tt_str_op(cp_alloc,OP_EQ, "");
    202  tor_free(cp_alloc);
    203  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
    204  tt_str_op(cp_alloc,OP_EQ, "XY");
    205  tor_free(cp_alloc);
    206 
    207  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
    208                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
    209  tt_int_op(3,OP_EQ, smartlist_len(sl));
    210  tt_str_op("z",OP_EQ, smartlist_get(sl, 0));
    211  tt_str_op("zhasd",OP_EQ, smartlist_get(sl, 1));
    212  tt_str_op("bnud",OP_EQ, smartlist_get(sl, 2));
    213  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
    214                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
    215  tt_int_op(5,OP_EQ, smartlist_len(sl));
    216  tt_str_op("z",OP_EQ, smartlist_get(sl, 3));
    217  tt_str_op("zhasd <>  <> bnud<>",OP_EQ, smartlist_get(sl, 4));
    218  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    219  smartlist_clear(sl);
    220 
    221  smartlist_split_string(sl, "abcd\n", "\n",
    222                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
    223  tt_int_op(1,OP_EQ, smartlist_len(sl));
    224  tt_str_op("abcd",OP_EQ, smartlist_get(sl, 0));
    225  smartlist_split_string(sl, "efgh", "\n",
    226                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
    227  tt_int_op(2,OP_EQ, smartlist_len(sl));
    228  tt_str_op("efgh",OP_EQ, smartlist_get(sl, 1));
    229 
    230  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    231  smartlist_clear(sl);
    232 
    233  /* Test swapping, shuffling, and sorting. */
    234  smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
    235  tt_int_op(7,OP_EQ, smartlist_len(sl));
    236  smartlist_sort(sl, compare_strs_);
    237  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
    238  tt_str_op(cp_alloc,OP_EQ, "and,arma,by,nickm,onion,router,the");
    239  tor_free(cp_alloc);
    240  smartlist_swap(sl, 1, 5);
    241  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
    242  tt_str_op(cp_alloc,OP_EQ, "and,router,by,nickm,onion,arma,the");
    243  tor_free(cp_alloc);
    244  smartlist_shuffle(sl);
    245  tt_int_op(7,OP_EQ, smartlist_len(sl));
    246  tt_assert(smartlist_contains_string(sl, "and"));
    247  tt_assert(smartlist_contains_string(sl, "router"));
    248  tt_assert(smartlist_contains_string(sl, "by"));
    249  tt_assert(smartlist_contains_string(sl, "nickm"));
    250  tt_assert(smartlist_contains_string(sl, "onion"));
    251  tt_assert(smartlist_contains_string(sl, "arma"));
    252  tt_assert(smartlist_contains_string(sl, "the"));
    253 
    254  /* Test bsearch. */
    255  smartlist_sort(sl, compare_strs_);
    256  tt_str_op("nickm",OP_EQ, smartlist_bsearch(sl, "zNicKM",
    257                                        cmp_without_first_));
    258  tt_str_op("and",OP_EQ,
    259            smartlist_bsearch(sl, " AND", cmp_without_first_));
    260  tt_ptr_op(NULL,OP_EQ, smartlist_bsearch(sl, " ANz", cmp_without_first_));
    261 
    262  /* Test bsearch_idx */
    263  {
    264    int f;
    265    smartlist_t *tmp = NULL;
    266 
    267    tt_int_op(0,OP_EQ,smartlist_bsearch_idx(sl," aaa",cmp_without_first_,&f));
    268    tt_int_op(f,OP_EQ, 0);
    269    tt_int_op(0,OP_EQ, smartlist_bsearch_idx(sl," and",cmp_without_first_,&f));
    270    tt_int_op(f,OP_EQ, 1);
    271    tt_int_op(1,OP_EQ, smartlist_bsearch_idx(sl," arm",cmp_without_first_,&f));
    272    tt_int_op(f,OP_EQ, 0);
    273    tt_int_op(1,OP_EQ,
    274              smartlist_bsearch_idx(sl," arma",cmp_without_first_,&f));
    275    tt_int_op(f,OP_EQ, 1);
    276    tt_int_op(2,OP_EQ,
    277              smartlist_bsearch_idx(sl," armb",cmp_without_first_,&f));
    278    tt_int_op(f,OP_EQ, 0);
    279    tt_int_op(7,OP_EQ,
    280              smartlist_bsearch_idx(sl," zzzz",cmp_without_first_,&f));
    281    tt_int_op(f,OP_EQ, 0);
    282 
    283    /* Test trivial cases for list of length 0 or 1 */
    284    tmp = smartlist_new();
    285    tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
    286                                     compare_strs_for_bsearch_, &f));
    287    tt_int_op(f,OP_EQ, 0);
    288    smartlist_insert(tmp, 0, (void *)("bar"));
    289    tt_int_op(1,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
    290                                     compare_strs_for_bsearch_, &f));
    291    tt_int_op(f,OP_EQ, 0);
    292    tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "aaa",
    293                                     compare_strs_for_bsearch_, &f));
    294    tt_int_op(f,OP_EQ, 0);
    295    tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "bar",
    296                                     compare_strs_for_bsearch_, &f));
    297    tt_int_op(f,OP_EQ, 1);
    298    /* ... and one for length 2 */
    299    smartlist_insert(tmp, 1, (void *)("foo"));
    300    tt_int_op(1,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
    301                                     compare_strs_for_bsearch_, &f));
    302    tt_int_op(f,OP_EQ, 1);
    303    tt_int_op(2,OP_EQ, smartlist_bsearch_idx(tmp, "goo",
    304                                     compare_strs_for_bsearch_, &f));
    305    tt_int_op(f,OP_EQ, 0);
    306    smartlist_free(tmp);
    307  }
    308 
    309  /* Test reverse() and pop_last() */
    310  smartlist_reverse(sl);
    311  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
    312  tt_str_op(cp_alloc,OP_EQ, "the,router,onion,nickm,by,arma,and");
    313  tor_free(cp_alloc);
    314  cp_alloc = smartlist_pop_last(sl);
    315  tt_str_op(cp_alloc,OP_EQ, "and");
    316  tor_free(cp_alloc);
    317  tt_int_op(smartlist_len(sl),OP_EQ, 6);
    318  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    319  smartlist_clear(sl);
    320  cp_alloc = smartlist_pop_last(sl);
    321  tt_ptr_op(cp_alloc,OP_EQ, NULL);
    322 
    323  /* Test uniq() */
    324  smartlist_split_string(sl,
    325                     "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
    326                     ",", 0, 0);
    327  smartlist_sort(sl, compare_strs_);
    328  smartlist_uniq(sl, compare_strs_, tor_free_);
    329  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
    330  tt_str_op(cp_alloc,OP_EQ, "50,a,canal,man,noon,panama,plan,radar");
    331  tor_free(cp_alloc);
    332 
    333  /* Test contains_string, contains_string_case and contains_int_as_string */
    334  tt_assert(smartlist_contains_string(sl, "noon"));
    335  tt_assert(!smartlist_contains_string(sl, "noonoon"));
    336  tt_assert(smartlist_contains_string_case(sl, "nOOn"));
    337  tt_assert(!smartlist_contains_string_case(sl, "nooNooN"));
    338  tt_assert(smartlist_contains_int_as_string(sl, 50));
    339  tt_assert(!smartlist_contains_int_as_string(sl, 60));
    340 
    341  /* Test smartlist_choose */
    342  {
    343    int i;
    344    int allsame = 1;
    345    int allin = 1;
    346    void *first = smartlist_choose(sl);
    347    tt_assert(smartlist_contains(sl, first));
    348    for (i = 0; i < 100; ++i) {
    349      void *second = smartlist_choose(sl);
    350      if (second != first)
    351        allsame = 0;
    352      if (!smartlist_contains(sl, second))
    353        allin = 0;
    354    }
    355    tt_assert(!allsame);
    356    tt_assert(allin);
    357  }
    358  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    359  smartlist_clear(sl);
    360 
    361  /* Test string_remove and remove and join_strings2 */
    362  smartlist_split_string(sl,
    363                    "Some say the Earth will end in ice and some in fire",
    364                    " ", 0, 0);
    365  cp = smartlist_get(sl, 4);
    366  tt_str_op(cp,OP_EQ, "will");
    367  smartlist_add(sl, cp);
    368  smartlist_remove(sl, cp);
    369  tor_free(cp);
    370  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
    371  tt_str_op(cp_alloc,OP_EQ, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
    372  tor_free(cp_alloc);
    373  smartlist_string_remove(sl, "in");
    374  cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
    375  tt_str_op(cp_alloc,OP_EQ, "Some+say+the+Earth+fire+end+some+ice+and");
    376  tt_int_op((int)sz,OP_EQ, 40);
    377 
    378 done:
    379 
    380  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    381  smartlist_free(sl);
    382  tor_free(cp_alloc);
    383 }
    384 
    385 /** Run unit tests for smartlist set manipulation functions. */
    386 static void
    387 test_container_smartlist_overlap(void *arg)
    388 {
    389  smartlist_t *sl = smartlist_new();
    390  smartlist_t *ints = smartlist_new();
    391  smartlist_t *odds = smartlist_new();
    392  smartlist_t *evens = smartlist_new();
    393  smartlist_t *primes = smartlist_new();
    394  int i;
    395  (void)arg;
    396  for (i=1; i < 10; i += 2)
    397    smartlist_add(odds, (void*)(uintptr_t)i);
    398  for (i=0; i < 10; i += 2)
    399    smartlist_add(evens, (void*)(uintptr_t)i);
    400 
    401  /* add_all */
    402  smartlist_add_all(ints, odds);
    403  smartlist_add_all(ints, evens);
    404  tt_int_op(smartlist_len(ints),OP_EQ, 10);
    405 
    406  smartlist_add(primes, (void*)2);
    407  smartlist_add(primes, (void*)3);
    408  smartlist_add(primes, (void*)5);
    409  smartlist_add(primes, (void*)7);
    410 
    411  /* overlap */
    412  tt_assert(smartlist_overlap(ints, odds));
    413  tt_assert(smartlist_overlap(odds, primes));
    414  tt_assert(smartlist_overlap(evens, primes));
    415  tt_assert(!smartlist_overlap(odds, evens));
    416 
    417  /* intersect */
    418  smartlist_add_all(sl, odds);
    419  smartlist_intersect(sl, primes);
    420  tt_int_op(smartlist_len(sl),OP_EQ, 3);
    421  tt_assert(smartlist_contains(sl, (void*)3));
    422  tt_assert(smartlist_contains(sl, (void*)5));
    423  tt_assert(smartlist_contains(sl, (void*)7));
    424 
    425  /* subtract */
    426  smartlist_add_all(sl, primes);
    427  smartlist_subtract(sl, odds);
    428  tt_int_op(smartlist_len(sl),OP_EQ, 1);
    429  tt_assert(smartlist_contains(sl, (void*)2));
    430 
    431 done:
    432  smartlist_free(odds);
    433  smartlist_free(evens);
    434  smartlist_free(ints);
    435  smartlist_free(primes);
    436  smartlist_free(sl);
    437 }
    438 
    439 /** Run unit tests for smartlist-of-digests functions. */
    440 static void
    441 test_container_smartlist_digests(void *arg)
    442 {
    443  smartlist_t *sl = smartlist_new();
    444 
    445  /* contains_digest */
    446  (void)arg;
    447  smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
    448  smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
    449  smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
    450  tt_int_op(0,OP_EQ, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA"));
    451  tt_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA"));
    452  tt_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA"));
    453  tt_int_op(0,OP_EQ, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA"));
    454 
    455  /* sort digests */
    456  smartlist_sort_digests(sl);
    457  tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
    458  tt_mem_op(smartlist_get(sl, 1),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
    459  tt_mem_op(smartlist_get(sl, 2),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
    460  tt_int_op(3,OP_EQ, smartlist_len(sl));
    461 
    462  /* uniq_digests */
    463  smartlist_uniq_digests(sl);
    464  tt_int_op(2,OP_EQ, smartlist_len(sl));
    465  tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
    466  tt_mem_op(smartlist_get(sl, 1),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
    467 
    468 done:
    469  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    470  smartlist_free(sl);
    471 }
    472 
    473 /** Run unit tests for concatenate-a-smartlist-of-strings functions. */
    474 static void
    475 test_container_smartlist_join(void *arg)
    476 {
    477  smartlist_t *sl = smartlist_new();
    478  smartlist_t *sl2 = smartlist_new(), *sl3 = smartlist_new(),
    479    *sl4 = smartlist_new();
    480  char *joined=NULL;
    481  /* unique, sorted. */
    482  (void)arg;
    483  smartlist_split_string(sl,
    484                         "Abashments Ambush Anchorman Bacon Banks Borscht "
    485                         "Bunks Inhumane Insurance Knish Know Manners "
    486                         "Maraschinos Stamina Sunbonnets Unicorns Wombats",
    487                         " ", 0, 0);
    488  /* non-unique, sorted. */
    489  smartlist_split_string(sl2,
    490                         "Ambush Anchorman Anchorman Anemias Anemias Bacon "
    491                         "Crossbowmen Inhumane Insurance Knish Know Manners "
    492                         "Manners Maraschinos Wombats Wombats Work",
    493                         " ", 0, 0);
    494  SMARTLIST_FOREACH_JOIN(sl, char *, cp1,
    495                         sl2, char *, cp2,
    496                         strcmp(cp1,cp2),
    497                         smartlist_add(sl3, cp2)) {
    498    tt_str_op(cp1,OP_EQ, cp2);
    499    smartlist_add(sl4, cp1);
    500  } SMARTLIST_FOREACH_JOIN_END(cp1, cp2);
    501 
    502  SMARTLIST_FOREACH(sl3, const char *, cp,
    503                    tt_assert(smartlist_contains(sl2, cp) &&
    504                                !smartlist_contains_string(sl, cp)));
    505  SMARTLIST_FOREACH(sl4, const char *, cp,
    506                    tt_assert(smartlist_contains(sl, cp) &&
    507                                smartlist_contains_string(sl2, cp)));
    508  joined = smartlist_join_strings(sl3, ",", 0, NULL);
    509  tt_str_op(joined,OP_EQ, "Anemias,Anemias,Crossbowmen,Work");
    510  tor_free(joined);
    511  joined = smartlist_join_strings(sl4, ",", 0, NULL);
    512  tt_str_op(joined,OP_EQ,
    513            "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
    514             "Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");
    515  tor_free(joined);
    516 
    517 done:
    518  smartlist_free(sl4);
    519  smartlist_free(sl3);
    520  SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
    521  smartlist_free(sl2);
    522  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    523  smartlist_free(sl);
    524  tor_free(joined);
    525 }
    526 
    527 static void
    528 test_container_smartlist_pos(void *arg)
    529 {
    530  (void) arg;
    531  smartlist_t *sl = smartlist_new();
    532 
    533  smartlist_add_strdup(sl, "This");
    534  smartlist_add_strdup(sl, "is");
    535  smartlist_add_strdup(sl, "a");
    536  smartlist_add_strdup(sl, "test");
    537  smartlist_add_strdup(sl, "for");
    538  smartlist_add_strdup(sl, "a");
    539  smartlist_add_strdup(sl, "function");
    540 
    541  /* Test string_pos */
    542  tt_int_op(smartlist_string_pos(NULL, "Fred"), OP_EQ, -1);
    543  tt_int_op(smartlist_string_pos(sl, "Fred"), OP_EQ, -1);
    544  tt_int_op(smartlist_string_pos(sl, "This"), OP_EQ, 0);
    545  tt_int_op(smartlist_string_pos(sl, "a"), OP_EQ, 2);
    546  tt_int_op(smartlist_string_pos(sl, "function"), OP_EQ, 6);
    547 
    548  /* Test pos */
    549  tt_int_op(smartlist_pos(NULL, "Fred"), OP_EQ, -1);
    550  tt_int_op(smartlist_pos(sl, "Fred"), OP_EQ, -1);
    551  tt_int_op(smartlist_pos(sl, "This"), OP_EQ, -1);
    552  tt_int_op(smartlist_pos(sl, "a"), OP_EQ, -1);
    553  tt_int_op(smartlist_pos(sl, "function"), OP_EQ, -1);
    554  tt_int_op(smartlist_pos(sl, smartlist_get(sl,0)), OP_EQ, 0);
    555  tt_int_op(smartlist_pos(sl, smartlist_get(sl,2)), OP_EQ, 2);
    556  tt_int_op(smartlist_pos(sl, smartlist_get(sl,5)), OP_EQ, 5);
    557  tt_int_op(smartlist_pos(sl, smartlist_get(sl,6)), OP_EQ, 6);
    558 
    559 done:
    560  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
    561  smartlist_free(sl);
    562 }
    563 
    564 static void
    565 test_container_smartlist_ints_eq(void *arg)
    566 {
    567  smartlist_t *sl1 = NULL, *sl2 = NULL;
    568  int x;
    569  (void)arg;
    570 
    571  tt_assert(smartlist_ints_eq(NULL, NULL));
    572 
    573  sl1 = smartlist_new();
    574  tt_assert(!smartlist_ints_eq(sl1, NULL));
    575  tt_assert(!smartlist_ints_eq(NULL, sl1));
    576 
    577  sl2 = smartlist_new();
    578  tt_assert(smartlist_ints_eq(sl1, sl2));
    579 
    580  x = 5;
    581  smartlist_add(sl1, tor_memdup(&x, sizeof(int)));
    582  smartlist_add(sl2, tor_memdup(&x, sizeof(int)));
    583  x = 90;
    584  smartlist_add(sl1, tor_memdup(&x, sizeof(int)));
    585  smartlist_add(sl2, tor_memdup(&x, sizeof(int)));
    586  tt_assert(smartlist_ints_eq(sl1, sl2));
    587 
    588  x = -50;
    589  smartlist_add(sl1, tor_memdup(&x, sizeof(int)));
    590  tt_assert(! smartlist_ints_eq(sl1, sl2));
    591  tt_assert(! smartlist_ints_eq(sl2, sl1));
    592  smartlist_add(sl2, tor_memdup(&x, sizeof(int)));
    593  tt_assert(smartlist_ints_eq(sl1, sl2));
    594 
    595  *(int*)smartlist_get(sl1, 1) = 101010;
    596  tt_assert(! smartlist_ints_eq(sl2, sl1));
    597  *(int*)smartlist_get(sl2, 1) = 101010;
    598  tt_assert(smartlist_ints_eq(sl1, sl2));
    599 
    600 done:
    601  if (sl1)
    602    SMARTLIST_FOREACH(sl1, int *, ip, tor_free(ip));
    603  if (sl2)
    604    SMARTLIST_FOREACH(sl2, int *, ip, tor_free(ip));
    605  smartlist_free(sl1);
    606  smartlist_free(sl2);
    607 }
    608 
    609 static void
    610 test_container_smartlist_grow(void *arg)
    611 {
    612  (void)arg;
    613  smartlist_t *sl = smartlist_new();
    614  int i;
    615  const char *s[] = { "first", "2nd", "3rd" };
    616 
    617  /* case 1: starting from empty. */
    618  smartlist_grow(sl, 10);
    619  tt_int_op(10, OP_EQ, smartlist_len(sl));
    620  for (i = 0; i < 10; ++i) {
    621    tt_ptr_op(smartlist_get(sl, i), OP_EQ, NULL);
    622  }
    623 
    624  /* case 2: starting with a few elements, probably not reallocating. */
    625  smartlist_free(sl);
    626  sl = smartlist_new();
    627  smartlist_add(sl, (char*)s[0]);
    628  smartlist_add(sl, (char*)s[1]);
    629  smartlist_add(sl, (char*)s[2]);
    630  smartlist_grow(sl, 5);
    631  tt_int_op(5, OP_EQ, smartlist_len(sl));
    632  for (i = 0; i < 3; ++i) {
    633    tt_ptr_op(smartlist_get(sl, i), OP_EQ, s[i]);
    634  }
    635  tt_ptr_op(smartlist_get(sl, 3), OP_EQ, NULL);
    636  tt_ptr_op(smartlist_get(sl, 4), OP_EQ, NULL);
    637 
    638  /* case 3: starting with a few elements, but reallocating. */
    639  smartlist_free(sl);
    640  sl = smartlist_new();
    641  smartlist_add(sl, (char*)s[0]);
    642  smartlist_add(sl, (char*)s[1]);
    643  smartlist_add(sl, (char*)s[2]);
    644  smartlist_grow(sl, 100);
    645  tt_int_op(100, OP_EQ, smartlist_len(sl));
    646  for (i = 0; i < 3; ++i) {
    647    tt_ptr_op(smartlist_get(sl, i), OP_EQ, s[i]);
    648  }
    649  for (i = 3; i < 100; ++i) {
    650    tt_ptr_op(smartlist_get(sl, i), OP_EQ, NULL);
    651  }
    652 
    653  /* case 4: shrinking doesn't happen. */
    654  smartlist_free(sl);
    655  sl = smartlist_new();
    656  smartlist_add(sl, (char*)s[0]);
    657  smartlist_add(sl, (char*)s[1]);
    658  smartlist_add(sl, (char*)s[2]);
    659  smartlist_grow(sl, 1);
    660  tt_int_op(3, OP_EQ, smartlist_len(sl));
    661  for (i = 0; i < 3; ++i) {
    662    tt_ptr_op(smartlist_get(sl, i), OP_EQ, s[i]);
    663  }
    664 
    665 done:
    666  smartlist_free(sl);
    667 }
    668 
    669 /** Run unit tests for bitarray code */
    670 static void
    671 test_container_bitarray(void *arg)
    672 {
    673  bitarray_t *ba = NULL;
    674  int i, j, ok=1;
    675 
    676  (void)arg;
    677  ba = bitarray_init_zero(1);
    678  tt_assert(ba);
    679  tt_assert(! bitarray_is_set(ba, 0));
    680  bitarray_set(ba, 0);
    681  tt_assert(bitarray_is_set(ba, 0));
    682  bitarray_clear(ba, 0);
    683  tt_assert(! bitarray_is_set(ba, 0));
    684  bitarray_free(ba);
    685 
    686  ba = bitarray_init_zero(1023);
    687  for (i = 1; i < 64; ) {
    688    for (j = 0; j < 1023; ++j) {
    689      if (j % i)
    690        bitarray_set(ba, j);
    691      else
    692        bitarray_clear(ba, j);
    693    }
    694    for (j = 0; j < 1023; ++j) {
    695      if (!bool_eq(bitarray_is_set(ba, j), j%i))
    696        ok = 0;
    697    }
    698    tt_assert(ok);
    699    if (i < 7)
    700      ++i;
    701    else if (i == 28)
    702      i = 32;
    703    else
    704      i += 7;
    705  }
    706 
    707 done:
    708  if (ba)
    709    bitarray_free(ba);
    710 }
    711 
    712 /** Run unit tests for digest set code (implemented as a hashtable or as a
    713 * bloom filter) */
    714 static void
    715 test_container_digestset(void *arg)
    716 {
    717  smartlist_t *included = smartlist_new();
    718  char d[DIGEST_LEN];
    719  int i;
    720  int ok = 1;
    721  int false_positives = 0;
    722  digestset_t *set = NULL;
    723 
    724  (void)arg;
    725  for (i = 0; i < 1000; ++i) {
    726    crypto_rand(d, DIGEST_LEN);
    727    smartlist_add(included, tor_memdup(d, DIGEST_LEN));
    728  }
    729  set = digestset_new(1000);
    730  SMARTLIST_FOREACH(included, const char *, cp,
    731                    if (digestset_probably_contains(set, cp))
    732                      ok = 0);
    733  tt_assert(ok);
    734  SMARTLIST_FOREACH(included, const char *, cp,
    735                    digestset_add(set, cp));
    736  SMARTLIST_FOREACH(included, const char *, cp,
    737                    if (!digestset_probably_contains(set, cp))
    738                      ok = 0);
    739  tt_assert(ok);
    740  for (i = 0; i < 1000; ++i) {
    741    crypto_rand(d, DIGEST_LEN);
    742    if (digestset_probably_contains(set, d))
    743      ++false_positives;
    744  }
    745  tt_int_op(50, OP_GT, false_positives); /* Should be far lower. */
    746 
    747 done:
    748  if (set)
    749    digestset_free(set);
    750  SMARTLIST_FOREACH(included, char *, cp, tor_free(cp));
    751  smartlist_free(included);
    752 }
    753 
    754 typedef struct pq_entry_t {
    755  const char *val;
    756  int idx;
    757 } pq_entry_t;
    758 
    759 /** Helper: return a tristate based on comparing two pq_entry_t values. */
    760 static int
    761 compare_strings_for_pqueue_(const void *p1, const void *p2)
    762 {
    763  const pq_entry_t *e1=p1, *e2=p2;
    764  return strcmp(e1->val, e2->val);
    765 }
    766 
    767 /** Run unit tests for heap-based priority queue functions. */
    768 static void
    769 test_container_pqueue(void *arg)
    770 {
    771  smartlist_t *sl = smartlist_new();
    772  int (*cmp)(const void *, const void*);
    773  const int offset = offsetof(pq_entry_t, idx);
    774 #define ENTRY(s) pq_entry_t s = { #s, -1 }
    775  ENTRY(cows);
    776  ENTRY(zebras);
    777  ENTRY(fish);
    778  ENTRY(frogs);
    779  ENTRY(apples);
    780  ENTRY(squid);
    781  ENTRY(daschunds);
    782  ENTRY(eggplants);
    783  ENTRY(weissbier);
    784  ENTRY(lobsters);
    785  ENTRY(roquefort);
    786  ENTRY(chinchillas);
    787  ENTRY(fireflies);
    788 
    789 #define OK() smartlist_pqueue_assert_ok(sl, cmp, offset)
    790 
    791  (void)arg;
    792 
    793  cmp = compare_strings_for_pqueue_;
    794  smartlist_pqueue_add(sl, cmp, offset, &cows);
    795  smartlist_pqueue_add(sl, cmp, offset, &zebras);
    796  smartlist_pqueue_add(sl, cmp, offset, &fish);
    797  smartlist_pqueue_add(sl, cmp, offset, &frogs);
    798  smartlist_pqueue_add(sl, cmp, offset, &apples);
    799  smartlist_pqueue_add(sl, cmp, offset, &squid);
    800  smartlist_pqueue_add(sl, cmp, offset, &daschunds);
    801  smartlist_pqueue_add(sl, cmp, offset, &eggplants);
    802  smartlist_pqueue_add(sl, cmp, offset, &weissbier);
    803  smartlist_pqueue_add(sl, cmp, offset, &lobsters);
    804  smartlist_pqueue_add(sl, cmp, offset, &roquefort);
    805 
    806  OK();
    807 
    808  tt_int_op(smartlist_len(sl),OP_EQ, 11);
    809  tt_ptr_op(smartlist_get(sl, 0),OP_EQ, &apples);
    810  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &apples);
    811  tt_int_op(smartlist_len(sl),OP_EQ, 10);
    812  OK();
    813  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &cows);
    814  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &daschunds);
    815  smartlist_pqueue_add(sl, cmp, offset, &chinchillas);
    816  OK();
    817  smartlist_pqueue_add(sl, cmp, offset, &fireflies);
    818  OK();
    819  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &chinchillas);
    820  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &eggplants);
    821  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fireflies);
    822  OK();
    823  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fish);
    824  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &frogs);
    825  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &lobsters);
    826  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &roquefort);
    827  OK();
    828  tt_int_op(smartlist_len(sl),OP_EQ, 3);
    829  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &squid);
    830  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &weissbier);
    831  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &zebras);
    832  tt_int_op(smartlist_len(sl),OP_EQ, 0);
    833  OK();
    834 
    835  /* Now test remove. */
    836  smartlist_pqueue_add(sl, cmp, offset, &cows);
    837  smartlist_pqueue_add(sl, cmp, offset, &fish);
    838  smartlist_pqueue_add(sl, cmp, offset, &frogs);
    839  smartlist_pqueue_add(sl, cmp, offset, &apples);
    840  smartlist_pqueue_add(sl, cmp, offset, &squid);
    841  smartlist_pqueue_add(sl, cmp, offset, &zebras);
    842  tt_int_op(smartlist_len(sl),OP_EQ, 6);
    843  OK();
    844  smartlist_pqueue_remove(sl, cmp, offset, &zebras);
    845  tt_int_op(smartlist_len(sl),OP_EQ, 5);
    846  OK();
    847  smartlist_pqueue_remove(sl, cmp, offset, &cows);
    848  tt_int_op(smartlist_len(sl),OP_EQ, 4);
    849  OK();
    850  smartlist_pqueue_remove(sl, cmp, offset, &apples);
    851  tt_int_op(smartlist_len(sl),OP_EQ, 3);
    852  OK();
    853  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fish);
    854  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &frogs);
    855  tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &squid);
    856  tt_int_op(smartlist_len(sl),OP_EQ, 0);
    857  OK();
    858 
    859 #undef OK
    860 
    861 done:
    862 
    863  smartlist_free(sl);
    864 }
    865 
    866 /** Run unit tests for string-to-void* map functions */
    867 static void
    868 test_container_strmap(void *arg)
    869 {
    870  strmap_t *map;
    871  strmap_iter_t *iter;
    872  const char *k;
    873  void *v;
    874  char *visited = NULL;
    875  smartlist_t *found_keys = NULL;
    876  char *v1 = tor_strdup("v1");
    877  char *v99 = tor_strdup("v99");
    878  char *v100 = tor_strdup("v100");
    879  char *v101 = tor_strdup("v101");
    880  char *v102 = tor_strdup("v102");
    881  char *v103 = tor_strdup("v103");
    882  char *v104 = tor_strdup("v104");
    883  char *v105 = tor_strdup("v105");
    884 
    885  (void)arg;
    886  map = strmap_new();
    887  tt_assert(map);
    888  tt_int_op(strmap_size(map),OP_EQ, 0);
    889  tt_assert(strmap_isempty(map));
    890  v = strmap_set(map, "K1", v99);
    891  tt_ptr_op(v,OP_EQ, NULL);
    892  tt_assert(!strmap_isempty(map));
    893  v = strmap_set(map, "K2", v101);
    894  tt_ptr_op(v,OP_EQ, NULL);
    895  v = strmap_set(map, "K1", v100);
    896  tt_ptr_op(v,OP_EQ, v99);
    897  tt_ptr_op(strmap_get(map,"K1"),OP_EQ, v100);
    898  tt_ptr_op(strmap_get(map,"K2"),OP_EQ, v101);
    899  tt_ptr_op(strmap_get(map,"K-not-there"),OP_EQ, NULL);
    900  strmap_assert_ok(map);
    901 
    902  v = strmap_remove(map,"K2");
    903  strmap_assert_ok(map);
    904  tt_ptr_op(v,OP_EQ, v101);
    905  tt_ptr_op(strmap_get(map,"K2"),OP_EQ, NULL);
    906  tt_ptr_op(strmap_remove(map,"K2"),OP_EQ, NULL);
    907 
    908  strmap_set(map, "K2", v101);
    909  strmap_set(map, "K3", v102);
    910  strmap_set(map, "K4", v103);
    911  tt_int_op(strmap_size(map),OP_EQ, 4);
    912  strmap_assert_ok(map);
    913  strmap_set(map, "K5", v104);
    914  strmap_set(map, "K6", v105);
    915  strmap_assert_ok(map);
    916 
    917  /* Test iterator. */
    918  iter = strmap_iter_init(map);
    919  found_keys = smartlist_new();
    920  while (!strmap_iter_done(iter)) {
    921    strmap_iter_get(iter,&k,&v);
    922    smartlist_add_strdup(found_keys, k);
    923    tt_ptr_op(v,OP_EQ, strmap_get(map, k));
    924 
    925    if (!strcmp(k, "K2")) {
    926      iter = strmap_iter_next_rmv(map,iter);
    927    } else {
    928      iter = strmap_iter_next(map,iter);
    929    }
    930  }
    931 
    932  /* Make sure we removed K2, but not the others. */
    933  tt_ptr_op(strmap_get(map, "K2"),OP_EQ, NULL);
    934  tt_ptr_op(strmap_get(map, "K5"),OP_EQ, v104);
    935  /* Make sure we visited everyone once */
    936  smartlist_sort_strings(found_keys);
    937  visited = smartlist_join_strings(found_keys, ":", 0, NULL);
    938  tt_str_op(visited,OP_EQ, "K1:K2:K3:K4:K5:K6");
    939 
    940  strmap_assert_ok(map);
    941  /* Clean up after ourselves. */
    942  strmap_free(map, NULL);
    943  map = NULL;
    944 
    945  /* Now try some lc functions. */
    946  map = strmap_new();
    947  strmap_set_lc(map,"Ab.C", v1);
    948  tt_ptr_op(strmap_get(map,"ab.c"),OP_EQ, v1);
    949  strmap_assert_ok(map);
    950  tt_ptr_op(strmap_get_lc(map,"AB.C"),OP_EQ, v1);
    951  tt_ptr_op(strmap_get(map,"AB.C"),OP_EQ, NULL);
    952  tt_ptr_op(strmap_remove_lc(map,"aB.C"),OP_EQ, v1);
    953  strmap_assert_ok(map);
    954  tt_ptr_op(strmap_get_lc(map,"AB.C"),OP_EQ, NULL);
    955 
    956 done:
    957  if (map)
    958    strmap_free(map,NULL);
    959  if (found_keys) {
    960    SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp));
    961    smartlist_free(found_keys);
    962  }
    963  tor_free(visited);
    964  tor_free(v1);
    965  tor_free(v99);
    966  tor_free(v100);
    967  tor_free(v101);
    968  tor_free(v102);
    969  tor_free(v103);
    970  tor_free(v104);
    971  tor_free(v105);
    972 }
    973 
    974 static void
    975 test_container_smartlist_remove(void *arg)
    976 {
    977  (void) arg;
    978  int array[5];
    979  smartlist_t *sl = smartlist_new();
    980  int i,j;
    981 
    982  for (j=0; j < 2; ++j)
    983    for (i=0; i < 5; ++i)
    984      smartlist_add(sl, &array[i]);
    985 
    986  smartlist_remove(sl, &array[0]);
    987  smartlist_remove(sl, &array[3]);
    988  smartlist_remove(sl, &array[4]);
    989  tt_assert(! smartlist_contains(sl, &array[0]));
    990  tt_assert(smartlist_contains(sl, &array[1]));
    991  tt_assert(smartlist_contains(sl, &array[2]));
    992  tt_assert(! smartlist_contains(sl, &array[3]));
    993  tt_assert(! smartlist_contains(sl, &array[4]));
    994  tt_int_op(smartlist_len(sl), OP_EQ, 4);
    995 
    996  smartlist_clear(sl);
    997  for (j=0; j < 2; ++j)
    998    for (i=0; i < 5; ++i)
    999      smartlist_add(sl, &array[i]);
   1000 
   1001  smartlist_remove_keeporder(sl, &array[0]);
   1002  smartlist_remove_keeporder(sl, &array[3]);
   1003  smartlist_remove_keeporder(sl, &array[4]);
   1004  tt_int_op(smartlist_len(sl), OP_EQ, 4);
   1005  tt_ptr_op(smartlist_get(sl, 0), OP_EQ, &array[1]);
   1006  tt_ptr_op(smartlist_get(sl, 1), OP_EQ, &array[2]);
   1007  tt_ptr_op(smartlist_get(sl, 2), OP_EQ, &array[1]);
   1008  tt_ptr_op(smartlist_get(sl, 3), OP_EQ, &array[2]);
   1009  /* Ordinary code should never look at this pointer; we're doing it here
   1010   * to make sure that we really cleared the pointer we removed.
   1011   */
   1012  tt_ptr_op(sl->list[4], OP_EQ, NULL);
   1013 
   1014 done:
   1015  smartlist_free(sl);
   1016 }
   1017 
   1018 /** Run unit tests for getting the median of a list. */
   1019 static void
   1020 test_container_order_functions(void *arg)
   1021 {
   1022  int lst[25], n = 0;
   1023  uint32_t lst_2[25];
   1024  //  int a=12,b=24,c=25,d=60,e=77;
   1025 
   1026 #define median() median_int(lst, n)
   1027 
   1028  (void)arg;
   1029  lst[n++] = 12;
   1030  tt_int_op(12,OP_EQ, median()); /* 12 */
   1031  lst[n++] = 77;
   1032  //smartlist_shuffle(sl);
   1033  tt_int_op(12,OP_EQ, median()); /* 12, 77 */
   1034  lst[n++] = 77;
   1035  //smartlist_shuffle(sl);
   1036  tt_int_op(77,OP_EQ, median()); /* 12, 77, 77 */
   1037  lst[n++] = 24;
   1038  tt_int_op(24,OP_EQ, median()); /* 12,24,77,77 */
   1039  lst[n++] = 60;
   1040  lst[n++] = 12;
   1041  lst[n++] = 25;
   1042  //smartlist_shuffle(sl);
   1043  tt_int_op(25,OP_EQ, median()); /* 12,12,24,25,60,77,77 */
   1044 #undef median
   1045 
   1046 #define third_quartile() third_quartile_uint32(lst_2, n)
   1047 
   1048  n = 0;
   1049  lst_2[n++] = 1;
   1050  tt_int_op(1,OP_EQ, third_quartile()); /* ~1~ */
   1051  lst_2[n++] = 2;
   1052  tt_int_op(2,OP_EQ, third_quartile()); /* 1, ~2~ */
   1053  lst_2[n++] = 3;
   1054  lst_2[n++] = 4;
   1055  lst_2[n++] = 5;
   1056  tt_int_op(4,OP_EQ, third_quartile()); /* 1, 2, 3, ~4~, 5 */
   1057  lst_2[n++] = 6;
   1058  lst_2[n++] = 7;
   1059  lst_2[n++] = 8;
   1060  lst_2[n++] = 9;
   1061  tt_int_op(7,OP_EQ, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */
   1062  lst_2[n++] = 10;
   1063  lst_2[n++] = 11;
   1064  /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */
   1065  tt_int_op(9,OP_EQ, third_quartile());
   1066 
   1067 #undef third_quartile
   1068 
   1069  double dbls[] = { 1.0, 10.0, 100.0, 1e4, 1e5, 1e6 };
   1070  tt_double_eq(1.0, median_double(dbls, 1));
   1071  tt_double_eq(1.0, median_double(dbls, 2));
   1072  tt_double_eq(10.0, median_double(dbls, 3));
   1073  tt_double_eq(10.0, median_double(dbls, 4));
   1074  tt_double_eq(100.0, median_double(dbls, 5));
   1075  tt_double_eq(100.0, median_double(dbls, 6));
   1076 
   1077  time_t times[] = { 5, 10, 20, 25, 15 };
   1078 
   1079  tt_assert(5 == median_time(times, 1));
   1080  tt_assert(5 == median_time(times, 2));
   1081  tt_assert(10 == median_time(times, 3));
   1082  tt_assert(10 == median_time(times, 4));
   1083  tt_assert(15 == median_time(times, 5));
   1084 
   1085  int32_t int32s[] = { -5, -10, -50, 100 };
   1086  tt_int_op(-5, OP_EQ, median_int32(int32s, 1));
   1087  tt_int_op(-10, OP_EQ, median_int32(int32s, 2));
   1088  tt_int_op(-10, OP_EQ, median_int32(int32s, 3));
   1089  tt_int_op(-10, OP_EQ, median_int32(int32s, 4));
   1090 
   1091  long longs[] = { -30, 30, 100, -100, 7 };
   1092  tt_int_op(7, OP_EQ, find_nth_long(longs, 5, 2));
   1093 
   1094 done:
   1095  ;
   1096 }
   1097 
   1098 static void
   1099 test_container_di_map(void *arg)
   1100 {
   1101  di_digest256_map_t *map = NULL;
   1102  const uint8_t key1[] = "In view of the fact that it was ";
   1103  const uint8_t key2[] = "superficially convincing, being ";
   1104  const uint8_t key3[] = "properly enciphered in a one-tim";
   1105  const uint8_t key4[] = "e cipher scheduled for use today";
   1106  char *v1 = tor_strdup(", it came close to causing a disaster...");
   1107  char *v2 = tor_strdup("I regret to have to advise you that the mission");
   1108  char *v3 = tor_strdup("was actually initiated...");
   1109  /* -- John Brunner, _The Shockwave Rider_ */
   1110 
   1111  (void)arg;
   1112 
   1113  /* Try searching on an empty map. */
   1114  tt_ptr_op(NULL, OP_EQ, dimap_search(map, key1, NULL));
   1115  tt_ptr_op(NULL, OP_EQ, dimap_search(map, key2, NULL));
   1116  tt_ptr_op(v3, OP_EQ, dimap_search(map, key2, v3));
   1117  dimap_free(map, NULL);
   1118  map = NULL;
   1119 
   1120  /* Add a single entry. */
   1121  dimap_add_entry(&map, key1, v1);
   1122  tt_ptr_op(NULL, OP_EQ, dimap_search(map, key2, NULL));
   1123  tt_ptr_op(v3, OP_EQ, dimap_search(map, key2, v3));
   1124  tt_ptr_op(v1, OP_EQ, dimap_search(map, key1, NULL));
   1125 
   1126  /* Now try it with three entries in the map. */
   1127  dimap_add_entry(&map, key2, v2);
   1128  dimap_add_entry(&map, key3, v3);
   1129  tt_ptr_op(v1, OP_EQ, dimap_search(map, key1, NULL));
   1130  tt_ptr_op(v2, OP_EQ, dimap_search(map, key2, NULL));
   1131  tt_ptr_op(v3, OP_EQ, dimap_search(map, key3, NULL));
   1132  tt_ptr_op(NULL, OP_EQ, dimap_search(map, key4, NULL));
   1133  tt_ptr_op(v1, OP_EQ, dimap_search(map, key4, v1));
   1134 
   1135 done:
   1136  tor_free(v1);
   1137  tor_free(v2);
   1138  tor_free(v3);
   1139  dimap_free(map, NULL);
   1140 }
   1141 
   1142 /** Run unit tests for fp_pair-to-void* map functions */
   1143 static void
   1144 test_container_fp_pair_map(void *arg)
   1145 {
   1146  fp_pair_map_t *map;
   1147  fp_pair_t fp1, fp2, fp3, fp4, fp5, fp6;
   1148  void *v;
   1149  fp_pair_map_iter_t *iter;
   1150  fp_pair_t k;
   1151  char *v99 = tor_strdup("99");
   1152  char *v100 = tor_strdup("v100");
   1153  char *v101 = tor_strdup("v101");
   1154  char *v102 = tor_strdup("v102");
   1155  char *v103 = tor_strdup("v103");
   1156  char *v104 = tor_strdup("v104");
   1157  char *v105 = tor_strdup("v105");
   1158 
   1159  (void)arg;
   1160  map = fp_pair_map_new();
   1161  tt_assert(map);
   1162  tt_int_op(fp_pair_map_size(map),OP_EQ, 0);
   1163  tt_assert(fp_pair_map_isempty(map));
   1164 
   1165  memset(fp1.first, 0x11, DIGEST_LEN);
   1166  memset(fp1.second, 0x12, DIGEST_LEN);
   1167  memset(fp2.first, 0x21, DIGEST_LEN);
   1168  memset(fp2.second, 0x22, DIGEST_LEN);
   1169  memset(fp3.first, 0x31, DIGEST_LEN);
   1170  memset(fp3.second, 0x32, DIGEST_LEN);
   1171  memset(fp4.first, 0x41, DIGEST_LEN);
   1172  memset(fp4.second, 0x42, DIGEST_LEN);
   1173  memset(fp5.first, 0x51, DIGEST_LEN);
   1174  memset(fp5.second, 0x52, DIGEST_LEN);
   1175  memset(fp6.first, 0x61, DIGEST_LEN);
   1176  memset(fp6.second, 0x62, DIGEST_LEN);
   1177 
   1178  v = fp_pair_map_set(map, &fp1, v99);
   1179  tt_ptr_op(v, OP_EQ, NULL);
   1180  tt_assert(!fp_pair_map_isempty(map));
   1181  v = fp_pair_map_set(map, &fp2, v101);
   1182  tt_ptr_op(v, OP_EQ, NULL);
   1183  v = fp_pair_map_set(map, &fp1, v100);
   1184  tt_ptr_op(v, OP_EQ, v99);
   1185  tt_ptr_op(fp_pair_map_get(map, &fp1),OP_EQ, v100);
   1186  tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, v101);
   1187  tt_ptr_op(fp_pair_map_get(map, &fp3),OP_EQ, NULL);
   1188  fp_pair_map_assert_ok(map);
   1189 
   1190  v = fp_pair_map_remove(map, &fp2);
   1191  fp_pair_map_assert_ok(map);
   1192  tt_ptr_op(v,OP_EQ, v101);
   1193  tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, NULL);
   1194  tt_ptr_op(fp_pair_map_remove(map, &fp2),OP_EQ, NULL);
   1195 
   1196  fp_pair_map_set(map, &fp2, v101);
   1197  fp_pair_map_set(map, &fp3, v102);
   1198  fp_pair_map_set(map, &fp4, v103);
   1199  tt_int_op(fp_pair_map_size(map),OP_EQ, 4);
   1200  fp_pair_map_assert_ok(map);
   1201  fp_pair_map_set(map, &fp5, v104);
   1202  fp_pair_map_set_by_digests(map, fp6.first, fp6.second, v105);
   1203  fp_pair_map_assert_ok(map);
   1204 
   1205  /* Test iterator. */
   1206  iter = fp_pair_map_iter_init(map);
   1207  while (!fp_pair_map_iter_done(iter)) {
   1208    fp_pair_map_iter_get(iter, &k, &v);
   1209    tt_ptr_op(v,OP_EQ, fp_pair_map_get(map, &k));
   1210 
   1211    if (tor_memeq(&fp2, &k, sizeof(fp2))) {
   1212      iter = fp_pair_map_iter_next_rmv(map, iter);
   1213    } else {
   1214      iter = fp_pair_map_iter_next(map, iter);
   1215    }
   1216  }
   1217 
   1218  /* Make sure we removed fp2, but not the others. */
   1219  tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, NULL);
   1220  tt_ptr_op(fp_pair_map_get_by_digests(map, fp5.first, fp5.second),
   1221            OP_EQ, v104);
   1222 
   1223  fp_pair_map_assert_ok(map);
   1224  /* Clean up after ourselves. */
   1225  fp_pair_map_free(map, NULL);
   1226  map = NULL;
   1227 
   1228 done:
   1229  if (map)
   1230    fp_pair_map_free(map, NULL);
   1231  tor_free(v99);
   1232  tor_free(v100);
   1233  tor_free(v101);
   1234  tor_free(v102);
   1235  tor_free(v103);
   1236  tor_free(v104);
   1237  tor_free(v105);
   1238 }
   1239 
   1240 static void
   1241 test_container_smartlist_most_frequent(void *arg)
   1242 {
   1243  (void) arg;
   1244  smartlist_t *sl = smartlist_new();
   1245 
   1246  int count = -1;
   1247  const char *cp;
   1248 
   1249  cp = smartlist_get_most_frequent_string_(sl, &count);
   1250  tt_int_op(count, OP_EQ, 0);
   1251  tt_ptr_op(cp, OP_EQ, NULL);
   1252 
   1253  /* String must be sorted before we call get_most_frequent */
   1254  smartlist_split_string(sl, "abc:def:ghi", ":", 0, 0);
   1255 
   1256  cp = smartlist_get_most_frequent_string_(sl, &count);
   1257  tt_int_op(count, OP_EQ, 1);
   1258  tt_str_op(cp, OP_EQ, "ghi"); /* Ties broken in favor of later element */
   1259 
   1260  smartlist_split_string(sl, "def:ghi", ":", 0, 0);
   1261  smartlist_sort_strings(sl);
   1262 
   1263  cp = smartlist_get_most_frequent_string_(sl, &count);
   1264  tt_int_op(count, OP_EQ, 2);
   1265  tt_ptr_op(cp, OP_NE, NULL);
   1266  tt_str_op(cp, OP_EQ, "ghi"); /* Ties broken in favor of later element */
   1267 
   1268  smartlist_split_string(sl, "def:abc:qwop", ":", 0, 0);
   1269  smartlist_sort_strings(sl);
   1270 
   1271  cp = smartlist_get_most_frequent_string_(sl, &count);
   1272  tt_int_op(count, OP_EQ, 3);
   1273  tt_ptr_op(cp, OP_NE, NULL);
   1274  tt_str_op(cp, OP_EQ, "def"); /* No tie */
   1275 
   1276 done:
   1277  SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
   1278  smartlist_free(sl);
   1279 }
   1280 
   1281 static void
   1282 test_container_smartlist_sort_ptrs(void *arg)
   1283 {
   1284  (void)arg;
   1285  int array[10];
   1286  int *arrayptrs[11];
   1287  smartlist_t *sl = smartlist_new();
   1288  unsigned i=0, j;
   1289 
   1290  for (j = 0; j < ARRAY_LENGTH(array); ++j) {
   1291    smartlist_add(sl, &array[j]);
   1292    arrayptrs[i++] = &array[j];
   1293    if (j == 5) {
   1294      smartlist_add(sl, &array[j]);
   1295      arrayptrs[i++] = &array[j];
   1296    }
   1297  }
   1298 
   1299  for (i = 0; i < 10; ++i) {
   1300    smartlist_shuffle(sl);
   1301    smartlist_sort_pointers(sl);
   1302    for (j = 0; j < ARRAY_LENGTH(arrayptrs); ++j) {
   1303      tt_ptr_op(smartlist_get(sl, j), OP_EQ, arrayptrs[j]);
   1304    }
   1305  }
   1306 
   1307 done:
   1308  smartlist_free(sl);
   1309 }
   1310 
   1311 static void
   1312 test_container_smartlist_strings_eq(void *arg)
   1313 {
   1314  (void)arg;
   1315  smartlist_t *sl1 = smartlist_new();
   1316  smartlist_t *sl2 = smartlist_new();
   1317 #define EQ_SHOULD_SAY(s1,s2,val)                                \
   1318  do {                                                          \
   1319    SMARTLIST_FOREACH(sl1, char *, cp, tor_free(cp));           \
   1320    SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));           \
   1321    smartlist_clear(sl1);                                       \
   1322    smartlist_clear(sl2);                                       \
   1323    smartlist_split_string(sl1, (s1), ":", 0, 0);               \
   1324    smartlist_split_string(sl2, (s2), ":", 0, 0);               \
   1325    tt_int_op((val), OP_EQ, smartlist_strings_eq(sl1, sl2));    \
   1326  } while (0)
   1327 
   1328  /* Both NULL, so equal */
   1329  tt_int_op(1, OP_EQ, smartlist_strings_eq(NULL, NULL));
   1330 
   1331  /* One NULL, not equal. */
   1332  tt_int_op(0, OP_EQ, smartlist_strings_eq(NULL, sl1));
   1333  tt_int_op(0, OP_EQ, smartlist_strings_eq(sl1, NULL));
   1334 
   1335  /* Both empty, both equal. */
   1336  EQ_SHOULD_SAY("", "", 1);
   1337 
   1338  /* One empty, not equal */
   1339  EQ_SHOULD_SAY("", "ab", 0);
   1340  EQ_SHOULD_SAY("", "xy:z", 0);
   1341  EQ_SHOULD_SAY("abc", "", 0);
   1342  EQ_SHOULD_SAY("abc:cd", "", 0);
   1343 
   1344  /* Different lengths, not equal. */
   1345  EQ_SHOULD_SAY("hello:world", "hello", 0);
   1346  EQ_SHOULD_SAY("hello", "hello:friends", 0);
   1347 
   1348  /* Same lengths, not equal */
   1349  EQ_SHOULD_SAY("Hello:world", "goodbye:world", 0);
   1350  EQ_SHOULD_SAY("Hello:world", "Hello:stars", 0);
   1351 
   1352  /* Actually equal */
   1353  EQ_SHOULD_SAY("ABC", "ABC", 1);
   1354  EQ_SHOULD_SAY(" ab : cd : e", " ab : cd : e", 1);
   1355 
   1356 done:
   1357  SMARTLIST_FOREACH(sl1, char *, cp, tor_free(cp));
   1358  SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
   1359  smartlist_free(sl1);
   1360  smartlist_free(sl2);
   1361 }
   1362 
   1363 #define CONTAINER_LEGACY(name)                                          \
   1364  { #name, test_container_ ## name , 0, NULL, NULL }
   1365 
   1366 #define CONTAINER(name, flags)                                          \
   1367  { #name, test_container_ ## name, (flags), NULL, NULL }
   1368 
   1369 struct testcase_t container_tests[] = {
   1370  CONTAINER_LEGACY(smartlist_basic),
   1371  CONTAINER_LEGACY(smartlist_strings),
   1372  CONTAINER_LEGACY(smartlist_foreach_reverse),
   1373  CONTAINER_LEGACY(smartlist_overlap),
   1374  CONTAINER_LEGACY(smartlist_digests),
   1375  CONTAINER_LEGACY(smartlist_join),
   1376  CONTAINER_LEGACY(smartlist_pos),
   1377  CONTAINER(smartlist_remove, 0),
   1378  CONTAINER(smartlist_ints_eq, 0),
   1379  CONTAINER(smartlist_grow, 0),
   1380  CONTAINER_LEGACY(bitarray),
   1381  CONTAINER_LEGACY(digestset),
   1382  CONTAINER_LEGACY(strmap),
   1383  CONTAINER_LEGACY(pqueue),
   1384  CONTAINER_LEGACY(order_functions),
   1385  CONTAINER(di_map, 0),
   1386  CONTAINER_LEGACY(fp_pair_map),
   1387  CONTAINER(smartlist_most_frequent, 0),
   1388  CONTAINER(smartlist_sort_ptrs, 0),
   1389  CONTAINER(smartlist_strings_eq, 0),
   1390  END_OF_TESTCASES
   1391 };