dns: Wake up a dormant tor with a DNSPort request
[tor.git] / src / test / test_circuitstats.c
blob889adc152303f1d3f46655f8db691e04a9b114b0
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define CIRCUITBUILD_PRIVATE
5 #define CIRCUITSTATS_PRIVATE
6 #define CIRCUITLIST_PRIVATE
7 #define CHANNEL_FILE_PRIVATE
9 #include "core/or/or.h"
10 #include "test/test.h"
11 #include "test/test_helpers.h"
12 #include "test/log_test_helpers.h"
13 #include "app/config/config.h"
14 #include "core/or/circuitlist.h"
15 #include "core/or/circuitbuild.h"
16 #include "core/or/circuitstats.h"
17 #include "core/or/circuituse.h"
18 #include "core/or/channel.h"
20 #include "core/or/crypt_path_st.h"
21 #include "core/or/extend_info_st.h"
22 #include "core/or/origin_circuit_st.h"
24 static origin_circuit_t *add_opened_threehop(void);
25 static origin_circuit_t *build_unopened_fourhop(struct timeval);
26 static origin_circuit_t *subtest_fourhop_circuit(struct timeval, int);
28 static int marked_for_close;
29 /* Mock function because we are not trying to test the close circuit that does
30 * an awful lot of checks on the circuit object. */
31 static void
32 mock_circuit_mark_for_close(circuit_t *circ, int reason, int line,
33 const char *file)
35 (void) circ;
36 (void) reason;
37 (void) line;
38 (void) file;
39 marked_for_close = 1;
40 return;
43 static origin_circuit_t *
44 add_opened_threehop(void)
46 struct timeval circ_start_time;
47 memset(&circ_start_time, 0, sizeof(circ_start_time));
48 extend_info_t fakehop;
49 memset(&fakehop, 0, sizeof(fakehop));
50 extend_info_t *fakehop_list[DEFAULT_ROUTE_LEN] = {&fakehop,
51 &fakehop,
52 &fakehop};
54 return new_test_origin_circuit(true,
55 circ_start_time,
56 DEFAULT_ROUTE_LEN,
57 fakehop_list);
60 static origin_circuit_t *
61 build_unopened_fourhop(struct timeval circ_start_time)
63 extend_info_t fakehop;
64 memset(&fakehop, 0, sizeof(fakehop));
65 extend_info_t *fakehop_list[4] = {&fakehop,
66 &fakehop,
67 &fakehop,
68 &fakehop};
70 return new_test_origin_circuit(false,
71 circ_start_time,
73 fakehop_list);
76 static origin_circuit_t *
77 subtest_fourhop_circuit(struct timeval circ_start_time, int should_timeout)
79 origin_circuit_t *origin_circ = build_unopened_fourhop(circ_start_time);
81 // Now make them open one at a time and call
82 // circuit_build_times_handle_completed_hop();
83 origin_circ->cpath->state = CPATH_STATE_OPEN;
84 circuit_build_times_handle_completed_hop(origin_circ);
85 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 0);
87 origin_circ->cpath->next->state = CPATH_STATE_OPEN;
88 circuit_build_times_handle_completed_hop(origin_circ);
89 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 0);
91 // Third hop: We should count it now.
92 origin_circ->cpath->next->next->state = CPATH_STATE_OPEN;
93 circuit_build_times_handle_completed_hop(origin_circ);
94 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ,
95 !should_timeout); // 1 if counted, 0 otherwise
97 // Fourth hop: Don't double count
98 origin_circ->cpath->next->next->next->state = CPATH_STATE_OPEN;
99 circuit_build_times_handle_completed_hop(origin_circ);
100 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ,
101 !should_timeout);
103 done:
104 return origin_circ;
107 static void
108 test_circuitstats_hoplen(void *arg)
110 /* Plan:
111 * 0. Test no other opened circs (relaxed timeout)
112 * 1. Check >3 hop circ building w/o timeout
113 * 2. Check >3 hop circs w/ timeouts..
115 struct timeval circ_start_time;
116 origin_circuit_t *threehop = NULL;
117 origin_circuit_t *fourhop = NULL;
118 (void)arg;
119 MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
121 circuit_build_times_init(get_circuit_build_times_mutable());
123 // Let's set a close_ms to 2X the initial timeout, so we can
124 // test relaxed functionality (which uses the close_ms timeout)
125 get_circuit_build_times_mutable()->close_ms *= 2;
127 tor_gettimeofday(&circ_start_time);
128 circ_start_time.tv_sec -= 119; // make us hit "relaxed" cutoff
130 // Test 1: Build a fourhop circuit that should get marked
131 // as relaxed and eventually counted by circuit_expire_building
132 // (but not before)
133 fourhop = subtest_fourhop_circuit(circ_start_time, 0);
134 tt_int_op(fourhop->relaxed_timeout, OP_EQ, 0);
135 tt_int_op(marked_for_close, OP_EQ, 0);
136 circuit_expire_building();
137 tt_int_op(marked_for_close, OP_EQ, 0);
138 tt_int_op(fourhop->relaxed_timeout, OP_EQ, 1);
139 TO_CIRCUIT(fourhop)->timestamp_began.tv_sec -= 119;
140 circuit_expire_building();
141 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
142 tt_int_op(marked_for_close, OP_EQ, 1);
144 circuit_free_(TO_CIRCUIT(fourhop));
145 circuit_build_times_reset(get_circuit_build_times_mutable());
147 // Test 2: Add a threehop circuit for non-relaxed timeouts
148 threehop = add_opened_threehop();
150 /* This circuit should not timeout */
151 tor_gettimeofday(&circ_start_time);
152 circ_start_time.tv_sec -= 59;
153 fourhop = subtest_fourhop_circuit(circ_start_time, 0);
154 circuit_expire_building();
155 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
156 tt_int_op(TO_CIRCUIT(fourhop)->purpose, OP_NE,
157 CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
159 circuit_free_((circuit_t *)fourhop);
160 circuit_build_times_reset(get_circuit_build_times_mutable());
162 /* Test 3: This circuit should now time out and get marked as a
163 * measurement circuit, but still get counted (and counted only once)
165 circ_start_time.tv_sec -= 2;
166 fourhop = subtest_fourhop_circuit(circ_start_time, 0);
167 tt_int_op(TO_CIRCUIT(fourhop)->purpose, OP_EQ,
168 CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
169 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
170 circuit_expire_building();
171 tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
173 done:
174 UNMOCK(circuit_mark_for_close_);
175 circuit_free_(TO_CIRCUIT(threehop));
176 circuit_free_(TO_CIRCUIT(fourhop));
177 circuit_build_times_free_timeouts(get_circuit_build_times_mutable());
180 #define TEST_CIRCUITSTATS(name, flags) \
181 { #name, test_##name, (flags), &helper_pubsub_setup, NULL }
183 struct testcase_t circuitstats_tests[] = {
184 TEST_CIRCUITSTATS(circuitstats_hoplen, TT_FORK),
185 END_OF_TESTCASES