LCOV - code coverage report
Current view: top level - test - test_nodelist.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 741 741 100.0 %
Date: 2021-11-24 03:28:48 Functions: 21 21 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2007-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : /**
       5             :  * \file test_nodelist.c
       6             :  * \brief Unit tests for nodelist related functions.
       7             :  **/
       8             : 
       9             : #define NODELIST_PRIVATE
      10             : #define NETWORKSTATUS_PRIVATE
      11             : 
      12             : #include "core/or/or.h"
      13             : #include "lib/crypt_ops/crypto_rand.h"
      14             : #include "lib/crypt_ops/crypto_format.h"
      15             : #include "feature/nodelist/describe.h"
      16             : #include "feature/nodelist/networkstatus.h"
      17             : #include "feature/nodelist/nodefamily.h"
      18             : #include "feature/nodelist/nodelist.h"
      19             : #include "feature/nodelist/torcert.h"
      20             : 
      21             : #include "core/or/extend_info_st.h"
      22             : #include "feature/dirauth/dirvote.h"
      23             : #include "feature/nodelist/fmt_routerstatus.h"
      24             : #include "feature/nodelist/microdesc_st.h"
      25             : #include "feature/nodelist/networkstatus_st.h"
      26             : #include "feature/nodelist/node_st.h"
      27             : #include "feature/nodelist/nodefamily_st.h"
      28             : #include "feature/nodelist/routerinfo_st.h"
      29             : #include "feature/nodelist/routerstatus_st.h"
      30             : 
      31             : #include "test/test.h"
      32             : #include "test/log_test_helpers.h"
      33             : 
      34             : /** Test the case when node_get_by_id() returns NULL,
      35             :  * node_get_verbose_nickname_by_id should return the base 16 encoding
      36             :  * of the id.
      37             :  */
      38             : static void
      39           1 : test_nodelist_node_get_verbose_nickname_by_id_null_node(void *arg)
      40             : {
      41           1 :   char vname[MAX_VERBOSE_NICKNAME_LEN+1];
      42           1 :   const char ID[] = "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
      43             :                     "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
      44           1 :   (void) arg;
      45             : 
      46             :   /* make sure node_get_by_id returns NULL */
      47           1 :   tt_assert(!node_get_by_id(ID));
      48           1 :   node_get_verbose_nickname_by_id(ID, vname);
      49           1 :   tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
      50           1 :  done:
      51           1 :   return;
      52             : }
      53             : 
      54             : /** For routers without named flag, get_verbose_nickname should return
      55             :  * "Fingerprint~Nickname"
      56             :  */
      57             : static void
      58           1 : test_nodelist_node_get_verbose_nickname_not_named(void *arg)
      59             : {
      60           1 :   node_t mock_node;
      61           1 :   routerstatus_t mock_rs;
      62             : 
      63           1 :   char vname[MAX_VERBOSE_NICKNAME_LEN+1];
      64             : 
      65           1 :   (void) arg;
      66             : 
      67           1 :   memset(&mock_node, 0, sizeof(node_t));
      68           1 :   memset(&mock_rs, 0, sizeof(routerstatus_t));
      69             : 
      70             :   /* verbose nickname should use ~ instead of = for unnamed routers */
      71           1 :   strlcpy(mock_rs.nickname, "TestOR", sizeof(mock_rs.nickname));
      72           1 :   mock_node.rs = &mock_rs;
      73           1 :   memcpy(mock_node.identity,
      74             :           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
      75             :           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
      76             :           DIGEST_LEN);
      77           1 :   node_get_verbose_nickname(&mock_node, vname);
      78           1 :   tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
      79             : 
      80           1 :  done:
      81           1 :   return;
      82             : }
      83             : 
      84             : /** A node should be considered a directory server if it has an open dirport
      85             :  * or it accepts tunnelled directory requests.
      86             :  */
      87             : static void
      88           1 : test_nodelist_node_is_dir(void *arg)
      89             : {
      90           1 :   (void)arg;
      91             : 
      92           1 :   routerstatus_t rs;
      93           1 :   routerinfo_t ri;
      94           1 :   node_t node;
      95           1 :   memset(&node, 0, sizeof(node_t));
      96           1 :   memset(&rs, 0, sizeof(routerstatus_t));
      97           1 :   memset(&ri, 0, sizeof(routerinfo_t));
      98             : 
      99           1 :   tt_assert(!node_is_dir(&node));
     100             : 
     101           1 :   node.rs = &rs;
     102           1 :   tt_assert(!node_is_dir(&node));
     103             : 
     104           1 :   rs.is_v2_dir = 1;
     105           1 :   tt_assert(node_is_dir(&node));
     106             : 
     107           1 :   rs.is_v2_dir = 0;
     108           1 :   rs.ipv4_dirport = 1;
     109           1 :   tt_assert(! node_is_dir(&node));
     110             : 
     111           1 :   node.rs = NULL;
     112           1 :   tt_assert(!node_is_dir(&node));
     113           1 :   node.ri = &ri;
     114           1 :   ri.supports_tunnelled_dir_requests = 1;
     115           1 :   tt_assert(node_is_dir(&node));
     116           1 :   ri.supports_tunnelled_dir_requests = 0;
     117           1 :   ri.ipv4_dirport = 1;
     118           1 :   tt_assert(! node_is_dir(&node));
     119             : 
     120           1 :  done:
     121           1 :   return;
     122             : }
     123             : 
     124             : static networkstatus_t *dummy_ns = NULL;
     125             : static networkstatus_t *
     126           1 : mock_networkstatus_get_latest_consensus(void)
     127             : {
     128           1 :   return dummy_ns;
     129             : }
     130             : static networkstatus_t *
     131           3 : mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
     132             : {
     133           3 :   tor_assert(f == FLAV_MICRODESC);
     134           3 :   return dummy_ns;
     135             : }
     136             : 
     137             : static void
     138           1 : test_nodelist_ed_id(void *arg)
     139             : {
     140             : #define N_NODES 5
     141           1 :   routerstatus_t *rs[N_NODES];
     142           1 :   microdesc_t *md[N_NODES];
     143           1 :   routerinfo_t *ri[N_NODES];
     144           1 :   networkstatus_t *ns;
     145           1 :   int i;
     146           1 :   (void)arg;
     147             : 
     148           1 :   ns = tor_malloc_zero(sizeof(networkstatus_t));
     149           1 :   ns->flavor = FLAV_MICRODESC;
     150           1 :   ns->routerstatus_list = smartlist_new();
     151           1 :   dummy_ns = ns;
     152           1 :   MOCK(networkstatus_get_latest_consensus,
     153             :        mock_networkstatus_get_latest_consensus);
     154           1 :   MOCK(networkstatus_get_latest_consensus_by_flavor,
     155             :        mock_networkstatus_get_latest_consensus_by_flavor);
     156             : 
     157             :   /* Make a bunch of dummy objects that we can play around with.  Only set the
     158             :      necessary fields */
     159             : 
     160           6 :   for (i = 0; i < N_NODES; ++i) {
     161           5 :     rs[i] = tor_malloc_zero(sizeof(*rs[i]));
     162           5 :     md[i] = tor_malloc_zero(sizeof(*md[i]));
     163           5 :     ri[i] = tor_malloc_zero(sizeof(*ri[i]));
     164             : 
     165           5 :     crypto_rand(md[i]->digest, sizeof(md[i]->digest));
     166           5 :     md[i]->ed25519_identity_pkey = tor_malloc(sizeof(ed25519_public_key_t));
     167           5 :     crypto_rand((char*)md[i]->ed25519_identity_pkey,
     168             :                 sizeof(ed25519_public_key_t));
     169           5 :     crypto_rand(rs[i]->identity_digest, sizeof(rs[i]->identity_digest));
     170           5 :     memcpy(ri[i]->cache_info.identity_digest, rs[i]->identity_digest,
     171             :            DIGEST_LEN);
     172           5 :     memcpy(rs[i]->descriptor_digest, md[i]->digest, DIGEST256_LEN);
     173           5 :     ri[i]->cache_info.signing_key_cert = tor_malloc_zero(sizeof(tor_cert_t));
     174           5 :     memcpy(&ri[i]->cache_info.signing_key_cert->signing_key,
     175           5 :            md[i]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
     176             : 
     177           5 :     if (i < 3)
     178           3 :       smartlist_add(ns->routerstatus_list, rs[i]);
     179             :   }
     180             : 
     181           1 :   tt_int_op(0, OP_EQ, smartlist_len(nodelist_get_list()));
     182             : 
     183           1 :   nodelist_set_consensus(ns);
     184             : 
     185           1 :   tt_int_op(3, OP_EQ, smartlist_len(nodelist_get_list()));
     186             : 
     187             :   /* No Ed25519 info yet, so nothing has an ED id. */
     188           1 :   tt_ptr_op(NULL, OP_EQ, node_get_by_ed25519_id(md[0]->ed25519_identity_pkey));
     189             : 
     190             :   /* Register the first one by md, then look it up. */
     191           1 :   node_t *n = nodelist_add_microdesc(md[0]);
     192           1 :   tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[0]->ed25519_identity_pkey));
     193             : 
     194             :   /* Register the second by ri, then look it up. */
     195           1 :   routerinfo_t *ri_old = NULL;
     196           1 :   n = nodelist_set_routerinfo(ri[1], &ri_old);
     197           1 :   tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[1]->ed25519_identity_pkey));
     198           1 :   tt_ptr_op(ri_old, OP_EQ, NULL);
     199             : 
     200             :   /* Register it by md too. */
     201           1 :   node_t *n2 = nodelist_add_microdesc(md[1]);
     202           1 :   tt_ptr_op(n2, OP_EQ, n);
     203           1 :   tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[1]->ed25519_identity_pkey));
     204             : 
     205             :   /* Register the 4th by ri only -- we never put it into the networkstatus,
     206             :    * so it has to be independent */
     207           1 :   node_t *n3 = nodelist_set_routerinfo(ri[3], &ri_old);
     208           1 :   tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
     209           1 :   tt_ptr_op(ri_old, OP_EQ, NULL);
     210           1 :   tt_int_op(4, OP_EQ, smartlist_len(nodelist_get_list()));
     211             : 
     212             :   /* Register the 5th by ri only, and rewrite its ed25519 pubkey to be
     213             :    * the same as the 4th, to test the duplicate ed25519 key logging in
     214             :    * nodelist.c */
     215           1 :   memcpy(md[4]->ed25519_identity_pkey, md[3]->ed25519_identity_pkey,
     216             :          sizeof(ed25519_public_key_t));
     217           1 :   memcpy(&ri[4]->cache_info.signing_key_cert->signing_key,
     218           1 :          md[3]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
     219             : 
     220           1 :   setup_capture_of_logs(LOG_NOTICE);
     221           1 :   node_t *n4 = nodelist_set_routerinfo(ri[4], &ri_old);
     222           1 :   tt_ptr_op(ri_old, OP_EQ, NULL);
     223           1 :   tt_int_op(5, OP_EQ, smartlist_len(nodelist_get_list()));
     224           1 :   tt_ptr_op(n4, OP_NE, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
     225           1 :   tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
     226           1 :   expect_log_msg_containing("Reused ed25519_id");
     227             : 
     228           1 :  done:
     229           1 :   teardown_capture_of_logs();
     230           7 :   for (i = 0; i < N_NODES; ++i) {
     231           5 :     tor_free(rs[i]);
     232           5 :     tor_free(md[i]->ed25519_identity_pkey);
     233           5 :     tor_free(md[i]);
     234           5 :     tor_free(ri[i]->cache_info.signing_key_cert);
     235           5 :     tor_free(ri[i]);
     236             :   }
     237           1 :   smartlist_clear(ns->routerstatus_list);
     238           1 :   networkstatus_vote_free(ns);
     239           1 :   UNMOCK(networkstatus_get_latest_consensus);
     240           1 :   UNMOCK(networkstatus_get_latest_consensus_by_flavor);
     241             : #undef N_NODES
     242           1 : }
     243             : 
     244             : static void
     245           1 : test_nodelist_nodefamily(void *arg)
     246             : {
     247           1 :   (void)arg;
     248             :   /* hex ID digests */
     249           1 :   const char h1[] = "5B435D6869206861206C65207363617270652070";
     250           1 :   const char h2[] = "75C3B220616E6461726520696E206769726F2061";
     251           1 :   const char h3[] = "2074726F766172206461206D616E67696172652C";
     252           1 :   const char h4[] = "206D656E747265206E6F6E2076616C65206C2769";
     253           1 :   const char h5[] = "6E766572736F2E202D2D5072696D6F204C657669";
     254             : 
     255             :   /* binary ID digests */
     256           1 :   uint8_t d1[DIGEST_LEN], d2[DIGEST_LEN], d3[DIGEST_LEN], d4[DIGEST_LEN],
     257             :     d5[DIGEST_LEN];
     258           1 :   base16_decode((char*)d1, sizeof(d1), h1, strlen(h1));
     259           1 :   base16_decode((char*)d2, sizeof(d2), h2, strlen(h2));
     260           1 :   base16_decode((char*)d3, sizeof(d3), h3, strlen(h3));
     261           1 :   base16_decode((char*)d4, sizeof(d4), h4, strlen(h4));
     262           1 :   base16_decode((char*)d5, sizeof(d5), h5, strlen(h5));
     263             : 
     264           1 :   char *enc=NULL, *enc2=NULL;
     265             : 
     266           1 :   nodefamily_t *nf1 = NULL;
     267           1 :   nodefamily_t *nf2 = NULL;
     268           1 :   nodefamily_t *nf3 = NULL;
     269             : 
     270           1 :   enc = nodefamily_format(NULL);
     271           1 :   tt_str_op(enc, OP_EQ, "");
     272           1 :   tor_free(enc);
     273             : 
     274             :   /* Make sure that sorting and de-duplication work. */
     275           1 :   tor_asprintf(&enc, "$%s hello", h1);
     276           1 :   nf1 = nodefamily_parse(enc, NULL, 0);
     277           1 :   tt_assert(nf1);
     278           1 :   tor_free(enc);
     279             : 
     280           1 :   tor_asprintf(&enc, "hello hello $%s hello", h1);
     281           1 :   nf2 = nodefamily_parse(enc, NULL, 0);
     282           1 :   tt_assert(nf2);
     283           1 :   tt_ptr_op(nf1, OP_EQ, nf2);
     284           1 :   tor_free(enc);
     285             : 
     286           1 :   tor_asprintf(&enc, "%s $%s hello", h1, h1);
     287           1 :   nf3 = nodefamily_parse(enc, NULL, 0);
     288           1 :   tt_assert(nf3);
     289           1 :   tt_ptr_op(nf1, OP_EQ, nf3);
     290           1 :   tor_free(enc);
     291             : 
     292           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d1));
     293           1 :   tt_assert(! nodefamily_contains_rsa_id(nf1, d2));
     294           1 :   tt_assert(nodefamily_contains_nickname(nf1, "hello"));
     295           1 :   tt_assert(nodefamily_contains_nickname(nf1, "HELLO"));
     296           1 :   tt_assert(! nodefamily_contains_nickname(nf1, "goodbye"));
     297             : 
     298           1 :   tt_int_op(nf1->refcnt, OP_EQ, 3);
     299           1 :   nodefamily_free(nf3);
     300           1 :   tt_int_op(nf1->refcnt, OP_EQ, 2);
     301             : 
     302             :   /* Try parsing with a provided self RSA digest. */
     303           1 :   nf3 = nodefamily_parse("hello ", d1, 0);
     304           1 :   tt_assert(nf3);
     305           1 :   tt_ptr_op(nf1, OP_EQ, nf3);
     306             : 
     307             :   /* Do we get the expected result when we re-encode? */
     308           1 :   tor_asprintf(&enc, "$%s hello", h1);
     309           1 :   enc2 = nodefamily_format(nf1);
     310           1 :   tt_str_op(enc2, OP_EQ, enc);
     311           1 :   tor_free(enc2);
     312           1 :   tor_free(enc);
     313             : 
     314             :   /* Make sure that we get a different result if we give a different digest. */
     315           1 :   nodefamily_free(nf3);
     316           1 :   tor_asprintf(&enc, "hello $%s hello", h3);
     317           1 :   nf3 = nodefamily_parse(enc, NULL, 0);
     318           1 :   tt_assert(nf3);
     319           1 :   tt_ptr_op(nf1, OP_NE, nf3);
     320           1 :   tor_free(enc);
     321             : 
     322           1 :   tt_assert(nodefamily_contains_rsa_id(nf3, d3));
     323           1 :   tt_assert(! nodefamily_contains_rsa_id(nf3, d2));
     324           1 :   tt_assert(! nodefamily_contains_rsa_id(nf3, d1));
     325           1 :   tt_assert(nodefamily_contains_nickname(nf3, "hello"));
     326           1 :   tt_assert(! nodefamily_contains_nickname(nf3, "goodbye"));
     327             : 
     328           1 :   nodefamily_free(nf1);
     329           1 :   nodefamily_free(nf2);
     330           1 :   nodefamily_free(nf3);
     331             : 
     332             :   /* Try one with several digests, all with nicknames appended, in different
     333             :      formats. */
     334           1 :   tor_asprintf(&enc, "%s $%s $%s=res $%s~ist", h1, h2, h3, h4);
     335           1 :   nf1 = nodefamily_parse(enc, d5, 0);
     336           1 :   tt_assert(nf1);
     337           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d1));
     338           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d2));
     339           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d3));
     340           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d4));
     341           1 :   tt_assert(nodefamily_contains_rsa_id(nf1, d5));
     342             :   /* Nicknames aren't preserved when ids are present, since node naming is
     343             :    * deprecated */
     344           1 :   tt_assert(! nodefamily_contains_nickname(nf3, "res"));
     345           1 :   tor_free(enc);
     346           1 :   tor_asprintf(&enc, "$%s $%s $%s $%s $%s", h4, h3, h1, h5, h2);
     347           1 :   enc2 = nodefamily_format(nf1);
     348           1 :   tt_str_op(enc, OP_EQ, enc2);
     349           1 :   tor_free(enc);
     350           1 :   tor_free(enc2);
     351             : 
     352             :   /* Try ones where we parse the empty string. */
     353           1 :   nf2 = nodefamily_parse("", NULL, 0);
     354           1 :   nf3 = nodefamily_parse("", d4, 0);
     355           1 :   tt_assert(nf2);
     356           1 :   tt_assert(nf3);
     357           1 :   tt_ptr_op(nf2, OP_NE, nf3);
     358             : 
     359           1 :   tt_assert(! nodefamily_contains_rsa_id(nf2, d4));
     360           1 :   tt_assert(nodefamily_contains_rsa_id(nf3, d4));
     361           1 :   tt_assert(! nodefamily_contains_rsa_id(nf2, d5));
     362           1 :   tt_assert(! nodefamily_contains_rsa_id(nf3, d5));
     363           1 :   tt_assert(! nodefamily_contains_nickname(nf2, "fred"));
     364           1 :   tt_assert(! nodefamily_contains_nickname(nf3, "bosco"));
     365             : 
     366             :   /* The NULL family should contain nothing. */
     367           1 :   tt_assert(! nodefamily_contains_rsa_id(NULL, d4));
     368           1 :   tt_assert(! nodefamily_contains_rsa_id(NULL, d5));
     369             : 
     370           1 :  done:
     371           1 :   tor_free(enc);
     372           1 :   tor_free(enc2);
     373           1 :   nodefamily_free(nf1);
     374           1 :   nodefamily_free(nf2);
     375           1 :   nodefamily_free(nf3);
     376           1 :   nodefamily_free_all();
     377           1 : }
     378             : 
     379             : static void
     380           1 : test_nodelist_nodefamily_parse_err(void *arg)
     381             : {
     382           1 :   (void)arg;
     383           1 :   nodefamily_t *nf1 = NULL;
     384           1 :   char *enc = NULL;
     385           1 :   const char *semibogus =
     386             :     "sdakljfdslkfjdsaklfjdkl9sdf " // too long for nickname
     387             :     "$jkASDFLkjsadfjhkl " // not hex
     388             :     "$7468696e67732d696e2d7468656d73656c766573 " // ok
     389             :     "reticulatogranulate "// ok
     390             :     "$73656d69616e7468726f706f6c6f676963616c6c79 " // too long for hex
     391             :     "$616273656e746d696e6465646e6573736573" // too short for hex
     392             :     ;
     393             : 
     394           1 :   setup_capture_of_logs(LOG_WARN);
     395             : 
     396             :   // We only get two items when we parse this.
     397           3 :   for (int reject = 0; reject <= 1; ++reject) {
     398           6 :     for (int log_at_warn = 0; log_at_warn <= 1; ++log_at_warn) {
     399           4 :       unsigned flags = log_at_warn ? NF_WARN_MALFORMED : 0;
     400           4 :       flags |= reject ? NF_REJECT_MALFORMED : 0;
     401           4 :       nf1 = nodefamily_parse(semibogus, NULL, flags);
     402           4 :       if (reject) {
     403           2 :         tt_assert(nf1 == NULL);
     404             :       } else {
     405           2 :         tt_assert(nf1);
     406           2 :         enc = nodefamily_format(nf1);
     407           2 :         tt_str_op(enc, OP_EQ,
     408             :                   "$7468696E67732D696E2D7468656D73656C766573 "
     409             :                   "reticulatogranulate");
     410           2 :         tor_free(enc);
     411             :       }
     412             : 
     413           4 :       if (log_at_warn) {
     414           2 :         expect_log_msg_containing("$616273656e746d696e6465646e6573736573");
     415           2 :         expect_log_msg_containing("sdakljfdslkfjdsaklfjdkl9sdf");
     416             :       } else {
     417           2 :         tt_int_op(mock_saved_log_n_entries(), OP_EQ, 0);
     418             :       }
     419           4 :       mock_clean_saved_logs();
     420             :     }
     421             :   }
     422             : 
     423           1 :  done:
     424           1 :   tor_free(enc);
     425           1 :   nodefamily_free(nf1);
     426           1 :   teardown_capture_of_logs();
     427           1 : }
     428             : 
     429             : static const node_t *
     430           4 : mock_node_get_by_id(const char *id)
     431             : {
     432           4 :   if (fast_memeq(id, "!!!!!!!!!!!!!!!!!!!!", DIGEST_LEN))
     433             :     return NULL;
     434             : 
     435             :   // use tor_free, not node_free.
     436           3 :   node_t *fake_node = tor_malloc_zero(sizeof(node_t));
     437           3 :   memcpy(fake_node->identity, id, DIGEST_LEN);
     438           3 :   return fake_node;
     439             : }
     440             : 
     441             : static const node_t *
     442           5 : mock_node_get_by_nickname(const char *nn, unsigned flags)
     443             : {
     444           5 :   (void)flags;
     445           5 :   if (!strcmp(nn, "nonesuch"))
     446             :     return NULL;
     447             : 
     448             :   // use tor_free, not node_free.
     449           4 :   node_t *fake_node = tor_malloc_zero(sizeof(node_t));
     450           4 :   strlcpy(fake_node->identity, nn, DIGEST_LEN);
     451           4 :   return fake_node;
     452             : }
     453             : 
     454             : static void
     455           1 : test_nodelist_nodefamily_lookup(void *arg)
     456             : {
     457           1 :   (void)arg;
     458           1 :   MOCK(node_get_by_nickname, mock_node_get_by_nickname);
     459           1 :   MOCK(node_get_by_id, mock_node_get_by_id);
     460           1 :   smartlist_t *sl = smartlist_new();
     461           1 :   nodefamily_t *nf1 = NULL;
     462           1 :   char *mem_op_hex_tmp = NULL;
     463             : 
     464             :   // 'null' is allowed.
     465           1 :   nodefamily_add_nodes_to_smartlist(NULL, sl);
     466           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 0);
     467             : 
     468             :   // Try a real family
     469           1 :   nf1 = nodefamily_parse("$EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE "
     470             :                          "$2121212121212121212121212121212121212121 "
     471             :                          "$3333333333333333333333333333333333333333 "
     472             :                          "erewhon nonesuch", NULL, 0);
     473           1 :   tt_assert(nf1);
     474           1 :   nodefamily_add_nodes_to_smartlist(nf1, sl);
     475             :   // There were 5 elements; 2 were dropped because the mocked lookup failed.
     476           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
     477             : 
     478           1 :   const node_t *n = smartlist_get(sl, 0);
     479           1 :   test_memeq_hex(n->identity, "3333333333333333333333333333333333333333");
     480           1 :   n = smartlist_get(sl, 1);
     481           1 :   test_memeq_hex(n->identity, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
     482           1 :   n = smartlist_get(sl, 2);
     483           1 :   tt_str_op(n->identity, OP_EQ, "erewhon");
     484             : 
     485           1 :  done:
     486           1 :   UNMOCK(node_get_by_nickname);
     487           1 :   UNMOCK(node_get_by_id);
     488           4 :   SMARTLIST_FOREACH(sl, node_t *, fake_node, tor_free(fake_node));
     489           1 :   smartlist_free(sl);
     490           1 :   nodefamily_free(nf1);
     491           1 :   tor_free(mem_op_hex_tmp);
     492           1 : }
     493             : 
     494             : static void
     495           1 : test_nodelist_nickname_matches(void *arg)
     496             : {
     497           1 :   (void)arg;
     498           1 :   node_t mock_node;
     499           1 :   routerstatus_t mock_rs;
     500           1 :   memset(&mock_node, 0, sizeof(mock_node));
     501           1 :   memset(&mock_rs, 0, sizeof(mock_rs));
     502             : 
     503           1 :   strlcpy(mock_rs.nickname, "evilgeniuses", sizeof(mock_rs.nickname));
     504           1 :   mock_node.rs = &mock_rs;
     505           1 :   memcpy(mock_node.identity, ".forabettertomorrow.", DIGEST_LEN);
     506             : 
     507             : #define match(x) tt_assert(node_nickname_matches(&mock_node, (x)))
     508             : #define no_match(x) tt_assert(! node_nickname_matches(&mock_node, (x)))
     509             : 
     510           1 :   match("evilgeniuses");
     511           1 :   match("EvilGeniuses");
     512           1 :   match("EvilGeniuses");
     513           1 :   match("2e666f7261626574746572746f6d6f72726f772e");
     514           1 :   match("2E666F7261626574746572746F6D6F72726F772E");
     515           1 :   match("$2e666f7261626574746572746f6d6f72726f772e");
     516           1 :   match("$2E666F7261626574746572746F6D6F72726F772E");
     517           1 :   match("$2E666F7261626574746572746F6D6F72726F772E~evilgeniuses");
     518           1 :   match("$2E666F7261626574746572746F6D6F72726F772E~EVILGENIUSES");
     519             : 
     520           1 :   no_match("evilgenius");
     521           1 :   no_match("evilgeniuseses");
     522           1 :   no_match("evil.genius");
     523           1 :   no_match("$2E666F7261626574746572746F6D6F72726FFFFF");
     524           1 :   no_match("2E666F7261626574746572746F6D6F72726FFFFF");
     525           1 :   no_match("$2E666F7261626574746572746F6D6F72726F772E~fred");
     526           1 :   no_match("$2E666F7261626574746572746F6D6F72726F772E=EVILGENIUSES");
     527           1 :  done:
     528           1 :   ;
     529           1 : }
     530             : 
     531             : static void
     532           1 : test_nodelist_node_nodefamily(void *arg)
     533             : {
     534           1 :   (void)arg;
     535           1 :   node_t mock_node1;
     536           1 :   routerstatus_t mock_rs;
     537           1 :   microdesc_t mock_md;
     538             : 
     539           1 :   node_t mock_node2;
     540           1 :   routerinfo_t mock_ri;
     541             : 
     542           1 :   smartlist_t *nodes=smartlist_new();
     543             : 
     544           1 :   memset(&mock_node1, 0, sizeof(mock_node1));
     545           1 :   memset(&mock_node2, 0, sizeof(mock_node2));
     546           1 :   memset(&mock_rs, 0, sizeof(mock_rs));
     547           1 :   memset(&mock_md, 0, sizeof(mock_md));
     548           1 :   memset(&mock_ri, 0, sizeof(mock_ri));
     549             : 
     550           1 :   mock_node1.rs = &mock_rs;
     551           1 :   mock_node1.md = &mock_md;
     552             : 
     553           1 :   mock_node2.ri = &mock_ri;
     554             : 
     555           1 :   strlcpy(mock_rs.nickname, "nodeone", sizeof(mock_rs.nickname));
     556           1 :   mock_ri.nickname = tor_strdup("nodetwo");
     557             : 
     558           1 :   memcpy(mock_node1.identity, "NodeOneNode1NodeOne1", DIGEST_LEN);
     559           1 :   memcpy(mock_node2.identity, "SecondNodeWe'reTestn", DIGEST_LEN);
     560             : 
     561             :   // empty families.
     562           1 :   tt_assert(! node_family_contains(&mock_node1, &mock_node2));
     563           1 :   tt_assert(! node_family_contains(&mock_node2, &mock_node1));
     564             : 
     565             :   // Families contain nodes, but not these nodes
     566           1 :   mock_ri.declared_family = smartlist_new();
     567           1 :   smartlist_add(mock_ri.declared_family, (char*)"NodeThree");
     568           1 :   mock_md.family = nodefamily_parse("NodeFour", NULL, 0);
     569           1 :   tt_assert(! node_family_contains(&mock_node1, &mock_node2));
     570           1 :   tt_assert(! node_family_contains(&mock_node2, &mock_node1));
     571             : 
     572             :   // Families contain one another.
     573           1 :   smartlist_add(mock_ri.declared_family, (char*)
     574             :                 "4e6f64654f6e654e6f6465314e6f64654f6e6531");
     575           1 :   tt_assert(! node_family_contains(&mock_node1, &mock_node2));
     576           1 :   tt_assert(node_family_contains(&mock_node2, &mock_node1));
     577             : 
     578           1 :   nodefamily_free(mock_md.family);
     579           1 :   mock_md.family = nodefamily_parse(
     580             :             "NodeFour "
     581             :             "5365636f6e644e6f64655765277265546573746e", NULL, 0);
     582           1 :   tt_assert(node_family_contains(&mock_node1, &mock_node2));
     583           1 :   tt_assert(node_family_contains(&mock_node2, &mock_node1));
     584             : 
     585             :   // Try looking up families now.
     586           1 :   MOCK(node_get_by_nickname, mock_node_get_by_nickname);
     587           1 :   MOCK(node_get_by_id, mock_node_get_by_id);
     588             : 
     589           1 :   node_lookup_declared_family(nodes, &mock_node1);
     590           1 :   tt_int_op(smartlist_len(nodes), OP_EQ, 2);
     591           1 :   const node_t *n = smartlist_get(nodes, 0);
     592           1 :   tt_mem_op(n->identity, OP_EQ, "SecondNodeWe'reTestn", DIGEST_LEN);
     593           1 :   n = smartlist_get(nodes, 1);
     594           1 :   tt_str_op(n->identity, OP_EQ, "nodefour");
     595             : 
     596             :   // free, try the other one.
     597           3 :   SMARTLIST_FOREACH(nodes, node_t *, x, tor_free(x));
     598           1 :   smartlist_clear(nodes);
     599             : 
     600           1 :   node_lookup_declared_family(nodes, &mock_node2);
     601           1 :   tt_int_op(smartlist_len(nodes), OP_EQ, 2);
     602           1 :   n = smartlist_get(nodes, 0);
     603             :   // This gets a truncated hex hex ID since it was looked up by name
     604           1 :   tt_str_op(n->identity, OP_EQ, "NodeThree");
     605           1 :   n = smartlist_get(nodes, 1);
     606           1 :   tt_str_op(n->identity, OP_EQ, "4e6f64654f6e654e6f6");
     607             : 
     608           1 :  done:
     609           1 :   UNMOCK(node_get_by_nickname);
     610           1 :   UNMOCK(node_get_by_id);
     611           1 :   smartlist_free(mock_ri.declared_family);
     612           1 :   nodefamily_free(mock_md.family);
     613           1 :   tor_free(mock_ri.nickname);
     614             :   // use tor_free, these aren't real nodes
     615           3 :   SMARTLIST_FOREACH(nodes, node_t *, x, tor_free(x));
     616           1 :   smartlist_free(nodes);
     617           1 : }
     618             : 
     619             : static void
     620           1 : test_nodelist_nodefamily_canonicalize(void *arg)
     621             : {
     622           1 :   (void)arg;
     623           1 :   char *c = NULL;
     624             : 
     625           1 :   c = nodefamily_canonicalize("", NULL, 0);
     626           1 :   tt_str_op(c, OP_EQ, "");
     627           1 :   tor_free(c);
     628             : 
     629           1 :   uint8_t own_id[20];
     630           1 :   memset(own_id, 0, sizeof(own_id));
     631           1 :   c = nodefamily_canonicalize(
     632             :            "alice BOB caroL %potrzebie !!!@#@# "
     633             :            "$bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=fred "
     634             :            "ffffffffffffffffffffffffffffffffffffffff "
     635             :            "$cccccccccccccccccccccccccccccccccccccccc ", own_id, 0);
     636           1 :   tt_str_op(c, OP_EQ,
     637             :            "!!!@#@# "
     638             :            "$0000000000000000000000000000000000000000 "
     639             :            "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB "
     640             :            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC "
     641             :            "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF "
     642             :            "%potrzebie "
     643             :            "alice bob carol");
     644             : 
     645           1 :  done:
     646           1 :   tor_free(c);
     647           1 : }
     648             : 
     649             : /** format_node_description() should return
     650             :  * "Fingerprint~Nickname at IPv4 and [IPv6]".
     651             :  * The nickname and addresses are optional.
     652             :  */
     653             : static void
     654           1 : test_nodelist_format_node_description(void *arg)
     655             : {
     656           1 :   char mock_digest[DIGEST_LEN];
     657           1 :   char mock_nickname[MAX_NICKNAME_LEN+1];
     658           1 :   tor_addr_t mock_null_ip;
     659           1 :   tor_addr_t mock_ipv4;
     660           1 :   tor_addr_t mock_ipv6;
     661           1 :   ed25519_public_key_t ed_id;
     662             : 
     663           1 :   char ndesc[NODE_DESC_BUF_LEN];
     664           1 :   const char *rv = NULL;
     665             : 
     666           1 :   (void) arg;
     667             : 
     668             :   /* Clear variables */
     669           1 :   memset(ndesc, 0, sizeof(ndesc));
     670           1 :   memset(mock_digest, 0, sizeof(mock_digest));
     671           1 :   memset(mock_nickname, 0, sizeof(mock_nickname));
     672           1 :   memset(&mock_null_ip, 0, sizeof(mock_null_ip));
     673           1 :   memset(&mock_ipv4, 0, sizeof(mock_ipv4));
     674           1 :   memset(&mock_ipv6, 0, sizeof(mock_ipv6));
     675             : 
     676             :   /* Set variables */
     677           1 :   memcpy(mock_digest,
     678             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     679             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
     680             :          sizeof(mock_digest));
     681           1 :   strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
     682           1 :   tor_addr_parse(&mock_ipv4, "111.222.233.244");
     683           1 :   tor_addr_parse(&mock_ipv6, "[1111:2222:3333:4444:5555:6666:7777:8888]");
     684             : 
     685             :   /* Test function with variables */
     686           1 :   rv = format_node_description(ndesc,
     687             :                                mock_digest,
     688             :                                NULL,
     689             :                                NULL,
     690             :                                NULL,
     691             :                                NULL);
     692           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     693           1 :   tt_str_op(ndesc, OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
     694             : 
     695             :   /* format node description should use ~ because named is deprecated */
     696           1 :   rv = format_node_description(ndesc,
     697             :                                mock_digest,
     698             :                                NULL,
     699             :                                mock_nickname,
     700             :                                NULL,
     701             :                                NULL);
     702           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     703           1 :   tt_str_op(ndesc, OP_EQ,
     704             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~""TestOR7890123456789");
     705             : 
     706             :   /* Try a null IP address, rather than NULL */
     707           1 :   rv = format_node_description(ndesc,
     708             :                                mock_digest,
     709             :                                NULL,
     710             :                                mock_nickname,
     711             :                                NULL,
     712             :                                &mock_null_ip);
     713           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     714           1 :   tt_str_op(ndesc, OP_EQ,
     715             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789");
     716             : 
     717             :   /* Try some real IP addresses */
     718           1 :   rv = format_node_description(ndesc,
     719             :                                mock_digest,
     720             :                                NULL,
     721             :                                NULL,
     722             :                                &mock_ipv4,
     723             :                                NULL);
     724           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     725           1 :   tt_str_op(ndesc, OP_EQ,
     726             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA at 111.222.233.244");
     727             : 
     728           1 :   rv = format_node_description(ndesc,
     729             :                                mock_digest,
     730             :                                NULL,
     731             :                                mock_nickname,
     732             :                                NULL,
     733             :                                &mock_ipv6);
     734           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     735           1 :   tt_str_op(ndesc, OP_EQ,
     736             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     737             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
     738             : 
     739           1 :   rv = format_node_description(ndesc,
     740             :                                mock_digest,
     741             :                                NULL,
     742             :                                mock_nickname,
     743             :                                &mock_ipv4,
     744             :                                &mock_ipv6);
     745           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     746           1 :   tt_str_op(ndesc, OP_EQ,
     747             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     748             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
     749             : 
     750             :   /* Try some ed25519 keys. */
     751           1 :   int n = ed25519_public_from_base64(&ed_id,
     752             :               "+wBP6WVZzqKK+eTdwU7Hhb80xEm40FSZDBMNozTJpDE");
     753           1 :   tt_int_op(n,OP_EQ,0);
     754           1 :   rv = format_node_description(ndesc,
     755             :                                mock_digest,
     756             :                                &ed_id,
     757             :                                mock_nickname,
     758             :                                &mock_ipv4,
     759             :                                &mock_ipv6);
     760           1 :   tt_str_op(ndesc, OP_EQ,
     761             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 "
     762             :             "[+wBP6WVZzqKK+eTdwU7Hhb80xEm40FSZDBMNozTJpDE] at "
     763             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
     764             : 
     765             :   /* test NULL handling */
     766           1 :   rv = format_node_description(NULL, NULL, NULL, NULL, NULL, NULL);
     767           1 :   tt_str_op(rv, OP_EQ, "<NULL BUFFER>");
     768             : 
     769           1 :   rv = format_node_description(ndesc, NULL, NULL, NULL, NULL, NULL);
     770           1 :   tt_ptr_op(rv, OP_EQ, ndesc);
     771           1 :   tt_str_op(rv, OP_EQ, "<NULL ID DIGEST>");
     772             : 
     773           1 :  done:
     774           1 :   return;
     775             : }
     776             : 
     777             : /** router_describe() is a wrapper for format_node_description(), see that
     778             :  * test for details.
     779             :  *
     780             :  * The routerinfo-only node_describe() tests are in this function,
     781             :  * so we can re-use the same mocked variables.
     782             :  */
     783             : static void
     784           1 : test_nodelist_router_describe(void *arg)
     785             : {
     786           1 :   char mock_nickname[MAX_NICKNAME_LEN+1];
     787           1 :   routerinfo_t mock_ri_ipv4;
     788           1 :   routerinfo_t mock_ri_ipv6;
     789           1 :   routerinfo_t mock_ri_dual;
     790             : 
     791           1 :   const char *rv = NULL;
     792             : 
     793           1 :   (void) arg;
     794             : 
     795             :   /* Clear variables */
     796           1 :   memset(mock_nickname, 0, sizeof(mock_nickname));
     797           1 :   memset(&mock_ri_ipv4, 0, sizeof(mock_ri_ipv4));
     798           1 :   memset(&mock_ri_ipv6, 0, sizeof(mock_ri_ipv6));
     799           1 :   memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
     800             : 
     801             :   /* Set up the dual-stack routerinfo */
     802           1 :   memcpy(mock_ri_dual.cache_info.identity_digest,
     803             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     804             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
     805             :          sizeof(mock_ri_dual.cache_info.identity_digest));
     806           1 :   strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
     807           1 :   mock_ri_dual.nickname = mock_nickname;
     808           1 :   tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
     809           1 :   tor_addr_parse(&mock_ri_dual.ipv6_addr,
     810             :                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
     811             : 
     812             :   /* Create and modify the other routerinfos.
     813             :    * mock_nickname is referenced from all 3 routerinfos.
     814             :    * That's ok, all their memory is static. */
     815           1 :   memcpy(&mock_ri_ipv4, &mock_ri_dual, sizeof(mock_ri_ipv4));
     816           1 :   memcpy(&mock_ri_ipv6, &mock_ri_dual, sizeof(mock_ri_ipv6));
     817             :   /* Clear the unnecessary addresses */
     818           1 :   memset(&mock_ri_ipv4.ipv6_addr, 0, sizeof(mock_ri_ipv4.ipv6_addr));
     819           1 :   tor_addr_make_unspec(&mock_ri_ipv6.ipv4_addr);
     820             : 
     821             :   /* We don't test the no-nickname and no-IP cases, because they're covered by
     822             :    * format_node_description(), and we don't expect to see them in Tor code. */
     823             : 
     824             :   /* Try some real IP addresses */
     825           1 :   rv = router_describe(&mock_ri_ipv4);
     826           1 :   tt_str_op(rv, OP_EQ,
     827             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     828             :             "111.222.233.244");
     829             : 
     830           1 :   rv = router_describe(&mock_ri_ipv6);
     831           1 :   tt_str_op(rv, OP_EQ,
     832             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     833             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
     834             : 
     835           1 :   rv = router_describe(&mock_ri_dual);
     836           1 :   tt_str_op(rv, OP_EQ,
     837             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     838             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
     839             : 
     840             :   /* test NULL handling */
     841           1 :   rv = router_describe(NULL);
     842           1 :   tt_str_op(rv, OP_EQ, "<null>");
     843             : 
     844             :   /* Now test a node with only these routerinfos */
     845           1 :   node_t mock_node;
     846           1 :   memset(&mock_node, 0, sizeof(mock_node));
     847           1 :   memcpy(mock_node.identity,
     848             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     849             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
     850             :          sizeof(mock_node.identity));
     851             : 
     852             :   /* Try some real IP addresses */
     853           1 :   mock_node.ri = &mock_ri_ipv4;
     854           1 :   rv = node_describe(&mock_node);
     855           1 :   tt_str_op(rv, OP_EQ,
     856             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     857             :             "111.222.233.244");
     858             : 
     859           1 :   mock_node.ri = &mock_ri_ipv6;
     860           1 :   rv = node_describe(&mock_node);
     861           1 :   tt_str_op(rv, OP_EQ,
     862             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     863             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
     864             : 
     865           1 :   mock_node.ri = &mock_ri_dual;
     866           1 :   rv = node_describe(&mock_node);
     867           1 :   tt_str_op(rv, OP_EQ,
     868             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
     869             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
     870             : 
     871           1 :  done:
     872           1 :   return;
     873             : }
     874             : 
     875             : /** node_describe() is a wrapper for format_node_description(), see that
     876             :  * test for details.
     877             :  *
     878             :  * The routerinfo-only and routerstatus-only node_describe() tests are in
     879             :  * test_nodelist_router_describe() and test_nodelist_routerstatus_describe(),
     880             :  * so we can re-use their mocked variables.
     881             :  */
     882             : static void
     883           1 : test_nodelist_node_describe(void *arg)
     884             : {
     885           1 :   char mock_nickname[MAX_NICKNAME_LEN+1];
     886             : 
     887           1 :   const char *rv = NULL;
     888             : 
     889           1 :   (void) arg;
     890             : 
     891             :   /* Routerinfos */
     892           1 :   routerinfo_t mock_ri_dual;
     893             : 
     894             :   /* Clear variables */
     895           1 :   memset(mock_nickname, 0, sizeof(mock_nickname));
     896           1 :   memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
     897             : 
     898             :   /* Set up the dual-stack routerinfo */
     899           1 :   memcpy(mock_ri_dual.cache_info.identity_digest,
     900             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     901             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
     902             :          sizeof(mock_ri_dual.cache_info.identity_digest));
     903           1 :   strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
     904           1 :   mock_ri_dual.nickname = mock_nickname;
     905           1 :   tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
     906           1 :   tor_addr_parse(&mock_ri_dual.ipv6_addr,
     907             :                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
     908             : 
     909             :   /* Routerstatuses */
     910           1 :   routerstatus_t mock_rs_ipv4;
     911           1 :   routerstatus_t mock_rs_dual;
     912             : 
     913             :   /* Clear variables */
     914           1 :   memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
     915           1 :   memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
     916             : 
     917             :   /* Set up the dual-stack routerstatus */
     918           1 :   memcpy(mock_rs_dual.identity_digest,
     919             :          "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
     920             :          "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB",
     921             :          sizeof(mock_rs_dual.identity_digest));
     922           1 :   strlcpy(mock_rs_dual.nickname, "Bbb",
     923             :           sizeof(mock_rs_dual.nickname));
     924           1 :   tor_addr_parse(&mock_rs_dual.ipv4_addr, "2.2.2.2");
     925           1 :   tor_addr_parse(&mock_rs_dual.ipv6_addr,
     926             :                  "[bbbb::bbbb]");
     927             : 
     928             :   /* Create and modify the other routerstatus. */
     929           1 :   memcpy(&mock_rs_ipv4, &mock_rs_dual, sizeof(mock_rs_ipv4));
     930             :   /* Clear the unnecessary IPv6 address */
     931           1 :   memset(&mock_rs_ipv4.ipv6_addr, 0, sizeof(mock_rs_ipv4.ipv6_addr));
     932             : 
     933             :   /* Microdescs */
     934           1 :   microdesc_t mock_md_null;
     935           1 :   microdesc_t mock_md_ipv6;
     936             : 
     937             :   /* Clear variables */
     938           1 :   memset(&mock_md_null, 0, sizeof(mock_md_null));
     939           1 :   memset(&mock_md_ipv6, 0, sizeof(mock_md_ipv6));
     940             : 
     941             :   /* Set up the microdesc */
     942           1 :   tor_addr_parse(&mock_md_ipv6.ipv6_addr,
     943             :                  "[eeee::6000:6000]");
     944             : 
     945             :   /* Set up the node */
     946           1 :   node_t mock_node;
     947           1 :   memset(&mock_node, 0, sizeof(mock_node));
     948           1 :   memcpy(mock_node.identity,
     949             :          "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
     950             :          "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC",
     951             :          sizeof(mock_node.identity));
     952             : 
     953             :   /* Test that the routerinfo and routerstatus work separately, but the
     954             :    * identity comes from the node */
     955           1 :   mock_node.ri = &mock_ri_dual;
     956           1 :   mock_node.rs = NULL;
     957           1 :   mock_node.md = NULL;
     958           1 :   rv = node_describe(&mock_node);
     959           1 :   tt_str_op(rv, OP_EQ,
     960             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~TestOR7890123456789 at "
     961             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
     962             : 
     963           1 :   mock_node.ri = NULL;
     964           1 :   mock_node.rs = &mock_rs_ipv4;
     965           1 :   mock_node.md = NULL;
     966           1 :   rv = node_describe(&mock_node);
     967           1 :   tt_str_op(rv, OP_EQ,
     968             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
     969             :             "2.2.2.2");
     970             : 
     971           1 :   mock_node.ri = NULL;
     972           1 :   mock_node.rs = &mock_rs_dual;
     973           1 :   mock_node.md = NULL;
     974           1 :   rv = node_describe(&mock_node);
     975           1 :   tt_str_op(rv, OP_EQ,
     976             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
     977             :             "2.2.2.2 and [bbbb::bbbb]");
     978             : 
     979             :   /* Test that the routerstatus overrides the routerinfo */
     980           1 :   mock_node.ri = &mock_ri_dual;
     981           1 :   mock_node.rs = &mock_rs_ipv4;
     982           1 :   mock_node.md = NULL;
     983           1 :   rv = node_describe(&mock_node);
     984           1 :   tt_str_op(rv, OP_EQ,
     985             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
     986             :             "2.2.2.2");
     987             : 
     988           1 :   mock_node.ri = &mock_ri_dual;
     989           1 :   mock_node.rs = &mock_rs_dual;
     990           1 :   mock_node.md = NULL;
     991           1 :   rv = node_describe(&mock_node);
     992           1 :   tt_str_op(rv, OP_EQ,
     993             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
     994             :             "2.2.2.2 and [bbbb::bbbb]");
     995             : 
     996             :   /* Test that the microdesc IPv6 is used if the routerinfo doesn't have IPv6
     997             :    */
     998           1 :   mock_node.ri = NULL;
     999           1 :   mock_node.rs = &mock_rs_ipv4;
    1000           1 :   mock_node.md = &mock_md_ipv6;
    1001           1 :   rv = node_describe(&mock_node);
    1002           1 :   tt_str_op(rv, OP_EQ,
    1003             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1004             :             "2.2.2.2 and [eeee::6000:6000]");
    1005             : 
    1006           1 :   mock_node.ri = NULL;
    1007           1 :   mock_node.rs = &mock_rs_ipv4;
    1008           1 :   mock_node.md = &mock_md_null;
    1009           1 :   rv = node_describe(&mock_node);
    1010           1 :   tt_str_op(rv, OP_EQ,
    1011             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1012             :             "2.2.2.2");
    1013             : 
    1014           1 :   mock_node.ri = NULL;
    1015           1 :   mock_node.rs = &mock_rs_dual;
    1016           1 :   mock_node.md = &mock_md_ipv6;
    1017           1 :   rv = node_describe(&mock_node);
    1018           1 :   tt_str_op(rv, OP_EQ,
    1019             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1020             :             "2.2.2.2 and [bbbb::bbbb]");
    1021             : 
    1022           1 :   mock_node.ri = NULL;
    1023           1 :   mock_node.rs = &mock_rs_dual;
    1024           1 :   mock_node.md = &mock_md_null;
    1025           1 :   rv = node_describe(&mock_node);
    1026           1 :   tt_str_op(rv, OP_EQ,
    1027             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1028             :             "2.2.2.2 and [bbbb::bbbb]");
    1029             : 
    1030             :   /* Test that the routerinfo doesn't change the results above
    1031             :    */
    1032           1 :   mock_node.ri = &mock_ri_dual;
    1033           1 :   mock_node.rs = &mock_rs_ipv4;
    1034           1 :   mock_node.md = &mock_md_ipv6;
    1035           1 :   rv = node_describe(&mock_node);
    1036           1 :   tt_str_op(rv, OP_EQ,
    1037             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1038             :             "2.2.2.2 and [eeee::6000:6000]");
    1039             : 
    1040           1 :   mock_node.ri = &mock_ri_dual;
    1041           1 :   mock_node.rs = &mock_rs_ipv4;
    1042           1 :   mock_node.md = &mock_md_null;
    1043           1 :   rv = node_describe(&mock_node);
    1044           1 :   tt_str_op(rv, OP_EQ,
    1045             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1046             :             "2.2.2.2");
    1047             : 
    1048           1 :   mock_node.ri = &mock_ri_dual;
    1049           1 :   mock_node.rs = &mock_rs_dual;
    1050           1 :   mock_node.md = &mock_md_ipv6;
    1051           1 :   rv = node_describe(&mock_node);
    1052           1 :   tt_str_op(rv, OP_EQ,
    1053             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1054             :             "2.2.2.2 and [bbbb::bbbb]");
    1055             : 
    1056           1 :   mock_node.ri = &mock_ri_dual;
    1057           1 :   mock_node.rs = &mock_rs_dual;
    1058           1 :   mock_node.md = &mock_md_null;
    1059           1 :   rv = node_describe(&mock_node);
    1060           1 :   tt_str_op(rv, OP_EQ,
    1061             :             "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    1062             :             "2.2.2.2 and [bbbb::bbbb]");
    1063             : 
    1064             :   /* test NULL handling */
    1065           1 :   rv = node_describe(NULL);
    1066           1 :   tt_str_op(rv, OP_EQ, "<null>");
    1067             : 
    1068           1 :   mock_node.ri = NULL;
    1069           1 :   mock_node.rs = NULL;
    1070           1 :   mock_node.md = NULL;
    1071           1 :   rv = node_describe(&mock_node);
    1072           1 :   tt_str_op(rv, OP_EQ,
    1073             :             "<null rs and ri>");
    1074             : 
    1075           1 :  done:
    1076           1 :   return;
    1077             : }
    1078             : 
    1079             : /** routerstatus_describe() is a wrapper for format_node_description(), see
    1080             :  * that test for details.
    1081             :  *
    1082             :  * The routerstatus-only node_describe() tests are in this function,
    1083             :  * so we can re-use the same mocked variables.
    1084             :  */
    1085             : static void
    1086           1 : test_nodelist_routerstatus_describe(void *arg)
    1087             : {
    1088           1 :   routerstatus_t mock_rs_ipv4;
    1089           1 :   routerstatus_t mock_rs_ipv6;
    1090           1 :   routerstatus_t mock_rs_dual;
    1091             : 
    1092           1 :   const char *rv = NULL;
    1093             : 
    1094           1 :   (void) arg;
    1095             : 
    1096             :   /* Clear variables */
    1097           1 :   memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
    1098           1 :   memset(&mock_rs_ipv6, 0, sizeof(mock_rs_ipv6));
    1099           1 :   memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
    1100             : 
    1101             :   /* Set up the dual-stack routerstatus */
    1102           1 :   memcpy(mock_rs_dual.identity_digest,
    1103             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    1104             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    1105             :          sizeof(mock_rs_dual.identity_digest));
    1106           1 :   strlcpy(mock_rs_dual.nickname, "TestOR7890123456789",
    1107             :           sizeof(mock_rs_dual.nickname));
    1108           1 :   tor_addr_parse(&mock_rs_dual.ipv4_addr, "111.222.233.244");
    1109           1 :   tor_addr_parse(&mock_rs_dual.ipv6_addr,
    1110             :                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
    1111             : 
    1112             :   /* Create and modify the other routerstatuses. */
    1113           1 :   memcpy(&mock_rs_ipv4, &mock_rs_dual, sizeof(mock_rs_ipv4));
    1114           1 :   memcpy(&mock_rs_ipv6, &mock_rs_dual, sizeof(mock_rs_ipv6));
    1115             :   /* Clear the unnecessary addresses */
    1116           1 :   memset(&mock_rs_ipv4.ipv6_addr, 0, sizeof(mock_rs_ipv4.ipv6_addr));
    1117           1 :   tor_addr_make_unspec(&mock_rs_ipv6.ipv4_addr);
    1118             : 
    1119             :   /* We don't test the no-nickname and no-IP cases, because they're covered by
    1120             :    * format_node_description(), and we don't expect to see them in Tor code. */
    1121             : 
    1122             :   /* Try some real IP addresses */
    1123           1 :   rv = routerstatus_describe(&mock_rs_ipv4);
    1124           1 :   tt_str_op(rv, OP_EQ,
    1125             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1126             :             "111.222.233.244");
    1127             : 
    1128           1 :   rv = routerstatus_describe(&mock_rs_ipv6);
    1129           1 :   tt_str_op(rv, OP_EQ,
    1130             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1131             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
    1132             : 
    1133           1 :   rv = routerstatus_describe(&mock_rs_dual);
    1134           1 :   tt_str_op(rv, OP_EQ,
    1135             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1136             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    1137             : 
    1138             :   /* test NULL handling */
    1139           1 :   rv = routerstatus_describe(NULL);
    1140           1 :   tt_str_op(rv, OP_EQ, "<null>");
    1141             : 
    1142             :   /* Now test a node with only these routerstatuses */
    1143           1 :   node_t mock_node;
    1144           1 :   memset(&mock_node, 0, sizeof(mock_node));
    1145           1 :   memcpy(mock_node.identity,
    1146             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    1147             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    1148             :          sizeof(mock_node.identity));
    1149             : 
    1150             :   /* Try some real IP addresses */
    1151           1 :   mock_node.rs = &mock_rs_ipv4;
    1152           1 :   rv = node_describe(&mock_node);
    1153           1 :   tt_str_op(rv, OP_EQ,
    1154             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1155             :             "111.222.233.244");
    1156             : 
    1157           1 :   mock_node.rs = &mock_rs_ipv6;
    1158           1 :   rv = node_describe(&mock_node);
    1159           1 :   tt_str_op(rv, OP_EQ,
    1160             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1161             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
    1162             : 
    1163           1 :   mock_node.rs = &mock_rs_dual;
    1164           1 :   rv = node_describe(&mock_node);
    1165           1 :   tt_str_op(rv, OP_EQ,
    1166             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1167             :             "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    1168             : 
    1169           1 :  done:
    1170           1 :   return;
    1171             : }
    1172             : 
    1173             : /** extend_info_describe() is a wrapper for format_node_description(), see
    1174             :  * that test for details.
    1175             :  */
    1176             : static void
    1177           1 : test_nodelist_extend_info_describe(void *arg)
    1178             : {
    1179           1 :   extend_info_t mock_ei_ipv4;
    1180           1 :   extend_info_t mock_ei_ipv6;
    1181             : 
    1182           1 :   const char *rv = NULL;
    1183             : 
    1184           1 :   (void) arg;
    1185             : 
    1186             :   /* Clear variables */
    1187           1 :   memset(&mock_ei_ipv4, 0, sizeof(mock_ei_ipv4));
    1188           1 :   memset(&mock_ei_ipv6, 0, sizeof(mock_ei_ipv6));
    1189             : 
    1190             :   /* Set up the IPv4 extend info */
    1191           1 :   memcpy(mock_ei_ipv4.identity_digest,
    1192             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    1193             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    1194             :          sizeof(mock_ei_ipv4.identity_digest));
    1195           1 :   strlcpy(mock_ei_ipv4.nickname, "TestOR7890123456789",
    1196             :           sizeof(mock_ei_ipv4.nickname));
    1197           1 :   tor_addr_parse(&mock_ei_ipv4.orports[0].addr, "111.222.233.244");
    1198             : 
    1199             :   /* Create and modify the other extend info. */
    1200           1 :   memcpy(&mock_ei_ipv6, &mock_ei_ipv4, sizeof(mock_ei_ipv6));
    1201           1 :   tor_addr_parse(&mock_ei_ipv6.orports[0].addr,
    1202             :                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
    1203             : 
    1204             :   /* We don't test the no-nickname and no-IP cases, because they're covered by
    1205             :    * format_node_description(), and we don't expect to see them in Tor code. */
    1206             : 
    1207             :   /* Try some real IP addresses */
    1208           1 :   rv = extend_info_describe(&mock_ei_ipv4);
    1209           1 :   tt_str_op(rv, OP_EQ,
    1210             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1211             :             "111.222.233.244");
    1212             : 
    1213           1 :   rv = extend_info_describe(&mock_ei_ipv6);
    1214           1 :   tt_str_op(rv, OP_EQ,
    1215             :             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    1216             :             "[1111:2222:3333:4444:5555:6666:7777:8888]");
    1217             : 
    1218             :   /* Extend infos only have one IP address, so there is no dual case */
    1219             : 
    1220             :   /* test NULL handling */
    1221           1 :   rv = extend_info_describe(NULL);
    1222           1 :   tt_str_op(rv, OP_EQ, "<null>");
    1223             : 
    1224           1 :  done:
    1225           1 :   return;
    1226             : }
    1227             : 
    1228             : /** router_get_verbose_nickname() should return "Fingerprint~Nickname"
    1229             :  */
    1230             : static void
    1231           1 : test_nodelist_router_get_verbose_nickname(void *arg)
    1232             : {
    1233           1 :   routerinfo_t mock_ri;
    1234           1 :   char mock_nickname[MAX_NICKNAME_LEN+1];
    1235             : 
    1236           1 :   char vname[MAX_VERBOSE_NICKNAME_LEN+1];
    1237             : 
    1238           1 :   (void) arg;
    1239             : 
    1240           1 :   memset(&mock_ri, 0, sizeof(routerinfo_t));
    1241           1 :   memset(mock_nickname, 0, sizeof(mock_nickname));
    1242           1 :   mock_ri.nickname = mock_nickname;
    1243             : 
    1244             :   /* verbose nickname should use ~ because named is deprecated */
    1245           1 :   strlcpy(mock_nickname, "TestOR", sizeof(mock_nickname));
    1246           1 :   memcpy(mock_ri.cache_info.identity_digest,
    1247             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    1248             :          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    1249             :          DIGEST_LEN);
    1250           1 :   router_get_verbose_nickname(vname, &mock_ri);
    1251           1 :   tt_str_op(vname, OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
    1252             : 
    1253             :   /* test NULL router handling */
    1254           1 :   router_get_verbose_nickname(vname, NULL);
    1255           1 :   tt_str_op(vname, OP_EQ, "<null>");
    1256             : 
    1257           1 :   router_get_verbose_nickname(NULL, &mock_ri);
    1258           1 :   router_get_verbose_nickname(NULL, NULL);
    1259             : 
    1260           1 :  done:
    1261           1 :   return;
    1262             : }
    1263             : 
    1264             : static void
    1265           1 : test_nodelist_routerstatus_has_visibly_changed(void *arg)
    1266             : {
    1267           1 :   (void)arg;
    1268           1 :   routerstatus_t rs_orig, rs;
    1269           1 :   char *fmt_orig = NULL, *fmt = NULL;
    1270           1 :   memset(&rs_orig, 0, sizeof(rs_orig));
    1271           1 :   strlcpy(rs_orig.nickname, "friendly", sizeof(rs_orig.nickname));
    1272           1 :   memcpy(rs_orig.identity_digest, "abcdefghijklmnopqrst", 20);
    1273           1 :   memcpy(rs_orig.descriptor_digest, "abcdefghijklmnopqrst", 20);
    1274           1 :   tor_addr_from_ipv4h(&rs_orig.ipv4_addr, 0x7f000001);
    1275           1 :   rs_orig.ipv4_orport = 3;
    1276           1 :   rs_orig.published_on = time(NULL);
    1277           1 :   rs_orig.has_bandwidth = 1;
    1278           1 :   rs_orig.bandwidth_kb = 20;
    1279             : 
    1280             : #define COPY() memcpy(&rs, &rs_orig, sizeof(rs))
    1281             : #define FORMAT() \
    1282             :   STMT_BEGIN \
    1283             :     tor_free(fmt_orig);                                                   \
    1284             :     tor_free(fmt);                                                        \
    1285             :     fmt_orig = routerstatus_format_entry(&rs_orig, NULL, NULL,            \
    1286             :                           NS_CONTROL_PORT,                                \
    1287             :                           NULL);                                          \
    1288             :     fmt = routerstatus_format_entry(&rs, NULL, NULL, NS_CONTROL_PORT,     \
    1289             :                           NULL);                                          \
    1290             :     tt_assert(fmt_orig);                                                  \
    1291             :     tt_assert(fmt);                                                       \
    1292             :   STMT_END
    1293             : #define ASSERT_SAME() \
    1294             :   STMT_BEGIN                                                    \
    1295             :     tt_assert(! routerstatus_has_visibly_changed(&rs_orig, &rs));       \
    1296             :     FORMAT();                                                   \
    1297             :     tt_str_op(fmt_orig, OP_EQ, fmt);                            \
    1298             :     COPY();                                                     \
    1299             :   STMT_END
    1300             : #define ASSERT_CHANGED() \
    1301             :   STMT_BEGIN                                                    \
    1302             :     tt_assert(routerstatus_has_visibly_changed(&rs_orig, &rs));         \
    1303             :     FORMAT();                                                   \
    1304             :     tt_str_op(fmt_orig, OP_NE, fmt);                            \
    1305             :     COPY();                                                     \
    1306             :   STMT_END
    1307             : #define ASSERT_CHANGED_NO_FORMAT() \
    1308             :   STMT_BEGIN                                                    \
    1309             :     tt_assert(routerstatus_has_visibly_changed(&rs_orig, &rs));         \
    1310             :     COPY();                                                     \
    1311             :   STMT_END
    1312             : 
    1313           1 :   COPY();
    1314           1 :   ASSERT_SAME();
    1315             : 
    1316           1 :   tor_addr_from_ipv4h(&rs.ipv4_addr, 0x7f000002);
    1317           1 :   ASSERT_CHANGED();
    1318             : 
    1319           1 :   strlcpy(rs.descriptor_digest, "hello world", sizeof(rs.descriptor_digest));
    1320           1 :   ASSERT_CHANGED();
    1321             : 
    1322           1 :   strlcpy(rs.nickname, "fr1end1y", sizeof(rs.nickname));
    1323           1 :   ASSERT_CHANGED();
    1324             : 
    1325           1 :   rs.published_on += 3600;
    1326           1 :   ASSERT_CHANGED();
    1327             : 
    1328           1 :   rs.ipv4_orport = 55;
    1329           1 :   ASSERT_CHANGED();
    1330             : 
    1331           1 :   rs.ipv4_dirport = 9999;
    1332           1 :   ASSERT_CHANGED();
    1333             : 
    1334           1 :   tor_addr_parse(&rs.ipv6_addr, "1234::56");
    1335           1 :   ASSERT_CHANGED();
    1336             : 
    1337           1 :   tor_addr_parse(&rs_orig.ipv6_addr, "1234::56");
    1338           1 :   rs_orig.ipv6_orport = 99;
    1339           1 :   COPY();
    1340           1 :   rs.ipv6_orport = 22;
    1341           1 :   ASSERT_CHANGED();
    1342             : 
    1343           1 :   rs.is_authority = 1;
    1344           1 :   ASSERT_CHANGED();
    1345             : 
    1346           1 :   rs.is_exit = 1;
    1347           1 :   ASSERT_CHANGED();
    1348             : 
    1349           1 :   rs.is_stable = 1;
    1350           1 :   ASSERT_CHANGED();
    1351             : 
    1352           1 :   rs.is_fast = 1;
    1353           1 :   ASSERT_CHANGED();
    1354             : 
    1355           1 :   rs.is_flagged_running = 1;
    1356           1 :   ASSERT_CHANGED();
    1357             : 
    1358             :   // This option is obsolete and not actually formatted.
    1359           1 :   rs.is_named = 1;
    1360           1 :   ASSERT_CHANGED_NO_FORMAT();
    1361             : 
    1362             :   // This option is obsolete and not actually formatted.
    1363           1 :   rs.is_unnamed = 1;
    1364           1 :   ASSERT_CHANGED_NO_FORMAT();
    1365             : 
    1366           1 :   rs.is_valid = 1;
    1367           1 :   ASSERT_CHANGED();
    1368             : 
    1369           1 :   rs.is_possible_guard = 1;
    1370           1 :   ASSERT_CHANGED();
    1371             : 
    1372           1 :   rs.is_bad_exit = 1;
    1373           1 :   ASSERT_CHANGED();
    1374             : 
    1375           1 :   rs.is_hs_dir = 1;
    1376           1 :   ASSERT_CHANGED();
    1377             : 
    1378           1 :   rs.is_v2_dir = 1;
    1379           1 :   ASSERT_CHANGED();
    1380             : 
    1381           1 :   rs.is_staledesc = 1;
    1382           1 :   ASSERT_CHANGED();
    1383             : 
    1384             :   // Setting this to zero crashes us with an assertion failure in
    1385             :   // routerstatus_format_entry() if we don't have a descriptor.
    1386           1 :   rs.has_bandwidth = 0;
    1387           1 :   ASSERT_CHANGED_NO_FORMAT();
    1388             : 
    1389             :   // Does not actually matter; not visible to controller.
    1390           1 :   rs.has_exitsummary = 1;
    1391           1 :   ASSERT_SAME();
    1392             : 
    1393             :   // Does not actually matter; not visible to the controller.
    1394           1 :   rs.bw_is_unmeasured = 1;
    1395           1 :   ASSERT_SAME();
    1396             : 
    1397           1 :   rs.bandwidth_kb = 2000;
    1398           1 :   ASSERT_CHANGED();
    1399             : 
    1400             :   // not visible to the controller.
    1401           1 :   rs.has_guardfraction = 1;
    1402           1 :   rs.guardfraction_percentage = 22;
    1403           1 :   ASSERT_SAME();
    1404             : 
    1405             :   // not visible to the controller.
    1406           1 :   rs_orig.has_guardfraction = 1;
    1407           1 :   rs_orig.guardfraction_percentage = 20;
    1408           1 :   COPY();
    1409           1 :   rs.guardfraction_percentage = 25;
    1410           1 :   ASSERT_SAME();
    1411             : 
    1412             :   // not visible to the controller.
    1413           1 :   rs.exitsummary = (char*)"accept 1-2";
    1414           1 :   ASSERT_SAME();
    1415             : 
    1416           1 :  done:
    1417             : #undef COPY
    1418             : #undef ASSERT_SAME
    1419             : #undef ASSERT_CHANGED
    1420           1 :   tor_free(fmt_orig);
    1421           1 :   tor_free(fmt);
    1422           1 :   return;
    1423             : }
    1424             : 
    1425             : #define NODE(name, flags) \
    1426             :   { #name, test_nodelist_##name, (flags), NULL, NULL }
    1427             : 
    1428             : struct testcase_t nodelist_tests[] = {
    1429             :   NODE(node_get_verbose_nickname_by_id_null_node, TT_FORK),
    1430             :   NODE(node_get_verbose_nickname_not_named, TT_FORK),
    1431             :   NODE(node_is_dir, TT_FORK),
    1432             :   NODE(ed_id, TT_FORK),
    1433             :   NODE(nodefamily, TT_FORK),
    1434             :   NODE(nodefamily_parse_err, TT_FORK),
    1435             :   NODE(nodefamily_lookup, TT_FORK),
    1436             :   NODE(nickname_matches, 0),
    1437             :   NODE(node_nodefamily, TT_FORK),
    1438             :   NODE(nodefamily_canonicalize, 0),
    1439             :   NODE(format_node_description, 0),
    1440             :   NODE(router_describe, 0),
    1441             :   NODE(node_describe, 0),
    1442             :   NODE(routerstatus_describe, 0),
    1443             :   NODE(extend_info_describe, 0),
    1444             :   NODE(router_get_verbose_nickname, 0),
    1445             :   NODE(routerstatus_has_visibly_changed, 0),
    1446             :   END_OF_TESTCASES
    1447             : };

Generated by: LCOV version 1.14