Line data Source code
1 : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define ROUTERSET_PRIVATE
5 :
6 : #include "core/or/or.h"
7 : #include "core/or/policies.h"
8 : #include "feature/dirparse/policy_parse.h"
9 : #include "feature/nodelist/nodelist.h"
10 : #include "feature/nodelist/routerset.h"
11 : #include "lib/geoip/geoip.h"
12 :
13 : #include "core/or/addr_policy_st.h"
14 : #include "core/or/extend_info_st.h"
15 : #include "feature/nodelist/node_st.h"
16 : #include "feature/nodelist/routerinfo_st.h"
17 : #include "feature/nodelist/routerstatus_st.h"
18 :
19 : #include "test/test.h"
20 :
21 : /*
22 : * Functional (blackbox) test to determine that each member of the routerset
23 : * is non-NULL
24 : */
25 :
26 : static void
27 1 : test_rset_new(void *arg)
28 : {
29 1 : routerset_t *rs;
30 1 : (void)arg;
31 :
32 1 : rs = routerset_new();
33 :
34 1 : tt_ptr_op(rs, OP_NE, NULL);
35 1 : tt_ptr_op(rs->list, OP_NE, NULL);
36 1 : tt_ptr_op(rs->names, OP_NE, NULL);
37 1 : tt_ptr_op(rs->digests, OP_NE, NULL);
38 1 : tt_ptr_op(rs->policies, OP_NE, NULL);
39 1 : tt_ptr_op(rs->country_names, OP_NE, NULL);
40 :
41 1 : done:
42 1 : routerset_free(rs);
43 1 : }
44 :
45 : /*
46 : * Functional test to strip the braces from a "{xx}" country code string.
47 : */
48 :
49 : static void
50 1 : test_rset_get_countryname(void *arg)
51 : {
52 1 : const char *input;
53 1 : char *name;
54 1 : (void)arg;
55 :
56 : /* strlen(c) < 4 */
57 1 : input = "xxx";
58 1 : name = routerset_get_countryname(input);
59 1 : tt_ptr_op(name, OP_EQ, NULL);
60 1 : tor_free(name);
61 :
62 : /* c[0] != '{' */
63 1 : input = "xxx}";
64 1 : name = routerset_get_countryname(input);
65 1 : tt_ptr_op(name, OP_EQ, NULL);
66 1 : tor_free(name);
67 :
68 : /* c[3] != '}' */
69 1 : input = "{xxx";
70 1 : name = routerset_get_countryname(input);
71 1 : tt_ptr_op(name, OP_EQ, NULL);
72 1 : tor_free(name);
73 :
74 : /* tor_strlower */
75 1 : input = "{XX}";
76 1 : name = routerset_get_countryname(input);
77 1 : tt_str_op(name, OP_EQ, "xx");
78 1 : tor_free(name);
79 :
80 1 : input = "{xx}";
81 1 : name = routerset_get_countryname(input);
82 1 : tt_str_op(name, OP_EQ, "xx");
83 1 : done:
84 1 : tor_free(name);
85 1 : }
86 :
87 : /*
88 : * Structural (whitebox) test for routerset_refresh_counties, when the GeoIP DB
89 : * is not loaded.
90 : */
91 :
92 : static int rset_refresh_geoip_not_loaded_geoip_is_loaded(sa_family_t family);
93 : static int rset_refresh_geoip_not_loaded_geoip_is_loaded_called = 0;
94 : static int rset_refresh_geoip_not_loaded_geoip_get_n_countries(void);
95 : static int rset_refresh_geoip_not_loaded_geoip_get_n_countries_called = 0;
96 :
97 : static void
98 1 : test_rset_refresh_geoip_not_loaded(void *arg)
99 : {
100 1 : routerset_t *set = routerset_new();
101 1 : (void)arg;
102 :
103 1 : MOCK(geoip_is_loaded,
104 : rset_refresh_geoip_not_loaded_geoip_is_loaded);
105 1 : MOCK(geoip_get_n_countries,
106 : rset_refresh_geoip_not_loaded_geoip_get_n_countries);
107 :
108 1 : routerset_refresh_countries(set);
109 :
110 1 : tt_ptr_op(set->countries, OP_EQ, NULL);
111 1 : tt_int_op(set->n_countries, OP_EQ, 0);
112 1 : tt_int_op(rset_refresh_geoip_not_loaded_geoip_is_loaded_called, OP_EQ, 1);
113 1 : tt_int_op(rset_refresh_geoip_not_loaded_geoip_get_n_countries_called,
114 : OP_EQ, 0);
115 :
116 1 : done:
117 1 : UNMOCK(geoip_is_loaded);
118 1 : UNMOCK(geoip_get_n_countries);
119 1 : routerset_free(set);
120 1 : }
121 :
122 : static int
123 1 : rset_refresh_geoip_not_loaded_geoip_is_loaded(sa_family_t family)
124 : {
125 1 : (void)family;
126 1 : rset_refresh_geoip_not_loaded_geoip_is_loaded_called++;
127 :
128 1 : return 0;
129 : }
130 :
131 : static int
132 0 : rset_refresh_geoip_not_loaded_geoip_get_n_countries(void)
133 : {
134 0 : rset_refresh_geoip_not_loaded_geoip_get_n_countries_called++;
135 :
136 0 : return 0;
137 : }
138 :
139 : /*
140 : * Structural test for routerset_refresh_counties, when there are no countries.
141 : */
142 :
143 : static int rset_refresh_no_countries_geoip_is_loaded(sa_family_t family);
144 : static int rset_refresh_no_countries_geoip_is_loaded_called = 0;
145 : static int rset_refresh_no_countries_geoip_get_n_countries(void);
146 : static int rset_refresh_no_countries_geoip_get_n_countries_called = 0;
147 : static country_t rset_refresh_no_countries_geoip_get_country(
148 : const char *country);
149 : static int rset_refresh_no_countries_geoip_get_country_called = 0;
150 :
151 : static void
152 1 : test_rset_refresh_no_countries(void *arg)
153 : {
154 1 : routerset_t *set = routerset_new();
155 1 : (void)arg;
156 :
157 1 : MOCK(geoip_is_loaded,
158 : rset_refresh_no_countries_geoip_is_loaded);
159 1 : MOCK(geoip_get_n_countries,
160 : rset_refresh_no_countries_geoip_get_n_countries);
161 1 : MOCK(geoip_get_country,
162 : rset_refresh_no_countries_geoip_get_country);
163 :
164 1 : routerset_refresh_countries(set);
165 :
166 1 : tt_ptr_op(set->countries, OP_NE, NULL);
167 1 : tt_int_op(set->n_countries, OP_EQ, 1);
168 1 : tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
169 1 : tt_int_op(rset_refresh_no_countries_geoip_is_loaded_called, OP_EQ, 1);
170 1 : tt_int_op(rset_refresh_no_countries_geoip_get_n_countries_called, OP_EQ, 1);
171 1 : tt_int_op(rset_refresh_no_countries_geoip_get_country_called, OP_EQ, 0);
172 :
173 1 : done:
174 1 : UNMOCK(geoip_is_loaded);
175 1 : UNMOCK(geoip_get_n_countries);
176 1 : UNMOCK(geoip_get_country);
177 1 : routerset_free(set);
178 1 : }
179 :
180 : static int
181 1 : rset_refresh_no_countries_geoip_is_loaded(sa_family_t family)
182 : {
183 1 : (void)family;
184 1 : rset_refresh_no_countries_geoip_is_loaded_called++;
185 :
186 1 : return 1;
187 : }
188 :
189 : static int
190 1 : rset_refresh_no_countries_geoip_get_n_countries(void)
191 : {
192 1 : rset_refresh_no_countries_geoip_get_n_countries_called++;
193 :
194 1 : return 1;
195 : }
196 :
197 : static country_t
198 0 : rset_refresh_no_countries_geoip_get_country(const char *countrycode)
199 : {
200 0 : (void)countrycode;
201 0 : rset_refresh_no_countries_geoip_get_country_called++;
202 :
203 0 : return 1;
204 : }
205 :
206 : /*
207 : * Structural test for routerset_refresh_counties, with one valid country.
208 : */
209 :
210 : static int rset_refresh_one_valid_country_geoip_is_loaded(sa_family_t family);
211 : static int rset_refresh_one_valid_country_geoip_is_loaded_called = 0;
212 : static int rset_refresh_one_valid_country_geoip_get_n_countries(void);
213 : static int rset_refresh_one_valid_country_geoip_get_n_countries_called = 0;
214 : static country_t rset_refresh_one_valid_country_geoip_get_country(
215 : const char *country);
216 : static int rset_refresh_one_valid_country_geoip_get_country_called = 0;
217 :
218 : static void
219 1 : test_rset_refresh_one_valid_country(void *arg)
220 : {
221 1 : routerset_t *set = routerset_new();
222 1 : (void)arg;
223 :
224 1 : MOCK(geoip_is_loaded,
225 : rset_refresh_one_valid_country_geoip_is_loaded);
226 1 : MOCK(geoip_get_n_countries,
227 : rset_refresh_one_valid_country_geoip_get_n_countries);
228 1 : MOCK(geoip_get_country,
229 : rset_refresh_one_valid_country_geoip_get_country);
230 1 : smartlist_add(set->country_names, tor_strndup("foo", 3));
231 :
232 1 : routerset_refresh_countries(set);
233 :
234 1 : tt_ptr_op(set->countries, OP_NE, NULL);
235 1 : tt_int_op(set->n_countries, OP_EQ, 2);
236 1 : tt_int_op(rset_refresh_one_valid_country_geoip_is_loaded_called, OP_EQ, 1);
237 1 : tt_int_op(rset_refresh_one_valid_country_geoip_get_n_countries_called,
238 : OP_EQ, 1);
239 1 : tt_int_op(rset_refresh_one_valid_country_geoip_get_country_called, OP_EQ, 1);
240 1 : tt_int_op((unsigned int)(*set->countries), OP_NE, 0);
241 :
242 1 : done:
243 1 : UNMOCK(geoip_is_loaded);
244 1 : UNMOCK(geoip_get_n_countries);
245 1 : UNMOCK(geoip_get_country);
246 1 : routerset_free(set);
247 1 : }
248 :
249 : static int
250 1 : rset_refresh_one_valid_country_geoip_is_loaded(sa_family_t family)
251 : {
252 1 : (void)family;
253 1 : rset_refresh_one_valid_country_geoip_is_loaded_called++;
254 :
255 1 : return 1;
256 : }
257 :
258 : static int
259 1 : rset_refresh_one_valid_country_geoip_get_n_countries(void)
260 : {
261 1 : rset_refresh_one_valid_country_geoip_get_n_countries_called++;
262 :
263 1 : return 2;
264 : }
265 :
266 : static country_t
267 1 : rset_refresh_one_valid_country_geoip_get_country(const char *countrycode)
268 : {
269 1 : (void)countrycode;
270 1 : rset_refresh_one_valid_country_geoip_get_country_called++;
271 :
272 1 : return 1;
273 : }
274 :
275 : /*
276 : * Structural test for routerset_refresh_counties, with one invalid
277 : * country code..
278 : */
279 :
280 : static int rset_refresh_one_invalid_country_geoip_is_loaded(
281 : sa_family_t family);
282 : static int rset_refresh_one_invalid_country_geoip_is_loaded_called = 0;
283 : static int rset_refresh_one_invalid_country_geoip_get_n_countries(void);
284 : static int rset_refresh_one_invalid_country_geoip_get_n_countries_called = 0;
285 : static country_t rset_refresh_one_invalid_country_geoip_get_country(
286 : const char *country);
287 : static int rset_refresh_one_invalid_country_geoip_get_country_called = 0;
288 :
289 : static void
290 1 : test_rset_refresh_one_invalid_country(void *arg)
291 : {
292 1 : routerset_t *set = routerset_new();
293 1 : (void)arg;
294 :
295 1 : MOCK(geoip_is_loaded,
296 : rset_refresh_one_invalid_country_geoip_is_loaded);
297 1 : MOCK(geoip_get_n_countries,
298 : rset_refresh_one_invalid_country_geoip_get_n_countries);
299 1 : MOCK(geoip_get_country,
300 : rset_refresh_one_invalid_country_geoip_get_country);
301 1 : smartlist_add(set->country_names, tor_strndup("foo", 3));
302 :
303 1 : routerset_refresh_countries(set);
304 :
305 1 : tt_ptr_op(set->countries, OP_NE, NULL);
306 1 : tt_int_op(set->n_countries, OP_EQ, 2);
307 1 : tt_int_op(rset_refresh_one_invalid_country_geoip_is_loaded_called, OP_EQ, 1);
308 1 : tt_int_op(rset_refresh_one_invalid_country_geoip_get_n_countries_called,
309 : OP_EQ, 1);
310 1 : tt_int_op(rset_refresh_one_invalid_country_geoip_get_country_called,
311 : OP_EQ, 1);
312 1 : tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
313 :
314 1 : done:
315 1 : UNMOCK(geoip_is_loaded);
316 1 : UNMOCK(geoip_get_n_countries);
317 1 : UNMOCK(geoip_get_country);
318 1 : routerset_free(set);
319 1 : }
320 :
321 : static int
322 1 : rset_refresh_one_invalid_country_geoip_is_loaded(sa_family_t family)
323 : {
324 1 : (void)family;
325 1 : rset_refresh_one_invalid_country_geoip_is_loaded_called++;
326 :
327 1 : return 1;
328 : }
329 :
330 : static int
331 1 : rset_refresh_one_invalid_country_geoip_get_n_countries(void)
332 : {
333 1 : rset_refresh_one_invalid_country_geoip_get_n_countries_called++;
334 :
335 1 : return 2;
336 : }
337 :
338 : static country_t
339 1 : rset_refresh_one_invalid_country_geoip_get_country(const char *countrycode)
340 : {
341 1 : (void)countrycode;
342 1 : rset_refresh_one_invalid_country_geoip_get_country_called++;
343 :
344 1 : return -1;
345 : }
346 :
347 : /*
348 : * Functional test, with a malformed string to parse.
349 : */
350 :
351 : static void
352 1 : test_rset_parse_malformed(void *arg)
353 : {
354 1 : routerset_t *set = routerset_new();
355 1 : const char *s = "_";
356 1 : int r;
357 1 : (void)arg;
358 :
359 1 : r = routerset_parse(set, s, "");
360 :
361 1 : tt_int_op(r, OP_EQ, -1);
362 :
363 1 : done:
364 1 : routerset_free(set);
365 1 : }
366 :
367 : /*
368 : * Functional test for routerset_parse, that routerset_parse returns 0
369 : * on a valid hexdigest entry.
370 : */
371 :
372 : static void
373 1 : test_rset_parse_valid_hexdigest(void *arg)
374 : {
375 1 : routerset_t *set;
376 1 : const char *s;
377 1 : int r;
378 1 : (void)arg;
379 :
380 1 : set = routerset_new();
381 1 : s = "$0000000000000000000000000000000000000000";
382 1 : r = routerset_parse(set, s, "");
383 1 : tt_int_op(r, OP_EQ, 0);
384 1 : tt_int_op(digestmap_isempty(set->digests), OP_NE, 1);
385 :
386 1 : done:
387 1 : routerset_free(set);
388 1 : }
389 :
390 : /*
391 : * Functional test for routerset_parse, when given a valid nickname as input.
392 : */
393 :
394 : static void
395 1 : test_rset_parse_valid_nickname(void *arg)
396 : {
397 1 : routerset_t *set;
398 1 : const char *s;
399 1 : int r;
400 1 : (void)arg;
401 :
402 1 : set = routerset_new();
403 1 : s = "fred";
404 1 : r = routerset_parse(set, s, "");
405 1 : tt_int_op(r, OP_EQ, 0);
406 1 : tt_int_op(strmap_isempty(set->names), OP_NE, 1);
407 :
408 1 : done:
409 1 : routerset_free(set);
410 1 : }
411 :
412 : /*
413 : * Functional test for routerset_parse, when given a valid countryname.
414 : */
415 :
416 : static void
417 1 : test_rset_parse_get_countryname(void *arg)
418 : {
419 1 : routerset_t *set;
420 1 : const char *s;
421 1 : int r;
422 1 : (void)arg;
423 :
424 1 : set = routerset_new();
425 1 : s = "{cc}";
426 1 : r = routerset_parse(set, s, "");
427 1 : tt_int_op(r, OP_EQ, 0);
428 1 : tt_int_op(smartlist_len(set->country_names), OP_NE, 0);
429 :
430 1 : done:
431 1 : routerset_free(set);
432 1 : }
433 :
434 : /*
435 : * Structural test for routerset_parse, when given a valid wildcard policy.
436 : */
437 :
438 : static addr_policy_t * rset_parse_policy_wildcard_parse_item_from_string(
439 : const char *s, int assume_action, int *malformed_list);
440 : static int rset_parse_policy_wildcard_parse_item_from_string_called = 0;
441 :
442 : static addr_policy_t *rset_parse_policy_wildcard_mock_addr_policy;
443 :
444 : static void
445 1 : test_rset_parse_policy_wildcard(void *arg)
446 : {
447 1 : routerset_t *set;
448 1 : const char *s;
449 1 : int r;
450 1 : (void)arg;
451 :
452 1 : MOCK(router_parse_addr_policy_item_from_string,
453 : rset_parse_policy_wildcard_parse_item_from_string);
454 2 : rset_parse_policy_wildcard_mock_addr_policy =
455 1 : tor_malloc_zero(sizeof(addr_policy_t));
456 :
457 1 : set = routerset_new();
458 1 : s = "*";
459 1 : r = routerset_parse(set, s, "");
460 1 : tt_int_op(r, OP_EQ, 0);
461 1 : tt_int_op(smartlist_len(set->policies), OP_NE, 0);
462 1 : tt_int_op(rset_parse_policy_wildcard_parse_item_from_string_called,
463 : OP_EQ, 1);
464 :
465 1 : done:
466 1 : routerset_free(set);
467 1 : }
468 :
469 : addr_policy_t *
470 1 : rset_parse_policy_wildcard_parse_item_from_string(const char *s,
471 : int assume_action,
472 : int *malformed_list)
473 : {
474 1 : (void)s;
475 1 : (void)assume_action;
476 1 : (void)malformed_list;
477 1 : rset_parse_policy_wildcard_parse_item_from_string_called++;
478 :
479 1 : return rset_parse_policy_wildcard_mock_addr_policy;
480 : }
481 :
482 : /*
483 : * Structural test for routerset_parse, when given a valid IPv4 address
484 : * literal policy.
485 : */
486 :
487 : static addr_policy_t * rset_parse_policy_ipv4_parse_item_from_string(
488 : const char *s, int assume_action, int *bogus);
489 : static int rset_parse_policy_ipv4_parse_item_from_string_called = 0;
490 :
491 : static addr_policy_t *rset_parse_policy_ipv4_mock_addr_policy;
492 :
493 : static void
494 1 : test_rset_parse_policy_ipv4(void *arg)
495 : {
496 1 : routerset_t *set;
497 1 : const char *s;
498 1 : int r;
499 1 : (void)arg;
500 :
501 1 : MOCK(router_parse_addr_policy_item_from_string,
502 : rset_parse_policy_ipv4_parse_item_from_string);
503 2 : rset_parse_policy_ipv4_mock_addr_policy =
504 1 : tor_malloc_zero(sizeof(addr_policy_t));
505 :
506 1 : set = routerset_new();
507 1 : s = "127.0.0.1";
508 1 : r = routerset_parse(set, s, "");
509 1 : tt_int_op(r, OP_EQ, 0);
510 1 : tt_int_op(smartlist_len(set->policies), OP_NE, 0);
511 1 : tt_int_op(rset_parse_policy_ipv4_parse_item_from_string_called, OP_EQ, 1);
512 :
513 1 : done:
514 1 : routerset_free(set);
515 1 : }
516 :
517 : addr_policy_t *
518 1 : rset_parse_policy_ipv4_parse_item_from_string(
519 : const char *s, int assume_action,
520 : int *bogus)
521 : {
522 1 : (void)s;
523 1 : (void)assume_action;
524 1 : rset_parse_policy_ipv4_parse_item_from_string_called++;
525 1 : *bogus = 0;
526 :
527 1 : return rset_parse_policy_ipv4_mock_addr_policy;
528 : }
529 :
530 : /*
531 : * Structural test for routerset_parse, when given a valid IPv6 address
532 : * literal policy.
533 : */
534 :
535 : static addr_policy_t * rset_parse_policy_ipv6_parse_item_from_string(
536 : const char *s, int assume_action, int *bad);
537 : static int rset_parse_policy_ipv6_parse_item_from_string_called = 0;
538 :
539 : static addr_policy_t *rset_parse_policy_ipv6_mock_addr_policy;
540 :
541 : static void
542 1 : test_rset_parse_policy_ipv6(void *arg)
543 : {
544 1 : routerset_t *set;
545 1 : const char *s;
546 1 : int r;
547 1 : (void)arg;
548 :
549 1 : MOCK(router_parse_addr_policy_item_from_string,
550 : rset_parse_policy_ipv6_parse_item_from_string);
551 2 : rset_parse_policy_ipv6_mock_addr_policy =
552 1 : tor_malloc_zero(sizeof(addr_policy_t));
553 :
554 1 : set = routerset_new();
555 1 : s = "::1";
556 1 : r = routerset_parse(set, s, "");
557 1 : tt_int_op(r, OP_EQ, 0);
558 1 : tt_int_op(smartlist_len(set->policies), OP_NE, 0);
559 1 : tt_int_op(rset_parse_policy_ipv6_parse_item_from_string_called, OP_EQ, 1);
560 :
561 1 : done:
562 1 : routerset_free(set);
563 1 : }
564 :
565 : addr_policy_t *
566 1 : rset_parse_policy_ipv6_parse_item_from_string(const char *s,
567 : int assume_action, int *bad)
568 : {
569 1 : (void)s;
570 1 : (void)assume_action;
571 1 : rset_parse_policy_ipv6_parse_item_from_string_called++;
572 1 : *bad = 0;
573 :
574 1 : return rset_parse_policy_ipv6_mock_addr_policy;
575 : }
576 :
577 : /*
578 : * Structural test for routerset_union, when given a bad source argument.
579 : */
580 :
581 : static smartlist_t * rset_union_source_bad_smartlist_new(void);
582 : static int rset_union_source_bad_smartlist_new_called = 0;
583 :
584 : static void
585 1 : test_rset_union_source_bad(void *arg)
586 : {
587 1 : routerset_t *set, *bad_set;
588 1 : (void)arg;
589 :
590 1 : set = routerset_new();
591 1 : bad_set = routerset_new();
592 1 : smartlist_free(bad_set->list);
593 1 : bad_set->list = NULL;
594 :
595 1 : MOCK(smartlist_new,
596 : rset_union_source_bad_smartlist_new);
597 :
598 1 : routerset_union(set, NULL);
599 1 : tt_int_op(rset_union_source_bad_smartlist_new_called, OP_EQ, 0);
600 :
601 1 : routerset_union(set, bad_set);
602 1 : tt_int_op(rset_union_source_bad_smartlist_new_called, OP_EQ, 0);
603 :
604 1 : done:
605 1 : UNMOCK(smartlist_new);
606 1 : routerset_free(set);
607 :
608 : /* Just recreate list, so we can simply use routerset_free. */
609 1 : bad_set->list = smartlist_new();
610 1 : routerset_free(bad_set);
611 1 : }
612 :
613 : static smartlist_t *
614 0 : rset_union_source_bad_smartlist_new(void)
615 : {
616 0 : rset_union_source_bad_smartlist_new_called++;
617 :
618 0 : return NULL;
619 : }
620 :
621 : /*
622 : * Functional test for routerset_union.
623 : */
624 :
625 : static void
626 1 : test_rset_union_one(void *arg)
627 : {
628 1 : routerset_t *src = routerset_new();
629 1 : routerset_t *tgt;
630 1 : (void)arg;
631 :
632 1 : tgt = routerset_new();
633 1 : smartlist_add_strdup(src->list, "{xx}");
634 1 : routerset_union(tgt, src);
635 :
636 1 : tt_int_op(smartlist_len(tgt->list), OP_NE, 0);
637 :
638 1 : done:
639 1 : routerset_free(src);
640 1 : routerset_free(tgt);
641 1 : }
642 :
643 : /*
644 : * Functional tests for routerset_is_list.
645 : */
646 :
647 : static void
648 1 : test_rset_is_list(void *arg)
649 : {
650 1 : routerset_t *set;
651 1 : addr_policy_t *policy;
652 1 : int is_list;
653 1 : (void)arg;
654 :
655 : /* len(set->country_names) == 0, len(set->policies) == 0 */
656 1 : set = routerset_new();
657 1 : is_list = routerset_is_list(set);
658 1 : routerset_free(set);
659 1 : set = NULL;
660 1 : tt_int_op(is_list, OP_NE, 0);
661 :
662 : /* len(set->country_names) != 0, len(set->policies) == 0 */
663 1 : set = routerset_new();
664 1 : smartlist_add(set->country_names, tor_strndup("foo", 3));
665 1 : is_list = routerset_is_list(set);
666 1 : routerset_free(set);
667 1 : set = NULL;
668 1 : tt_int_op(is_list, OP_EQ, 0);
669 :
670 : /* len(set->country_names) == 0, len(set->policies) != 0 */
671 1 : set = routerset_new();
672 1 : policy = tor_malloc_zero(sizeof(addr_policy_t));
673 1 : smartlist_add(set->policies, (void *)policy);
674 1 : is_list = routerset_is_list(set);
675 1 : routerset_free(set);
676 1 : set = NULL;
677 1 : tt_int_op(is_list, OP_EQ, 0);
678 :
679 : /* len(set->country_names) != 0, len(set->policies) != 0 */
680 1 : set = routerset_new();
681 1 : smartlist_add(set->country_names, tor_strndup("foo", 3));
682 1 : policy = tor_malloc_zero(sizeof(addr_policy_t));
683 1 : smartlist_add(set->policies, (void *)policy);
684 1 : is_list = routerset_is_list(set);
685 1 : routerset_free(set);
686 1 : set = NULL;
687 1 : tt_int_op(is_list, OP_EQ, 0);
688 :
689 1 : done:
690 1 : ;
691 1 : }
692 :
693 : /*
694 : * Functional tests for routerset_needs_geoip.
695 : */
696 :
697 : static void
698 1 : test_rset_needs_geoip(void *arg)
699 : {
700 1 : routerset_t *set;
701 1 : int needs_geoip;
702 1 : (void)arg;
703 :
704 1 : set = NULL;
705 1 : needs_geoip = routerset_needs_geoip(set);
706 1 : tt_int_op(needs_geoip, OP_EQ, 0);
707 :
708 1 : set = routerset_new();
709 1 : needs_geoip = routerset_needs_geoip(set);
710 1 : routerset_free(set);
711 1 : tt_int_op(needs_geoip, OP_EQ, 0);
712 1 : set = NULL;
713 :
714 1 : set = routerset_new();
715 1 : smartlist_add(set->country_names, tor_strndup("xx", 2));
716 1 : needs_geoip = routerset_needs_geoip(set);
717 1 : routerset_free(set);
718 1 : set = NULL;
719 1 : tt_int_op(needs_geoip, OP_NE, 0);
720 :
721 1 : done:
722 1 : ;
723 1 : }
724 :
725 : /*
726 : * Functional tests for routerset_is_empty.
727 : */
728 :
729 : static void
730 1 : test_rset_is_empty(void *arg)
731 : {
732 1 : routerset_t *set = NULL;
733 1 : int is_empty;
734 1 : (void)arg;
735 :
736 1 : is_empty = routerset_is_empty(set);
737 1 : tt_int_op(is_empty, OP_NE, 0);
738 :
739 1 : set = routerset_new();
740 1 : is_empty = routerset_is_empty(set);
741 1 : routerset_free(set);
742 1 : set = NULL;
743 1 : tt_int_op(is_empty, OP_NE, 0);
744 :
745 1 : set = routerset_new();
746 1 : smartlist_add_strdup(set->list, "{xx}");
747 1 : is_empty = routerset_is_empty(set);
748 1 : routerset_free(set);
749 1 : set = NULL;
750 1 : tt_int_op(is_empty, OP_EQ, 0);
751 :
752 1 : done:
753 1 : ;
754 1 : }
755 :
756 : /*
757 : * Functional test for routerset_contains, when given a NULL set or the
758 : * set has a NULL list.
759 : */
760 :
761 : static void
762 1 : test_rset_contains_null_set_or_list(void *arg)
763 : {
764 1 : routerset_t *set = NULL;
765 1 : int contains;
766 1 : (void)arg;
767 :
768 1 : contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
769 :
770 1 : tt_int_op(contains, OP_EQ, 0);
771 :
772 1 : set = tor_malloc_zero(sizeof(routerset_t));
773 1 : set->list = NULL;
774 1 : contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
775 1 : tor_free(set);
776 1 : tt_int_op(contains, OP_EQ, 0);
777 :
778 1 : done:
779 1 : ;
780 1 : }
781 :
782 : /*
783 : * Functional test for routerset_contains, when given a valid routerset but a
784 : * NULL nickname.
785 : */
786 :
787 : static void
788 1 : test_rset_contains_null_nickname(void *arg)
789 : {
790 1 : routerset_t *set = routerset_new();
791 1 : char *nickname = NULL;
792 1 : int contains;
793 1 : (void)arg;
794 :
795 1 : contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
796 1 : routerset_free(set);
797 :
798 1 : tt_int_op(contains, OP_EQ, 0);
799 :
800 1 : done:
801 1 : ;
802 1 : }
803 :
804 : /*
805 : * Functional test for routerset_contains, when given a valid routerset
806 : * and the nickname is in the routerset.
807 : */
808 :
809 : static void
810 1 : test_rset_contains_nickname(void *arg)
811 : {
812 1 : routerset_t *set = routerset_new();
813 1 : const char *nickname;
814 1 : int contains;
815 1 : (void)arg;
816 :
817 1 : nickname = "Foo"; /* This tests the lowercase comparison as well. */
818 1 : strmap_set_lc(set->names, nickname, (void *)1);
819 1 : contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
820 1 : routerset_free(set);
821 :
822 1 : tt_int_op(contains, OP_EQ, 4);
823 1 : done:
824 1 : ;
825 1 : }
826 :
827 : /*
828 : * Functional test for routerset_contains, when given a valid routerset
829 : * and the nickname is not in the routerset.
830 : */
831 :
832 : static void
833 1 : test_rset_contains_no_nickname(void *arg)
834 : {
835 1 : routerset_t *set = routerset_new();
836 1 : int contains;
837 1 : (void)arg;
838 :
839 1 : strmap_set_lc(set->names, "bar", (void *)1);
840 1 : contains = routerset_contains(set, NULL, 0, "foo", NULL, 0);
841 1 : routerset_free(set);
842 :
843 1 : tt_int_op(contains, OP_EQ, 0);
844 1 : done:
845 1 : ;
846 1 : }
847 :
848 : /*
849 : * Functional test for routerset_contains, when given a valid routerset
850 : * and the digest is contained in the routerset.
851 : */
852 :
853 : static void
854 1 : test_rset_contains_digest(void *arg)
855 : {
856 1 : routerset_t *set = routerset_new();
857 1 : int contains;
858 1 : uint8_t foo[20] = { 2, 3, 4 };
859 1 : (void)arg;
860 :
861 1 : digestmap_set(set->digests, (const char*)foo, (void *)1);
862 1 : contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
863 1 : routerset_free(set);
864 :
865 1 : tt_int_op(contains, OP_EQ, 4);
866 1 : done:
867 1 : ;
868 1 : }
869 :
870 : /*
871 : * Functional test for routerset_contains, when given a valid routerset
872 : * and the digest is not contained in the routerset.
873 : */
874 :
875 : static void
876 1 : test_rset_contains_no_digest(void *arg)
877 : {
878 1 : routerset_t *set = routerset_new();
879 1 : int contains;
880 1 : uint8_t bar[20] = { 9, 10, 11, 55 };
881 1 : uint8_t foo[20] = { 1, 2, 3, 4};
882 1 : (void)arg;
883 :
884 1 : digestmap_set(set->digests, (const char*)bar, (void *)1);
885 1 : contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
886 1 : routerset_free(set);
887 :
888 1 : tt_int_op(contains, OP_EQ, 0);
889 1 : done:
890 1 : ;
891 1 : }
892 :
893 : /*
894 : * Functional test for routerset_contains, when given a valid routerset
895 : * and the digest is NULL.
896 : */
897 :
898 : static void
899 1 : test_rset_contains_null_digest(void *arg)
900 : {
901 1 : routerset_t *set = routerset_new();
902 1 : int contains;
903 1 : uint8_t bar[20] = { 9, 10, 11, 55 };
904 1 : (void)arg;
905 :
906 1 : digestmap_set(set->digests, (const char*)bar, (void *)1);
907 1 : contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
908 1 : routerset_free(set);
909 :
910 1 : tt_int_op(contains, OP_EQ, 0);
911 1 : done:
912 1 : ;
913 1 : }
914 :
915 : /*
916 : * Structural test for routerset_contains, when given a valid routerset
917 : * and the address is rejected by policy.
918 : */
919 :
920 : static addr_policy_result_t rset_contains_addr_cmp_addr_to_policy(
921 : const tor_addr_t *addr, uint16_t port,
922 : const smartlist_t *policy);
923 : static int rset_contains_addr_cmp_addr_to_policy_called = 0;
924 :
925 : static tor_addr_t MOCK_TOR_ADDR;
926 : #define MOCK_TOR_ADDR_PTR (&MOCK_TOR_ADDR)
927 :
928 : static void
929 1 : test_rset_contains_addr(void *arg)
930 : {
931 1 : routerset_t *set = routerset_new();
932 1 : tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
933 1 : int contains;
934 1 : (void)arg;
935 :
936 1 : MOCK(compare_tor_addr_to_addr_policy,
937 : rset_contains_addr_cmp_addr_to_policy);
938 :
939 1 : contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
940 1 : routerset_free(set);
941 :
942 1 : tt_int_op(rset_contains_addr_cmp_addr_to_policy_called, OP_EQ, 1);
943 1 : tt_int_op(contains, OP_EQ, 3);
944 :
945 1 : done:
946 1 : ;
947 1 : }
948 :
949 : addr_policy_result_t
950 1 : rset_contains_addr_cmp_addr_to_policy(const tor_addr_t *addr, uint16_t port,
951 : const smartlist_t *policy)
952 : {
953 1 : (void)port;
954 1 : (void)policy;
955 1 : rset_contains_addr_cmp_addr_to_policy_called++;
956 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
957 : return ADDR_POLICY_REJECTED;
958 :
959 0 : done:
960 0 : return 0;
961 : }
962 :
963 : /*
964 : * Structural test for routerset_contains, when given a valid routerset
965 : * and the address is not rejected by policy.
966 : */
967 :
968 : static addr_policy_result_t rset_contains_no_addr_cmp_addr_to_policy(
969 : const tor_addr_t *addr, uint16_t port,
970 : const smartlist_t *policy);
971 : static int rset_contains_no_addr_cmp_addr_to_policy_called = 0;
972 :
973 : static void
974 1 : test_rset_contains_no_addr(void *arg)
975 : {
976 1 : routerset_t *set = routerset_new();
977 1 : tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
978 1 : int contains;
979 1 : (void)arg;
980 :
981 1 : MOCK(compare_tor_addr_to_addr_policy,
982 : rset_contains_no_addr_cmp_addr_to_policy);
983 :
984 1 : contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
985 1 : routerset_free(set);
986 :
987 1 : tt_int_op(rset_contains_no_addr_cmp_addr_to_policy_called, OP_EQ, 1);
988 1 : tt_int_op(contains, OP_EQ, 0);
989 :
990 1 : done:
991 1 : ;
992 1 : }
993 :
994 : addr_policy_result_t
995 1 : rset_contains_no_addr_cmp_addr_to_policy(const tor_addr_t *addr, uint16_t port,
996 : const smartlist_t *policy)
997 : {
998 1 : (void)port;
999 1 : (void)policy;
1000 1 : rset_contains_no_addr_cmp_addr_to_policy_called++;
1001 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1002 :
1003 : return ADDR_POLICY_ACCEPTED;
1004 :
1005 0 : done:
1006 0 : return 0;
1007 : }
1008 :
1009 : /*
1010 : * Structural test for routerset_contains, when given a valid routerset
1011 : * and the address is NULL.
1012 : */
1013 :
1014 : static addr_policy_result_t rset_contains_null_addr_cmp_addr_to_policy(
1015 : const tor_addr_t *addr, uint16_t port,
1016 : const smartlist_t *policy);
1017 : static int rset_contains_null_addr_cmp_addr_to_policy_called = 0;
1018 :
1019 : static void
1020 1 : test_rset_contains_null_addr(void *arg)
1021 : {
1022 1 : routerset_t *set = routerset_new();
1023 1 : int contains;
1024 1 : (void)arg;
1025 :
1026 1 : MOCK(compare_tor_addr_to_addr_policy,
1027 : rset_contains_null_addr_cmp_addr_to_policy);
1028 :
1029 1 : contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
1030 1 : routerset_free(set);
1031 :
1032 1 : tt_int_op(contains, OP_EQ, 0);
1033 :
1034 1 : done:
1035 1 : ;
1036 1 : }
1037 :
1038 : addr_policy_result_t
1039 0 : rset_contains_null_addr_cmp_addr_to_policy(
1040 : const tor_addr_t *addr, uint16_t port,
1041 : const smartlist_t *policy)
1042 : {
1043 0 : (void)port;
1044 0 : (void)policy;
1045 0 : rset_contains_null_addr_cmp_addr_to_policy_called++;
1046 0 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1047 :
1048 : return ADDR_POLICY_ACCEPTED;
1049 :
1050 0 : done:
1051 0 : return 0;
1052 : }
1053 :
1054 : /*
1055 : * Structural test for routerset_contains, when there is no matching country
1056 : * for the address.
1057 : */
1058 :
1059 : static addr_policy_result_t rset_countries_no_geoip_cmp_addr_to_policy(
1060 : const tor_addr_t *addr, uint16_t port,
1061 : const smartlist_t *policy);
1062 : static int rset_countries_no_geoip_cmp_addr_to_policy_called = 0;
1063 : static int rset_countries_no_geoip_geoip_get_country_by_addr(
1064 : const tor_addr_t *addr);
1065 : static int rset_countries_no_geoip_geoip_get_country_by_addr_called = 0;
1066 :
1067 : static void
1068 1 : test_rset_countries_no_geoip(void *arg)
1069 : {
1070 1 : routerset_t *set = routerset_new();
1071 1 : int contains = 1;
1072 1 : (void)arg;
1073 :
1074 1 : MOCK(compare_tor_addr_to_addr_policy,
1075 : rset_countries_no_geoip_cmp_addr_to_policy);
1076 1 : MOCK(geoip_get_country_by_addr,
1077 : rset_countries_no_geoip_geoip_get_country_by_addr);
1078 :
1079 1 : set->countries = bitarray_init_zero(1);
1080 1 : bitarray_set(set->countries, 1);
1081 1 : contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
1082 1 : routerset_free(set);
1083 :
1084 1 : tt_int_op(contains, OP_EQ, 0);
1085 1 : tt_int_op(rset_countries_no_geoip_cmp_addr_to_policy_called,
1086 : OP_EQ, 1);
1087 1 : tt_int_op(rset_countries_no_geoip_geoip_get_country_by_addr_called,
1088 : OP_EQ, 1);
1089 :
1090 1 : done:
1091 1 : ;
1092 1 : }
1093 :
1094 : addr_policy_result_t
1095 1 : rset_countries_no_geoip_cmp_addr_to_policy(
1096 : const tor_addr_t *addr, uint16_t port,
1097 : const smartlist_t *policy)
1098 : {
1099 1 : (void)port;
1100 1 : (void)policy;
1101 1 : rset_countries_no_geoip_cmp_addr_to_policy_called++;
1102 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1103 :
1104 1 : done:
1105 1 : return ADDR_POLICY_ACCEPTED;
1106 : }
1107 :
1108 : int
1109 1 : rset_countries_no_geoip_geoip_get_country_by_addr(const tor_addr_t *addr)
1110 : {
1111 1 : rset_countries_no_geoip_geoip_get_country_by_addr_called++;
1112 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1113 :
1114 1 : done:
1115 1 : return -1;
1116 : }
1117 :
1118 : /*
1119 : * Structural test for routerset_contains, when there a matching country
1120 : * for the address.
1121 : */
1122 :
1123 : static addr_policy_result_t rset_countries_geoip_cmp_addr_to_policy(
1124 : const tor_addr_t *addr, uint16_t port,
1125 : const smartlist_t *policy);
1126 : static int rset_countries_geoip_cmp_addr_to_policy_called = 0;
1127 : static int rset_countries_geoip_geoip_get_country_by_addr(
1128 : const tor_addr_t *addr);
1129 : static int rset_countries_geoip_geoip_get_country_by_addr_called = 0;
1130 :
1131 : static void
1132 1 : test_rset_countries_geoip(void *arg)
1133 : {
1134 1 : routerset_t *set = routerset_new();
1135 1 : int contains = 1;
1136 1 : (void)arg;
1137 :
1138 1 : MOCK(compare_tor_addr_to_addr_policy,
1139 : rset_countries_geoip_cmp_addr_to_policy);
1140 1 : MOCK(geoip_get_country_by_addr,
1141 : rset_countries_geoip_geoip_get_country_by_addr);
1142 :
1143 1 : set->n_countries = 2;
1144 1 : set->countries = bitarray_init_zero(1);
1145 1 : bitarray_set(set->countries, 1);
1146 1 : contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
1147 1 : routerset_free(set);
1148 :
1149 1 : tt_int_op(contains, OP_EQ, 2);
1150 1 : tt_int_op(
1151 : rset_countries_geoip_cmp_addr_to_policy_called,
1152 : OP_EQ, 1);
1153 1 : tt_int_op(rset_countries_geoip_geoip_get_country_by_addr_called,
1154 : OP_EQ, 1);
1155 :
1156 1 : done:
1157 1 : ;
1158 1 : }
1159 :
1160 : addr_policy_result_t
1161 1 : rset_countries_geoip_cmp_addr_to_policy(
1162 : const tor_addr_t *addr, uint16_t port,
1163 : const smartlist_t *policy)
1164 : {
1165 1 : (void)port;
1166 1 : (void)policy;
1167 1 : rset_countries_geoip_cmp_addr_to_policy_called++;
1168 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1169 :
1170 1 : done:
1171 1 : return ADDR_POLICY_ACCEPTED;
1172 : }
1173 :
1174 : int
1175 1 : rset_countries_geoip_geoip_get_country_by_addr(const tor_addr_t *addr)
1176 : {
1177 1 : rset_countries_geoip_geoip_get_country_by_addr_called++;
1178 1 : tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
1179 :
1180 1 : done:
1181 1 : return 1;
1182 : }
1183 :
1184 : /*
1185 : * Functional test for routerset_add_unknown_ccs, where only_if_some_cc_set
1186 : * is set and there are no country names.
1187 : */
1188 :
1189 : static void
1190 1 : test_rset_add_unknown_ccs_only_flag(void *arg)
1191 : {
1192 1 : routerset_t *set = routerset_new();
1193 1 : routerset_t **setp = &set;
1194 1 : int r;
1195 1 : (void)arg;
1196 :
1197 1 : r = routerset_add_unknown_ccs(setp, 1);
1198 :
1199 1 : tt_int_op(r, OP_EQ, 0);
1200 :
1201 1 : done:
1202 1 : routerset_free(set);
1203 1 : }
1204 :
1205 : /*
1206 : * Functional test for routerset_add_unknown_ccs, where the set argument
1207 : * is created if passed in as NULL.
1208 : */
1209 :
1210 : /* The mock is only used to stop the test from asserting erroneously. */
1211 : static country_t rset_add_unknown_ccs_creates_set_geoip_get_country(
1212 : const char *country);
1213 : static int rset_add_unknown_ccs_creates_set_geoip_get_country_called = 0;
1214 :
1215 : static void
1216 1 : test_rset_add_unknown_ccs_creates_set(void *arg)
1217 : {
1218 1 : routerset_t *set = NULL;
1219 1 : routerset_t **setp = &set;
1220 1 : int r;
1221 1 : (void)arg;
1222 :
1223 1 : MOCK(geoip_get_country,
1224 : rset_add_unknown_ccs_creates_set_geoip_get_country);
1225 :
1226 1 : r = routerset_add_unknown_ccs(setp, 0);
1227 :
1228 1 : tt_ptr_op(*setp, OP_NE, NULL);
1229 1 : tt_int_op(r, OP_EQ, 0);
1230 :
1231 1 : done:
1232 1 : if (set != NULL)
1233 1 : routerset_free(set);
1234 1 : }
1235 :
1236 : country_t
1237 2 : rset_add_unknown_ccs_creates_set_geoip_get_country(const char *country)
1238 : {
1239 2 : (void)country;
1240 2 : rset_add_unknown_ccs_creates_set_geoip_get_country_called++;
1241 :
1242 2 : return -1;
1243 : }
1244 :
1245 : /*
1246 : * Structural test for routerset_add_unknown_ccs, that the "{??}"
1247 : * country code is added to the list.
1248 : */
1249 :
1250 : static country_t rset_add_unknown_ccs_add_unknown_geoip_get_country(
1251 : const char *country);
1252 : static int rset_add_unknown_ccs_add_unknown_geoip_get_country_called = 0;
1253 : static int rset_add_unknown_ccs_add_unknown_geoip_is_loaded(
1254 : sa_family_t family);
1255 : static int rset_add_unknown_ccs_add_unknown_geoip_is_loaded_called = 0;
1256 :
1257 : static void
1258 1 : test_rset_add_unknown_ccs_add_unknown(void *arg)
1259 : {
1260 1 : routerset_t *set = routerset_new();
1261 1 : routerset_t **setp = &set;
1262 1 : int r;
1263 1 : (void)arg;
1264 :
1265 1 : MOCK(geoip_get_country,
1266 : rset_add_unknown_ccs_add_unknown_geoip_get_country);
1267 1 : MOCK(geoip_is_loaded,
1268 : rset_add_unknown_ccs_add_unknown_geoip_is_loaded);
1269 :
1270 1 : r = routerset_add_unknown_ccs(setp, 0);
1271 :
1272 1 : tt_int_op(r, OP_EQ, 1);
1273 1 : tt_int_op(smartlist_contains_string(set->country_names, "??"), OP_EQ, 1);
1274 1 : tt_int_op(smartlist_contains_string(set->list, "{??}"), OP_EQ, 1);
1275 :
1276 1 : done:
1277 1 : if (set != NULL)
1278 1 : routerset_free(set);
1279 1 : }
1280 :
1281 : country_t
1282 2 : rset_add_unknown_ccs_add_unknown_geoip_get_country(const char *country)
1283 : {
1284 2 : int arg_is_qq, arg_is_a1;
1285 :
1286 2 : rset_add_unknown_ccs_add_unknown_geoip_get_country_called++;
1287 :
1288 2 : arg_is_qq = !strcmp(country, "??");
1289 2 : arg_is_a1 = !strcmp(country, "A1");
1290 :
1291 2 : tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
1292 :
1293 2 : if (arg_is_qq)
1294 1 : return 1;
1295 :
1296 1 : done:
1297 : return -1;
1298 : }
1299 :
1300 : int
1301 1 : rset_add_unknown_ccs_add_unknown_geoip_is_loaded(sa_family_t family)
1302 : {
1303 1 : rset_add_unknown_ccs_add_unknown_geoip_is_loaded_called++;
1304 :
1305 1 : tt_int_op(family, OP_EQ, AF_INET);
1306 :
1307 1 : done:
1308 1 : return 0;
1309 : }
1310 :
1311 : /*
1312 : * Structural test for routerset_add_unknown_ccs, that the "{a1}"
1313 : * country code is added to the list.
1314 : */
1315 :
1316 : static country_t rset_add_unknown_ccs_add_a1_geoip_get_country(
1317 : const char *country);
1318 : static int rset_add_unknown_ccs_add_a1_geoip_get_country_called = 0;
1319 : static int rset_add_unknown_ccs_add_a1_geoip_is_loaded(sa_family_t family);
1320 : static int rset_add_unknown_ccs_add_a1_geoip_is_loaded_called = 0;
1321 :
1322 : static void
1323 1 : test_rset_add_unknown_ccs_add_a1(void *arg)
1324 : {
1325 1 : routerset_t *set = routerset_new();
1326 1 : routerset_t **setp = &set;
1327 1 : int r;
1328 1 : (void)arg;
1329 :
1330 1 : MOCK(geoip_get_country,
1331 : rset_add_unknown_ccs_add_a1_geoip_get_country);
1332 1 : MOCK(geoip_is_loaded,
1333 : rset_add_unknown_ccs_add_a1_geoip_is_loaded);
1334 :
1335 1 : r = routerset_add_unknown_ccs(setp, 0);
1336 :
1337 1 : tt_int_op(r, OP_EQ, 1);
1338 1 : tt_int_op(smartlist_contains_string(set->country_names, "a1"), OP_EQ, 1);
1339 1 : tt_int_op(smartlist_contains_string(set->list, "{a1}"), OP_EQ, 1);
1340 :
1341 1 : done:
1342 1 : if (set != NULL)
1343 1 : routerset_free(set);
1344 1 : }
1345 :
1346 : country_t
1347 2 : rset_add_unknown_ccs_add_a1_geoip_get_country(const char *country)
1348 : {
1349 2 : int arg_is_qq, arg_is_a1;
1350 :
1351 2 : rset_add_unknown_ccs_add_a1_geoip_get_country_called++;
1352 :
1353 2 : arg_is_qq = !strcmp(country, "??");
1354 2 : arg_is_a1 = !strcmp(country, "A1");
1355 :
1356 2 : tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
1357 :
1358 2 : if (arg_is_a1)
1359 1 : return 1;
1360 :
1361 1 : done:
1362 : return -1;
1363 : }
1364 :
1365 : int
1366 1 : rset_add_unknown_ccs_add_a1_geoip_is_loaded(sa_family_t family)
1367 : {
1368 1 : rset_add_unknown_ccs_add_a1_geoip_is_loaded_called++;
1369 :
1370 1 : tt_int_op(family, OP_EQ, AF_INET);
1371 :
1372 1 : done:
1373 1 : return 0;
1374 : }
1375 :
1376 : /*
1377 : * Functional test for routerset_contains_extendinfo.
1378 : */
1379 :
1380 : static void
1381 1 : test_rset_contains_extendinfo(void *arg)
1382 : {
1383 1 : routerset_t *set = routerset_new();
1384 1 : extend_info_t ei;
1385 1 : int r;
1386 1 : const char *nickname = "foo";
1387 1 : (void)arg;
1388 :
1389 1 : memset(&ei, 0, sizeof(ei));
1390 1 : strmap_set_lc(set->names, nickname, (void *)1);
1391 1 : strncpy(ei.nickname, nickname, sizeof(ei.nickname) - 1);
1392 1 : ei.nickname[sizeof(ei.nickname) - 1] = '\0';
1393 :
1394 1 : r = routerset_contains_extendinfo(set, &ei);
1395 :
1396 1 : tt_int_op(r, OP_EQ, 4);
1397 1 : done:
1398 1 : routerset_free(set);
1399 1 : }
1400 :
1401 : /*
1402 : * Functional test for routerset_contains_router.
1403 : */
1404 :
1405 : static void
1406 1 : test_rset_contains_router(void *arg)
1407 : {
1408 1 : routerset_t *set = routerset_new();
1409 1 : routerinfo_t ri;
1410 1 : country_t country = 1;
1411 1 : int r;
1412 1 : const char *nickname = "foo";
1413 1 : (void)arg;
1414 :
1415 1 : memset(&ri, 0, sizeof(ri));
1416 1 : strmap_set_lc(set->names, nickname, (void *)1);
1417 1 : ri.nickname = (char *)nickname;
1418 :
1419 1 : r = routerset_contains_router(set, &ri, country);
1420 1 : tt_int_op(r, OP_EQ, 4);
1421 :
1422 1 : done:
1423 1 : routerset_free(set);
1424 1 : }
1425 :
1426 : static void
1427 1 : test_rset_contains_router_ipv4(void *arg)
1428 : {
1429 1 : routerset_t *set;
1430 1 : routerinfo_t ri;
1431 1 : country_t country = 1;
1432 1 : int r;
1433 1 : const char *s;
1434 1 : (void) arg;
1435 :
1436 : /* IPv4 address test. */
1437 1 : memset(&ri, 0, sizeof(ri));
1438 1 : set = routerset_new();
1439 1 : s = "10.0.0.1";
1440 1 : r = routerset_parse(set, s, "");
1441 1 : tor_addr_from_ipv4h(&ri.ipv4_addr, 0x0a000001);
1442 1 : ri.ipv4_orport = 1234;
1443 :
1444 1 : r = routerset_contains_router(set, &ri, country);
1445 1 : tt_int_op(r, OP_EQ, 3);
1446 :
1447 1 : done:
1448 1 : routerset_free(set);
1449 1 : }
1450 :
1451 : static void
1452 1 : test_rset_contains_router_ipv6(void *arg)
1453 : {
1454 1 : routerset_t *set;
1455 1 : routerinfo_t ri;
1456 1 : country_t country = 1;
1457 1 : int r;
1458 1 : const char *s;
1459 1 : (void) arg;
1460 :
1461 : /* IPv6 address test. */
1462 1 : memset(&ri, 0, sizeof(ri));
1463 1 : set = routerset_new();
1464 1 : s = "2600::1";
1465 1 : r = routerset_parse(set, s, "");
1466 1 : tor_addr_parse(&ri.ipv6_addr, "2600::1");
1467 1 : ri.ipv6_orport = 12345;
1468 :
1469 1 : r = routerset_contains_router(set, &ri, country);
1470 1 : tt_int_op(r, OP_EQ, 3);
1471 :
1472 1 : done:
1473 1 : routerset_free(set);
1474 1 : }
1475 :
1476 : /*
1477 : * Functional test for routerset_contains_routerstatus.
1478 : */
1479 :
1480 : // XXX: This is a bit brief. It only populates and tests the nickname fields
1481 : // ie., enough to make the containment check succeed. Perhaps it should do
1482 : // a bit more or test a bit more.
1483 :
1484 : static void
1485 1 : test_rset_contains_routerstatus(void *arg)
1486 : {
1487 1 : routerset_t *set = routerset_new();
1488 1 : routerstatus_t rs;
1489 1 : country_t country = 1;
1490 1 : int r;
1491 1 : const char *nickname = "foo";
1492 1 : (void)arg;
1493 :
1494 1 : memset(&rs, 0, sizeof(rs));
1495 1 : strmap_set_lc(set->names, nickname, (void *)1);
1496 1 : strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
1497 1 : rs.nickname[sizeof(rs.nickname) - 1] = '\0';
1498 :
1499 1 : r = routerset_contains_routerstatus(set, &rs, country);
1500 :
1501 1 : tt_int_op(r, OP_EQ, 4);
1502 1 : done:
1503 1 : routerset_free(set);
1504 1 : }
1505 :
1506 : /*
1507 : * Functional test for routerset_contains_node, when the node has no
1508 : * routerset or routerinfo.
1509 : */
1510 :
1511 : static node_t rset_contains_none_mock_node;
1512 :
1513 : static void
1514 1 : test_rset_contains_none(void *arg)
1515 : {
1516 1 : routerset_t *set = routerset_new();
1517 1 : int r;
1518 1 : (void)arg;
1519 :
1520 1 : memset(&rset_contains_none_mock_node, 0,
1521 : sizeof(rset_contains_none_mock_node));
1522 1 : rset_contains_none_mock_node.ri = NULL;
1523 1 : rset_contains_none_mock_node.rs = NULL;
1524 :
1525 1 : r = routerset_contains_node(set, &rset_contains_none_mock_node);
1526 1 : tt_int_op(r, OP_EQ, 0);
1527 :
1528 1 : done:
1529 1 : routerset_free(set);
1530 1 : }
1531 :
1532 : /*
1533 : * Functional test for routerset_contains_node, when the node has a
1534 : * routerset and no routerinfo.
1535 : */
1536 :
1537 : static node_t rset_contains_rs_mock_node;
1538 :
1539 : static void
1540 1 : test_rset_contains_rs(void *arg)
1541 : {
1542 1 : routerset_t *set = routerset_new();
1543 1 : int r;
1544 1 : const char *nickname = "foo";
1545 1 : routerstatus_t rs;
1546 1 : (void)arg;
1547 :
1548 1 : strmap_set_lc(set->names, nickname, (void *)1);
1549 :
1550 1 : strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
1551 1 : rs.nickname[sizeof(rs.nickname) - 1] = '\0';
1552 1 : memset(&rset_contains_rs_mock_node, 0, sizeof(rset_contains_rs_mock_node));
1553 1 : rset_contains_rs_mock_node.ri = NULL;
1554 1 : rset_contains_rs_mock_node.rs = &rs;
1555 :
1556 1 : r = routerset_contains_node(set, &rset_contains_rs_mock_node);
1557 :
1558 1 : tt_int_op(r, OP_EQ, 4);
1559 1 : done:
1560 1 : routerset_free(set);
1561 1 : }
1562 :
1563 : /*
1564 : * Functional test for routerset_contains_node, when the node has no
1565 : * routerset and a routerinfo.
1566 : */
1567 :
1568 : static void
1569 1 : test_rset_contains_routerinfo(void *arg)
1570 : {
1571 1 : routerset_t *set = routerset_new();
1572 1 : int r;
1573 1 : const char *nickname = "foo";
1574 1 : routerinfo_t ri;
1575 1 : node_t mock_node;
1576 1 : (void)arg;
1577 :
1578 1 : strmap_set_lc(set->names, nickname, (void *)1);
1579 :
1580 1 : ri.nickname = (char *)nickname;
1581 1 : memset(&mock_node, 0, sizeof(mock_node));
1582 1 : mock_node.ri = &ri;
1583 1 : mock_node.rs = NULL;
1584 :
1585 1 : r = routerset_contains_node(set, &mock_node);
1586 :
1587 1 : tt_int_op(r, OP_EQ, 4);
1588 1 : done:
1589 1 : routerset_free(set);
1590 1 : }
1591 :
1592 : /*
1593 : * Functional test for routerset_get_all_nodes, when routerset is NULL or
1594 : * the routerset list is NULL.
1595 : */
1596 :
1597 : static void
1598 1 : test_rset_get_all_no_routerset(void *arg)
1599 : {
1600 1 : smartlist_t *out = smartlist_new();
1601 1 : routerset_t *set = NULL;
1602 1 : (void)arg;
1603 :
1604 1 : tt_int_op(smartlist_len(out), OP_EQ, 0);
1605 1 : routerset_get_all_nodes(out, NULL, NULL, 0);
1606 :
1607 1 : tt_int_op(smartlist_len(out), OP_EQ, 0);
1608 :
1609 1 : set = routerset_new();
1610 1 : smartlist_free(set->list);
1611 1 : routerset_get_all_nodes(out, NULL, NULL, 0);
1612 1 : tt_int_op(smartlist_len(out), OP_EQ, 0);
1613 :
1614 : /* Just recreate list, so we can simply use routerset_free. */
1615 1 : set->list = smartlist_new();
1616 :
1617 1 : done:
1618 1 : routerset_free(set);
1619 1 : smartlist_free(out);
1620 1 : }
1621 :
1622 : /*
1623 : * Structural test for routerset_get_all_nodes, when the routerset list
1624 : * is empty.
1625 : */
1626 :
1627 : static const node_t * rset_get_all_l_no_nodes_node_get_by_nickname(
1628 : const char *nickname, unsigned flags);
1629 : static int rset_get_all_l_no_nodes_node_get_by_nickname_called = 0;
1630 : static const char *rset_get_all_l_no_nodes_mock_nickname;
1631 :
1632 : static void
1633 1 : test_rset_get_all_l_no_nodes(void *arg)
1634 : {
1635 1 : smartlist_t *out = smartlist_new();
1636 1 : routerset_t *set = routerset_new();
1637 1 : int out_len;
1638 1 : (void)arg;
1639 :
1640 1 : MOCK(node_get_by_nickname,
1641 : rset_get_all_l_no_nodes_node_get_by_nickname);
1642 :
1643 1 : rset_get_all_l_no_nodes_mock_nickname = "foo";
1644 1 : smartlist_add_strdup(set->list, rset_get_all_l_no_nodes_mock_nickname);
1645 :
1646 1 : routerset_get_all_nodes(out, set, NULL, 0);
1647 1 : out_len = smartlist_len(out);
1648 :
1649 1 : smartlist_free(out);
1650 1 : routerset_free(set);
1651 :
1652 1 : tt_int_op(out_len, OP_EQ, 0);
1653 1 : tt_int_op(rset_get_all_l_no_nodes_node_get_by_nickname_called, OP_EQ, 1);
1654 :
1655 1 : done:
1656 1 : ;
1657 1 : }
1658 :
1659 : const node_t *
1660 1 : rset_get_all_l_no_nodes_node_get_by_nickname(const char *nickname,
1661 : unsigned flags)
1662 : {
1663 1 : rset_get_all_l_no_nodes_node_get_by_nickname_called++;
1664 1 : tt_str_op(nickname, OP_EQ, rset_get_all_l_no_nodes_mock_nickname);
1665 1 : tt_uint_op(flags, OP_EQ, 0);
1666 :
1667 1 : done:
1668 1 : return NULL;
1669 : }
1670 :
1671 : /*
1672 : * Structural test for routerset_get_all_nodes, with the running_only flag
1673 : * is set but the nodes are not running.
1674 : */
1675 :
1676 : static const node_t * rset_get_all_l_not_running_node_get_by_nickname(
1677 : const char *nickname, unsigned flags);
1678 : static int rset_get_all_l_not_running_node_get_by_nickname_called = 0;
1679 : static const char *rset_get_all_l_not_running_mock_nickname;
1680 : static node_t rset_get_all_l_not_running_mock_node;
1681 :
1682 : static void
1683 1 : test_rset_get_all_l_not_running(void *arg)
1684 : {
1685 1 : smartlist_t *out = smartlist_new();
1686 1 : routerset_t *set = routerset_new();
1687 1 : int out_len;
1688 1 : (void)arg;
1689 :
1690 1 : MOCK(node_get_by_nickname,
1691 : rset_get_all_l_not_running_node_get_by_nickname);
1692 :
1693 1 : rset_get_all_l_not_running_mock_node.is_running = 0;
1694 1 : rset_get_all_l_not_running_mock_nickname = "foo";
1695 1 : smartlist_add_strdup(set->list, rset_get_all_l_not_running_mock_nickname);
1696 :
1697 1 : routerset_get_all_nodes(out, set, NULL, 1);
1698 1 : out_len = smartlist_len(out);
1699 :
1700 1 : smartlist_free(out);
1701 1 : routerset_free(set);
1702 :
1703 1 : tt_int_op(out_len, OP_EQ, 0);
1704 1 : tt_int_op(rset_get_all_l_not_running_node_get_by_nickname_called, OP_EQ, 1);
1705 :
1706 1 : done:
1707 1 : ;
1708 1 : }
1709 :
1710 : const node_t *
1711 1 : rset_get_all_l_not_running_node_get_by_nickname(const char *nickname,
1712 : unsigned flags)
1713 : {
1714 1 : rset_get_all_l_not_running_node_get_by_nickname_called++;
1715 1 : tt_str_op(nickname, OP_EQ, rset_get_all_l_not_running_mock_nickname);
1716 1 : tt_int_op(flags, OP_EQ, 0);
1717 :
1718 1 : done:
1719 1 : return &rset_get_all_l_not_running_mock_node;
1720 : }
1721 :
1722 : /*
1723 : * Structural test for routerset_get_all_nodes.
1724 : */
1725 :
1726 : static const node_t * rset_get_all_list_node_get_by_nickname(
1727 : const char *nickname, unsigned flags);
1728 : static int rset_get_all_list_node_get_by_nickname_called = 0;
1729 : static char *rset_get_all_list_mock_nickname;
1730 : static node_t rset_get_all_list_mock_node;
1731 :
1732 : static void
1733 1 : test_rset_get_all_list(void *arg)
1734 : {
1735 1 : smartlist_t *out = smartlist_new();
1736 1 : routerset_t *set = routerset_new();
1737 1 : int out_len;
1738 1 : node_t *ent;
1739 1 : (void)arg;
1740 :
1741 1 : MOCK(node_get_by_nickname,
1742 : rset_get_all_list_node_get_by_nickname);
1743 :
1744 1 : rset_get_all_list_mock_nickname = tor_strdup("foo");
1745 1 : smartlist_add(set->list, rset_get_all_list_mock_nickname);
1746 :
1747 1 : routerset_get_all_nodes(out, set, NULL, 0);
1748 1 : out_len = smartlist_len(out);
1749 1 : ent = (node_t *)smartlist_get(out, 0);
1750 :
1751 1 : smartlist_free(out);
1752 1 : routerset_free(set);
1753 :
1754 1 : tt_int_op(out_len, OP_EQ, 1);
1755 1 : tt_ptr_op(ent, OP_EQ, &rset_get_all_list_mock_node);
1756 1 : tt_int_op(rset_get_all_list_node_get_by_nickname_called, OP_EQ, 1);
1757 :
1758 1 : done:
1759 1 : ;
1760 1 : }
1761 :
1762 : const node_t *
1763 1 : rset_get_all_list_node_get_by_nickname(const char *nickname, unsigned flags)
1764 : {
1765 1 : rset_get_all_list_node_get_by_nickname_called++;
1766 1 : tt_str_op(nickname, OP_EQ, rset_get_all_list_mock_nickname);
1767 1 : tt_int_op(flags, OP_EQ, 0);
1768 :
1769 1 : done:
1770 1 : return &rset_get_all_list_mock_node;
1771 : }
1772 :
1773 : /*
1774 : * Structural test for routerset_get_all_nodes, when the nodelist has no nodes.
1775 : */
1776 :
1777 : static const smartlist_t * rset_get_all_n_no_nodes_nodelist_get_list(void);
1778 : static int rset_get_all_n_no_nodes_nodelist_get_list_called = 0;
1779 :
1780 : static smartlist_t *rset_get_all_n_no_nodes_mock_smartlist;
1781 : static void
1782 1 : test_rset_get_all_n_no_nodes(void *arg)
1783 : {
1784 1 : routerset_t *set = routerset_new();
1785 1 : smartlist_t *out = smartlist_new();
1786 1 : int r;
1787 1 : (void)arg;
1788 :
1789 1 : MOCK(nodelist_get_list,
1790 : rset_get_all_n_no_nodes_nodelist_get_list);
1791 :
1792 1 : smartlist_add_strdup(set->country_names, "{xx}");
1793 1 : rset_get_all_n_no_nodes_mock_smartlist = smartlist_new();
1794 :
1795 1 : routerset_get_all_nodes(out, set, NULL, 1);
1796 1 : r = smartlist_len(out);
1797 1 : routerset_free(set);
1798 1 : smartlist_free(out);
1799 1 : smartlist_free(rset_get_all_n_no_nodes_mock_smartlist);
1800 :
1801 1 : tt_int_op(r, OP_EQ, 0);
1802 1 : tt_int_op(rset_get_all_n_no_nodes_nodelist_get_list_called, OP_EQ, 1);
1803 :
1804 1 : done:
1805 1 : ;
1806 1 : }
1807 :
1808 : const smartlist_t *
1809 1 : rset_get_all_n_no_nodes_nodelist_get_list(void)
1810 : {
1811 1 : rset_get_all_n_no_nodes_nodelist_get_list_called++;
1812 :
1813 1 : return rset_get_all_n_no_nodes_mock_smartlist;
1814 : }
1815 :
1816 : /*
1817 : * Structural test for routerset_get_all_nodes, with a non-list routerset
1818 : * the running_only flag is set, but the nodes are not running.
1819 : */
1820 :
1821 : static const smartlist_t * rset_get_all_n_not_running_nodelist_get_list(void);
1822 : static int rset_get_all_n_not_running_nodelist_get_list_called = 0;
1823 :
1824 : static smartlist_t *rset_get_all_n_not_running_mock_smartlist;
1825 : static node_t rset_get_all_n_not_running_mock_node;
1826 :
1827 : static void
1828 1 : test_rset_get_all_n_not_running(void *arg)
1829 : {
1830 1 : routerset_t *set = routerset_new();
1831 1 : smartlist_t *out = smartlist_new();
1832 1 : int r;
1833 1 : (void)arg;
1834 :
1835 1 : MOCK(nodelist_get_list,
1836 : rset_get_all_n_not_running_nodelist_get_list);
1837 :
1838 1 : smartlist_add_strdup(set->country_names, "{xx}");
1839 1 : rset_get_all_n_not_running_mock_smartlist = smartlist_new();
1840 1 : rset_get_all_n_not_running_mock_node.is_running = 0;
1841 1 : smartlist_add(rset_get_all_n_not_running_mock_smartlist,
1842 : (void *)&rset_get_all_n_not_running_mock_node);
1843 :
1844 1 : routerset_get_all_nodes(out, set, NULL, 1);
1845 1 : r = smartlist_len(out);
1846 1 : routerset_free(set);
1847 1 : smartlist_free(out);
1848 1 : smartlist_free(rset_get_all_n_not_running_mock_smartlist);
1849 :
1850 1 : tt_int_op(r, OP_EQ, 0);
1851 1 : tt_int_op(rset_get_all_n_not_running_nodelist_get_list_called, OP_EQ, 1);
1852 :
1853 1 : done:
1854 1 : ;
1855 1 : }
1856 :
1857 : const smartlist_t *
1858 1 : rset_get_all_n_not_running_nodelist_get_list(void)
1859 : {
1860 1 : rset_get_all_n_not_running_nodelist_get_list_called++;
1861 :
1862 1 : return rset_get_all_n_not_running_mock_smartlist;
1863 : }
1864 :
1865 : /*
1866 : * Functional test for routerset_subtract_nodes.
1867 : */
1868 :
1869 : static void
1870 1 : test_rset_subtract_nodes(void *arg)
1871 : {
1872 1 : routerset_t *set = routerset_new();
1873 1 : smartlist_t *list = smartlist_new();
1874 1 : const char *nickname = "foo";
1875 1 : routerinfo_t ri;
1876 1 : node_t mock_node;
1877 1 : (void)arg;
1878 :
1879 1 : strmap_set_lc(set->names, nickname, (void *)1);
1880 :
1881 1 : ri.nickname = (char *)nickname;
1882 1 : mock_node.rs = NULL;
1883 1 : mock_node.ri = &ri;
1884 1 : smartlist_add(list, (void *)&mock_node);
1885 :
1886 1 : tt_int_op(smartlist_len(list), OP_NE, 0);
1887 1 : routerset_subtract_nodes(list, set);
1888 :
1889 1 : tt_int_op(smartlist_len(list), OP_EQ, 0);
1890 1 : done:
1891 1 : routerset_free(set);
1892 1 : smartlist_free(list);
1893 1 : }
1894 :
1895 : /*
1896 : * Functional test for routerset_subtract_nodes, with a NULL routerset.
1897 : */
1898 :
1899 : static void
1900 1 : test_rset_subtract_nodes_null_routerset(void *arg)
1901 : {
1902 1 : routerset_t *set = NULL;
1903 1 : smartlist_t *list = smartlist_new();
1904 1 : const char *nickname = "foo";
1905 1 : routerinfo_t ri;
1906 1 : node_t mock_node;
1907 1 : (void)arg;
1908 :
1909 1 : ri.nickname = (char *)nickname;
1910 1 : mock_node.ri = &ri;
1911 1 : smartlist_add(list, (void *)&mock_node);
1912 :
1913 1 : tt_int_op(smartlist_len(list), OP_NE, 0);
1914 1 : routerset_subtract_nodes(list, set);
1915 :
1916 1 : tt_int_op(smartlist_len(list), OP_NE, 0);
1917 1 : done:
1918 1 : routerset_free(set);
1919 1 : smartlist_free(list);
1920 1 : }
1921 :
1922 : /*
1923 : * Functional test for routerset_to_string.
1924 : */
1925 :
1926 : static void
1927 1 : test_rset_to_string(void *arg)
1928 : {
1929 1 : routerset_t *set = NULL;
1930 1 : char *s = NULL;
1931 1 : (void)arg;
1932 :
1933 1 : set = NULL;
1934 1 : s = routerset_to_string(set);
1935 1 : tt_str_op(s, OP_EQ, "");
1936 1 : tor_free(s);
1937 :
1938 1 : set = routerset_new();
1939 1 : s = routerset_to_string(set);
1940 1 : tt_str_op(s, OP_EQ, "");
1941 1 : tor_free(s);
1942 1 : routerset_free(set); set = NULL;
1943 :
1944 1 : set = routerset_new();
1945 1 : smartlist_add(set->list, tor_strndup("a", 1));
1946 1 : s = routerset_to_string(set);
1947 1 : tt_str_op(s, OP_EQ, "a");
1948 1 : tor_free(s);
1949 1 : routerset_free(set); set = NULL;
1950 :
1951 1 : set = routerset_new();
1952 1 : smartlist_add(set->list, tor_strndup("a", 1));
1953 1 : smartlist_add(set->list, tor_strndup("b", 1));
1954 1 : s = routerset_to_string(set);
1955 1 : tt_str_op(s, OP_EQ, "a,b");
1956 1 : tor_free(s);
1957 1 : routerset_free(set); set = NULL;
1958 :
1959 1 : done:
1960 1 : tor_free(s);
1961 1 : routerset_free(set);
1962 1 : }
1963 :
1964 : /*
1965 : * Functional test for routerset_equal, with both routersets empty.
1966 : */
1967 :
1968 : static void
1969 1 : test_rset_equal_empty_empty(void *arg)
1970 : {
1971 1 : routerset_t *a = routerset_new(), *b = routerset_new();
1972 1 : int r;
1973 1 : (void)arg;
1974 :
1975 1 : r = routerset_equal(a, b);
1976 1 : routerset_free(a);
1977 1 : routerset_free(b);
1978 :
1979 1 : tt_int_op(r, OP_EQ, 1);
1980 :
1981 1 : done:
1982 1 : ;
1983 1 : }
1984 :
1985 : /*
1986 : * Functional test for routerset_equal, with one routersets empty.
1987 : */
1988 :
1989 : static void
1990 1 : test_rset_equal_empty_not_empty(void *arg)
1991 : {
1992 1 : routerset_t *a = routerset_new(), *b = routerset_new();
1993 1 : int r;
1994 1 : (void)arg;
1995 :
1996 1 : smartlist_add_strdup(b->list, "{xx}");
1997 1 : r = routerset_equal(a, b);
1998 1 : routerset_free(a);
1999 1 : routerset_free(b);
2000 :
2001 1 : tt_int_op(r, OP_EQ, 0);
2002 1 : done:
2003 1 : ;
2004 1 : }
2005 :
2006 : /*
2007 : * Functional test for routerset_equal, with the routersets having
2008 : * differing lengths.
2009 : */
2010 :
2011 : static void
2012 1 : test_rset_equal_differing_lengths(void *arg)
2013 : {
2014 1 : routerset_t *a = routerset_new(), *b = routerset_new();
2015 1 : int r;
2016 1 : (void)arg;
2017 :
2018 1 : smartlist_add_strdup(a->list, "{aa}");
2019 1 : smartlist_add_strdup(b->list, "{b1}");
2020 1 : smartlist_add_strdup(b->list, "{b2}");
2021 1 : r = routerset_equal(a, b);
2022 1 : routerset_free(a);
2023 1 : routerset_free(b);
2024 :
2025 1 : tt_int_op(r, OP_EQ, 0);
2026 1 : done:
2027 1 : ;
2028 1 : }
2029 :
2030 : /*
2031 : * Functional test for routerset_equal, with the routersets being
2032 : * different.
2033 : */
2034 :
2035 : static void
2036 1 : test_rset_equal_unequal(void *arg)
2037 : {
2038 1 : routerset_t *a = routerset_new(), *b = routerset_new();
2039 1 : int r;
2040 1 : (void)arg;
2041 :
2042 1 : smartlist_add_strdup(a->list, "foo");
2043 1 : smartlist_add_strdup(b->list, "bar");
2044 1 : r = routerset_equal(a, b);
2045 1 : routerset_free(a);
2046 1 : routerset_free(b);
2047 :
2048 1 : tt_int_op(r, OP_EQ, 0);
2049 1 : done:
2050 1 : ;
2051 1 : }
2052 :
2053 : /*
2054 : * Functional test for routerset_equal, with the routersets being
2055 : * equal.
2056 : */
2057 :
2058 : static void
2059 1 : test_rset_equal_equal(void *arg)
2060 : {
2061 1 : routerset_t *a = routerset_new(), *b = routerset_new();
2062 1 : int r;
2063 1 : (void)arg;
2064 :
2065 1 : smartlist_add_strdup(a->list, "foo");
2066 1 : smartlist_add_strdup(b->list, "foo");
2067 1 : r = routerset_equal(a, b);
2068 1 : routerset_free(a);
2069 1 : routerset_free(b);
2070 :
2071 1 : tt_int_op(r, OP_EQ, 1);
2072 1 : done:
2073 1 : ;
2074 1 : }
2075 :
2076 : /*
2077 : * Structural test for routerset_free, where the routerset is NULL.
2078 : */
2079 :
2080 : static void rset_free_null_routerset_smartlist_free_(smartlist_t *sl);
2081 : static int rset_free_null_routerset_smartlist_free__called = 0;
2082 :
2083 : static void
2084 1 : test_rset_free_null_routerset(void *arg)
2085 : {
2086 1 : (void)arg;
2087 :
2088 1 : MOCK(smartlist_free_,
2089 : rset_free_null_routerset_smartlist_free_);
2090 :
2091 1 : routerset_free_(NULL);
2092 :
2093 1 : tt_int_op(rset_free_null_routerset_smartlist_free__called, OP_EQ, 0);
2094 :
2095 1 : done:
2096 1 : ;
2097 1 : }
2098 :
2099 : void
2100 0 : rset_free_null_routerset_smartlist_free_(smartlist_t *s)
2101 : {
2102 0 : (void)s;
2103 0 : rset_free_null_routerset_smartlist_free__called++;
2104 0 : }
2105 :
2106 : /*
2107 : * Structural test for routerset_free.
2108 : */
2109 :
2110 : static void rset_free_smartlist_free_(smartlist_t *sl);
2111 : static int rset_free_smartlist_free__called = 0;
2112 : static void rset_free_strmap_free_(strmap_t *map, void (*free_val)(void*));
2113 : static int rset_free_strmap_free__called = 0;
2114 : static void rset_free_digestmap_free_(digestmap_t *map,
2115 : void (*free_val)(void*));
2116 : static int rset_free_digestmap_free__called = 0;
2117 :
2118 : static void
2119 1 : test_rset_free(void *arg)
2120 : {
2121 1 : routerset_t *routerset = routerset_new();
2122 1 : (void)arg;
2123 :
2124 1 : MOCK(smartlist_free_,
2125 : rset_free_smartlist_free_);
2126 1 : MOCK(strmap_free_,
2127 : rset_free_strmap_free_);
2128 1 : MOCK(digestmap_free_,
2129 : rset_free_digestmap_free_);
2130 :
2131 1 : routerset_free(routerset);
2132 :
2133 1 : tt_int_op(rset_free_smartlist_free__called, OP_NE, 0);
2134 1 : tt_int_op(rset_free_strmap_free__called, OP_NE, 0);
2135 1 : tt_int_op(rset_free_digestmap_free__called, OP_NE, 0);
2136 :
2137 1 : done:
2138 1 : ;
2139 1 : }
2140 :
2141 : void
2142 3 : rset_free_smartlist_free_(smartlist_t *s)
2143 : {
2144 3 : rset_free_smartlist_free__called++;
2145 3 : smartlist_free___real(s);
2146 3 : }
2147 :
2148 : void
2149 1 : rset_free_strmap_free_(strmap_t *map, void (*free_val)(void*))
2150 : {
2151 1 : rset_free_strmap_free__called++;
2152 1 : strmap_free___real(map, free_val);
2153 1 : }
2154 :
2155 : void
2156 1 : rset_free_digestmap_free_(digestmap_t *map, void (*free_val)(void*))
2157 : {
2158 1 : rset_free_digestmap_free__called++;
2159 1 : digestmap_free___real(map, free_val);
2160 1 : }
2161 :
2162 : struct testcase_t routerset_tests[] = {
2163 : { "new", test_rset_new, TT_FORK, NULL, NULL },
2164 : { "get_countryname", test_rset_get_countryname, TT_FORK, NULL, NULL },
2165 : { "is_list", test_rset_is_list, TT_FORK, NULL, NULL },
2166 : { "needs_geoip", test_rset_needs_geoip, TT_FORK, NULL, NULL },
2167 : { "is_empty", test_rset_is_empty, TT_FORK, NULL, NULL },
2168 : { "contains_null_set_or_list", test_rset_contains_null_set_or_list,
2169 : TT_FORK, NULL, NULL },
2170 : { "contains_nickname", test_rset_contains_nickname, TT_FORK, NULL, NULL },
2171 : { "contains_null_nickname", test_rset_contains_null_nickname,
2172 : TT_FORK, NULL, NULL },
2173 : { "contains_no_nickname", test_rset_contains_no_nickname,
2174 : TT_FORK, NULL, NULL },
2175 : { "contains_digest", test_rset_contains_digest, TT_FORK, NULL, NULL },
2176 : { "contains_no_digest", test_rset_contains_no_digest, TT_FORK, NULL, NULL },
2177 : { "contains_null_digest", test_rset_contains_null_digest,
2178 : TT_FORK, NULL, NULL },
2179 : { "contains_addr", test_rset_contains_addr, TT_FORK, NULL, NULL },
2180 : { "contains_no_addr", test_rset_contains_no_addr, TT_FORK, NULL, NULL },
2181 : { "contains_null_addr", test_rset_contains_null_addr, TT_FORK, NULL, NULL },
2182 : { "contains_countries_no_geoip", test_rset_countries_no_geoip,
2183 : TT_FORK, NULL, NULL },
2184 : { "contains_countries_geoip", test_rset_countries_geoip,
2185 : TT_FORK, NULL, NULL },
2186 : { "add_unknown_ccs_only_flag", test_rset_add_unknown_ccs_only_flag,
2187 : TT_FORK, NULL, NULL },
2188 : { "add_unknown_ccs_creates_set", test_rset_add_unknown_ccs_creates_set,
2189 : TT_FORK, NULL, NULL },
2190 : { "add_unknown_ccs_add_unknown", test_rset_add_unknown_ccs_add_unknown,
2191 : TT_FORK, NULL, NULL },
2192 : { "add_unknown_ccs_add_a1", test_rset_add_unknown_ccs_add_a1,
2193 : TT_FORK, NULL, NULL },
2194 : { "contains_extendinfo", test_rset_contains_extendinfo,
2195 : TT_FORK, NULL, NULL },
2196 : { "contains_router", test_rset_contains_router, TT_FORK, NULL, NULL },
2197 : { "contains_router_ipv4", test_rset_contains_router_ipv4,
2198 : TT_FORK, NULL, NULL },
2199 : { "contains_router_ipv6", test_rset_contains_router_ipv6,
2200 : TT_FORK, NULL, NULL },
2201 : { "contains_routerstatus", test_rset_contains_routerstatus,
2202 : TT_FORK, NULL, NULL },
2203 : { "contains_none", test_rset_contains_none, TT_FORK, NULL, NULL },
2204 : { "contains_routerinfo", test_rset_contains_routerinfo,
2205 : TT_FORK, NULL, NULL },
2206 : { "contains_rs", test_rset_contains_rs, TT_FORK, NULL, NULL },
2207 : { "get_all_no_routerset", test_rset_get_all_no_routerset,
2208 : TT_FORK, NULL, NULL },
2209 : { "get_all_l_no_nodes", test_rset_get_all_l_no_nodes, TT_FORK, NULL, NULL },
2210 : { "get_all_l_not_running", test_rset_get_all_l_not_running,
2211 : TT_FORK, NULL, NULL },
2212 : { "get_all_list", test_rset_get_all_list, TT_FORK, NULL, NULL },
2213 : { "get_all_n_no_nodes", test_rset_get_all_n_no_nodes, TT_FORK, NULL, NULL },
2214 : { "get_all_n_not_running", test_rset_get_all_n_not_running,
2215 : TT_FORK, NULL, NULL },
2216 : { "refresh_geoip_not_loaded", test_rset_refresh_geoip_not_loaded,
2217 : TT_FORK, NULL, NULL },
2218 : { "refresh_no_countries", test_rset_refresh_no_countries,
2219 : TT_FORK, NULL, NULL },
2220 : { "refresh_one_valid_country", test_rset_refresh_one_valid_country,
2221 : TT_FORK, NULL, NULL },
2222 : { "refresh_one_invalid_country", test_rset_refresh_one_invalid_country,
2223 : TT_FORK, NULL, NULL },
2224 : { "union_source_bad", test_rset_union_source_bad, TT_FORK, NULL, NULL },
2225 : { "union_one", test_rset_union_one, TT_FORK, NULL, NULL },
2226 : { "parse_malformed", test_rset_parse_malformed, TT_FORK, NULL, NULL },
2227 : { "parse_valid_hexdigest", test_rset_parse_valid_hexdigest,
2228 : TT_FORK, NULL, NULL },
2229 : { "parse_valid_nickname", test_rset_parse_valid_nickname,
2230 : TT_FORK, NULL, NULL },
2231 : { "parse_get_countryname", test_rset_parse_get_countryname,
2232 : TT_FORK, NULL, NULL },
2233 : { "parse_policy_wildcard", test_rset_parse_policy_wildcard,
2234 : TT_FORK, NULL, NULL },
2235 : { "parse_policy_ipv4", test_rset_parse_policy_ipv4, TT_FORK, NULL, NULL },
2236 : { "parse_policy_ipv6", test_rset_parse_policy_ipv6, TT_FORK, NULL, NULL },
2237 : { "subtract_nodes", test_rset_subtract_nodes, TT_FORK, NULL, NULL },
2238 : { "subtract_nodes_null_routerset", test_rset_subtract_nodes_null_routerset,
2239 : TT_FORK, NULL, NULL },
2240 : { "to_string", test_rset_to_string, TT_FORK, NULL, NULL },
2241 : { "equal_empty_empty", test_rset_equal_empty_empty, TT_FORK, NULL, NULL },
2242 : { "equal_empty_not_empty", test_rset_equal_empty_not_empty,
2243 : TT_FORK, NULL, NULL },
2244 : { "equal_differing_lengths", test_rset_equal_differing_lengths,
2245 : TT_FORK, NULL, NULL },
2246 : { "equal_unequal", test_rset_equal_unequal, TT_FORK, NULL, NULL },
2247 : { "equal_equal", test_rset_equal_equal, TT_FORK, NULL, NULL },
2248 : { "free_null_routerset", test_rset_free_null_routerset,
2249 : TT_FORK, NULL, NULL },
2250 : { "free", test_rset_free, TT_FORK, NULL, NULL },
2251 : END_OF_TESTCASES
2252 : };
|