[tor-commits] [tor/maint-0.3.2] test: Add unit tests for addressset.c

nickm at torproject.org nickm at torproject.org
Fri Feb 16 14:56:19 UTC 2018


commit a445327b80478c72093d8f1b0e205a279318f651
Author: David Goulet <dgoulet at torproject.org>
Date:   Thu Feb 8 14:35:22 2018 -0500

    test: Add unit tests for addressset.c
    
    This also adds one that tests the integration with the nodelist.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/nodelist.c           |  14 +++-
 src/or/nodelist.h           |   2 +
 src/test/include.am         |   1 +
 src/test/test.c             |   1 +
 src/test/test.h             |   1 +
 src/test/test_address_set.c | 174 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 192 insertions(+), 1 deletion(-)

diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index c2080db12..5a02648c5 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -275,6 +275,17 @@ nodelist_add_microdesc(microdesc_t *md)
   return node;
 }
 
+/* Default value. */
+#define ESTIMATED_ADDRESS_PER_NODE 2
+
+/* Return the estimated number of address per node_t. This is used for the
+ * size of the bloom filter in the nodelist (node_addrs). */
+MOCK_IMPL(int,
+get_estimated_address_per_node, (void))
+{
+  return ESTIMATED_ADDRESS_PER_NODE;
+}
+
 /** Tell the nodelist that the current usable consensus is <b>ns</b>.
  * This makes the nodelist change all of the routerstatus entries for
  * the nodes, drop nodes that no longer have enough info to get used,
@@ -294,7 +305,8 @@ nodelist_set_consensus(networkstatus_t *ns)
                     node->rs = NULL);
 
   /* Conservatively estimate that every node will have 2 addresses. */
-  const int estimated_addresses = smartlist_len(ns->routerstatus_list) * 2;
+  const int estimated_addresses = smartlist_len(ns->routerstatus_list) *
+                                  get_estimated_address_per_node();
   address_set_free(the_nodelist->node_addrs);
   the_nodelist->node_addrs = address_set_new(estimated_addresses);
 
diff --git a/src/or/nodelist.h b/src/or/nodelist.h
index 355057f39..098f1d155 100644
--- a/src/or/nodelist.h
+++ b/src/or/nodelist.h
@@ -125,5 +125,7 @@ void router_dir_info_changed(void);
 const char *get_dir_info_status_string(void);
 int count_loading_descriptors_progress(void);
 
+MOCK_DECL(int, get_estimated_address_per_node, (void));
+
 #endif
 
diff --git a/src/test/include.am b/src/test/include.am
index 8ecfaf10c..cf29d4cb2 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -72,6 +72,7 @@ src_test_test_SOURCES = \
 	src/test/test_accounting.c \
 	src/test/test_addr.c \
 	src/test/test_address.c \
+	src/test/test_address_set.c \
 	src/test/test_buffers.c \
 	src/test/test_cell_formats.c \
 	src/test/test_cell_queue.c \
diff --git a/src/test/test.c b/src/test/test.c
index 9a41b976b..9b0775ce4 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1182,6 +1182,7 @@ struct testgroup_t testgroups[] = {
   { "accounting/", accounting_tests },
   { "addr/", addr_tests },
   { "address/", address_tests },
+  { "address_set/", address_set_tests },
   { "buffer/", buffer_tests },
   { "cellfmt/", cell_format_tests },
   { "cellqueue/", cell_queue_tests },
diff --git a/src/test/test.h b/src/test/test.h
index 25336ac83..22b207207 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -175,6 +175,7 @@ extern const struct testcase_setup_t ed25519_test_setup;
 extern struct testcase_t accounting_tests[];
 extern struct testcase_t addr_tests[];
 extern struct testcase_t address_tests[];
+extern struct testcase_t address_set_tests[];
 extern struct testcase_t buffer_tests[];
 extern struct testcase_t cell_format_tests[];
 extern struct testcase_t cell_queue_tests[];
diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c
new file mode 100644
index 000000000..df022f539
--- /dev/null
+++ b/src/test/test_address_set.c
@@ -0,0 +1,174 @@
+/* Copyright (c) 2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "or.h"
+#include "address_set.h"
+#include "microdesc.h"
+#include "networkstatus.h"
+#include "nodelist.h"
+#include "routerlist.h"
+#include "torcert.h"
+
+#include "test.h"
+
+static networkstatus_t *dummy_ns = NULL;
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus(void)
+{
+  return dummy_ns;
+}
+
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
+{
+  tor_assert(f == FLAV_MICRODESC);
+  return dummy_ns;
+}
+
+/* Number of address a single node_t can have. Default to the production
+ * value. This is to control the size of the bloom filter. */
+static int addr_per_node = 2;
+static int
+mock_get_estimated_address_per_node(void)
+{
+  return addr_per_node;
+}
+
+static void
+test_contains(void *arg)
+{
+  int ret;
+  address_set_t *set = NULL;
+
+  (void) arg;
+
+  /* Setup an IPv4 and IPv6 addresses. */
+  tor_addr_t addr_v6;
+  tor_addr_parse(&addr_v6, "1:2:3:4::");
+  tor_addr_t addr_v4;
+  tor_addr_parse(&addr_v4, "42.42.42.42");
+  uint32_t ipv4h = tor_addr_to_ipv4h(&addr_v4);
+
+  /* Make it very big so the chance of failing the contain test will be
+   * extremely rare. */
+  set = address_set_new(1024);
+  tt_assert(set);
+
+  /* Add and lookup IPv6. */
+  address_set_add(set, &addr_v6);
+  ret = address_set_probably_contains(set, &addr_v6);
+  tt_int_op(ret, OP_EQ, 1);
+
+  /* Add and lookup IPv4. */
+  address_set_add_ipv4h(set, ipv4h);
+  ret = address_set_probably_contains(set, &addr_v4);
+  tt_int_op(ret, OP_EQ, 1);
+
+  /* Try a lookup of rubbish. */
+  tor_addr_t dummy_addr;
+  memset(&dummy_addr, 'A', sizeof(dummy_addr));
+  dummy_addr.family = AF_INET;
+  ret = address_set_probably_contains(set, &dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+  dummy_addr.family = AF_INET6;
+  ret = address_set_probably_contains(set, &dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+
+ done:
+  address_set_free(set);
+}
+
+static void
+test_nodelist(void *arg)
+{
+  int ret;
+  routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
+
+  (void) arg;
+
+  MOCK(networkstatus_get_latest_consensus,
+       mock_networkstatus_get_latest_consensus);
+  MOCK(networkstatus_get_latest_consensus_by_flavor,
+       mock_networkstatus_get_latest_consensus_by_flavor);
+  MOCK(get_estimated_address_per_node,
+       mock_get_estimated_address_per_node);
+
+  dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
+  dummy_ns->flavor = FLAV_MICRODESC;
+  dummy_ns->routerstatus_list = smartlist_new();
+
+  tor_addr_t addr_v4, addr_v6, dummy_addr;
+  tor_addr_parse(&addr_v4, "42.42.42.42");
+  uint32_t ipv4h = tor_addr_to_ipv4h(&addr_v4);
+  tor_addr_parse(&addr_v6, "1:2:3:4::");
+  memset(&dummy_addr, 'A', sizeof(dummy_addr));
+
+  /* This will make the nodelist bloom filter very large
+   * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
+  addr_per_node = 1024;
+
+  /* No node no nothing. The lookups should be empty. */
+  nodelist_set_consensus(dummy_ns);
+
+  /* The address set should be empty. */
+  ret = nodelist_probably_contains_address(&addr_v4);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = nodelist_probably_contains_address(&addr_v6);
+  tt_int_op(ret, OP_EQ, 0);
+  dummy_addr.family = AF_INET;
+  ret = nodelist_probably_contains_address(&dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+  dummy_addr.family = AF_INET6;
+  ret = nodelist_probably_contains_address(&dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+
+  md = tor_malloc_zero(sizeof(*md));
+  ri = tor_malloc_zero(sizeof(*ri));
+  rs = tor_malloc_zero(sizeof(*rs));
+  crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
+  crypto_rand(md->digest, sizeof(md->digest));
+  memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
+
+  /* Setup the rs, ri and md addresses. */
+  rs->addr = ipv4h;
+  tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
+  ri->addr = ipv4h;
+  tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
+  tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
+
+  /* Add the rs to the consensus becoming a node_t. */
+  smartlist_add(dummy_ns->routerstatus_list, rs);
+  nodelist_set_consensus(dummy_ns);
+
+  /* At this point, the address set should be initialized in the nodelist and
+   * we should be able to lookup. */
+  ret = nodelist_probably_contains_address(&addr_v4);
+  tt_int_op(ret, OP_EQ, 1);
+  ret = nodelist_probably_contains_address(&addr_v6);
+  tt_int_op(ret, OP_EQ, 1);
+  /* Lookup unknown address. */
+  dummy_addr.family = AF_INET;
+  ret = nodelist_probably_contains_address(&dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+  dummy_addr.family = AF_INET6;
+  ret = nodelist_probably_contains_address(&dummy_addr);
+  tt_int_op(ret, OP_EQ, 0);
+
+ done:
+  routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
+  smartlist_clear(dummy_ns->routerstatus_list);
+  networkstatus_vote_free(dummy_ns);
+  UNMOCK(networkstatus_get_latest_consensus);
+  UNMOCK(networkstatus_get_latest_consensus_by_flavor);
+  UNMOCK(get_estimated_address_per_node);
+}
+
+struct testcase_t address_set_tests[] = {
+  { "contains", test_contains, TT_FORK,
+    NULL, NULL },
+  { "nodelist", test_nodelist, TT_FORK,
+    NULL, NULL },
+
+  END_OF_TESTCASES
+};
+





More information about the tor-commits mailing list