1 /* Copyright (c) 2013-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define CIRCUITMUX_PRIVATE
5 #define CIRCUITMUX_EWMA_PRIVATE
7 #include "core/or/or.h"
8 #include "core/or/circuitmux.h"
9 #include "core/or/circuitmux_ewma.h"
11 #include "test/fakechans.h"
12 #include "test/fakecircs.h"
13 #include "test/test.h"
16 test_cmux_ewma_active_circuit(void *arg
)
18 circuitmux_t cmux
; /* garbage */
19 circuitmux_policy_data_t
*pol_data
= NULL
;
20 circuit_t circ
; /* garbage */
21 circuitmux_policy_circ_data_t
*circ_data
= NULL
;
25 pol_data
= ewma_policy
.alloc_cmux_data(&cmux
);
27 circ_data
= ewma_policy
.alloc_circ_data(&cmux
, pol_data
, &circ
,
28 CELL_DIRECTION_OUT
, 42);
31 /* Get EWMA specific objects. */
33 /* Make circuit active. */
34 ewma_policy
.notify_circ_active(&cmux
, pol_data
, &circ
, circ_data
);
36 circuit_t
*entry
= ewma_policy
.pick_active_circuit(&cmux
, pol_data
);
37 tt_mem_op(entry
, OP_EQ
, &circ
, sizeof(circ
));
40 ewma_policy
.free_circ_data(&cmux
, pol_data
, &circ
, circ_data
);
41 ewma_policy
.free_cmux_data(&cmux
, pol_data
);
45 test_cmux_ewma_xmit_cell(void *arg
)
47 circuitmux_t cmux
; /* garbage */
48 circuitmux_policy_data_t
*pol_data
= NULL
;
49 circuit_t circ
; /* garbage */
50 circuitmux_policy_circ_data_t
*circ_data
= NULL
;
51 ewma_policy_data_t
*ewma_pol_data
;
52 ewma_policy_circ_data_t
*ewma_data
;
53 double old_cell_count
;
57 pol_data
= ewma_policy
.alloc_cmux_data(&cmux
);
59 circ_data
= ewma_policy
.alloc_circ_data(&cmux
, pol_data
, &circ
,
60 CELL_DIRECTION_OUT
, 42);
62 ewma_pol_data
= TO_EWMA_POL_DATA(pol_data
);
63 ewma_data
= TO_EWMA_POL_CIRC_DATA(circ_data
);
65 /* Make circuit active. */
66 ewma_policy
.notify_circ_active(&cmux
, pol_data
, &circ
, circ_data
);
68 /* Move back in time the last time we calibrated so we scale the active
69 * circuit when emitting a cell. */
70 ewma_pol_data
->active_circuit_pqueue_last_recalibrated
-= 100;
71 ewma_data
->cell_ewma
.last_adjusted_tick
=
72 ewma_pol_data
->active_circuit_pqueue_last_recalibrated
;
74 /* Grab old cell count. */
75 old_cell_count
= ewma_data
->cell_ewma
.cell_count
;
77 ewma_policy
.notify_xmit_cells(&cmux
, pol_data
, &circ
, circ_data
, 1);
79 /* Our old cell count should be lower to what we have since we just emitted
80 * a cell and thus we scale. */
81 tt_double_op(old_cell_count
, OP_LT
, ewma_data
->cell_ewma
.cell_count
);
84 ewma_policy
.free_circ_data(&cmux
, pol_data
, &circ
, circ_data
);
85 ewma_policy
.free_cmux_data(&cmux
, pol_data
);
89 test_cmux_ewma_notify_circ(void *arg
)
91 circuitmux_t cmux
; /* garbage */
92 circuitmux_policy_data_t
*pol_data
= NULL
;
93 circuit_t circ
; /* garbage */
94 circuitmux_policy_circ_data_t
*circ_data
= NULL
;
95 const ewma_policy_data_t
*ewma_pol_data
;
99 pol_data
= ewma_policy
.alloc_cmux_data(&cmux
);
101 circ_data
= ewma_policy
.alloc_circ_data(&cmux
, pol_data
, &circ
,
102 CELL_DIRECTION_OUT
, 42);
103 tt_assert(circ_data
);
105 /* Currently, notify_circ_active() ignores cmux and circ. They can not be
106 * NULL so it is fine to pass garbage. */
107 ewma_policy
.notify_circ_active(&cmux
, pol_data
, &circ
, circ_data
);
109 /* We should have an active circuit in the queue so its EWMA value can be
111 ewma_pol_data
= TO_EWMA_POL_DATA(pol_data
);
112 tt_int_op(smartlist_len(ewma_pol_data
->active_circuit_pqueue
), OP_EQ
, 1);
113 tt_uint_op(ewma_pol_data
->active_circuit_pqueue_last_recalibrated
, OP_NE
, 0);
115 ewma_policy
.notify_circ_inactive(&cmux
, pol_data
, &circ
, circ_data
);
116 /* Should be removed from the active queue. */
117 ewma_pol_data
= TO_EWMA_POL_DATA(pol_data
);
118 tt_int_op(smartlist_len(ewma_pol_data
->active_circuit_pqueue
), OP_EQ
, 0);
119 tt_uint_op(ewma_pol_data
->active_circuit_pqueue_last_recalibrated
, OP_NE
, 0);
122 ewma_policy
.free_circ_data(&cmux
, pol_data
, &circ
, circ_data
);
123 ewma_policy
.free_cmux_data(&cmux
, pol_data
);
127 test_cmux_ewma_policy_circ_data(void *arg
)
129 circuitmux_t cmux
; /* garbage */
130 circuitmux_policy_data_t pol_data
; /* garbage */
131 circuit_t circ
; /* garbage */
132 circuitmux_policy_circ_data_t
*circ_data
= NULL
;
133 const ewma_policy_circ_data_t
*ewma_data
;
137 /* Currently, alloc_circ_data() ignores every parameter _except_ the cell
138 * direction so it is OK to pass garbage. They can not be NULL. */
139 circ_data
= ewma_policy
.alloc_circ_data(&cmux
, &pol_data
, &circ
,
140 CELL_DIRECTION_OUT
, 42);
141 tt_assert(circ_data
);
142 tt_uint_op(circ_data
->magic
, OP_EQ
, EWMA_POL_CIRC_DATA_MAGIC
);
144 ewma_data
= TO_EWMA_POL_CIRC_DATA(circ_data
);
145 tt_mem_op(ewma_data
->circ
, OP_EQ
, &circ
, sizeof(circuit_t
));
146 tt_double_op(ewma_data
->cell_ewma
.cell_count
, OP_LE
, 0.0);
147 tt_int_op(ewma_data
->cell_ewma
.heap_index
, OP_EQ
, -1);
148 tt_uint_op(ewma_data
->cell_ewma
.is_for_p_chan
, OP_EQ
, 0);
149 ewma_policy
.free_circ_data(&cmux
, &pol_data
, &circ
, circ_data
);
151 circ_data
= ewma_policy
.alloc_circ_data(&cmux
, &pol_data
, &circ
,
152 CELL_DIRECTION_IN
, 42);
153 tt_assert(circ_data
);
154 tt_uint_op(circ_data
->magic
, OP_EQ
, EWMA_POL_CIRC_DATA_MAGIC
);
156 ewma_data
= TO_EWMA_POL_CIRC_DATA(circ_data
);
157 tt_mem_op(ewma_data
->circ
, OP_EQ
, &circ
, sizeof(circuit_t
));
158 tt_double_op(ewma_data
->cell_ewma
.cell_count
, OP_LE
, 0.0);
159 tt_int_op(ewma_data
->cell_ewma
.heap_index
, OP_EQ
, -1);
160 tt_uint_op(ewma_data
->cell_ewma
.is_for_p_chan
, OP_EQ
, 1);
163 ewma_policy
.free_circ_data(&cmux
, &pol_data
, &circ
, circ_data
);
167 test_cmux_ewma_policy_data(void *arg
)
169 circuitmux_t cmux
; /* garbage. */
170 circuitmux_policy_data_t
*pol_data
= NULL
;
171 const ewma_policy_data_t
*ewma_pol_data
;
175 pol_data
= ewma_policy
.alloc_cmux_data(&cmux
);
177 tt_uint_op(pol_data
->magic
, OP_EQ
, EWMA_POL_DATA_MAGIC
);
179 /* Test EWMA object. */
180 ewma_pol_data
= TO_EWMA_POL_DATA(pol_data
);
181 tt_assert(ewma_pol_data
->active_circuit_pqueue
);
182 tt_uint_op(ewma_pol_data
->active_circuit_pqueue_last_recalibrated
, OP_NE
, 0);
185 ewma_policy
.free_cmux_data(&cmux
, pol_data
);
189 cmux_ewma_setup_test(const struct testcase_t
*tc
)
195 cell_ewma_initialize_ticks();
196 cmux_ewma_set_options(NULL
, NULL
);
202 cmux_ewma_cleanup_test(const struct testcase_t
*tc
, void *ptr
)
207 circuitmux_ewma_free_all();
212 static struct testcase_setup_t cmux_ewma_test_setup
= {
213 .setup_fn
= cmux_ewma_setup_test
,
214 .cleanup_fn
= cmux_ewma_cleanup_test
,
217 #define TEST_CMUX_EWMA(name) \
218 { #name, test_cmux_ewma_##name, TT_FORK, &cmux_ewma_test_setup, NULL }
220 struct testcase_t circuitmux_ewma_tests
[] = {
221 TEST_CMUX_EWMA(active_circuit
),
222 TEST_CMUX_EWMA(policy_data
),
223 TEST_CMUX_EWMA(policy_circ_data
),
224 TEST_CMUX_EWMA(notify_circ
),
225 TEST_CMUX_EWMA(xmit_cell
),