Merge remote-tracking branch 'isis-github/bug25425_squashed2'

This commit is contained in:
Nick Mathewson 2018-04-10 15:32:26 -04:00
commit 6bdfaa8b24
9 changed files with 658 additions and 9 deletions

4
changes/bug25425 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (testing):
- A new unittests module specifically for testing the functions in the
(new-ish) bridges.c module has been created with new unittests, raising
the code coverage percentages. Closes 25425.

View File

@ -11,6 +11,8 @@
* Bridges are fixed entry nodes, used for censorship circumvention.
**/
#define TOR_BRIDGES_PRIVATE
#include "or.h"
#include "bridges.h"
#include "circuitbuild.h"
@ -93,7 +95,7 @@ sweep_bridge_list(void)
}
/** Initialize the bridge list to empty, creating it if needed. */
static void
STATIC void
clear_bridge_list(void)
{
if (!bridge_list)
@ -156,7 +158,7 @@ bridge_get_addr_port(const bridge_info_t *bridge)
* bridge with no known digest whose address matches any of the
* tor_addr_port_t's in <b>orports</b>, return that bridge. Else return
* NULL. */
static bridge_info_t *
STATIC bridge_info_t *
get_configured_bridge_by_orports_digest(const char *digest,
const smartlist_t *orports)
{
@ -350,7 +352,7 @@ bridge_has_digest(const bridge_info_t *bridge, const char *digest)
* existing bridge with the same address and port, and warn the user as
* appropriate.
*/
static void
STATIC void
bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
const char *digest, const char *transport_name)
{
@ -471,7 +473,7 @@ bridge_add_from_config(bridge_line_t *bridge_line)
}
/** If <b>digest</b> is one of our known bridges, return it. */
bridge_info_t *
STATIC bridge_info_t *
find_bridge_by_digest(const char *digest)
{
if (! bridge_list)

View File

@ -20,7 +20,6 @@ typedef struct bridge_info_t bridge_info_t;
void mark_bridge_list(void);
void sweep_bridge_list(void);
const smartlist_t *bridge_list_get(void);
bridge_info_t *find_bridge_by_digest(const char *digest);
const uint8_t *bridge_get_rsa_id_digest(const bridge_info_t *bridge);
const tor_addr_port_t * bridge_get_addr_port(const bridge_info_t *bridge);
bridge_info_t *get_configured_bridge_by_addr_port_digest(
@ -65,5 +64,17 @@ MOCK_DECL(download_status_t *, get_bridge_dl_status_by_id,
void bridges_free_all(void);
#ifdef TOR_BRIDGES_PRIVATE
STATIC void clear_bridge_list(void);
STATIC bridge_info_t *find_bridge_by_digest(const char *digest);
STATIC bridge_info_t *get_configured_bridge_by_orports_digest(
const char *digest,
const smartlist_t *orports);
STATIC void bridge_resolve_conflicts(const tor_addr_t *addr,
uint16_t port,
const char *digest,
const char *transport_name);
#endif /* defined(TOR_BRIDGES_PRIVATE) */
#endif /* !defined(TOR_BRIDGES_H) */

View File

@ -135,7 +135,7 @@ static smartlist_t *transport_list = NULL;
/** Returns a transport_t struct for a transport proxy supporting the
protocol <b>name</b> listening at <b>addr</b>:<b>port</b> using
SOCKS version <b>socks_ver</b>. */
static transport_t *
STATIC transport_t *
transport_new(const tor_addr_t *addr, uint16_t port,
const char *name, int socks_ver,
const char *extra_info_args)
@ -222,8 +222,8 @@ transport_copy(const transport_t *transport)
/** Returns the transport in our transport list that has the name <b>name</b>.
* Else returns NULL. */
transport_t *
transport_get_by_name(const char *name)
MOCK_IMPL(transport_t *,
transport_get_by_name,(const char *name))
{
tor_assert(name);

View File

@ -38,7 +38,7 @@ MOCK_DECL(int, transport_add_from_config,
void transport_free_(transport_t *transport);
#define transport_free(tr) FREE_AND_NULL(transport_t, transport_free_, (tr))
transport_t *transport_get_by_name(const char *name);
MOCK_DECL(transport_t*, transport_get_by_name, (const char *name));
MOCK_DECL(void, pt_kickstart_proxy,
(const smartlist_t *transport_list, char **proxy_argv,
@ -113,6 +113,9 @@ typedef struct {
smartlist_t *transports;
} managed_proxy_t;
STATIC transport_t *transport_new(const tor_addr_t *addr, uint16_t port,
const char *name, int socks_ver,
const char *extra_info_args);
STATIC int parse_cmethod_line(const char *line, managed_proxy_t *mp);
STATIC int parse_smethod_line(const char *line, managed_proxy_t *mp);

View File

@ -88,6 +88,7 @@ src_test_test_SOURCES = \
src/test/test_addr.c \
src/test/test_address.c \
src/test/test_address_set.c \
src/test/test_bridges.c \
src/test/test_buffers.c \
src/test/test_cell_formats.c \
src/test/test_cell_queue.c \

View File

@ -811,6 +811,7 @@ struct testgroup_t testgroups[] = {
{ "addr/", addr_tests },
{ "address/", address_tests },
{ "address_set/", address_set_tests },
{ "bridges/", bridges_tests },
{ "buffer/", buffer_tests },
{ "cellfmt/", cell_format_tests },
{ "cellqueue/", cell_queue_tests },

View File

@ -72,6 +72,14 @@
I64_PRINTF_TYPE, I64_FORMAT, \
{print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
/**
* Declare that the test is done, even though no tt___op() calls were made.
*
* For use when you only want to test calling something, but not check
* any values/pointers/etc afterwards.
*/
#define tt_finished() TT_EXIT_TEST_FUNCTION
const char *get_fname(const char *name);
const char *get_fname_rnd(const char *name);
struct crypto_pk_t *pk_generate(int idx);
@ -178,6 +186,7 @@ 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 bridges_tests[];
extern struct testcase_t buffer_tests[];
extern struct testcase_t cell_format_tests[];
extern struct testcase_t cell_queue_tests[];

618
src/test/test_bridges.c Normal file
View File

@ -0,0 +1,618 @@
/* Copyright (c) 2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file test_bridges.c
* \brief Unittests for code in src/or/bridges.c
**/
#define TOR_BRIDGES_PRIVATE
#define PT_PRIVATE /* Only needed for the mock_* items below */
#include <stdbool.h>
#include "or.h"
#include "address.h"
#include "bridges.h"
#include "config.h"
#include "container.h"
#include "transports.h"
#include "util.h"
/* Test suite stuff */
#include "test.h"
/**
* A mocked transport_t, constructed via mock_transport_get_by_name().
*/
static transport_t *mock_transport = NULL;
/**
* Mock transport_get_by_name() to simply return a transport_t for the
* transport name that was input to it.
*/
static transport_t *
mock_transport_get_by_name(const char *name)
{
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 9999;
int socksv = 9;
char *args = tor_strdup("foo=bar");
if (!mock_transport) {
tor_addr_parse(addr, "99.99.99.99");
mock_transport = transport_new(addr, port, name, socksv, args);
}
tor_free(addr);
tor_free(args);
return mock_transport;
}
#undef PT_PRIVATE /* defined(PT_PRIVATE) */
/**
* Test helper: Add a variety of bridges to our global bridgelist.
*/
static void
helper_add_bridges_to_bridgelist(void *arg)
{
/* Note: the two bridges which do not have specified fingerprints will be
* internally stored as both having the same fingerprint of all-zero bytes.
*/
(void)arg;
char *bridge0 = tor_strdup("6.6.6.6:6666");
char *bridge1 = tor_strdup("6.6.6.7:6667 "
"A10C4F666D27364036B562823E5830BC448E046A");
char *bridge2 = tor_strdup("obfs4 198.245.60.51:443 "
"752CF7825B3B9EA6A98C83AC41F7099D67007EA5 "
"cert=xpmQtKUqQ/6v5X7ijgYE/f03+l2/EuQ1dexjyUhh16wQlu/"
"cpXUGalmhDIlhuiQPNEKmKw iat-mode=0");
char *bridge3 = tor_strdup("banana 5.5.5.5:5555 "
"9D6AE1BD4FDF39721CE908966E79E16F9BFCCF2F");
char *bridge4 = tor_strdup("obfs4 1.2.3.4:1234 "
"foo=abcdefghijklmnopqrstuvwxyz");
char *bridge5 = tor_strdup("apple 4.4.4.4:4444 "
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
"foo=abcdefghijklmnopqrstuvwxyz");
mark_bridge_list();
#define ADD_BRIDGE(bridge) \
bridge_line_t *bridge_line_ ##bridge = parse_bridge_line(bridge); \
if (!bridge_line_ ##bridge) { \
printf("Unparseable bridge line: '%s'", #bridge); \
} else { \
bridge_add_from_config(bridge_line_ ##bridge); \
} \
tor_free(bridge);
ADD_BRIDGE(bridge0);
ADD_BRIDGE(bridge1);
ADD_BRIDGE(bridge2);
ADD_BRIDGE(bridge3);
ADD_BRIDGE(bridge4);
ADD_BRIDGE(bridge5);
#undef ADD_BRIDGES
sweep_bridge_list();
}
/**
* Make sure our test helper works too.
*/
static void
test_bridges_helper_func_add_bridges_to_bridgelist(void *arg)
{
helper_add_bridges_to_bridgelist(arg);
tt_finished();
done:
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling bridge_list_get() should create a new bridgelist if we
* didn't have one before.
*/
static void
test_bridges_bridge_list_get_creates_new_bridgelist(void *arg)
{
const smartlist_t *bridgelist = bridge_list_get();
(void)arg;
tt_ptr_op(bridgelist, OP_NE, NULL);
done:
return;
}
/**
* Calling clear_bridge_list() should remove all bridges from the bridgelist.
*/
static void
test_bridges_clear_bridge_list(void *arg)
{
const smartlist_t *bridgelist;
const smartlist_t *bridgelist_after;
const bridge_info_t *bridge;
const bridge_info_t *bridge_after;
helper_add_bridges_to_bridgelist(arg);
bridgelist = bridge_list_get();
tt_ptr_op(bridgelist, OP_NE, NULL);
bridge = smartlist_get(bridgelist, 0);
tt_ptr_op(bridge, OP_NE, NULL);
clear_bridge_list();
bridgelist_after = bridge_list_get();
tt_ptr_op(bridgelist_after, OP_NE, NULL);
bridge_after = smartlist_get(bridgelist, 0);
// There now shouldn't be a first bridge
tt_ptr_op(bridge_after, OP_EQ, NULL);
done:
return;
}
/**
* Calling bridge_get_addrport() should give me the address and port
* of the bridge. In this case, we sort the smartlist of bridges on
* fingerprints and choose the first one.
*/
static void
test_bridges_bridge_get_addrport(void *arg)
{
smartlist_t *bridgelist;
const bridge_info_t *bridge;
const tor_addr_port_t *addrport;
helper_add_bridges_to_bridgelist(arg);
bridgelist = (smartlist_t*)bridge_list_get();
tt_ptr_op(bridgelist, OP_NE, NULL);
// This should be the bridge at 6.6.6.6:6666 with fingerprint
// 0000000000000000000000000000000000000000
bridge = smartlist_get(bridgelist, 0);
tt_ptr_op(bridge, OP_NE, NULL);
addrport = bridge_get_addr_port(bridge);
tt_int_op(addrport->port, OP_EQ, 6666);
done:
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_orports_digest() with two
* configured bridge orports and an invalid digest should return the
* bridge of the first addrport in the list.
*/
static void
test_bridges_get_configured_bridge_by_orports_digest(void *arg)
{
smartlist_t *orports = NULL;
const smartlist_t *bridgelist;
const bridge_info_t *bridge1;
const bridge_info_t *bridge2;
const bridge_info_t *ret;
tor_addr_port_t *addrport1;
tor_addr_port_t *addrport2;
const char *digest;
helper_add_bridges_to_bridgelist(arg);
bridgelist = bridge_list_get();
tt_ptr_op(bridgelist, OP_NE, NULL);
// This should be the bridge at 6.6.6.6:6666 with fingerprint
// 0000000000000000000000000000000000000000
bridge1 = smartlist_get(bridgelist, 0);
tt_ptr_op(bridge1, OP_NE, NULL);
// This should be the bridge at 6.6.6.7:6667 with fingerprint
// A10C4F666D27364036B562823E5830BC448E046A
bridge2 = smartlist_get(bridgelist, 1);
tt_ptr_op(bridge2, OP_NE, NULL);
addrport1 = (tor_addr_port_t*)bridge_get_addr_port(bridge1);
tt_int_op(addrport1->port, OP_EQ, 6666);
addrport2 = (tor_addr_port_t*)bridge_get_addr_port(bridge2);
tt_int_op(addrport2->port, OP_EQ, 6667);
orports = smartlist_new();
smartlist_add(orports, addrport1);
smartlist_add(orports, addrport2);
digest = "zzzzzzzzzzzzzzzz";
ret = get_configured_bridge_by_orports_digest(digest, orports);
tt_ptr_op(ret, OP_NE, NULL);
tt_mem_op(addrport1, OP_EQ, bridge_get_addr_port(ret), sizeof(ret));
done:
smartlist_free(orports);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_addr_port_digest() with a digest that we do
* have and an addr:port pair we don't should return the bridge for that
* digest.
*/
static void
test_bridges_get_configured_bridge_by_addr_port_digest_digest_only(void *arg)
{
char digest[DIGEST_LEN];
bridge_info_t *bridge;
const char fingerprint[HEX_DIGEST_LEN] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
char ret_addr[16];
uint16_t port = 11111;
int ret;
helper_add_bridges_to_bridgelist(arg);
// We don't actually have a bridge with this addr:port pair
base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
ret = tor_addr_parse(addr, "111.111.111.111");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge = get_configured_bridge_by_addr_port_digest(addr, port, digest);
tt_ptr_op(bridge, OP_NE, NULL);
tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
tt_str_op("4.4.4.4", OP_EQ, ret_addr);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_addr_port_digest() with only an
* addr:port (i.e. digest set to NULL) should return the bridge for
* that digest when there is such a bridge.
*/
static void
test_bridges_get_configured_bridge_by_addr_port_digest_address_only(void *arg)
{
bridge_info_t *bridge;
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
char ret_addr[16];
uint16_t port = 6666;
int ret;
helper_add_bridges_to_bridgelist(arg);
ret = tor_addr_parse(addr, "6.6.6.6");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge = get_configured_bridge_by_addr_port_digest(addr, port, NULL);
tt_ptr_op(bridge, OP_NE, NULL);
tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
tt_str_op("6.6.6.6", OP_EQ, ret_addr);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
* we do have, and an addr:port pair we don't have, should return NULL.
*/
static void
test_bridges_get_configured_bridge_by_exact_addr_port_digest_donly(void *arg)
{
char digest[DIGEST_LEN];
bridge_info_t *bridge;
const char fingerprint[HEX_DIGEST_LEN] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 11111;
int ret;
helper_add_bridges_to_bridgelist(arg);
// We don't actually have a bridge with this addr:port pair
base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
ret = tor_addr_parse(addr, "111.111.111.111");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
tt_ptr_op(bridge, OP_EQ, NULL);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
* we do have, and an addr:port pair we do have, should return the bridge.
*/
static void
test_bridges_get_configured_bridge_by_exact_addr_port_digest_both(void *arg)
{
char digest[DIGEST_LEN];
bridge_info_t *bridge;
const char fingerprint[HEX_DIGEST_LEN] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 4444;
char ret_addr[16];
int ret;
helper_add_bridges_to_bridgelist(arg);
base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
ret = tor_addr_parse(addr, "4.4.4.4");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
tt_ptr_op(bridge, OP_NE, NULL);
tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
tt_str_op("4.4.4.4", OP_EQ, ret_addr);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_configured_bridge_by_exact_addr_port_digest() with no digest,
* and an addr:port pair we do have, should return the bridge.
*/
static void
test_bridges_get_configured_bridge_by_exact_addr_port_digest_aonly(void *arg)
{
bridge_info_t *bridge;
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 4444;
char ret_addr[16];
int ret;
helper_add_bridges_to_bridgelist(arg);
ret = tor_addr_parse(addr, "4.4.4.4");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, NULL);
tt_ptr_op(bridge, OP_NE, NULL);
tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
tt_str_op("4.4.4.4", OP_EQ, ret_addr);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling find_bridge_by_digest() when we have a bridge with a known
* identity digest should return the bridge's information.
*/
static void
test_bridges_find_bridge_by_digest_known(void *arg)
{
char digest1[DIGEST_LEN];
bridge_info_t *bridge;
const char fingerprint[HEX_DIGEST_LEN] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
helper_add_bridges_to_bridgelist(arg);
base16_decode(digest1, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
bridge = find_bridge_by_digest(digest1);
tt_ptr_op(bridge, OP_NE, NULL);
/* We have to call bridge_get_rsa_id_digest() here because the bridge_info_t
* struct is opaquely defined in bridges.h. */
const uint8_t *digest2 = bridge_get_rsa_id_digest(bridge);
tt_mem_op((char*)digest2, OP_EQ, digest1, DIGEST_LEN);
done:
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling find_bridge_by_digest() when we do NOT have a bridge with that
* identity digest should return NULL.
*/
static void
test_bridges_find_bridge_by_digest_unknown(void *arg)
{
const char *fingerprint = "cccccccccccccccccccccccccccccccccccccccc";
bridge_info_t *bridge;
helper_add_bridges_to_bridgelist(arg);
bridge = find_bridge_by_digest(fingerprint);
tt_ptr_op(bridge, OP_EQ, NULL);
done:
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling bridge_resolve_conflicts() with an identical bridge to one we've
* already configure should mark the pre-configured bridge for removal.
*/
static void
test_bridges_bridge_resolve_conflicts(void *arg)
{
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 4444;
const char *digest = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
const char *transport = "apple";
int ret;
helper_add_bridges_to_bridgelist(arg);
ret = tor_addr_parse(addr, "4.4.4.4");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
bridge_resolve_conflicts((const tor_addr_t*)addr, port, digest, transport);
/* The bridge should now be marked for removal, and removed when we sweep the
* bridge_list */
sweep_bridge_list();
ret = addr_is_a_configured_bridge((const tor_addr_t*)addr, port, digest);
tt_int_op(ret, OP_EQ, 0);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling transport_is_needed() with a transport we do need ("obfs4") and a
* bogus transport that we don't need should return 1 and 0, respectively.
*/
static void
test_bridges_transport_is_needed(void *arg)
{
int ret;
helper_add_bridges_to_bridgelist(arg);
ret = transport_is_needed("obfs4");
tt_int_op(ret, OP_EQ, 1);
ret = transport_is_needed("apowefjaoewpaief");
tt_int_op(ret, OP_EQ, 0);
done:
mark_bridge_list();
sweep_bridge_list();
}
/**
* Calling get_transport_by_bridge_addrport() with the address and port of a
* configured bridge which uses a pluggable transport when there is no global
* transport_list should return -1 and the transport_t should be NULL.
*/
static void
test_bridges_get_transport_by_bridge_addrport_no_ptlist(void *arg)
{
transport_t *transport = NULL;
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 1234;
int ret;
helper_add_bridges_to_bridgelist(arg);
ret = tor_addr_parse(addr, "1.2.3.4");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success?
/* This will fail because the global transport_list has nothing in it, and so
* transport_get_by_name() has nothing to return, even the the bridge *did*
* say it had an obfs4 transport.
*/
ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port,
(const transport_t**)&transport);
tt_int_op(ret, OP_EQ, -1); // returns -1 on failure
tt_ptr_op(transport, OP_EQ, NULL);
done:
tor_free(addr);
mark_bridge_list();
sweep_bridge_list();
}
#define PT_PRIVATE
/**
* Calling get_transport_by_bridge_addrport() with the address and port of a
* configured bridge which uses a pluggable transport should return 0 and set
* appropriate transport_t.
*/
static void
test_bridges_get_transport_by_bridge_addrport(void *arg)
{
transport_t *transport = NULL;
tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
uint16_t port = 1234;
int ret;
helper_add_bridges_to_bridgelist(arg);
mark_transport_list(); // Also initialise our transport_list
ret = tor_addr_parse(addr, "1.2.3.4");
tt_int_op(ret, OP_EQ, 2); // it returns the address family on success?
/* After we mock transport_get_by_name() to return a bogus transport_t with
* the name it was asked for, the call should succeed.
*/
MOCK(transport_get_by_name, mock_transport_get_by_name);
ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port,
(const transport_t**)&transport);
tt_int_op(ret, OP_EQ, 0); // returns 0 on success
tt_ptr_op(transport, OP_NE, NULL);
tt_str_op(transport->name, OP_EQ, "obfs4");
done:
UNMOCK(transport_get_by_name);
tor_free(addr);
transport_free(transport);
mark_bridge_list();
sweep_bridge_list();
}
#undef PT_PRIVATE /* defined(PT_PRIVATE) */
#define B_TEST(name, flags) \
{ #name, test_bridges_ ##name, (flags), NULL, NULL }
struct testcase_t bridges_tests[] = {
B_TEST(helper_func_add_bridges_to_bridgelist, 0),
B_TEST(bridge_list_get_creates_new_bridgelist, 0),
B_TEST(clear_bridge_list, 0),
B_TEST(bridge_get_addrport, 0),
B_TEST(get_configured_bridge_by_orports_digest, 0),
B_TEST(get_configured_bridge_by_addr_port_digest_digest_only, 0),
B_TEST(get_configured_bridge_by_addr_port_digest_address_only, 0),
B_TEST(get_configured_bridge_by_exact_addr_port_digest_donly, 0),
B_TEST(get_configured_bridge_by_exact_addr_port_digest_both, 0),
B_TEST(get_configured_bridge_by_exact_addr_port_digest_aonly, 0),
B_TEST(find_bridge_by_digest_known, 0),
B_TEST(find_bridge_by_digest_unknown, 0),
B_TEST(bridge_resolve_conflicts, 0),
B_TEST(get_transport_by_bridge_addrport_no_ptlist, 0),
B_TEST(get_transport_by_bridge_addrport, 0),
B_TEST(transport_is_needed, 0),
END_OF_TESTCASES
};