commit 36f1fb3be30f2563c7fa1eb220cb0484767adc28 Author: David Goulet dgoulet@torproject.org Date: Wed Nov 22 12:46:45 2017 -0500
test: Add unit test for channel_check_for_duplicates()
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/channel.c | 3 +- src/or/channel.h | 2 + src/test/test_channel.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/src/or/channel.c b/src/or/channel.c index ffa827064..5a5a7e27d 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -149,7 +149,6 @@ HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash, channel_idmap_eq, 0.5, tor_reallocarray_, tor_free_)
/* Functions to maintain the digest map */ -static void channel_add_to_digest_map(channel_t *chan); static void channel_remove_from_digest_map(channel_t *chan);
static void channel_force_free(channel_t *chan); @@ -551,7 +550,7 @@ channel_listener_unregister(channel_listener_t *chan_l) * already exist. */
-static void +STATIC void channel_add_to_digest_map(channel_t *chan) { channel_idmap_entry_t *ent, search; diff --git a/src/or/channel.h b/src/or/channel.h index 5a2457faf..d88a77c9a 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -431,6 +431,8 @@ void channel_set_cmux_policy_everywhere(circuitmux_policy_t *pol);
#ifdef CHANNEL_PRIVATE_
+STATIC void channel_add_to_digest_map(channel_t *chan); + #endif /* defined(CHANNEL_PRIVATE_) */
/* Channel operations for subclasses and internal use only */ diff --git a/src/test/test_channel.c b/src/test/test_channel.c index 203fa1319..3f29d97c3 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -17,8 +17,10 @@ #include "relay.h" /* For init/free stuff */ #include "scheduler.h" +#include "networkstatus.h"
/* Test suite stuff */ +#include "log_test_helpers.h" #include "test.h" #include "fakechans.h"
@@ -36,6 +38,7 @@ static int test_releases_count = 0; static channel_t *dump_statistics_mock_target = NULL; static int dump_statistics_mock_matches = 0; static int test_close_called = 0; +static int test_chan_should_be_canonical = 0;
static void chan_test_channel_dump_statistics_mock( channel_t *chan, int severity); @@ -426,6 +429,18 @@ scheduler_release_channel_mock(channel_t *ch) return; }
+static int +test_chan_is_canonical(channel_t *chan, int req) +{ + tor_assert(chan); + (void) req; + + if (test_chan_should_be_canonical) { + return 1; + } + return 0; +} + /** * Test for channel_dumpstats() and limited test for * channel_dump_statistics() @@ -1279,6 +1294,90 @@ test_channel_state(void *arg) ; }
+static networkstatus_t *mock_ns = NULL; + +static networkstatus_t * +mock_networkstatus_get_latest_consensus(void) +{ + return mock_ns; +} + +static void +test_channel_duplicates(void *arg) +{ + channel_t *chan = NULL; + routerstatus_t rs; + + (void) arg; + + setup_full_capture_of_logs(LOG_INFO); + /* Try a flat call with channel nor connections. */ + channel_check_for_duplicates(); + expect_log_msg_containing( + "Found 0 connections to 0 relays. Found 0 current canonical " + "connections, in 0 of which we were a non-canonical peer. " + "0 relays had more than 1 connection, 0 had more than 2, and " + "0 had more than 4 connections."); + + mock_ns = tor_malloc_zero(sizeof(*mock_ns)); + mock_ns->routerstatus_list = smartlist_new(); + MOCK(networkstatus_get_latest_consensus, + mock_networkstatus_get_latest_consensus); + + chan = new_fake_channel(); + tt_assert(chan); + chan->is_canonical = test_chan_is_canonical; + memset(chan->identity_digest, 'A', sizeof(chan->identity_digest)); + channel_add_to_digest_map(chan); + tt_ptr_op(channel_find_by_remote_identity(chan->identity_digest, NULL), + OP_EQ, chan); + + /* No relay has been associated with this channel. */ + channel_check_for_duplicates(); + expect_log_msg_containing( + "Found 0 connections to 0 relays. Found 0 current canonical " + "connections, in 0 of which we were a non-canonical peer. " + "0 relays had more than 1 connection, 0 had more than 2, and " + "0 had more than 4 connections."); + + /* Associate relay to this connection in the consensus. */ + memset(&rs, 0, sizeof(rs)); + memset(rs.identity_digest, 'A', sizeof(rs.identity_digest)); + smartlist_add(mock_ns->routerstatus_list, &rs); + + /* Non opened channel. */ + chan->state = CHANNEL_STATE_CLOSING; + channel_check_for_duplicates(); + expect_log_msg_containing( + "Found 0 connections to 0 relays. Found 0 current canonical " + "connections, in 0 of which we were a non-canonical peer. " + "0 relays had more than 1 connection, 0 had more than 2, and " + "0 had more than 4 connections."); + chan->state = CHANNEL_STATE_OPEN; + + channel_check_for_duplicates(); + expect_log_msg_containing( + "Found 1 connections to 1 relays. Found 0 current canonical " + "connections, in 0 of which we were a non-canonical peer. " + "0 relays had more than 1 connection, 0 had more than 2, and " + "0 had more than 4 connections."); + + test_chan_should_be_canonical = 1; + channel_check_for_duplicates(); + expect_log_msg_containing( + "Found 1 connections to 1 relays. Found 1 current canonical " + "connections, in 1 of which we were a non-canonical peer. " + "0 relays had more than 1 connection, 0 had more than 2, and " + "0 had more than 4 connections."); + teardown_capture_of_logs(); + + done: + free_fake_channel(chan); + smartlist_clear(mock_ns->routerstatus_list); + networkstatus_vote_free(mock_ns); + UNMOCK(networkstatus_get_latest_consensus); +} + struct testcase_t channel_tests[] = { { "inbound_cell", test_channel_inbound_cell, TT_FORK, NULL, NULL }, @@ -1294,6 +1393,8 @@ struct testcase_t channel_tests[] = { NULL, NULL }, { "state", test_channel_state, TT_FORK, NULL, NULL }, + { "duplicates", test_channel_duplicates, TT_FORK, + NULL, NULL }, END_OF_TESTCASES };
tor-commits@lists.torproject.org