mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-15 07:43:31 +01:00
23c77f79fd
This is an automatically generated commit, made with the following kludgey perl script. It results in a number of wide lines, which I'll clean up in a subsequent commit. #/usr/bin/perl -w -i $mod = "NS_MODULE"; $submod = "NS_SUBMODULE"; $last_was_empty = 0; while (<>) { s/\bASPECT\(\s*(\w+)\s*,\s*(\w+)\s*\)/$1_$2/; if (/# *define +NS_MODULE +(\w+)/) { $mod = $1; next; } elsif (/# *define +NS_SUBMODULE +(\w+)/) { $submod = $1; next; } next if (/#undef NS_(SUB)?MODULE/); s/NS\(\s*test_main\s*\)/test_${mod}_${submod}/; s/NS\(\s*(\w+)\s*\)/${mod}_${submod}_$1/g; s/NS_FULL\(\\s*(\w+)\s*,\s*(\w+),\s*(\w+)\s*\)/$1_$2_$3/; s/^(\s*)NS_MOCK\(\s*(\w+)\s*\)/$1MOCK($2,\n$1 ${mod}_${submod}_$2)/; s/NS_UNMOCK\(\s*(\w+)\s*\)/UNMOCK($1)/; s/TEST_CASE\(\s*(\w+)\s*\)/{ "$1", test_${mod}_$1, TT_FORK, NULL, NULL }/; s/TEST_CASE_ASPECT\(\s*(\w+)\s*,\s*(\w+)\s*\)/{ "$1_$2", test_${mod}_$1_$2, TT_FORK, NULL, NULL }/; s/NS_DECL\(\s*([^,]+)\s*,\s*([^,]+)\s*,\s*(\(.*)\);/static $1 ${mod}_${submod}_$2$3;\nATTR_UNUSED static int ${mod}_${submod}_$2_called = 0;/; s/\bCALLED\(\s*(\w+)\s*\)/${mod}_${submod}_$1_called/; if (/^$/) { print if (! $last_was_empty); $last_was_empty = 1; } else { $last_was_empty = 0; print; } if (eof) { $mod = "NS_MODULE"; $submod = "NS_SUBMODULE"; $last_was_empty = 0; } } # Please enter the commit message for your changes. Lines starting # with '#' will be kept; you may remove them yourself if you want to. # An empty message aborts the commit. # # Date: Thu Jan 9 10:26:10 2020 -0500 # # On branch disable_ns_macro # Changes to be committed: # modified: src/test/test_accounting.c # modified: src/test/test_compat_libevent.c # modified: src/test/test_dir.c # modified: src/test/test_dir_handle_get.c # modified: src/test/test_dns.c # modified: src/test/test_options.c # modified: src/test/test_procmon.c # modified: src/test/test_rendcache.c # modified: src/test/test_router.c # modified: src/test/test_routerset.c # modified: src/test/test_status.c # modified: src/test/test_tortls.c # modified: src/test/test_tortls_openssl.c # modified: src/test/test_util_format.c # modified: src/test/test_util_process.c # # Untracked files: # experiments/ # locate_options.sh # un_ns.pl # # Please enter the commit message for your changes. Lines starting # with '#' will be kept; you may remove them yourself if you want to. # An empty message aborts the commit. # # Date: Thu Jan 9 10:26:10 2020 -0500 # # On branch disable_ns_macro # Changes to be committed: # modified: src/test/test_accounting.c # modified: src/test/test_compat_libevent.c # modified: src/test/test_dir.c # modified: src/test/test_dir_handle_get.c # modified: src/test/test_dns.c # modified: src/test/test_options.c # modified: src/test/test_procmon.c # modified: src/test/test_rendcache.c # modified: src/test/test_router.c # modified: src/test/test_routerset.c # modified: src/test/test_status.c # modified: src/test/test_tortls.c # modified: src/test/test_tortls_openssl.c # modified: src/test/test_util_format.c # modified: src/test/test_util_process.c # # Untracked files: # experiments/ # locate_options.sh # un_ns.pl #
2123 lines
54 KiB
C
2123 lines
54 KiB
C
/* Copyright (c) 2014-2020, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
#define ROUTERSET_PRIVATE
|
|
|
|
#include "core/or/or.h"
|
|
#include "core/or/policies.h"
|
|
#include "feature/dirparse/policy_parse.h"
|
|
#include "feature/nodelist/nodelist.h"
|
|
#include "feature/nodelist/routerset.h"
|
|
#include "lib/geoip/geoip.h"
|
|
|
|
#include "core/or/addr_policy_st.h"
|
|
#include "core/or/extend_info_st.h"
|
|
#include "feature/nodelist/node_st.h"
|
|
#include "feature/nodelist/routerinfo_st.h"
|
|
#include "feature/nodelist/routerstatus_st.h"
|
|
|
|
#include "test/test.h"
|
|
|
|
/*
|
|
* Functional (blackbox) test to determine that each member of the routerset
|
|
* is non-NULL
|
|
*/
|
|
|
|
static void
|
|
test_rset_new(void *arg)
|
|
{
|
|
routerset_t *rs;
|
|
(void)arg;
|
|
|
|
rs = routerset_new();
|
|
|
|
tt_ptr_op(rs, OP_NE, NULL);
|
|
tt_ptr_op(rs->list, OP_NE, NULL);
|
|
tt_ptr_op(rs->names, OP_NE, NULL);
|
|
tt_ptr_op(rs->digests, OP_NE, NULL);
|
|
tt_ptr_op(rs->policies, OP_NE, NULL);
|
|
tt_ptr_op(rs->country_names, OP_NE, NULL);
|
|
|
|
done:
|
|
routerset_free(rs);
|
|
}
|
|
|
|
/*
|
|
* Functional test to strip the braces from a "{xx}" country code string.
|
|
*/
|
|
|
|
static void
|
|
test_rset_get_countryname(void *arg)
|
|
{
|
|
const char *input;
|
|
char *name;
|
|
(void)arg;
|
|
|
|
/* strlen(c) < 4 */
|
|
input = "xxx";
|
|
name = routerset_get_countryname(input);
|
|
tt_ptr_op(name, OP_EQ, NULL);
|
|
tor_free(name);
|
|
|
|
/* c[0] != '{' */
|
|
input = "xxx}";
|
|
name = routerset_get_countryname(input);
|
|
tt_ptr_op(name, OP_EQ, NULL);
|
|
tor_free(name);
|
|
|
|
/* c[3] != '}' */
|
|
input = "{xxx";
|
|
name = routerset_get_countryname(input);
|
|
tt_ptr_op(name, OP_EQ, NULL);
|
|
tor_free(name);
|
|
|
|
/* tor_strlower */
|
|
input = "{XX}";
|
|
name = routerset_get_countryname(input);
|
|
tt_str_op(name, OP_EQ, "xx");
|
|
tor_free(name);
|
|
|
|
input = "{xx}";
|
|
name = routerset_get_countryname(input);
|
|
tt_str_op(name, OP_EQ, "xx");
|
|
done:
|
|
tor_free(name);
|
|
}
|
|
|
|
/*
|
|
* Structural (whitebox) test for routerset_refresh_counties, when the GeoIP DB
|
|
* is not loaded.
|
|
*/
|
|
|
|
static int rset_refresh_geoip_not_loaded_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_refresh_geoip_not_loaded_geoip_is_loaded_called = 0;
|
|
static int rset_refresh_geoip_not_loaded_geoip_get_n_countries(void);
|
|
ATTR_UNUSED static int rset_refresh_geoip_not_loaded_geoip_get_n_countries_called = 0;
|
|
|
|
static void
|
|
test_rset_refresh_geoip_not_loaded(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
(void)arg;
|
|
|
|
MOCK(geoip_is_loaded,
|
|
rset_refresh_geoip_not_loaded_geoip_is_loaded);
|
|
MOCK(geoip_get_n_countries,
|
|
rset_refresh_geoip_not_loaded_geoip_get_n_countries);
|
|
|
|
routerset_refresh_countries(set);
|
|
|
|
tt_ptr_op(set->countries, OP_EQ, NULL);
|
|
tt_int_op(set->n_countries, OP_EQ, 0);
|
|
tt_int_op(rset_refresh_geoip_not_loaded_geoip_is_loaded_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_geoip_not_loaded_geoip_get_n_countries_called, OP_EQ, 0);
|
|
|
|
done:
|
|
UNMOCK(geoip_is_loaded);
|
|
UNMOCK(geoip_get_n_countries);
|
|
routerset_free(set);
|
|
}
|
|
|
|
static int
|
|
rset_refresh_geoip_not_loaded_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
(void)family;
|
|
rset_refresh_geoip_not_loaded_geoip_is_loaded_called++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
rset_refresh_geoip_not_loaded_geoip_get_n_countries(void)
|
|
{
|
|
rset_refresh_geoip_not_loaded_geoip_get_n_countries_called++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_refresh_counties, when there are no countries.
|
|
*/
|
|
|
|
static int rset_refresh_no_countries_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_refresh_no_countries_geoip_is_loaded_called = 0;
|
|
static int rset_refresh_no_countries_geoip_get_n_countries(void);
|
|
ATTR_UNUSED static int rset_refresh_no_countries_geoip_get_n_countries_called = 0;
|
|
static country_t rset_refresh_no_countries_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_refresh_no_countries_geoip_get_country_called = 0;
|
|
|
|
static void
|
|
test_rset_refresh_no_countries(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
(void)arg;
|
|
|
|
MOCK(geoip_is_loaded,
|
|
rset_refresh_no_countries_geoip_is_loaded);
|
|
MOCK(geoip_get_n_countries,
|
|
rset_refresh_no_countries_geoip_get_n_countries);
|
|
MOCK(geoip_get_country,
|
|
rset_refresh_no_countries_geoip_get_country);
|
|
|
|
routerset_refresh_countries(set);
|
|
|
|
tt_ptr_op(set->countries, OP_NE, NULL);
|
|
tt_int_op(set->n_countries, OP_EQ, 1);
|
|
tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
|
|
tt_int_op(rset_refresh_no_countries_geoip_is_loaded_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_no_countries_geoip_get_n_countries_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_no_countries_geoip_get_country_called, OP_EQ, 0);
|
|
|
|
done:
|
|
UNMOCK(geoip_is_loaded);
|
|
UNMOCK(geoip_get_n_countries);
|
|
UNMOCK(geoip_get_country);
|
|
routerset_free(set);
|
|
}
|
|
|
|
static int
|
|
rset_refresh_no_countries_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
(void)family;
|
|
rset_refresh_no_countries_geoip_is_loaded_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
rset_refresh_no_countries_geoip_get_n_countries(void)
|
|
{
|
|
rset_refresh_no_countries_geoip_get_n_countries_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static country_t
|
|
rset_refresh_no_countries_geoip_get_country(const char *countrycode)
|
|
{
|
|
(void)countrycode;
|
|
rset_refresh_no_countries_geoip_get_country_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_refresh_counties, with one valid country.
|
|
*/
|
|
|
|
static int rset_refresh_one_valid_country_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_refresh_one_valid_country_geoip_is_loaded_called = 0;
|
|
static int rset_refresh_one_valid_country_geoip_get_n_countries(void);
|
|
ATTR_UNUSED static int rset_refresh_one_valid_country_geoip_get_n_countries_called = 0;
|
|
static country_t rset_refresh_one_valid_country_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_refresh_one_valid_country_geoip_get_country_called = 0;
|
|
|
|
static void
|
|
test_rset_refresh_one_valid_country(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
(void)arg;
|
|
|
|
MOCK(geoip_is_loaded,
|
|
rset_refresh_one_valid_country_geoip_is_loaded);
|
|
MOCK(geoip_get_n_countries,
|
|
rset_refresh_one_valid_country_geoip_get_n_countries);
|
|
MOCK(geoip_get_country,
|
|
rset_refresh_one_valid_country_geoip_get_country);
|
|
smartlist_add(set->country_names, tor_strndup("foo", 3));
|
|
|
|
routerset_refresh_countries(set);
|
|
|
|
tt_ptr_op(set->countries, OP_NE, NULL);
|
|
tt_int_op(set->n_countries, OP_EQ, 2);
|
|
tt_int_op(rset_refresh_one_valid_country_geoip_is_loaded_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_one_valid_country_geoip_get_n_countries_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_one_valid_country_geoip_get_country_called, OP_EQ, 1);
|
|
tt_int_op((unsigned int)(*set->countries), OP_NE, 0);
|
|
|
|
done:
|
|
UNMOCK(geoip_is_loaded);
|
|
UNMOCK(geoip_get_n_countries);
|
|
UNMOCK(geoip_get_country);
|
|
routerset_free(set);
|
|
}
|
|
|
|
static int
|
|
rset_refresh_one_valid_country_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
(void)family;
|
|
rset_refresh_one_valid_country_geoip_is_loaded_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
rset_refresh_one_valid_country_geoip_get_n_countries(void)
|
|
{
|
|
rset_refresh_one_valid_country_geoip_get_n_countries_called++;
|
|
|
|
return 2;
|
|
}
|
|
|
|
static country_t
|
|
rset_refresh_one_valid_country_geoip_get_country(const char *countrycode)
|
|
{
|
|
(void)countrycode;
|
|
rset_refresh_one_valid_country_geoip_get_country_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_refresh_counties, with one invalid
|
|
* country code..
|
|
*/
|
|
|
|
static int rset_refresh_one_invalid_country_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_refresh_one_invalid_country_geoip_is_loaded_called = 0;
|
|
static int rset_refresh_one_invalid_country_geoip_get_n_countries(void);
|
|
ATTR_UNUSED static int rset_refresh_one_invalid_country_geoip_get_n_countries_called = 0;
|
|
static country_t rset_refresh_one_invalid_country_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_refresh_one_invalid_country_geoip_get_country_called = 0;
|
|
|
|
static void
|
|
test_rset_refresh_one_invalid_country(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
(void)arg;
|
|
|
|
MOCK(geoip_is_loaded,
|
|
rset_refresh_one_invalid_country_geoip_is_loaded);
|
|
MOCK(geoip_get_n_countries,
|
|
rset_refresh_one_invalid_country_geoip_get_n_countries);
|
|
MOCK(geoip_get_country,
|
|
rset_refresh_one_invalid_country_geoip_get_country);
|
|
smartlist_add(set->country_names, tor_strndup("foo", 3));
|
|
|
|
routerset_refresh_countries(set);
|
|
|
|
tt_ptr_op(set->countries, OP_NE, NULL);
|
|
tt_int_op(set->n_countries, OP_EQ, 2);
|
|
tt_int_op(rset_refresh_one_invalid_country_geoip_is_loaded_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_one_invalid_country_geoip_get_n_countries_called, OP_EQ, 1);
|
|
tt_int_op(rset_refresh_one_invalid_country_geoip_get_country_called, OP_EQ, 1);
|
|
tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
|
|
|
|
done:
|
|
UNMOCK(geoip_is_loaded);
|
|
UNMOCK(geoip_get_n_countries);
|
|
UNMOCK(geoip_get_country);
|
|
routerset_free(set);
|
|
}
|
|
|
|
static int
|
|
rset_refresh_one_invalid_country_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
(void)family;
|
|
rset_refresh_one_invalid_country_geoip_is_loaded_called++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
rset_refresh_one_invalid_country_geoip_get_n_countries(void)
|
|
{
|
|
rset_refresh_one_invalid_country_geoip_get_n_countries_called++;
|
|
|
|
return 2;
|
|
}
|
|
|
|
static country_t
|
|
rset_refresh_one_invalid_country_geoip_get_country(const char *countrycode)
|
|
{
|
|
(void)countrycode;
|
|
rset_refresh_one_invalid_country_geoip_get_country_called++;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Functional test, with a malformed string to parse.
|
|
*/
|
|
|
|
static void
|
|
test_rset_parse_malformed(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
const char *s = "_";
|
|
int r;
|
|
(void)arg;
|
|
|
|
r = routerset_parse(set, s, "");
|
|
|
|
tt_int_op(r, OP_EQ, -1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_parse, that routerset_parse returns 0
|
|
* on a valid hexdigest entry.
|
|
*/
|
|
|
|
static void
|
|
test_rset_parse_valid_hexdigest(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
set = routerset_new();
|
|
s = "$0000000000000000000000000000000000000000";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(digestmap_isempty(set->digests), OP_NE, 1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_parse, when given a valid nickname as input.
|
|
*/
|
|
|
|
static void
|
|
test_rset_parse_valid_nickname(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
set = routerset_new();
|
|
s = "fred";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(strmap_isempty(set->names), OP_NE, 1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_parse, when given a valid countryname.
|
|
*/
|
|
|
|
static void
|
|
test_rset_parse_get_countryname(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
set = routerset_new();
|
|
s = "{cc}";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(smartlist_len(set->country_names), OP_NE, 0);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_parse, when given a valid wildcard policy.
|
|
*/
|
|
|
|
static addr_policy_t * rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string(const char *s, int assume_action, int *malformed_list);
|
|
ATTR_UNUSED static int rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string_called = 0;
|
|
|
|
static addr_policy_t *rset_parse_policy_wildcard_mock_addr_policy;
|
|
|
|
static void
|
|
test_rset_parse_policy_wildcard(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(router_parse_addr_policy_item_from_string,
|
|
rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string);
|
|
rset_parse_policy_wildcard_mock_addr_policy = tor_malloc_zero(sizeof(addr_policy_t));
|
|
|
|
set = routerset_new();
|
|
s = "*";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(smartlist_len(set->policies), OP_NE, 0);
|
|
tt_int_op(rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string_called, OP_EQ, 1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
addr_policy_t *
|
|
rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string(const char *s,
|
|
int assume_action,
|
|
int *malformed_list)
|
|
{
|
|
(void)s;
|
|
(void)assume_action;
|
|
(void)malformed_list;
|
|
rset_parse_policy_wildcard_router_parse_addr_policy_item_from_string_called++;
|
|
|
|
return rset_parse_policy_wildcard_mock_addr_policy;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_parse, when given a valid IPv4 address
|
|
* literal policy.
|
|
*/
|
|
|
|
static addr_policy_t * rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string(const char *s, int assume_action, int *bogus);
|
|
ATTR_UNUSED static int rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string_called = 0;
|
|
|
|
static addr_policy_t *rset_parse_policy_ipv4_mock_addr_policy;
|
|
|
|
static void
|
|
test_rset_parse_policy_ipv4(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(router_parse_addr_policy_item_from_string,
|
|
rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string);
|
|
rset_parse_policy_ipv4_mock_addr_policy = tor_malloc_zero(sizeof(addr_policy_t));
|
|
|
|
set = routerset_new();
|
|
s = "127.0.0.1";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(smartlist_len(set->policies), OP_NE, 0);
|
|
tt_int_op(rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string_called, OP_EQ, 1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
addr_policy_t *
|
|
rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string(const char *s, int assume_action,
|
|
int *bogus)
|
|
{
|
|
(void)s;
|
|
(void)assume_action;
|
|
rset_parse_policy_ipv4_router_parse_addr_policy_item_from_string_called++;
|
|
*bogus = 0;
|
|
|
|
return rset_parse_policy_ipv4_mock_addr_policy;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_parse, when given a valid IPv6 address
|
|
* literal policy.
|
|
*/
|
|
|
|
static addr_policy_t * rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string(const char *s, int assume_action, int *bad);
|
|
ATTR_UNUSED static int rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string_called = 0;
|
|
|
|
static addr_policy_t *rset_parse_policy_ipv6_mock_addr_policy;
|
|
|
|
static void
|
|
test_rset_parse_policy_ipv6(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
const char *s;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(router_parse_addr_policy_item_from_string,
|
|
rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string);
|
|
rset_parse_policy_ipv6_mock_addr_policy = tor_malloc_zero(sizeof(addr_policy_t));
|
|
|
|
set = routerset_new();
|
|
s = "::1";
|
|
r = routerset_parse(set, s, "");
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(smartlist_len(set->policies), OP_NE, 0);
|
|
tt_int_op(rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string_called, OP_EQ, 1);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
addr_policy_t *
|
|
rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string(const char *s,
|
|
int assume_action, int *bad)
|
|
{
|
|
(void)s;
|
|
(void)assume_action;
|
|
rset_parse_policy_ipv6_router_parse_addr_policy_item_from_string_called++;
|
|
*bad = 0;
|
|
|
|
return rset_parse_policy_ipv6_mock_addr_policy;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_union, when given a bad source argument.
|
|
*/
|
|
|
|
static smartlist_t * rset_union_source_bad_smartlist_new(void);
|
|
ATTR_UNUSED static int rset_union_source_bad_smartlist_new_called = 0;
|
|
|
|
static void
|
|
test_rset_union_source_bad(void *arg)
|
|
{
|
|
routerset_t *set, *bad_set;
|
|
(void)arg;
|
|
|
|
set = routerset_new();
|
|
bad_set = routerset_new();
|
|
smartlist_free(bad_set->list);
|
|
bad_set->list = NULL;
|
|
|
|
MOCK(smartlist_new,
|
|
rset_union_source_bad_smartlist_new);
|
|
|
|
routerset_union(set, NULL);
|
|
tt_int_op(rset_union_source_bad_smartlist_new_called, OP_EQ, 0);
|
|
|
|
routerset_union(set, bad_set);
|
|
tt_int_op(rset_union_source_bad_smartlist_new_called, OP_EQ, 0);
|
|
|
|
done:
|
|
UNMOCK(smartlist_new);
|
|
routerset_free(set);
|
|
|
|
/* Just recreate list, so we can simply use routerset_free. */
|
|
bad_set->list = smartlist_new();
|
|
routerset_free(bad_set);
|
|
}
|
|
|
|
static smartlist_t *
|
|
rset_union_source_bad_smartlist_new(void)
|
|
{
|
|
rset_union_source_bad_smartlist_new_called++;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_union.
|
|
*/
|
|
|
|
static void
|
|
test_rset_union_one(void *arg)
|
|
{
|
|
routerset_t *src = routerset_new();
|
|
routerset_t *tgt;
|
|
(void)arg;
|
|
|
|
tgt = routerset_new();
|
|
smartlist_add_strdup(src->list, "{xx}");
|
|
routerset_union(tgt, src);
|
|
|
|
tt_int_op(smartlist_len(tgt->list), OP_NE, 0);
|
|
|
|
done:
|
|
routerset_free(src);
|
|
routerset_free(tgt);
|
|
}
|
|
|
|
/*
|
|
* Functional tests for routerset_is_list.
|
|
*/
|
|
|
|
static void
|
|
test_rset_is_list(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
addr_policy_t *policy;
|
|
int is_list;
|
|
(void)arg;
|
|
|
|
/* len(set->country_names) == 0, len(set->policies) == 0 */
|
|
set = routerset_new();
|
|
is_list = routerset_is_list(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_list, OP_NE, 0);
|
|
|
|
/* len(set->country_names) != 0, len(set->policies) == 0 */
|
|
set = routerset_new();
|
|
smartlist_add(set->country_names, tor_strndup("foo", 3));
|
|
is_list = routerset_is_list(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_list, OP_EQ, 0);
|
|
|
|
/* len(set->country_names) == 0, len(set->policies) != 0 */
|
|
set = routerset_new();
|
|
policy = tor_malloc_zero(sizeof(addr_policy_t));
|
|
smartlist_add(set->policies, (void *)policy);
|
|
is_list = routerset_is_list(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_list, OP_EQ, 0);
|
|
|
|
/* len(set->country_names) != 0, len(set->policies) != 0 */
|
|
set = routerset_new();
|
|
smartlist_add(set->country_names, tor_strndup("foo", 3));
|
|
policy = tor_malloc_zero(sizeof(addr_policy_t));
|
|
smartlist_add(set->policies, (void *)policy);
|
|
is_list = routerset_is_list(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_list, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional tests for routerset_needs_geoip.
|
|
*/
|
|
|
|
static void
|
|
test_rset_needs_geoip(void *arg)
|
|
{
|
|
routerset_t *set;
|
|
int needs_geoip;
|
|
(void)arg;
|
|
|
|
set = NULL;
|
|
needs_geoip = routerset_needs_geoip(set);
|
|
tt_int_op(needs_geoip, OP_EQ, 0);
|
|
|
|
set = routerset_new();
|
|
needs_geoip = routerset_needs_geoip(set);
|
|
routerset_free(set);
|
|
tt_int_op(needs_geoip, OP_EQ, 0);
|
|
set = NULL;
|
|
|
|
set = routerset_new();
|
|
smartlist_add(set->country_names, tor_strndup("xx", 2));
|
|
needs_geoip = routerset_needs_geoip(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(needs_geoip, OP_NE, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional tests for routerset_is_empty.
|
|
*/
|
|
|
|
static void
|
|
test_rset_is_empty(void *arg)
|
|
{
|
|
routerset_t *set = NULL;
|
|
int is_empty;
|
|
(void)arg;
|
|
|
|
is_empty = routerset_is_empty(set);
|
|
tt_int_op(is_empty, OP_NE, 0);
|
|
|
|
set = routerset_new();
|
|
is_empty = routerset_is_empty(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_empty, OP_NE, 0);
|
|
|
|
set = routerset_new();
|
|
smartlist_add_strdup(set->list, "{xx}");
|
|
is_empty = routerset_is_empty(set);
|
|
routerset_free(set);
|
|
set = NULL;
|
|
tt_int_op(is_empty, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a NULL set or the
|
|
* set has a NULL list.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_null_set_or_list(void *arg)
|
|
{
|
|
routerset_t *set = NULL;
|
|
int contains;
|
|
(void)arg;
|
|
|
|
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
|
|
set = tor_malloc_zero(sizeof(routerset_t));
|
|
set->list = NULL;
|
|
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
|
tor_free(set);
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset but a
|
|
* NULL nickname.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_null_nickname(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
char *nickname = NULL;
|
|
int contains;
|
|
(void)arg;
|
|
|
|
contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset
|
|
* and the nickname is in the routerset.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_nickname(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
const char *nickname;
|
|
int contains;
|
|
(void)arg;
|
|
|
|
nickname = "Foo"; /* This tests the lowercase comparison as well. */
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 4);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset
|
|
* and the nickname is not in the routerset.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_no_nickname(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains;
|
|
(void)arg;
|
|
|
|
strmap_set_lc(set->names, "bar", (void *)1);
|
|
contains = routerset_contains(set, NULL, 0, "foo", NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset
|
|
* and the digest is contained in the routerset.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_digest(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains;
|
|
uint8_t foo[20] = { 2, 3, 4 };
|
|
(void)arg;
|
|
|
|
digestmap_set(set->digests, (const char*)foo, (void *)1);
|
|
contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 4);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset
|
|
* and the digest is not contained in the routerset.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_no_digest(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains;
|
|
uint8_t bar[20] = { 9, 10, 11, 55 };
|
|
uint8_t foo[20] = { 1, 2, 3, 4};
|
|
(void)arg;
|
|
|
|
digestmap_set(set->digests, (const char*)bar, (void *)1);
|
|
contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains, when given a valid routerset
|
|
* and the digest is NULL.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_null_digest(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains;
|
|
uint8_t bar[20] = { 9, 10, 11, 55 };
|
|
(void)arg;
|
|
|
|
digestmap_set(set->digests, (const char*)bar, (void *)1);
|
|
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_contains, when given a valid routerset
|
|
* and the address is rejected by policy.
|
|
*/
|
|
|
|
static addr_policy_result_t rset_contains_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy);
|
|
ATTR_UNUSED static int rset_contains_addr_compare_tor_addr_to_addr_policy_called = 0;
|
|
|
|
static tor_addr_t MOCK_TOR_ADDR;
|
|
#define MOCK_TOR_ADDR_PTR (&MOCK_TOR_ADDR)
|
|
|
|
static void
|
|
test_rset_contains_addr(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
|
|
int contains;
|
|
(void)arg;
|
|
|
|
MOCK(compare_tor_addr_to_addr_policy,
|
|
rset_contains_addr_compare_tor_addr_to_addr_policy);
|
|
|
|
contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(rset_contains_addr_compare_tor_addr_to_addr_policy_called, OP_EQ, 1);
|
|
tt_int_op(contains, OP_EQ, 3);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
addr_policy_result_t
|
|
rset_contains_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
|
|
const smartlist_t *policy)
|
|
{
|
|
(void)port;
|
|
(void)policy;
|
|
rset_contains_addr_compare_tor_addr_to_addr_policy_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
return ADDR_POLICY_REJECTED;
|
|
|
|
done:
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_contains, when given a valid routerset
|
|
* and the address is not rejected by policy.
|
|
*/
|
|
|
|
static addr_policy_result_t rset_contains_no_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy);
|
|
ATTR_UNUSED static int rset_contains_no_addr_compare_tor_addr_to_addr_policy_called = 0;
|
|
|
|
static void
|
|
test_rset_contains_no_addr(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
|
|
int contains;
|
|
(void)arg;
|
|
|
|
MOCK(compare_tor_addr_to_addr_policy,
|
|
rset_contains_no_addr_compare_tor_addr_to_addr_policy);
|
|
|
|
contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(rset_contains_no_addr_compare_tor_addr_to_addr_policy_called, OP_EQ, 1);
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
addr_policy_result_t
|
|
rset_contains_no_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
|
|
const smartlist_t *policy)
|
|
{
|
|
(void)port;
|
|
(void)policy;
|
|
rset_contains_no_addr_compare_tor_addr_to_addr_policy_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
return ADDR_POLICY_ACCEPTED;
|
|
|
|
done:
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_contains, when given a valid routerset
|
|
* and the address is NULL.
|
|
*/
|
|
|
|
static addr_policy_result_t rset_contains_null_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy);
|
|
ATTR_UNUSED static int rset_contains_null_addr_compare_tor_addr_to_addr_policy_called = 0;
|
|
|
|
static void
|
|
test_rset_contains_null_addr(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains;
|
|
(void)arg;
|
|
|
|
MOCK(compare_tor_addr_to_addr_policy,
|
|
rset_contains_null_addr_compare_tor_addr_to_addr_policy);
|
|
|
|
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
addr_policy_result_t
|
|
rset_contains_null_addr_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
|
|
const smartlist_t *policy)
|
|
{
|
|
(void)port;
|
|
(void)policy;
|
|
rset_contains_null_addr_compare_tor_addr_to_addr_policy_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
return ADDR_POLICY_ACCEPTED;
|
|
|
|
done:
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_contains, when there is no matching country
|
|
* for the address.
|
|
*/
|
|
|
|
static addr_policy_result_t rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy);
|
|
ATTR_UNUSED static int rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy_called = 0;
|
|
static int rset_contains_countries_no_geoip_geoip_get_country_by_addr(const tor_addr_t *addr);
|
|
ATTR_UNUSED static int rset_contains_countries_no_geoip_geoip_get_country_by_addr_called = 0;
|
|
|
|
static void
|
|
test_rset_contains_countries_no_geoip(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains = 1;
|
|
(void)arg;
|
|
|
|
MOCK(compare_tor_addr_to_addr_policy,
|
|
rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy);
|
|
MOCK(geoip_get_country_by_addr,
|
|
rset_contains_countries_no_geoip_geoip_get_country_by_addr);
|
|
|
|
set->countries = bitarray_init_zero(1);
|
|
bitarray_set(set->countries, 1);
|
|
contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 0);
|
|
tt_int_op(rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy_called, OP_EQ, 1);
|
|
tt_int_op(rset_contains_countries_no_geoip_geoip_get_country_by_addr_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
addr_policy_result_t
|
|
rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
|
|
const smartlist_t *policy)
|
|
{
|
|
(void)port;
|
|
(void)policy;
|
|
rset_contains_countries_no_geoip_compare_tor_addr_to_addr_policy_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
done:
|
|
return ADDR_POLICY_ACCEPTED;
|
|
}
|
|
|
|
int
|
|
rset_contains_countries_no_geoip_geoip_get_country_by_addr(const tor_addr_t *addr)
|
|
{
|
|
rset_contains_countries_no_geoip_geoip_get_country_by_addr_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
done:
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_contains, when there a matching country
|
|
* for the address.
|
|
*/
|
|
|
|
static addr_policy_result_t rset_contains_countries_geoip_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy);
|
|
ATTR_UNUSED static int rset_contains_countries_geoip_compare_tor_addr_to_addr_policy_called = 0;
|
|
static int rset_contains_countries_geoip_geoip_get_country_by_addr(const tor_addr_t *addr);
|
|
ATTR_UNUSED static int rset_contains_countries_geoip_geoip_get_country_by_addr_called = 0;
|
|
|
|
static void
|
|
test_rset_contains_countries_geoip(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int contains = 1;
|
|
(void)arg;
|
|
|
|
MOCK(compare_tor_addr_to_addr_policy,
|
|
rset_contains_countries_geoip_compare_tor_addr_to_addr_policy);
|
|
MOCK(geoip_get_country_by_addr,
|
|
rset_contains_countries_geoip_geoip_get_country_by_addr);
|
|
|
|
set->n_countries = 2;
|
|
set->countries = bitarray_init_zero(1);
|
|
bitarray_set(set->countries, 1);
|
|
contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(contains, OP_EQ, 2);
|
|
tt_int_op(rset_contains_countries_geoip_compare_tor_addr_to_addr_policy_called, OP_EQ, 1);
|
|
tt_int_op(rset_contains_countries_geoip_geoip_get_country_by_addr_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
addr_policy_result_t
|
|
rset_contains_countries_geoip_compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
|
|
const smartlist_t *policy)
|
|
{
|
|
(void)port;
|
|
(void)policy;
|
|
rset_contains_countries_geoip_compare_tor_addr_to_addr_policy_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
done:
|
|
return ADDR_POLICY_ACCEPTED;
|
|
}
|
|
|
|
int
|
|
rset_contains_countries_geoip_geoip_get_country_by_addr(const tor_addr_t *addr)
|
|
{
|
|
rset_contains_countries_geoip_geoip_get_country_by_addr_called++;
|
|
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
|
|
|
done:
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_add_unknown_ccs, where only_if_some_cc_set
|
|
* is set and there are no country names.
|
|
*/
|
|
|
|
static void
|
|
test_rset_add_unknown_ccs_only_flag(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
routerset_t **setp = &set;
|
|
int r;
|
|
(void)arg;
|
|
|
|
r = routerset_add_unknown_ccs(setp, 1);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_add_unknown_ccs, where the set argument
|
|
* is created if passed in as NULL.
|
|
*/
|
|
|
|
/* The mock is only used to stop the test from asserting erroneously. */
|
|
static country_t rset_add_unknown_ccs_creates_set_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_add_unknown_ccs_creates_set_geoip_get_country_called = 0;
|
|
|
|
static void
|
|
test_rset_add_unknown_ccs_creates_set(void *arg)
|
|
{
|
|
routerset_t *set = NULL;
|
|
routerset_t **setp = &set;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(geoip_get_country,
|
|
rset_add_unknown_ccs_creates_set_geoip_get_country);
|
|
|
|
r = routerset_add_unknown_ccs(setp, 0);
|
|
|
|
tt_ptr_op(*setp, OP_NE, NULL);
|
|
tt_int_op(r, OP_EQ, 0);
|
|
|
|
done:
|
|
if (set != NULL)
|
|
routerset_free(set);
|
|
}
|
|
|
|
country_t
|
|
rset_add_unknown_ccs_creates_set_geoip_get_country(const char *country)
|
|
{
|
|
(void)country;
|
|
rset_add_unknown_ccs_creates_set_geoip_get_country_called++;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_add_unknown_ccs, that the "{??}"
|
|
* country code is added to the list.
|
|
*/
|
|
|
|
static country_t rset_add_unknown_ccs_add_unknown_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_add_unknown_ccs_add_unknown_geoip_get_country_called = 0;
|
|
static int rset_add_unknown_ccs_add_unknown_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_add_unknown_ccs_add_unknown_geoip_is_loaded_called = 0;
|
|
|
|
static void
|
|
test_rset_add_unknown_ccs_add_unknown(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
routerset_t **setp = &set;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(geoip_get_country,
|
|
rset_add_unknown_ccs_add_unknown_geoip_get_country);
|
|
MOCK(geoip_is_loaded,
|
|
rset_add_unknown_ccs_add_unknown_geoip_is_loaded);
|
|
|
|
r = routerset_add_unknown_ccs(setp, 0);
|
|
|
|
tt_int_op(r, OP_EQ, 1);
|
|
tt_int_op(smartlist_contains_string(set->country_names, "??"), OP_EQ, 1);
|
|
tt_int_op(smartlist_contains_string(set->list, "{??}"), OP_EQ, 1);
|
|
|
|
done:
|
|
if (set != NULL)
|
|
routerset_free(set);
|
|
}
|
|
|
|
country_t
|
|
rset_add_unknown_ccs_add_unknown_geoip_get_country(const char *country)
|
|
{
|
|
int arg_is_qq, arg_is_a1;
|
|
|
|
rset_add_unknown_ccs_add_unknown_geoip_get_country_called++;
|
|
|
|
arg_is_qq = !strcmp(country, "??");
|
|
arg_is_a1 = !strcmp(country, "A1");
|
|
|
|
tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
|
|
|
|
if (arg_is_qq)
|
|
return 1;
|
|
|
|
done:
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
rset_add_unknown_ccs_add_unknown_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
rset_add_unknown_ccs_add_unknown_geoip_is_loaded_called++;
|
|
|
|
tt_int_op(family, OP_EQ, AF_INET);
|
|
|
|
done:
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_add_unknown_ccs, that the "{a1}"
|
|
* country code is added to the list.
|
|
*/
|
|
|
|
static country_t rset_add_unknown_ccs_add_a1_geoip_get_country(const char *country);
|
|
ATTR_UNUSED static int rset_add_unknown_ccs_add_a1_geoip_get_country_called = 0;
|
|
static int rset_add_unknown_ccs_add_a1_geoip_is_loaded(sa_family_t family);
|
|
ATTR_UNUSED static int rset_add_unknown_ccs_add_a1_geoip_is_loaded_called = 0;
|
|
|
|
static void
|
|
test_rset_add_unknown_ccs_add_a1(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
routerset_t **setp = &set;
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(geoip_get_country,
|
|
rset_add_unknown_ccs_add_a1_geoip_get_country);
|
|
MOCK(geoip_is_loaded,
|
|
rset_add_unknown_ccs_add_a1_geoip_is_loaded);
|
|
|
|
r = routerset_add_unknown_ccs(setp, 0);
|
|
|
|
tt_int_op(r, OP_EQ, 1);
|
|
tt_int_op(smartlist_contains_string(set->country_names, "a1"), OP_EQ, 1);
|
|
tt_int_op(smartlist_contains_string(set->list, "{a1}"), OP_EQ, 1);
|
|
|
|
done:
|
|
if (set != NULL)
|
|
routerset_free(set);
|
|
}
|
|
|
|
country_t
|
|
rset_add_unknown_ccs_add_a1_geoip_get_country(const char *country)
|
|
{
|
|
int arg_is_qq, arg_is_a1;
|
|
|
|
rset_add_unknown_ccs_add_a1_geoip_get_country_called++;
|
|
|
|
arg_is_qq = !strcmp(country, "??");
|
|
arg_is_a1 = !strcmp(country, "A1");
|
|
|
|
tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
|
|
|
|
if (arg_is_a1)
|
|
return 1;
|
|
|
|
done:
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
rset_add_unknown_ccs_add_a1_geoip_is_loaded(sa_family_t family)
|
|
{
|
|
rset_add_unknown_ccs_add_a1_geoip_is_loaded_called++;
|
|
|
|
tt_int_op(family, OP_EQ, AF_INET);
|
|
|
|
done:
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_extendinfo.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_extendinfo(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
extend_info_t ei;
|
|
int r;
|
|
const char *nickname = "foo";
|
|
(void)arg;
|
|
|
|
memset(&ei, 0, sizeof(ei));
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
strncpy(ei.nickname, nickname, sizeof(ei.nickname) - 1);
|
|
ei.nickname[sizeof(ei.nickname) - 1] = '\0';
|
|
|
|
r = routerset_contains_extendinfo(set, &ei);
|
|
|
|
tt_int_op(r, OP_EQ, 4);
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_router.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_router(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
routerinfo_t ri;
|
|
country_t country = 1;
|
|
int r;
|
|
const char *nickname = "foo";
|
|
(void)arg;
|
|
|
|
memset(&ri, 0, sizeof(ri));
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
ri.nickname = (char *)nickname;
|
|
|
|
r = routerset_contains_router(set, &ri, country);
|
|
|
|
tt_int_op(r, OP_EQ, 4);
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_routerstatus.
|
|
*/
|
|
|
|
// XXX: This is a bit brief. It only populates and tests the nickname fields
|
|
// ie., enough to make the containment check succeed. Perhaps it should do
|
|
// a bit more or test a bit more.
|
|
|
|
static void
|
|
test_rset_contains_routerstatus(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
routerstatus_t rs;
|
|
country_t country = 1;
|
|
int r;
|
|
const char *nickname = "foo";
|
|
(void)arg;
|
|
|
|
memset(&rs, 0, sizeof(rs));
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
|
|
rs.nickname[sizeof(rs.nickname) - 1] = '\0';
|
|
|
|
r = routerset_contains_routerstatus(set, &rs, country);
|
|
|
|
tt_int_op(r, OP_EQ, 4);
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_node, when the node has no
|
|
* routerset or routerinfo.
|
|
*/
|
|
|
|
static node_t rset_contains_none_mock_node;
|
|
|
|
static void
|
|
test_rset_contains_none(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
memset(&rset_contains_none_mock_node, 0, sizeof(rset_contains_none_mock_node));
|
|
rset_contains_none_mock_node.ri = NULL;
|
|
rset_contains_none_mock_node.rs = NULL;
|
|
|
|
r = routerset_contains_node(set, &rset_contains_none_mock_node);
|
|
tt_int_op(r, OP_EQ, 0);
|
|
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_node, when the node has a
|
|
* routerset and no routerinfo.
|
|
*/
|
|
|
|
static node_t rset_contains_rs_mock_node;
|
|
|
|
static void
|
|
test_rset_contains_rs(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int r;
|
|
const char *nickname = "foo";
|
|
routerstatus_t rs;
|
|
(void)arg;
|
|
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
|
|
strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
|
|
rs.nickname[sizeof(rs.nickname) - 1] = '\0';
|
|
memset(&rset_contains_rs_mock_node, 0, sizeof(rset_contains_rs_mock_node));
|
|
rset_contains_rs_mock_node.ri = NULL;
|
|
rset_contains_rs_mock_node.rs = &rs;
|
|
|
|
r = routerset_contains_node(set, &rset_contains_rs_mock_node);
|
|
|
|
tt_int_op(r, OP_EQ, 4);
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_contains_node, when the node has no
|
|
* routerset and a routerinfo.
|
|
*/
|
|
|
|
static void
|
|
test_rset_contains_routerinfo(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
int r;
|
|
const char *nickname = "foo";
|
|
routerinfo_t ri;
|
|
node_t mock_node;
|
|
(void)arg;
|
|
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
|
|
ri.nickname = (char *)nickname;
|
|
memset(&mock_node, 0, sizeof(mock_node));
|
|
mock_node.ri = &ri;
|
|
mock_node.rs = NULL;
|
|
|
|
r = routerset_contains_node(set, &mock_node);
|
|
|
|
tt_int_op(r, OP_EQ, 4);
|
|
done:
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_get_all_nodes, when routerset is NULL or
|
|
* the routerset list is NULL.
|
|
*/
|
|
|
|
static void
|
|
test_rset_get_all_no_routerset(void *arg)
|
|
{
|
|
smartlist_t *out = smartlist_new();
|
|
routerset_t *set = NULL;
|
|
(void)arg;
|
|
|
|
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
|
routerset_get_all_nodes(out, NULL, NULL, 0);
|
|
|
|
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
|
|
|
set = routerset_new();
|
|
smartlist_free(set->list);
|
|
routerset_get_all_nodes(out, NULL, NULL, 0);
|
|
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
|
|
|
/* Just recreate list, so we can simply use routerset_free. */
|
|
set->list = smartlist_new();
|
|
|
|
done:
|
|
routerset_free(set);
|
|
smartlist_free(out);
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_get_all_nodes, when the routerset list
|
|
* is empty.
|
|
*/
|
|
|
|
static const node_t * rset_get_all_l_no_nodes_node_get_by_nickname(const char *nickname, unsigned flags);
|
|
ATTR_UNUSED static int rset_get_all_l_no_nodes_node_get_by_nickname_called = 0;
|
|
static const char *rset_get_all_l_no_nodes_mock_nickname;
|
|
|
|
static void
|
|
test_rset_get_all_l_no_nodes(void *arg)
|
|
{
|
|
smartlist_t *out = smartlist_new();
|
|
routerset_t *set = routerset_new();
|
|
int out_len;
|
|
(void)arg;
|
|
|
|
MOCK(node_get_by_nickname,
|
|
rset_get_all_l_no_nodes_node_get_by_nickname);
|
|
|
|
rset_get_all_l_no_nodes_mock_nickname = "foo";
|
|
smartlist_add_strdup(set->list, rset_get_all_l_no_nodes_mock_nickname);
|
|
|
|
routerset_get_all_nodes(out, set, NULL, 0);
|
|
out_len = smartlist_len(out);
|
|
|
|
smartlist_free(out);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(out_len, OP_EQ, 0);
|
|
tt_int_op(rset_get_all_l_no_nodes_node_get_by_nickname_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
const node_t *
|
|
rset_get_all_l_no_nodes_node_get_by_nickname(const char *nickname, unsigned flags)
|
|
{
|
|
rset_get_all_l_no_nodes_node_get_by_nickname_called++;
|
|
tt_str_op(nickname, OP_EQ, rset_get_all_l_no_nodes_mock_nickname);
|
|
tt_uint_op(flags, OP_EQ, 0);
|
|
|
|
done:
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_get_all_nodes, with the running_only flag
|
|
* is set but the nodes are not running.
|
|
*/
|
|
|
|
static const node_t * rset_get_all_l_not_running_node_get_by_nickname(const char *nickname, unsigned flags);
|
|
ATTR_UNUSED static int rset_get_all_l_not_running_node_get_by_nickname_called = 0;
|
|
static const char *rset_get_all_l_not_running_mock_nickname;
|
|
static node_t rset_get_all_l_not_running_mock_node;
|
|
|
|
static void
|
|
test_rset_get_all_l_not_running(void *arg)
|
|
{
|
|
smartlist_t *out = smartlist_new();
|
|
routerset_t *set = routerset_new();
|
|
int out_len;
|
|
(void)arg;
|
|
|
|
MOCK(node_get_by_nickname,
|
|
rset_get_all_l_not_running_node_get_by_nickname);
|
|
|
|
rset_get_all_l_not_running_mock_node.is_running = 0;
|
|
rset_get_all_l_not_running_mock_nickname = "foo";
|
|
smartlist_add_strdup(set->list, rset_get_all_l_not_running_mock_nickname);
|
|
|
|
routerset_get_all_nodes(out, set, NULL, 1);
|
|
out_len = smartlist_len(out);
|
|
|
|
smartlist_free(out);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(out_len, OP_EQ, 0);
|
|
tt_int_op(rset_get_all_l_not_running_node_get_by_nickname_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
const node_t *
|
|
rset_get_all_l_not_running_node_get_by_nickname(const char *nickname, unsigned flags)
|
|
{
|
|
rset_get_all_l_not_running_node_get_by_nickname_called++;
|
|
tt_str_op(nickname, OP_EQ, rset_get_all_l_not_running_mock_nickname);
|
|
tt_int_op(flags, OP_EQ, 0);
|
|
|
|
done:
|
|
return &rset_get_all_l_not_running_mock_node;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_get_all_nodes.
|
|
*/
|
|
|
|
static const node_t * rset_get_all_list_node_get_by_nickname(const char *nickname, unsigned flags);
|
|
ATTR_UNUSED static int rset_get_all_list_node_get_by_nickname_called = 0;
|
|
static char *rset_get_all_list_mock_nickname;
|
|
static node_t rset_get_all_list_mock_node;
|
|
|
|
static void
|
|
test_rset_get_all_list(void *arg)
|
|
{
|
|
smartlist_t *out = smartlist_new();
|
|
routerset_t *set = routerset_new();
|
|
int out_len;
|
|
node_t *ent;
|
|
(void)arg;
|
|
|
|
MOCK(node_get_by_nickname,
|
|
rset_get_all_list_node_get_by_nickname);
|
|
|
|
rset_get_all_list_mock_nickname = tor_strdup("foo");
|
|
smartlist_add(set->list, rset_get_all_list_mock_nickname);
|
|
|
|
routerset_get_all_nodes(out, set, NULL, 0);
|
|
out_len = smartlist_len(out);
|
|
ent = (node_t *)smartlist_get(out, 0);
|
|
|
|
smartlist_free(out);
|
|
routerset_free(set);
|
|
|
|
tt_int_op(out_len, OP_EQ, 1);
|
|
tt_ptr_op(ent, OP_EQ, &rset_get_all_list_mock_node);
|
|
tt_int_op(rset_get_all_list_node_get_by_nickname_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
const node_t *
|
|
rset_get_all_list_node_get_by_nickname(const char *nickname, unsigned flags)
|
|
{
|
|
rset_get_all_list_node_get_by_nickname_called++;
|
|
tt_str_op(nickname, OP_EQ, rset_get_all_list_mock_nickname);
|
|
tt_int_op(flags, OP_EQ, 0);
|
|
|
|
done:
|
|
return &rset_get_all_list_mock_node;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_get_all_nodes, when the nodelist has no nodes.
|
|
*/
|
|
|
|
static const smartlist_t * rset_get_all_n_no_nodes_nodelist_get_list(void);
|
|
ATTR_UNUSED static int rset_get_all_n_no_nodes_nodelist_get_list_called = 0;
|
|
|
|
static smartlist_t *rset_get_all_n_no_nodes_mock_smartlist;
|
|
static void
|
|
test_rset_get_all_n_no_nodes(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
smartlist_t *out = smartlist_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(nodelist_get_list,
|
|
rset_get_all_n_no_nodes_nodelist_get_list);
|
|
|
|
smartlist_add_strdup(set->country_names, "{xx}");
|
|
rset_get_all_n_no_nodes_mock_smartlist = smartlist_new();
|
|
|
|
routerset_get_all_nodes(out, set, NULL, 1);
|
|
r = smartlist_len(out);
|
|
routerset_free(set);
|
|
smartlist_free(out);
|
|
smartlist_free(rset_get_all_n_no_nodes_mock_smartlist);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(rset_get_all_n_no_nodes_nodelist_get_list_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
const smartlist_t *
|
|
rset_get_all_n_no_nodes_nodelist_get_list(void)
|
|
{
|
|
rset_get_all_n_no_nodes_nodelist_get_list_called++;
|
|
|
|
return rset_get_all_n_no_nodes_mock_smartlist;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_get_all_nodes, with a non-list routerset
|
|
* the running_only flag is set, but the nodes are not running.
|
|
*/
|
|
|
|
static const smartlist_t * rset_get_all_n_not_running_nodelist_get_list(void);
|
|
ATTR_UNUSED static int rset_get_all_n_not_running_nodelist_get_list_called = 0;
|
|
|
|
static smartlist_t *rset_get_all_n_not_running_mock_smartlist;
|
|
static node_t rset_get_all_n_not_running_mock_node;
|
|
|
|
static void
|
|
test_rset_get_all_n_not_running(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
smartlist_t *out = smartlist_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
MOCK(nodelist_get_list,
|
|
rset_get_all_n_not_running_nodelist_get_list);
|
|
|
|
smartlist_add_strdup(set->country_names, "{xx}");
|
|
rset_get_all_n_not_running_mock_smartlist = smartlist_new();
|
|
rset_get_all_n_not_running_mock_node.is_running = 0;
|
|
smartlist_add(rset_get_all_n_not_running_mock_smartlist, (void *)&rset_get_all_n_not_running_mock_node);
|
|
|
|
routerset_get_all_nodes(out, set, NULL, 1);
|
|
r = smartlist_len(out);
|
|
routerset_free(set);
|
|
smartlist_free(out);
|
|
smartlist_free(rset_get_all_n_not_running_mock_smartlist);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
tt_int_op(rset_get_all_n_not_running_nodelist_get_list_called, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
const smartlist_t *
|
|
rset_get_all_n_not_running_nodelist_get_list(void)
|
|
{
|
|
rset_get_all_n_not_running_nodelist_get_list_called++;
|
|
|
|
return rset_get_all_n_not_running_mock_smartlist;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_subtract_nodes.
|
|
*/
|
|
|
|
static void
|
|
test_rset_subtract_nodes(void *arg)
|
|
{
|
|
routerset_t *set = routerset_new();
|
|
smartlist_t *list = smartlist_new();
|
|
const char *nickname = "foo";
|
|
routerinfo_t ri;
|
|
node_t mock_node;
|
|
(void)arg;
|
|
|
|
strmap_set_lc(set->names, nickname, (void *)1);
|
|
|
|
ri.nickname = (char *)nickname;
|
|
mock_node.rs = NULL;
|
|
mock_node.ri = &ri;
|
|
smartlist_add(list, (void *)&mock_node);
|
|
|
|
tt_int_op(smartlist_len(list), OP_NE, 0);
|
|
routerset_subtract_nodes(list, set);
|
|
|
|
tt_int_op(smartlist_len(list), OP_EQ, 0);
|
|
done:
|
|
routerset_free(set);
|
|
smartlist_free(list);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_subtract_nodes, with a NULL routerset.
|
|
*/
|
|
|
|
static void
|
|
test_rset_subtract_nodes_null_routerset(void *arg)
|
|
{
|
|
routerset_t *set = NULL;
|
|
smartlist_t *list = smartlist_new();
|
|
const char *nickname = "foo";
|
|
routerinfo_t ri;
|
|
node_t mock_node;
|
|
(void)arg;
|
|
|
|
ri.nickname = (char *)nickname;
|
|
mock_node.ri = &ri;
|
|
smartlist_add(list, (void *)&mock_node);
|
|
|
|
tt_int_op(smartlist_len(list), OP_NE, 0);
|
|
routerset_subtract_nodes(list, set);
|
|
|
|
tt_int_op(smartlist_len(list), OP_NE, 0);
|
|
done:
|
|
routerset_free(set);
|
|
smartlist_free(list);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_to_string.
|
|
*/
|
|
|
|
static void
|
|
test_rset_to_string(void *arg)
|
|
{
|
|
routerset_t *set = NULL;
|
|
char *s = NULL;
|
|
(void)arg;
|
|
|
|
set = NULL;
|
|
s = routerset_to_string(set);
|
|
tt_str_op(s, OP_EQ, "");
|
|
tor_free(s);
|
|
|
|
set = routerset_new();
|
|
s = routerset_to_string(set);
|
|
tt_str_op(s, OP_EQ, "");
|
|
tor_free(s);
|
|
routerset_free(set); set = NULL;
|
|
|
|
set = routerset_new();
|
|
smartlist_add(set->list, tor_strndup("a", 1));
|
|
s = routerset_to_string(set);
|
|
tt_str_op(s, OP_EQ, "a");
|
|
tor_free(s);
|
|
routerset_free(set); set = NULL;
|
|
|
|
set = routerset_new();
|
|
smartlist_add(set->list, tor_strndup("a", 1));
|
|
smartlist_add(set->list, tor_strndup("b", 1));
|
|
s = routerset_to_string(set);
|
|
tt_str_op(s, OP_EQ, "a,b");
|
|
tor_free(s);
|
|
routerset_free(set); set = NULL;
|
|
|
|
done:
|
|
tor_free(s);
|
|
routerset_free(set);
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_equal, with both routersets empty.
|
|
*/
|
|
|
|
static void
|
|
test_rset_equal_empty_empty(void *arg)
|
|
{
|
|
routerset_t *a = routerset_new(), *b = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
r = routerset_equal(a, b);
|
|
routerset_free(a);
|
|
routerset_free(b);
|
|
|
|
tt_int_op(r, OP_EQ, 1);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_equal, with one routersets empty.
|
|
*/
|
|
|
|
static void
|
|
test_rset_equal_empty_not_empty(void *arg)
|
|
{
|
|
routerset_t *a = routerset_new(), *b = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
smartlist_add_strdup(b->list, "{xx}");
|
|
r = routerset_equal(a, b);
|
|
routerset_free(a);
|
|
routerset_free(b);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_equal, with the routersets having
|
|
* differing lengths.
|
|
*/
|
|
|
|
static void
|
|
test_rset_equal_differing_lengths(void *arg)
|
|
{
|
|
routerset_t *a = routerset_new(), *b = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
smartlist_add_strdup(a->list, "{aa}");
|
|
smartlist_add_strdup(b->list, "{b1}");
|
|
smartlist_add_strdup(b->list, "{b2}");
|
|
r = routerset_equal(a, b);
|
|
routerset_free(a);
|
|
routerset_free(b);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_equal, with the routersets being
|
|
* different.
|
|
*/
|
|
|
|
static void
|
|
test_rset_equal_unequal(void *arg)
|
|
{
|
|
routerset_t *a = routerset_new(), *b = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
smartlist_add_strdup(a->list, "foo");
|
|
smartlist_add_strdup(b->list, "bar");
|
|
r = routerset_equal(a, b);
|
|
routerset_free(a);
|
|
routerset_free(b);
|
|
|
|
tt_int_op(r, OP_EQ, 0);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Functional test for routerset_equal, with the routersets being
|
|
* equal.
|
|
*/
|
|
|
|
static void
|
|
test_rset_equal_equal(void *arg)
|
|
{
|
|
routerset_t *a = routerset_new(), *b = routerset_new();
|
|
int r;
|
|
(void)arg;
|
|
|
|
smartlist_add_strdup(a->list, "foo");
|
|
smartlist_add_strdup(b->list, "foo");
|
|
r = routerset_equal(a, b);
|
|
routerset_free(a);
|
|
routerset_free(b);
|
|
|
|
tt_int_op(r, OP_EQ, 1);
|
|
done:
|
|
;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_free, where the routerset is NULL.
|
|
*/
|
|
|
|
static void rset_free_null_routerset_smartlist_free_(smartlist_t *sl);
|
|
ATTR_UNUSED static int rset_free_null_routerset_smartlist_free__called = 0;
|
|
|
|
static void
|
|
test_rset_free_null_routerset(void *arg)
|
|
{
|
|
(void)arg;
|
|
|
|
MOCK(smartlist_free_,
|
|
rset_free_null_routerset_smartlist_free_);
|
|
|
|
routerset_free_(NULL);
|
|
|
|
tt_int_op(rset_free_null_routerset_smartlist_free__called, OP_EQ, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
void
|
|
rset_free_null_routerset_smartlist_free_(smartlist_t *s)
|
|
{
|
|
(void)s;
|
|
rset_free_null_routerset_smartlist_free__called++;
|
|
}
|
|
|
|
/*
|
|
* Structural test for routerset_free.
|
|
*/
|
|
|
|
static void rset_free_smartlist_free_(smartlist_t *sl);
|
|
ATTR_UNUSED static int rset_free_smartlist_free__called = 0;
|
|
static void rset_free_strmap_free_(strmap_t *map, void (*free_val)(void*));
|
|
ATTR_UNUSED static int rset_free_strmap_free__called = 0;
|
|
static void rset_free_digestmap_free_(digestmap_t *map, void (*free_val)(void*));
|
|
ATTR_UNUSED static int rset_free_digestmap_free__called = 0;
|
|
|
|
static void
|
|
test_rset_free(void *arg)
|
|
{
|
|
routerset_t *routerset = routerset_new();
|
|
(void)arg;
|
|
|
|
MOCK(smartlist_free_,
|
|
rset_free_smartlist_free_);
|
|
MOCK(strmap_free_,
|
|
rset_free_strmap_free_);
|
|
MOCK(digestmap_free_,
|
|
rset_free_digestmap_free_);
|
|
|
|
routerset_free(routerset);
|
|
|
|
tt_int_op(rset_free_smartlist_free__called, OP_NE, 0);
|
|
tt_int_op(rset_free_strmap_free__called, OP_NE, 0);
|
|
tt_int_op(rset_free_digestmap_free__called, OP_NE, 0);
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
void
|
|
rset_free_smartlist_free_(smartlist_t *s)
|
|
{
|
|
rset_free_smartlist_free__called++;
|
|
smartlist_free___real(s);
|
|
}
|
|
|
|
void
|
|
rset_free_strmap_free_(strmap_t *map, void (*free_val)(void*))
|
|
{
|
|
rset_free_strmap_free__called++;
|
|
strmap_free___real(map, free_val);
|
|
}
|
|
|
|
void
|
|
rset_free_digestmap_free_(digestmap_t *map, void (*free_val)(void*))
|
|
{
|
|
rset_free_digestmap_free__called++;
|
|
digestmap_free___real(map, free_val);
|
|
}
|
|
|
|
struct testcase_t routerset_tests[] = {
|
|
{ "new", test_rset_new, TT_FORK, NULL, NULL },
|
|
{ "get_countryname", test_rset_get_countryname, TT_FORK, NULL, NULL },
|
|
{ "is_list", test_rset_is_list, TT_FORK, NULL, NULL },
|
|
{ "needs_geoip", test_rset_needs_geoip, TT_FORK, NULL, NULL },
|
|
{ "is_empty", test_rset_is_empty, TT_FORK, NULL, NULL },
|
|
{ "contains_null_set_or_list", test_rset_contains_null_set_or_list, TT_FORK, NULL, NULL },
|
|
{ "contains_nickname", test_rset_contains_nickname, TT_FORK, NULL, NULL },
|
|
{ "contains_null_nickname", test_rset_contains_null_nickname, TT_FORK, NULL, NULL },
|
|
{ "contains_no_nickname", test_rset_contains_no_nickname, TT_FORK, NULL, NULL },
|
|
{ "contains_digest", test_rset_contains_digest, TT_FORK, NULL, NULL },
|
|
{ "contains_no_digest", test_rset_contains_no_digest, TT_FORK, NULL, NULL },
|
|
{ "contains_null_digest", test_rset_contains_null_digest, TT_FORK, NULL, NULL },
|
|
{ "contains_addr", test_rset_contains_addr, TT_FORK, NULL, NULL },
|
|
{ "contains_no_addr", test_rset_contains_no_addr, TT_FORK, NULL, NULL },
|
|
{ "contains_null_addr", test_rset_contains_null_addr, TT_FORK, NULL, NULL },
|
|
{ "contains_countries_no_geoip", test_rset_contains_countries_no_geoip, TT_FORK, NULL, NULL },
|
|
{ "contains_countries_geoip", test_rset_contains_countries_geoip, TT_FORK, NULL, NULL },
|
|
{ "add_unknown_ccs_only_flag", test_rset_add_unknown_ccs_only_flag, TT_FORK, NULL, NULL },
|
|
{ "add_unknown_ccs_creates_set", test_rset_add_unknown_ccs_creates_set, TT_FORK, NULL, NULL },
|
|
{ "add_unknown_ccs_add_unknown", test_rset_add_unknown_ccs_add_unknown, TT_FORK, NULL, NULL },
|
|
{ "add_unknown_ccs_add_a1", test_rset_add_unknown_ccs_add_a1, TT_FORK, NULL, NULL },
|
|
{ "contains_extendinfo", test_rset_contains_extendinfo, TT_FORK, NULL, NULL },
|
|
{ "contains_router", test_rset_contains_router, TT_FORK, NULL, NULL },
|
|
{ "contains_routerstatus", test_rset_contains_routerstatus, TT_FORK, NULL, NULL },
|
|
{ "contains_none", test_rset_contains_none, TT_FORK, NULL, NULL },
|
|
{ "contains_routerinfo", test_rset_contains_routerinfo, TT_FORK, NULL, NULL },
|
|
{ "contains_rs", test_rset_contains_rs, TT_FORK, NULL, NULL },
|
|
{ "get_all_no_routerset", test_rset_get_all_no_routerset, TT_FORK, NULL, NULL },
|
|
{ "get_all_l_no_nodes", test_rset_get_all_l_no_nodes, TT_FORK, NULL, NULL },
|
|
{ "get_all_l_not_running", test_rset_get_all_l_not_running, TT_FORK, NULL, NULL },
|
|
{ "get_all_list", test_rset_get_all_list, TT_FORK, NULL, NULL },
|
|
{ "get_all_n_no_nodes", test_rset_get_all_n_no_nodes, TT_FORK, NULL, NULL },
|
|
{ "get_all_n_not_running", test_rset_get_all_n_not_running, TT_FORK, NULL, NULL },
|
|
{ "refresh_geoip_not_loaded", test_rset_refresh_geoip_not_loaded, TT_FORK, NULL, NULL },
|
|
{ "refresh_no_countries", test_rset_refresh_no_countries, TT_FORK, NULL, NULL },
|
|
{ "refresh_one_valid_country", test_rset_refresh_one_valid_country, TT_FORK, NULL, NULL },
|
|
{ "refresh_one_invalid_country", test_rset_refresh_one_invalid_country, TT_FORK, NULL, NULL },
|
|
{ "union_source_bad", test_rset_union_source_bad, TT_FORK, NULL, NULL },
|
|
{ "union_one", test_rset_union_one, TT_FORK, NULL, NULL },
|
|
{ "parse_malformed", test_rset_parse_malformed, TT_FORK, NULL, NULL },
|
|
{ "parse_valid_hexdigest", test_rset_parse_valid_hexdigest, TT_FORK, NULL, NULL },
|
|
{ "parse_valid_nickname", test_rset_parse_valid_nickname, TT_FORK, NULL, NULL },
|
|
{ "parse_get_countryname", test_rset_parse_get_countryname, TT_FORK, NULL, NULL },
|
|
{ "parse_policy_wildcard", test_rset_parse_policy_wildcard, TT_FORK, NULL, NULL },
|
|
{ "parse_policy_ipv4", test_rset_parse_policy_ipv4, TT_FORK, NULL, NULL },
|
|
{ "parse_policy_ipv6", test_rset_parse_policy_ipv6, TT_FORK, NULL, NULL },
|
|
{ "subtract_nodes", test_rset_subtract_nodes, TT_FORK, NULL, NULL },
|
|
{ "subtract_nodes_null_routerset", test_rset_subtract_nodes_null_routerset, TT_FORK, NULL, NULL },
|
|
{ "to_string", test_rset_to_string, TT_FORK, NULL, NULL },
|
|
{ "equal_empty_empty", test_rset_equal_empty_empty, TT_FORK, NULL, NULL },
|
|
{ "equal_empty_not_empty", test_rset_equal_empty_not_empty, TT_FORK, NULL, NULL },
|
|
{ "equal_differing_lengths", test_rset_equal_differing_lengths, TT_FORK, NULL, NULL },
|
|
{ "equal_unequal", test_rset_equal_unequal, TT_FORK, NULL, NULL },
|
|
{ "equal_equal", test_rset_equal_equal, TT_FORK, NULL, NULL },
|
|
{ "free_null_routerset", test_rset_free_null_routerset, TT_FORK, NULL, NULL },
|
|
{ "free", test_rset_free, TT_FORK, NULL, NULL },
|
|
END_OF_TESTCASES
|
|
};
|