[tor-commits] [tor/release-0.3.3] test: Add unittest for the OR connection failure cache

nickm at torproject.org nickm at torproject.org
Wed Mar 28 18:23:13 UTC 2018


commit ab16f1e2a10ee1b95118ec266ba454697e9af012
Author: George Kadianakis <desnacked at riseup.net>
Date:   Wed Feb 14 13:40:42 2018 +0200

    test: Add unittest for the OR connection failure cache
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/connection_or.c     |  5 ++-
 src/or/connection_or.h     |  5 +++
 src/or/nodelist.c          |  4 +-
 src/or/nodelist.h          |  2 +-
 src/test/test_connection.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 976889ad0..267463312 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -28,6 +28,7 @@
  * part of a subclass (channel_tls_t).
  */
 #define TOR_CHANNEL_INTERNAL_
+#define CONNECTION_OR_PRIVATE
 #include "channel.h"
 #include "channeltls.h"
 #include "circuitbuild.h"
@@ -1255,7 +1256,7 @@ or_connect_failure_find(const or_connection_t *or_conn)
 
 /* Note down in the connection failure cache that a failure occurred on the
  * given or_conn. */
-static void
+STATIC void
 note_or_connect_failed(const or_connection_t *or_conn)
 {
   or_connect_failure_entry_t *ocf = NULL;
@@ -1294,7 +1295,7 @@ or_connect_failure_map_cleanup(time_t cutoff)
  *
  * The or_conn MUST have gone through connection_or_check_canonicity() so the
  * base address is properly set to what we know or doesn't know. */
-static int
+STATIC int
 should_connect_to_relay(const or_connection_t *or_conn)
 {
   time_t now, cutoff;
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index 7c1dced63..158eb1fda 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -120,6 +120,11 @@ int connection_or_single_set_badness_(time_t now,
                                       int force);
 void connection_or_group_set_badness_(smartlist_t *group, int force);
 
+#ifdef CONNECTION_OR_PRIVATE
+STATIC int should_connect_to_relay(const or_connection_t *or_conn);
+STATIC void note_or_connect_failed(const or_connection_t *or_conn);
+#endif
+
 #ifdef TOR_UNIT_TESTS
 extern int certs_cell_ed25519_disabled_for_testing;
 #endif
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 391b31d68..7303539c8 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -161,8 +161,8 @@ init_nodelist(void)
 }
 
 /** As node_get_by_id, but returns a non-const pointer */
-node_t *
-node_get_mutable_by_id(const char *identity_digest)
+MOCK_IMPL(node_t *,
+node_get_mutable_by_id,(const char *identity_digest))
 {
   node_t search, *node;
   if (PREDICT_UNLIKELY(the_nodelist == NULL))
diff --git a/src/or/nodelist.h b/src/or/nodelist.h
index dc20eaf0a..043d7b341 100644
--- a/src/or/nodelist.h
+++ b/src/or/nodelist.h
@@ -16,7 +16,7 @@
     tor_assert((n)->ri || (n)->rs);                             \
   } STMT_END
 
-node_t *node_get_mutable_by_id(const char *identity_digest);
+MOCK_DECL(node_t *, node_get_mutable_by_id,(const char *identity_digest));
 MOCK_DECL(const node_t *, node_get_by_id, (const char *identity_digest));
 node_t *node_get_mutable_by_ed25519_id(const ed25519_public_key_t *ed_id);
 MOCK_DECL(const node_t *, node_get_by_ed25519_id,
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index 33f453b8b..dc0f6860d 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -5,6 +5,7 @@
 
 #define CONNECTION_PRIVATE
 #define MAIN_PRIVATE
+#define CONNECTION_OR_PRIVATE
 
 #include "or.h"
 #include "test.h"
@@ -13,9 +14,11 @@
 #include "hs_common.h"
 #include "main.h"
 #include "microdesc.h"
+#include "nodelist.h"
 #include "networkstatus.h"
 #include "rendcache.h"
 #include "directory.h"
+#include "connection_or.h"
 
 #include "test_connection.h"
 #include "test_helpers.h"
@@ -776,6 +779,99 @@ test_conn_download_status(void *arg)
   /* the teardown function removes all the connections in the global list*/;
 }
 
+static node_t test_node;
+
+static node_t *
+mock_node_get_mutable_by_id(const char *digest)
+{
+  (void) digest;
+  static routerinfo_t node_ri;
+  memset(&node_ri, 0, sizeof(node_ri));
+
+  test_node.ri = &node_ri;
+  memset(test_node.identity, 'c', sizeof(test_node.identity));
+
+  tor_addr_t ipv4_addr;
+  tor_addr_parse(&ipv4_addr, "18.0.0.1");
+  node_ri.addr = tor_addr_to_ipv4h(&ipv4_addr);
+  node_ri.or_port = 1;
+
+  return &test_node;
+}
+
+static const node_t *
+mock_node_get_by_id(const char *digest)
+{
+  (void) digest;
+  memset(test_node.identity, 'c', sizeof(test_node.identity));
+  return &test_node;
+}
+
+/* Test whether we correctly track failed connections between relays. */
+static void
+test_failed_orconn_tracker(void *arg)
+{
+  (void) arg;
+
+  int can_connect;
+  time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
+  (void) now;
+
+  update_approx_time(now);
+
+  /* Prepare the OR connection that will be used in this test */
+  or_connection_t or_conn;
+  tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.real_addr, "18.0.0.1"));
+  tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1"));
+  or_conn.base_.port = 1;
+  memset(or_conn.identity_digest, 'c', sizeof(or_conn.identity_digest));
+
+  /* Check whether we can connect with an empty failure cache:
+   * this should succeed */
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 1);
+
+  /* Now add the destination to the failure cache */
+  note_or_connect_failed(&or_conn);
+
+  /* Check again: now it shouldn't connect */
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 0);
+
+  /* Move time forward and check again: the cache should have been cleared and
+   * now it should connect */
+  now += 3600;
+  update_approx_time(now);
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 1);
+
+  /* Now mock the node_get_*by_id() functions to start using the node subsystem
+   * optimization. */
+  MOCK(node_get_by_id, mock_node_get_by_id);
+  MOCK(node_get_mutable_by_id, mock_node_get_mutable_by_id);
+
+  /* Since we just started using the node subsystem it will allow connections
+   * now */
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 1);
+
+  /* Mark it as failed */
+  note_or_connect_failed(&or_conn);
+
+  /* Check that it shouldn't connect now */
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 0);
+
+  /* Move time forward and check again: now it should connect  */
+  now += 3600;
+  update_approx_time(now);
+  can_connect = should_connect_to_relay(&or_conn);
+  tt_int_op(can_connect, OP_EQ, 1);
+
+ done:
+  ;
+}
+
 #define CONNECTION_TESTCASE(name, fork, setup)                           \
   { #name, test_conn_##name, fork, &setup, NULL }
 
@@ -792,6 +888,7 @@ struct testcase_t connection_tests[] = {
   CONNECTION_TESTCASE_ARG(download_status,  TT_FORK,
                           test_conn_download_status_st, FLAV_NS),
 //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
+  { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
   END_OF_TESTCASES
 };
 





More information about the tor-commits mailing list