summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test.h9
-rw-r--r--src/test/test_containers.c153
-rw-r--r--src/test/test_controller_events.c12
-rw-r--r--src/test/test_dir.c277
-rw-r--r--src/test/test_hs.c12
-rw-r--r--src/test/test_pt.c12
-rw-r--r--src/test/test_threads.c14
-rw-r--r--src/test/test_util.c70
-rw-r--r--src/test/testing_common.c2
9 files changed, 534 insertions, 27 deletions
diff --git a/src/test/test.h b/src/test/test.h
index b0c0946ac4..86699c3d07 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -40,6 +40,15 @@
tt_assert_test_type(a,b,#a" "#op" "#b,double,(val1_ op val2_),"%g", \
TT_EXIT_TEST_FUNCTION)
+/* Declare "double equal" in a sneaky way, so compiler won't complain about
+ * comparing floats with == or !=. Of course, only do this if you know what
+ * you're doing. */
+#define tt_double_eq(a,b) \
+ STMT_BEGIN \
+ tt_double_op((a), >=, (b)); \
+ tt_double_op((a), <=, (b)); \
+ STMT_END
+
#ifdef _MSC_VER
#define U64_PRINTF_TYPE uint64_t
#define I64_PRINTF_TYPE int64_t
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index 2ae81bf18d..1ee240fb0d 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -887,7 +887,7 @@ static void
test_container_order_functions(void *arg)
{
int lst[25], n = 0;
- unsigned int lst_2[25];
+ uint32_t lst_2[25];
// int a=12,b=24,c=25,d=60,e=77;
#define median() median_int(lst, n)
@@ -933,6 +933,31 @@ test_container_order_functions(void *arg)
#undef third_quartile
+ double dbls[] = { 1.0, 10.0, 100.0, 1e4, 1e5, 1e6 };
+ tt_double_eq(1.0, median_double(dbls, 1));
+ tt_double_eq(1.0, median_double(dbls, 2));
+ tt_double_eq(10.0, median_double(dbls, 3));
+ tt_double_eq(10.0, median_double(dbls, 4));
+ tt_double_eq(100.0, median_double(dbls, 5));
+ tt_double_eq(100.0, median_double(dbls, 6));
+
+ time_t times[] = { 5, 10, 20, 25, 15 };
+
+ tt_assert(5 == median_time(times, 1));
+ tt_assert(5 == median_time(times, 2));
+ tt_assert(10 == median_time(times, 3));
+ tt_assert(10 == median_time(times, 4));
+ tt_assert(15 == median_time(times, 5));
+
+ int32_t int32s[] = { -5, -10, -50, 100 };
+ tt_int_op(-5, ==, median_int32(int32s, 1));
+ tt_int_op(-10, ==, median_int32(int32s, 2));
+ tt_int_op(-10, ==, median_int32(int32s, 3));
+ tt_int_op(-10, ==, median_int32(int32s, 4));
+
+ long longs[] = { -30, 30, 100, -100, 7 };
+ tt_int_op(7, ==, find_nth_long(longs, 5, 2));
+
done:
;
}
@@ -1078,6 +1103,129 @@ test_container_fp_pair_map(void *arg)
tor_free(v105);
}
+static void
+test_container_smartlist_most_frequent(void *arg)
+{
+ (void) arg;
+ smartlist_t *sl = smartlist_new();
+
+ int count = -1;
+ const char *cp;
+
+ cp = smartlist_get_most_frequent_string_(sl, &count);
+ tt_int_op(count, ==, 0);
+ tt_ptr_op(cp, ==, NULL);
+
+ /* String must be sorted before we call get_most_frequent */
+ smartlist_split_string(sl, "abc:def:ghi", ":", 0, 0);
+
+ cp = smartlist_get_most_frequent_string_(sl, &count);
+ tt_int_op(count, ==, 1);
+ tt_str_op(cp, ==, "ghi"); /* Ties broken in favor of later element */
+
+ smartlist_split_string(sl, "def:ghi", ":", 0, 0);
+ smartlist_sort_strings(sl);
+
+ cp = smartlist_get_most_frequent_string_(sl, &count);
+ tt_int_op(count, ==, 2);
+ tt_ptr_op(cp, !=, NULL);
+ tt_str_op(cp, ==, "ghi"); /* Ties broken in favor of later element */
+
+ smartlist_split_string(sl, "def:abc:qwop", ":", 0, 0);
+ smartlist_sort_strings(sl);
+
+ cp = smartlist_get_most_frequent_string_(sl, &count);
+ tt_int_op(count, ==, 3);
+ tt_ptr_op(cp, !=, NULL);
+ tt_str_op(cp, ==, "def"); /* No tie */
+
+ done:
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+}
+
+static void
+test_container_smartlist_sort_ptrs(void *arg)
+{
+ (void)arg;
+ int array[10];
+ int *arrayptrs[11];
+ smartlist_t *sl = smartlist_new();
+ unsigned i=0, j;
+
+ for (j = 0; j < ARRAY_LENGTH(array); ++j) {
+ smartlist_add(sl, &array[j]);
+ arrayptrs[i++] = &array[j];
+ if (j == 5) {
+ smartlist_add(sl, &array[j]);
+ arrayptrs[i++] = &array[j];
+ }
+ }
+
+ for (i = 0; i < 10; ++i) {
+ smartlist_shuffle(sl);
+ smartlist_sort_pointers(sl);
+ for (j = 0; j < ARRAY_LENGTH(arrayptrs); ++j) {
+ tt_ptr_op(smartlist_get(sl, j), ==, arrayptrs[j]);
+ }
+ }
+
+ done:
+ smartlist_free(sl);
+}
+
+static void
+test_container_smartlist_strings_eq(void *arg)
+{
+ (void)arg;
+ smartlist_t *sl1 = smartlist_new();
+ smartlist_t *sl2 = smartlist_new();
+#define EQ_SHOULD_SAY(s1,s2,val) \
+ do { \
+ SMARTLIST_FOREACH(sl1, char *, cp, tor_free(cp)); \
+ SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp)); \
+ smartlist_clear(sl1); \
+ smartlist_clear(sl2); \
+ smartlist_split_string(sl1, (s1), ":", 0, 0); \
+ smartlist_split_string(sl2, (s2), ":", 0, 0); \
+ tt_int_op((val), OP_EQ, smartlist_strings_eq(sl1, sl2)); \
+ } while (0)
+
+ /* Both NULL, so equal */
+ tt_int_op(1, ==, smartlist_strings_eq(NULL, NULL));
+
+ /* One NULL, not equal. */
+ tt_int_op(0, ==, smartlist_strings_eq(NULL, sl1));
+ tt_int_op(0, ==, smartlist_strings_eq(sl1, NULL));
+
+ /* Both empty, both equal. */
+ EQ_SHOULD_SAY("", "", 1);
+
+ /* One empty, not equal */
+ EQ_SHOULD_SAY("", "ab", 0);
+ EQ_SHOULD_SAY("", "xy:z", 0);
+ EQ_SHOULD_SAY("abc", "", 0);
+ EQ_SHOULD_SAY("abc:cd", "", 0);
+
+ /* Different lengths, not equal. */
+ EQ_SHOULD_SAY("hello:world", "hello", 0);
+ EQ_SHOULD_SAY("hello", "hello:friends", 0);
+
+ /* Same lengths, not equal */
+ EQ_SHOULD_SAY("Hello:world", "goodbye:world", 0);
+ EQ_SHOULD_SAY("Hello:world", "Hello:stars", 0);
+
+ /* Actually equal */
+ EQ_SHOULD_SAY("ABC", "ABC", 1);
+ EQ_SHOULD_SAY(" ab : cd : e", " ab : cd : e", 1);
+
+ done:
+ SMARTLIST_FOREACH(sl1, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
+ smartlist_free(sl1);
+ smartlist_free(sl2);
+}
+
#define CONTAINER_LEGACY(name) \
{ #name, test_container_ ## name , 0, NULL, NULL }
@@ -1099,6 +1247,9 @@ struct testcase_t container_tests[] = {
CONTAINER_LEGACY(order_functions),
CONTAINER(di_map, 0),
CONTAINER_LEGACY(fp_pair_map),
+ CONTAINER(smartlist_most_frequent, 0),
+ CONTAINER(smartlist_sort_ptrs, 0),
+ CONTAINER(smartlist_strings_eq, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c
index bd91aecd94..7b439d490d 100644
--- a/src/test/test_controller_events.c
+++ b/src/test/test_controller_events.c
@@ -395,12 +395,12 @@ test_cntev_event_mask(void *arg)
{ #name, test_cntev_ ## name, flags, 0, NULL }
struct testcase_t controller_event_tests[] = {
- TEST(bucket_note_empty, 0),
- TEST(bucket_millis_empty, 0),
- TEST(sum_up_cell_stats, 0),
- TEST(append_cell_stats, 0),
- TEST(format_cell_stats, 0),
- TEST(event_mask, 0),
+ TEST(bucket_note_empty, TT_FORK),
+ TEST(bucket_millis_empty, TT_FORK),
+ TEST(sum_up_cell_stats, TT_FORK),
+ TEST(append_cell_stats, TT_FORK),
+ TEST(format_cell_stats, TT_FORK),
+ TEST(event_mask, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 35bd8ea166..855746e749 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -24,6 +24,7 @@
#include "routerkeys.h"
#include "routerlist.h"
#include "routerparse.h"
+#include "routerset.h"
#include "test.h"
#include "torcert.h"
@@ -2979,6 +2980,281 @@ test_dir_fmt_control_ns(void *arg)
tor_free(s);
}
+static int mock_get_options_calls = 0;
+static or_options_t *mock_options = NULL;
+
+static void
+reset_options(or_options_t *options, int *get_options_calls)
+{
+ memset(options, 0, sizeof(or_options_t));
+ options->TestingTorNetwork = 1;
+
+ *get_options_calls = 0;
+}
+
+static const or_options_t *
+mock_get_options(void)
+{
+ ++mock_get_options_calls;
+ tor_assert(mock_options);
+ return mock_options;
+}
+
+static void
+reset_routerstatus(routerstatus_t *rs,
+ const char *hex_identity_digest,
+ int32_t ipv4_addr)
+{
+ memset(rs, 0, sizeof(routerstatus_t));
+ base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
+ hex_identity_digest, HEX_DIGEST_LEN);
+ /* A zero address matches everything, so the address needs to be set.
+ * But the specific value is irrelevant. */
+ rs->addr = ipv4_addr;
+}
+
+#define ROUTER_A_ID_STR "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+#define ROUTER_A_IPV4 0xAA008801
+#define ROUTER_B_ID_STR "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+#define ROUTER_B_IPV4 0xBB008801
+
+#define ROUTERSET_ALL_STR "*"
+#define ROUTERSET_A_STR ROUTER_A_ID_STR
+#define ROUTERSET_NONE_STR ""
+
+/*
+ * Test that dirserv_set_routerstatus_testing sets router flags correctly
+ * Using "*" sets flags on A and B
+ * Using "A" sets flags on A
+ * Using "" sets flags on Neither
+ * If the router is not included:
+ * - if *Strict is set, the flag is set to 0,
+ * - otherwise, the flag is not modified. */
+static void
+test_dir_dirserv_set_routerstatus_testing(void *arg)
+{
+ (void)arg;
+
+ /* Init options */
+ mock_options = malloc(sizeof(or_options_t));
+ reset_options(mock_options, &mock_get_options_calls);
+
+ MOCK(get_options, mock_get_options);
+
+ /* Init routersets */
+ routerset_t *routerset_all = routerset_new();
+ routerset_parse(routerset_all, ROUTERSET_ALL_STR, "All routers");
+
+ routerset_t *routerset_a = routerset_new();
+ routerset_parse(routerset_a, ROUTERSET_A_STR, "Router A only");
+
+ routerset_t *routerset_none = routerset_new();
+ /* Routersets are empty when provided by routerset_new(),
+ * so this is not strictly necessary */
+ routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
+
+ /* Init routerstatuses */
+ routerstatus_t *rs_a = malloc(sizeof(routerstatus_t));
+ reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
+
+ routerstatus_t *rs_b = malloc(sizeof(routerstatus_t));
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ /* Sanity check that routersets correspond to routerstatuses.
+ * Return values are {2, 3, 4} */
+
+ /* We want 3 ("*" means match all addresses) */
+ tt_assert(routerset_contains_routerstatus(routerset_all, rs_a, 0) == 3);
+ tt_assert(routerset_contains_routerstatus(routerset_all, rs_b, 0) == 3);
+
+ /* We want 4 (match id_digest [or nickname]) */
+ tt_assert(routerset_contains_routerstatus(routerset_a, rs_a, 0) == 4);
+ tt_assert(routerset_contains_routerstatus(routerset_a, rs_b, 0) == 0);
+
+ tt_assert(routerset_contains_routerstatus(routerset_none, rs_a, 0) == 0);
+ tt_assert(routerset_contains_routerstatus(routerset_none, rs_b, 0) == 0);
+
+ /* Check that "*" sets flags on all routers: Exit
+ * Check the flags aren't being confused with each other */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_all;
+ mock_options->TestingDirAuthVoteExitIsStrict = 0;
+
+ dirserv_set_routerstatus_testing(rs_a);
+ tt_assert(mock_get_options_calls == 1);
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 2);
+
+ tt_assert(rs_a->is_exit == 1);
+ tt_assert(rs_b->is_exit == 1);
+ /* Be paranoid - check no other flags are set */
+ tt_assert(rs_a->is_possible_guard == 0);
+ tt_assert(rs_b->is_possible_guard == 0);
+ tt_assert(rs_a->is_hs_dir == 0);
+ tt_assert(rs_b->is_hs_dir == 0);
+
+ /* Check that "*" sets flags on all routers: Guard & HSDir
+ * Cover the remaining flags in one test */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteGuard = routerset_all;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 0;
+ mock_options->TestingDirAuthVoteHSDir = routerset_all;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
+
+ dirserv_set_routerstatus_testing(rs_a);
+ tt_assert(mock_get_options_calls == 1);
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 2);
+
+ tt_assert(rs_a->is_possible_guard == 1);
+ tt_assert(rs_b->is_possible_guard == 1);
+ tt_assert(rs_a->is_hs_dir == 1);
+ tt_assert(rs_b->is_hs_dir == 1);
+ /* Be paranoid - check exit isn't set */
+ tt_assert(rs_a->is_exit == 0);
+ tt_assert(rs_b->is_exit == 0);
+
+ /* Check routerset A sets all flags on router A,
+ * but leaves router B unmodified */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_a;
+ mock_options->TestingDirAuthVoteExitIsStrict = 0;
+ mock_options->TestingDirAuthVoteGuard = routerset_a;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 0;
+ mock_options->TestingDirAuthVoteHSDir = routerset_a;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
+
+ dirserv_set_routerstatus_testing(rs_a);
+ tt_assert(mock_get_options_calls == 1);
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 2);
+
+ tt_assert(rs_a->is_exit == 1);
+ tt_assert(rs_b->is_exit == 0);
+ tt_assert(rs_a->is_possible_guard == 1);
+ tt_assert(rs_b->is_possible_guard == 0);
+ tt_assert(rs_a->is_hs_dir == 1);
+ tt_assert(rs_b->is_hs_dir == 0);
+
+ /* Check routerset A unsets all flags on router B when Strict is set */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_a;
+ mock_options->TestingDirAuthVoteExitIsStrict = 1;
+ mock_options->TestingDirAuthVoteGuard = routerset_a;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 1;
+ mock_options->TestingDirAuthVoteHSDir = routerset_a;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 1;
+
+ rs_b->is_exit = 1;
+ rs_b->is_possible_guard = 1;
+ rs_b->is_hs_dir = 1;
+
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 1);
+
+ tt_assert(rs_b->is_exit == 0);
+ tt_assert(rs_b->is_possible_guard == 0);
+ tt_assert(rs_b->is_hs_dir == 0);
+
+ /* Check routerset A doesn't modify flags on router B without Strict set */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_a;
+ mock_options->TestingDirAuthVoteExitIsStrict = 0;
+ mock_options->TestingDirAuthVoteGuard = routerset_a;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 0;
+ mock_options->TestingDirAuthVoteHSDir = routerset_a;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
+
+ rs_b->is_exit = 1;
+ rs_b->is_possible_guard = 1;
+ rs_b->is_hs_dir = 1;
+
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 1);
+
+ tt_assert(rs_b->is_exit == 1);
+ tt_assert(rs_b->is_possible_guard == 1);
+ tt_assert(rs_b->is_hs_dir == 1);
+
+ /* Check the empty routerset zeroes all flags
+ * on routers A & B with Strict set */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_none;
+ mock_options->TestingDirAuthVoteExitIsStrict = 1;
+ mock_options->TestingDirAuthVoteGuard = routerset_none;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 1;
+ mock_options->TestingDirAuthVoteHSDir = routerset_none;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 1;
+
+ rs_b->is_exit = 1;
+ rs_b->is_possible_guard = 1;
+ rs_b->is_hs_dir = 1;
+
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 1);
+
+ tt_assert(rs_b->is_exit == 0);
+ tt_assert(rs_b->is_possible_guard == 0);
+ tt_assert(rs_b->is_hs_dir == 0);
+
+ /* Check the empty routerset doesn't modify any flags
+ * on A or B without Strict set */
+ reset_options(mock_options, &mock_get_options_calls);
+ reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
+ reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
+
+ mock_options->TestingDirAuthVoteExit = routerset_none;
+ mock_options->TestingDirAuthVoteExitIsStrict = 0;
+ mock_options->TestingDirAuthVoteGuard = routerset_none;
+ mock_options->TestingDirAuthVoteGuardIsStrict = 0;
+ mock_options->TestingDirAuthVoteHSDir = routerset_none;
+ mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
+
+ rs_b->is_exit = 1;
+ rs_b->is_possible_guard = 1;
+ rs_b->is_hs_dir = 1;
+
+ dirserv_set_routerstatus_testing(rs_a);
+ tt_assert(mock_get_options_calls == 1);
+ dirserv_set_routerstatus_testing(rs_b);
+ tt_assert(mock_get_options_calls == 2);
+
+ tt_assert(rs_a->is_exit == 0);
+ tt_assert(rs_a->is_possible_guard == 0);
+ tt_assert(rs_a->is_hs_dir == 0);
+ tt_assert(rs_b->is_exit == 1);
+ tt_assert(rs_b->is_possible_guard == 1);
+ tt_assert(rs_b->is_hs_dir == 1);
+
+ done:
+ free(mock_options);
+ mock_options = NULL;
+
+ UNMOCK(get_options);
+
+ routerset_free(routerset_all);
+ routerset_free(routerset_a);
+ routerset_free(routerset_none);
+
+ free(rs_a);
+ free(rs_b);
+}
+
static void
test_dir_http_handling(void *args)
{
@@ -3244,6 +3520,7 @@ struct testcase_t dir_tests[] = {
DIR_LEGACY(clip_unmeasured_bw_kb),
DIR_LEGACY(clip_unmeasured_bw_kb_alt),
DIR(fmt_control_ns, 0),
+ DIR(dirserv_set_routerstatus_testing, 0),
DIR(http_handling, 0),
DIR(purpose_needs_anonymity, 0),
DIR(fetch_type, 0),
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index 6d01798a63..126e211858 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -102,13 +102,11 @@ static char *received_msg = NULL;
/** Mock function for send_control_event_string
*/
static void
-send_control_event_string_replacement(uint16_t event, event_format_t which,
- const char *msg)
+queue_control_event_string_replacement(uint16_t event, char *msg)
{
(void) event;
- (void) which;
tor_free(received_msg);
- received_msg = tor_strdup(msg);
+ received_msg = msg;
}
/** Mock function for node_describe_longname_by_id, it returns either
@@ -141,8 +139,8 @@ test_hs_desc_event(void *arg)
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
(void) arg;
- MOCK(send_control_event_string,
- send_control_event_string_replacement);
+ MOCK(queue_control_event_string,
+ queue_control_event_string_replacement);
MOCK(node_describe_longname_by_id,
node_describe_longname_by_id_replacement);
@@ -225,7 +223,7 @@ test_hs_desc_event(void *arg)
smartlist_free(rend_query.hsdirs_fp);
done:
- UNMOCK(send_control_event_string);
+ UNMOCK(queue_control_event_string);
UNMOCK(node_describe_longname_by_id);
tor_free(received_msg);
}
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 996ef8666b..6c9aefc487 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -333,15 +333,13 @@ static uint16_t controlevent_event = 0;
static smartlist_t *controlevent_msgs = NULL;
static void
-send_control_event_string_replacement(uint16_t event, event_format_t which,
- const char *msg)
+queue_control_event_string_replacement(uint16_t event, char *msg)
{
- (void) which;
++controlevent_n;
controlevent_event = event;
if (!controlevent_msgs)
controlevent_msgs = smartlist_new();
- smartlist_add(controlevent_msgs, tor_strdup(msg));
+ smartlist_add(controlevent_msgs, msg);
}
/* Test the configure_proxy() function. */
@@ -360,8 +358,8 @@ test_pt_configure_proxy(void *arg)
tor_process_handle_destroy_replacement);
MOCK(get_or_state,
get_or_state_replacement);
- MOCK(send_control_event_string,
- send_control_event_string_replacement);
+ MOCK(queue_control_event_string,
+ queue_control_event_string_replacement);
control_testing_set_global_event_mask(EVENT_TRANSPORT_LAUNCHED);
@@ -435,7 +433,7 @@ test_pt_configure_proxy(void *arg)
UNMOCK(tor_get_lines_from_handle);
UNMOCK(tor_process_handle_destroy);
UNMOCK(get_or_state);
- UNMOCK(send_control_event_string);
+ UNMOCK(queue_control_event_string);
if (controlevent_msgs) {
SMARTLIST_FOREACH(controlevent_msgs, char *, cp, tor_free(cp));
smartlist_free(controlevent_msgs);
diff --git a/src/test/test_threads.c b/src/test/test_threads.c
index 2ac08d4d28..35f5dc8ea3 100644
--- a/src/test/test_threads.c
+++ b/src/test/test_threads.c
@@ -28,7 +28,7 @@ static unsigned long thread_fn_tid1, thread_fn_tid2;
static void thread_test_func_(void* _s) ATTR_NORETURN;
/** How many iterations have the threads in the unit test run? */
-static int t1_count = 0, t2_count = 0;
+static tor_threadlocal_t count;
/** Helper function for threading unit tests: This function runs in a
* subthread. It grabs its own mutex (start1 or start2) to make sure that it
@@ -38,19 +38,19 @@ static void
thread_test_func_(void* _s)
{
char *s = _s;
- int i, *count;
+ int i;
tor_mutex_t *m;
char buf[64];
char **cp;
+ int *mycount = tor_malloc_zero(sizeof(int));
+ tor_threadlocal_set(&count, mycount);
if (!strcmp(s, "thread 1")) {
m = thread_test_start1_;
cp = &thread1_name_;
- count = &t1_count;
thread_fn_tid1 = tor_get_thread_id();
} else {
m = thread_test_start2_;
cp = &thread2_name_;
- count = &t2_count;
thread_fn_tid2 = tor_get_thread_id();
}
@@ -62,8 +62,10 @@ thread_test_func_(void* _s)
for (i=0; i<10000; ++i) {
tor_mutex_acquire(thread_test_mutex_);
strmap_set(thread_test_strmap_, "last to run", *cp);
- ++*count;
tor_mutex_release(thread_test_mutex_);
+ int *tls_count = tor_threadlocal_get(&count);
+ tor_assert(tls_count == mycount);
+ ++*tls_count;
}
tor_mutex_acquire(thread_test_mutex_);
strmap_set(thread_test_strmap_, s, *cp);
@@ -89,6 +91,7 @@ test_threads_basic(void *arg)
tv.tv_usec=100*1000;
#endif
(void) arg;
+ tt_int_op(tor_threadlocal_init(&count), OP_EQ, 0);
set_main_thread();
@@ -128,7 +131,6 @@ test_threads_basic(void *arg)
tor_mutex_free(thread_test_mutex_);
if (timedout) {
- printf("\nTimed out: %d %d", t1_count, t2_count);
tt_assert(strmap_get(thread_test_strmap_, "thread 1"));
tt_assert(strmap_get(thread_test_strmap_, "thread 2"));
tt_assert(!timedout);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 2bffb17bfd..8b4513d34c 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -3611,6 +3611,50 @@ test_util_di_ops(void *arg)
;
}
+static void
+test_util_di_map(void *arg)
+{
+ (void)arg;
+ di_digest256_map_t *dimap = NULL;
+ uint8_t key1[] = "Robert Anton Wilson ";
+ uint8_t key2[] = "Martin Gardner, _Fads&fallacies";
+ uint8_t key3[] = "Tom Lehrer, _Be Prepared_. ";
+ uint8_t key4[] = "Ursula Le Guin,_A Wizard of... ";
+
+ char dflt_entry[] = "'You have made a good beginning', but no more";
+
+ tt_int_op(32, ==, sizeof(key1));
+ tt_int_op(32, ==, sizeof(key2));
+ tt_int_op(32, ==, sizeof(key3));
+
+ tt_ptr_op(dflt_entry, ==, dimap_search(dimap, key1, dflt_entry));
+
+ char *str1 = tor_strdup("You are precisely as big as what you love"
+ " and precisely as small as what you allow"
+ " to annoy you.");
+ char *str2 = tor_strdup("Let us hope that Lysenko's success in Russia will"
+ " serve for many generations to come as another"
+ " reminder to the world of how quickly and easily"
+ " a science can be corrupted when ignorant"
+ " political leaders deem themselves competent"
+ " to arbitrate scientific disputes");
+ char *str3 = tor_strdup("Don't write naughty words on walls "
+ "if you can't spell.");
+
+ dimap_add_entry(&dimap, key1, str1);
+ dimap_add_entry(&dimap, key2, str2);
+ dimap_add_entry(&dimap, key3, str3);
+
+ tt_ptr_op(str1, ==, dimap_search(dimap, key1, dflt_entry));
+ tt_ptr_op(str3, ==, dimap_search(dimap, key3, dflt_entry));
+ tt_ptr_op(str2, ==, dimap_search(dimap, key2, dflt_entry));
+ tt_ptr_op(dflt_entry, ==, dimap_search(dimap, key4, dflt_entry));
+
+ done:
+ dimap_free(dimap, tor_free_);
+}
+
+
/**
* Test counting high bits
*/
@@ -4347,6 +4391,30 @@ test_util_writepid(void *arg)
tor_free(contents);
}
+static void
+test_util_get_avail_disk_space(void *arg)
+{
+ (void) arg;
+ int64_t val;
+
+ /* No answer for nonexistent directory */
+ val = tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
+ tt_i64_op(val, OP_EQ, -1);
+
+ /* Try the current directory */
+ val = tor_get_avail_disk_space(".");
+
+#if !defined(HAVE_STATVFS) && !defined(_WIN32)
+ tt_i64_op(val, OP_EQ, -1); /* You don't have an implementation for this */
+#else
+ tt_i64_op(val, OP_GT, 0); /* You have some space. */
+ tt_i64_op(val, OP_LT, ((int64_t)1)<<56); /* You don't have a zebibyte */
+#endif
+
+ done:
+ ;
+}
+
struct testcase_t util_tests[] = {
UTIL_LEGACY(time),
UTIL_TEST(parse_http_time, 0),
@@ -4371,6 +4439,7 @@ struct testcase_t util_tests[] = {
UTIL_LEGACY(path_is_relative),
UTIL_LEGACY(strtok),
UTIL_LEGACY(di_ops),
+ UTIL_TEST(di_map, 0),
UTIL_TEST(round_to_next_multiple_of, 0),
UTIL_TEST(laplace, 0),
UTIL_TEST(find_str_at_start_of_line, 0),
@@ -4414,6 +4483,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(hostname_validation, 0),
UTIL_TEST(ipv4_validation, 0),
UTIL_TEST(writepid, 0),
+ UTIL_TEST(get_avail_disk_space, 0),
END_OF_TESTCASES
};
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 7f387c0b3d..441024bd7d 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -14,6 +14,7 @@ const char tor_git_revision[] = "";
#include "orconfig.h"
#include "or.h"
+#include "control.h"
#include "config.h"
#include "rephist.h"
#include "backtrace.h"
@@ -237,6 +238,7 @@ main(int c, const char **v)
update_approx_time(time(NULL));
options = options_new();
tor_threads_init();
+ control_initialize_event_queue();
init_logging(1);
configure_backtrace_handler(get_version());