Prop210: Refactor connection_get_* to produce lists and counts
[tor.git] / src / test / test_rendcache.c
blob77796994b421604e3b26cbafad2b1439de42e672
1 /* Copyright (c) 2010-2015, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #include "orconfig.h"
5 #include "or.h"
7 #include "test.h"
8 #define RENDCACHE_PRIVATE
9 #include "rendcache.h"
10 #include "router.h"
11 #include "routerlist.h"
12 #include "config.h"
13 #include <openssl/rsa.h>
14 #include "rend_test_helpers.h"
16 #define NS_MODULE rend_cache
18 static const int RECENT_TIME = -10;
19 static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \
20 REND_CACHE_MAX_SKEW + 10);
21 static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 10;
23 extern strmap_t *rend_cache;
24 extern digestmap_t *rend_cache_v2_dir;
25 extern strmap_t *rend_cache_failure;
26 extern size_t rend_cache_total_allocation;
28 static rend_data_t *
29 mock_rend_data(const char *onion_address)
31 rend_data_t *rend_query = tor_malloc_zero(sizeof(rend_data_t));
33 strlcpy(rend_query->onion_address, onion_address,
34 sizeof(rend_query->onion_address));
35 rend_query->auth_type = REND_NO_AUTH;
36 rend_query->hsdirs_fp = smartlist_new();
37 smartlist_add(rend_query->hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa",
38 DIGEST_LEN));
40 return rend_query;
43 static void
44 test_rend_cache_lookup_entry(void *data)
46 int ret;
47 rend_data_t *mock_rend_query = NULL;
48 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
49 rend_cache_entry_t *entry = NULL;
50 rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
51 char *service_id = NULL;
52 (void)data;
54 rend_cache_init();
56 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
58 ret = rend_cache_lookup_entry("abababababababab", 0, NULL);
59 tt_int_op(ret, OP_EQ, -ENOENT);
61 ret = rend_cache_lookup_entry("invalid query", 2, NULL);
62 tt_int_op(ret, OP_EQ, -EINVAL);
64 ret = rend_cache_lookup_entry("abababababababab", 2, NULL);
65 tt_int_op(ret, OP_EQ, -ENOENT);
67 ret = rend_cache_lookup_entry("abababababababab", 4224, NULL);
68 tt_int_op(ret, OP_EQ, -ENOENT);
70 mock_rend_query = mock_rend_data(service_id);
71 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
72 DIGEST_LEN);
73 rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32,
74 mock_rend_query, NULL);
76 ret = rend_cache_lookup_entry(service_id, 2, NULL);
77 tt_int_op(ret, OP_EQ, 0);
79 ret = rend_cache_lookup_entry(service_id, 2, &entry);
80 tt_assert(entry);
81 tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str));
82 tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str);
84 done:
85 rend_encoded_v2_service_descriptor_free(desc_holder);
86 tor_free(service_id);
87 rend_cache_free_all();
88 rend_data_free(mock_rend_query);
91 static void
92 test_rend_cache_store_v2_desc_as_client(void *data)
94 rend_cache_store_status_t ret;
95 rend_data_t *mock_rend_query;
96 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
97 rend_cache_entry_t *entry = NULL;
98 rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
99 char *service_id = NULL;
100 char client_cookie[REND_DESC_COOKIE_LEN];
101 (void)data;
103 rend_cache_init();
105 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
107 // Test success
108 mock_rend_query = mock_rend_data(service_id);
109 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
110 DIGEST_LEN);
111 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
112 desc_id_base32, mock_rend_query,
113 &entry);
115 tt_int_op(ret, OP_EQ, RCS_OKAY);
116 tt_assert(entry);
117 tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str));
118 tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str);
120 // Test various failure modes
122 // TODO: a too long desc_id_base32 argument crashes the function
123 /* ret = rend_cache_store_v2_desc_as_client( */
124 /* desc_holder->desc_str, */
125 /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */
126 /* &mock_rend_query, NULL); */
127 /* tt_int_op(ret, OP_EQ, RCS_BADDESC); */
129 // Test bad base32 failure
130 // This causes an assertion failure if we're running with assertions.
131 // But when doing coverage, we can test it.
132 #ifdef TOR_COVERAGE
133 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
134 "!xqunszqnaolrrfmtzgaki7mxelgvkj", mock_rend_query, NULL);
135 tt_int_op(ret, OP_EQ, RCS_BADDESC);
136 #endif
138 // Test invalid descriptor
139 ret = rend_cache_store_v2_desc_as_client("invalid descriptor",
140 "3xqunszqnaolrrfmtzgaki7mxelgvkje", mock_rend_query, NULL);
141 tt_int_op(ret, OP_EQ, RCS_BADDESC);
143 // TODO: it doesn't seem to be possible to test invalid service ID condition.
144 // that means it is likely not possible to have that condition without
145 // earlier conditions failing first (such as signature checking of the desc)
147 rend_cache_free_all();
149 // Test mismatch between service ID and onion address
150 rend_cache_init();
151 strncpy(mock_rend_query->onion_address, "abc", REND_SERVICE_ID_LEN_BASE32+1);
152 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
153 desc_id_base32,
154 mock_rend_query, NULL);
155 tt_int_op(ret, OP_EQ, RCS_BADDESC);
156 rend_cache_free_all();
157 rend_data_free(mock_rend_query);
159 // Test incorrect descriptor ID
160 rend_cache_init();
161 mock_rend_query = mock_rend_data(service_id);
162 desc_id_base32[0]++;
163 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
164 desc_id_base32, mock_rend_query,
165 NULL);
166 tt_int_op(ret, OP_EQ, RCS_BADDESC);
167 desc_id_base32[0]--;
168 rend_cache_free_all();
170 // Test too old descriptor
171 rend_cache_init();
172 rend_encoded_v2_service_descriptor_free(desc_holder);
173 tor_free(service_id);
174 rend_data_free(mock_rend_query);
176 generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3);
177 mock_rend_query = mock_rend_data(service_id);
178 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
179 DIGEST_LEN);
181 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
182 desc_id_base32,
183 mock_rend_query, NULL);
184 tt_int_op(ret, OP_EQ, RCS_BADDESC);
185 rend_cache_free_all();
187 // Test too new descriptor (in the future)
188 rend_cache_init();
189 rend_encoded_v2_service_descriptor_free(desc_holder);
190 tor_free(service_id);
191 rend_data_free(mock_rend_query);
193 generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
194 mock_rend_query = mock_rend_data(service_id);
195 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
196 DIGEST_LEN);
198 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
199 desc_id_base32, mock_rend_query,
200 NULL);
201 tt_int_op(ret, OP_EQ, RCS_BADDESC);
202 rend_cache_free_all();
204 // Test when a descriptor is already in the cache
205 rend_cache_init();
206 rend_encoded_v2_service_descriptor_free(desc_holder);
207 tor_free(service_id);
208 rend_data_free(mock_rend_query);
210 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
211 mock_rend_query = mock_rend_data(service_id);
212 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
213 DIGEST_LEN);
215 rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32,
216 mock_rend_query, NULL);
217 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
218 desc_id_base32, mock_rend_query,
219 NULL);
220 tt_int_op(ret, OP_EQ, RCS_OKAY);
222 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
223 desc_id_base32, mock_rend_query,
224 &entry);
225 tt_int_op(ret, OP_EQ, RCS_OKAY);
226 tt_assert(entry);
227 rend_cache_free_all();
229 // Test unsuccessful decrypting of introduction points
230 rend_cache_init();
231 rend_encoded_v2_service_descriptor_free(desc_holder);
232 tor_free(service_id);
233 rend_data_free(mock_rend_query);
235 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
236 mock_rend_query = mock_rend_data(service_id);
237 mock_rend_query->auth_type = REND_BASIC_AUTH;
238 client_cookie[0] = 'A';
239 memcpy(mock_rend_query->descriptor_cookie, client_cookie,
240 REND_DESC_COOKIE_LEN);
241 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
242 DIGEST_LEN);
243 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
244 desc_id_base32, mock_rend_query,
245 NULL);
246 tt_int_op(ret, OP_EQ, RCS_OKAY);
247 rend_cache_free_all();
249 // Test successful run when we have REND_BASIC_AUTH but not cookie
250 rend_cache_init();
251 rend_encoded_v2_service_descriptor_free(desc_holder);
252 tor_free(service_id);
253 rend_data_free(mock_rend_query);
255 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
256 mock_rend_query = mock_rend_data(service_id);
257 mock_rend_query->auth_type = REND_BASIC_AUTH;
258 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
259 DIGEST_LEN);
260 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
261 desc_id_base32, mock_rend_query,
262 NULL);
263 tt_int_op(ret, OP_EQ, RCS_OKAY);
265 rend_cache_free_all();
267 // Test when we have no introduction points
268 rend_cache_init();
269 rend_encoded_v2_service_descriptor_free(desc_holder);
270 tor_free(service_id);
271 rend_data_free(mock_rend_query);
273 generate_desc(RECENT_TIME, &desc_holder, &service_id, 0);
274 mock_rend_query = mock_rend_data(service_id);
275 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
276 DIGEST_LEN);
277 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
278 desc_id_base32, mock_rend_query,
279 NULL);
280 tt_int_op(ret, OP_EQ, RCS_BADDESC);
281 rend_cache_free_all();
283 // Test when we have too many intro points
284 rend_cache_init();
285 rend_encoded_v2_service_descriptor_free(desc_holder);
286 tor_free(service_id);
287 rend_data_free(mock_rend_query);
289 generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1);
290 mock_rend_query = mock_rend_data(service_id);
291 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
292 DIGEST_LEN);
293 ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
294 desc_id_base32, mock_rend_query,
295 NULL);
296 tt_int_op(ret, OP_EQ, RCS_BADDESC);
298 done:
299 rend_encoded_v2_service_descriptor_free(desc_holder);
300 tor_free(service_id);
301 rend_cache_free_all();
302 rend_data_free(mock_rend_query);
305 static void
306 test_rend_cache_store_v2_desc_as_client_with_different_time(void *data)
308 rend_cache_store_status_t ret;
309 rend_data_t *mock_rend_query;
310 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
311 rend_service_descriptor_t *generated = NULL;
312 smartlist_t *descs = smartlist_new();
313 time_t t;
314 char *service_id = NULL;
315 rend_encoded_v2_service_descriptor_t *desc_holder_newer;
316 rend_encoded_v2_service_descriptor_t *desc_holder_older;
318 t = time(NULL);
319 rend_cache_init();
321 create_descriptor(&generated, &service_id, 3);
323 generated->timestamp = t + RECENT_TIME;
324 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
325 REND_NO_AUTH, NULL, NULL);
326 desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)
327 smartlist_get(descs, 0));
328 smartlist_set(descs, 0, NULL);
330 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
331 rend_encoded_v2_service_descriptor_free(d));
332 smartlist_free(descs);
333 descs = smartlist_new();
335 generated->timestamp = (t + RECENT_TIME) - 20;
336 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
337 REND_NO_AUTH, NULL, NULL);
338 desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)
339 smartlist_get(descs, 0));
340 smartlist_set(descs, 0, NULL);
341 (void)data;
343 // Test when a descriptor is already in the cache and it is newer than the
344 // one we submit
345 mock_rend_query = mock_rend_data(service_id);
346 base32_encode(desc_id_base32, sizeof(desc_id_base32),
347 desc_holder_newer->desc_id, DIGEST_LEN);
348 rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str,
349 desc_id_base32, mock_rend_query, NULL);
350 ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str,
351 desc_id_base32, mock_rend_query,
352 NULL);
353 tt_int_op(ret, OP_EQ, RCS_OKAY);
355 rend_cache_free_all();
357 // Test when an old descriptor is in the cache and we submit a newer one
358 rend_cache_init();
359 rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str,
360 desc_id_base32, mock_rend_query, NULL);
361 ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str,
362 desc_id_base32, mock_rend_query,
363 NULL);
364 tt_int_op(ret, OP_EQ, RCS_OKAY);
366 done:
367 rend_encoded_v2_service_descriptor_free(desc_holder_newer);
368 rend_encoded_v2_service_descriptor_free(desc_holder_older);
369 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
370 rend_encoded_v2_service_descriptor_free(d));
371 smartlist_free(descs);
372 rend_service_descriptor_free(generated);
373 tor_free(service_id);
374 rend_cache_free_all();
375 rend_data_free(mock_rend_query);
378 #define NS_SUBMODULE lookup_v2_desc_as_dir
379 NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
380 NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id));
382 static routerinfo_t *mock_routerinfo;
383 static int hid_serv_responsible_for_desc_id_response;
385 static const routerinfo_t *
386 NS(router_get_my_routerinfo)(void)
388 if (!mock_routerinfo) {
389 mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
392 return mock_routerinfo;
395 static int
396 NS(hid_serv_responsible_for_desc_id)(const char *id)
398 (void)id;
399 return hid_serv_responsible_for_desc_id_response;
402 static void
403 test_rend_cache_lookup_v2_desc_as_dir(void *data)
405 int ret;
406 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
407 rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
408 char *service_id = NULL;
409 const char *ret_desc = NULL;
411 (void)data;
413 NS_MOCK(router_get_my_routerinfo);
414 NS_MOCK(hid_serv_responsible_for_desc_id);
416 rend_cache_init();
418 // Test invalid base32
419 ret = rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL);
420 tt_int_op(ret, OP_EQ, -1);
422 // Test non-existent descriptor but well formed
423 ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje",
424 NULL);
425 tt_int_op(ret, OP_EQ, 0);
427 // Test existing descriptor
428 hid_serv_responsible_for_desc_id_response = 1;
429 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
430 rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
431 base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
432 DIGEST_LEN);
433 ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc);
434 tt_int_op(ret, OP_EQ, 1);
435 tt_assert(ret_desc);
437 done:
438 NS_UNMOCK(router_get_my_routerinfo);
439 NS_UNMOCK(hid_serv_responsible_for_desc_id);
440 tor_free(mock_routerinfo);
441 rend_cache_free_all();
442 rend_encoded_v2_service_descriptor_free(desc_holder);
443 tor_free(service_id);
446 #undef NS_SUBMODULE
448 #define NS_SUBMODULE store_v2_desc_as_dir
449 NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
450 NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id));
452 static const routerinfo_t *
453 NS(router_get_my_routerinfo)(void)
455 return mock_routerinfo;
458 static int
459 NS(hid_serv_responsible_for_desc_id)(const char *id)
461 (void)id;
462 return hid_serv_responsible_for_desc_id_response;
465 static void
466 test_rend_cache_store_v2_desc_as_dir(void *data)
468 (void)data;
469 rend_cache_store_status_t ret;
470 rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
471 char *service_id = NULL;
473 NS_MOCK(router_get_my_routerinfo);
474 NS_MOCK(hid_serv_responsible_for_desc_id);
476 rend_cache_init();
478 // Test when we are not an HS dir
479 mock_routerinfo = NULL;
480 ret = rend_cache_store_v2_desc_as_dir("");
481 tt_int_op(ret, OP_EQ, RCS_NOTDIR);
483 // Test when we can't parse the descriptor
484 mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
485 hid_serv_responsible_for_desc_id_response = 1;
486 ret = rend_cache_store_v2_desc_as_dir("unparseable");
487 tt_int_op(ret, OP_EQ, RCS_BADDESC);
489 // Test when we are not responsible for an HS
490 hid_serv_responsible_for_desc_id_response = 0;
491 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
492 ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
493 tt_int_op(ret, OP_EQ, RCS_OKAY);
495 rend_encoded_v2_service_descriptor_free(desc_holder);
496 tor_free(service_id);
498 // Test when we have an old descriptor
499 hid_serv_responsible_for_desc_id_response = 1;
500 generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3);
501 ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
502 tt_int_op(ret, OP_EQ, RCS_OKAY);
504 rend_encoded_v2_service_descriptor_free(desc_holder);
505 tor_free(service_id);
507 // Test when we have a descriptor in the future
508 generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
509 ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
510 tt_int_op(ret, OP_EQ, RCS_OKAY);
512 rend_encoded_v2_service_descriptor_free(desc_holder);
513 tor_free(service_id);
515 // Test when two descriptors
516 generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
517 ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
518 tt_int_op(ret, OP_EQ, RCS_OKAY);
520 rend_encoded_v2_service_descriptor_free(desc_holder);
521 tor_free(service_id);
523 // Test when asking for hidden service statistics HiddenServiceStatistics
524 rend_cache_purge();
525 generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
526 get_options_mutable()->HiddenServiceStatistics = 1;
527 ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
528 tt_int_op(ret, OP_EQ, RCS_OKAY);
530 done:
531 NS_UNMOCK(router_get_my_routerinfo);
532 NS_UNMOCK(hid_serv_responsible_for_desc_id);
533 rend_encoded_v2_service_descriptor_free(desc_holder);
534 tor_free(service_id);
535 rend_cache_free_all();
536 tor_free(mock_routerinfo);
539 static void
540 test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data)
542 (void)data;
544 rend_cache_store_status_t ret;
545 rend_service_descriptor_t *generated = NULL;
546 smartlist_t *descs = smartlist_new();
547 time_t t;
548 char *service_id = NULL;
549 rend_encoded_v2_service_descriptor_t *desc_holder_newer;
550 rend_encoded_v2_service_descriptor_t *desc_holder_older;
552 NS_MOCK(router_get_my_routerinfo);
553 NS_MOCK(hid_serv_responsible_for_desc_id);
555 rend_cache_init();
557 t = time(NULL);
559 create_descriptor(&generated, &service_id, 3);
560 generated->timestamp = t + RECENT_TIME;
561 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
562 REND_NO_AUTH, NULL, NULL);
563 desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)
564 smartlist_get(descs, 0));
565 smartlist_set(descs, 0, NULL);
566 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
567 rend_encoded_v2_service_descriptor_free(d));
568 smartlist_free(descs);
569 descs = smartlist_new();
571 generated->timestamp = (t + RECENT_TIME) - 20;
572 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
573 REND_NO_AUTH, NULL, NULL);
574 desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)
575 smartlist_get(descs, 0));
576 smartlist_set(descs, 0, NULL);
578 // Test when we have a newer descriptor stored
579 mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
580 hid_serv_responsible_for_desc_id_response = 1;
581 rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str);
582 ret = rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str);
583 tt_int_op(ret, OP_EQ, RCS_OKAY);
585 // Test when we have an old descriptor stored
586 rend_cache_purge();
587 rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str);
588 ret = rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str);
589 tt_int_op(ret, OP_EQ, RCS_OKAY);
591 done:
592 NS_UNMOCK(router_get_my_routerinfo);
593 NS_UNMOCK(hid_serv_responsible_for_desc_id);
594 rend_cache_free_all();
595 rend_service_descriptor_free(generated);
596 tor_free(service_id);
597 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
598 rend_encoded_v2_service_descriptor_free(d));
599 smartlist_free(descs);
600 rend_encoded_v2_service_descriptor_free(desc_holder_newer);
601 rend_encoded_v2_service_descriptor_free(desc_holder_older);
602 tor_free(mock_routerinfo);
605 static void
606 test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data)
608 (void)data;
610 rend_cache_store_status_t ret;
611 rend_service_descriptor_t *generated = NULL;
612 smartlist_t *descs = smartlist_new();
613 time_t t;
614 char *service_id = NULL;
615 rend_encoded_v2_service_descriptor_t *desc_holder_one = NULL;
616 rend_encoded_v2_service_descriptor_t *desc_holder_two = NULL;
618 NS_MOCK(router_get_my_routerinfo);
619 NS_MOCK(hid_serv_responsible_for_desc_id);
621 rend_cache_init();
623 t = time(NULL);
625 create_descriptor(&generated, &service_id, 3);
626 generated->timestamp = t + RECENT_TIME;
627 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
628 REND_NO_AUTH, NULL, NULL);
629 desc_holder_one = ((rend_encoded_v2_service_descriptor_t *)
630 smartlist_get(descs, 0));
631 smartlist_set(descs, 0, NULL);
633 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
634 rend_encoded_v2_service_descriptor_free(d));
635 smartlist_free(descs);
636 descs = smartlist_new();
638 generated->timestamp = t + RECENT_TIME;
639 generated->protocols = 41;
640 rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
641 REND_NO_AUTH, NULL, NULL);
642 desc_holder_two = ((rend_encoded_v2_service_descriptor_t *)
643 smartlist_get(descs, 0));
644 smartlist_set(descs, 0, NULL);
646 // Test when we have another descriptor stored, with a different descriptor
647 mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
648 hid_serv_responsible_for_desc_id_response = 1;
649 rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str);
650 ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str);
651 tt_int_op(ret, OP_EQ, RCS_OKAY);
653 done:
654 NS_UNMOCK(router_get_my_routerinfo);
655 NS_UNMOCK(hid_serv_responsible_for_desc_id);
656 rend_cache_free_all();
657 rend_service_descriptor_free(generated);
658 tor_free(service_id);
659 SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
660 rend_encoded_v2_service_descriptor_free(d));
661 smartlist_free(descs);
662 rend_encoded_v2_service_descriptor_free(desc_holder_one);
663 rend_encoded_v2_service_descriptor_free(desc_holder_two);
666 #undef NS_SUBMODULE
668 static void
669 test_rend_cache_init(void *data)
671 (void)data;
673 tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting");
674 tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL "
675 "when starting");
676 tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when "
677 "starting");
679 rend_cache_init();
681 tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing");
682 tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL "
683 "after initing");
684 tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL "
685 "after initing");
687 tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
688 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
689 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
691 done:
692 rend_cache_free_all();
695 static void
696 test_rend_cache_decrement_allocation(void *data)
698 (void)data;
700 // Test when the cache has enough allocations
701 rend_cache_total_allocation = 10;
702 rend_cache_decrement_allocation(3);
703 tt_int_op(rend_cache_total_allocation, OP_EQ, 7);
705 // Test when there are not enough allocations
706 rend_cache_total_allocation = 1;
707 rend_cache_decrement_allocation(2);
708 tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
710 // And again
711 rend_cache_decrement_allocation(2);
712 tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
714 done:
715 (void)0;
718 static void
719 test_rend_cache_increment_allocation(void *data)
721 (void)data;
723 // Test when the cache is not overflowing
724 rend_cache_total_allocation = 5;
725 rend_cache_increment_allocation(3);
726 tt_int_op(rend_cache_total_allocation, OP_EQ, 8);
728 // Test when there are too many allocations
729 rend_cache_total_allocation = SIZE_MAX-1;
730 rend_cache_increment_allocation(2);
731 tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
733 // And again
734 rend_cache_increment_allocation(2);
735 tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
737 done:
738 (void)0;
741 static void
742 test_rend_cache_failure_intro_entry_new(void *data)
744 time_t now;
745 rend_cache_failure_intro_t *entry;
746 rend_intro_point_failure_t failure;
748 (void)data;
750 failure = INTRO_POINT_FAILURE_TIMEOUT;
751 now = time(NULL);
752 entry = rend_cache_failure_intro_entry_new(failure);
754 tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT);
755 tt_int_op(entry->created_ts, OP_GE, now-5);
756 tt_int_op(entry->created_ts, OP_LE, now+5);
758 done:
759 tor_free(entry);
762 static void
763 test_rend_cache_failure_intro_lookup(void *data)
765 (void)data;
766 int ret;
767 rend_cache_failure_t *failure;
768 rend_cache_failure_intro_t *ip;
769 rend_cache_failure_intro_t *entry;
770 const char key_ip_one[DIGEST_LEN] = "ip1";
771 const char key_ip_two[DIGEST_LEN] = "ip2";
772 const char key_foo[DIGEST_LEN] = "foo1";
774 rend_cache_init();
776 failure = rend_cache_failure_entry_new();
777 ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
778 digestmap_set(failure->intro_failures, key_ip_one, ip);
779 strmap_set_lc(rend_cache_failure, "foo1", failure);
781 // Test not found
782 ret = cache_failure_intro_lookup((const uint8_t *) key_foo, "foo2", NULL);
783 tt_int_op(ret, OP_EQ, 0);
785 // Test found with no intro failures in it
786 ret = cache_failure_intro_lookup((const uint8_t *) key_ip_two, "foo1", NULL);
787 tt_int_op(ret, OP_EQ, 0);
789 // Test found
790 ret = cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", NULL);
791 tt_int_op(ret, OP_EQ, 1);
793 // Test found and asking for entry
794 cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", &entry);
795 tt_assert(entry);
796 tt_assert(entry == ip);
798 done:
799 rend_cache_free_all();
802 static void
803 test_rend_cache_clean(void *data)
805 rend_cache_entry_t *one, *two;
806 rend_service_descriptor_t *desc_one, *desc_two;
807 strmap_iter_t *iter = NULL;
808 const char *key;
809 void *val;
811 (void)data;
813 rend_cache_init();
815 // Test with empty rendcache
816 rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
817 tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
819 // Test with two old entries
820 one = tor_malloc_zero(sizeof(rend_cache_entry_t));
821 two = tor_malloc_zero(sizeof(rend_cache_entry_t));
822 desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
823 desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t));
824 one->parsed = desc_one;
825 two->parsed = desc_two;
827 desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST;
828 desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10;
829 desc_one->pk = pk_generate(0);
830 desc_two->pk = pk_generate(1);
832 strmap_set_lc(rend_cache, "foo1", one);
833 strmap_set_lc(rend_cache, "foo2", two);
835 rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
836 tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
838 // Test with one old entry and one newer entry
839 one = tor_malloc_zero(sizeof(rend_cache_entry_t));
840 two = tor_malloc_zero(sizeof(rend_cache_entry_t));
841 desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
842 desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t));
843 one->parsed = desc_one;
844 two->parsed = desc_two;
846 desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10;
847 desc_two->timestamp = time(NULL) - 100;
848 desc_one->pk = pk_generate(0);
849 desc_two->pk = pk_generate(1);
851 strmap_set_lc(rend_cache, "foo1", one);
852 strmap_set_lc(rend_cache, "foo2", two);
854 rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
855 tt_int_op(strmap_size(rend_cache), OP_EQ, 1);
857 iter = strmap_iter_init(rend_cache);
858 strmap_iter_get(iter, &key, &val);
859 tt_str_op(key, OP_EQ, "foo2");
861 done:
862 rend_cache_free_all();
865 static void
866 test_rend_cache_failure_entry_new(void *data)
868 rend_cache_failure_t *failure;
870 (void)data;
872 failure = rend_cache_failure_entry_new();
873 tt_assert(failure);
874 tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 0);
876 done:
877 rend_cache_failure_entry_free(failure);
880 static void
881 test_rend_cache_failure_entry_free(void *data)
883 (void)data;
885 // Test that it can deal with a NULL argument
886 rend_cache_failure_entry_free(NULL);
888 /* done: */
889 /* (void)0; */
892 static void
893 test_rend_cache_failure_clean(void *data)
895 rend_cache_failure_t *failure;
896 rend_cache_failure_intro_t *ip_one, *ip_two;
898 const char key_one[DIGEST_LEN] = "ip1";
899 const char key_two[DIGEST_LEN] = "ip2";
901 (void)data;
903 rend_cache_init();
905 // Test with empty failure cache
906 rend_cache_failure_clean(time(NULL));
907 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
909 // Test with one empty failure entry
910 failure = rend_cache_failure_entry_new();
911 strmap_set_lc(rend_cache_failure, "foo1", failure);
912 rend_cache_failure_clean(time(NULL));
913 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
915 // Test with one new intro point
916 failure = rend_cache_failure_entry_new();
917 ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
918 digestmap_set(failure->intro_failures, key_one, ip_one);
919 strmap_set_lc(rend_cache_failure, "foo1", failure);
920 rend_cache_failure_clean(time(NULL));
921 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1);
923 // Test with one old intro point
924 rend_cache_failure_purge();
925 failure = rend_cache_failure_entry_new();
926 ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
927 ip_one->created_ts = time(NULL) - 7*60;
928 digestmap_set(failure->intro_failures, key_one, ip_one);
929 strmap_set_lc(rend_cache_failure, "foo1", failure);
930 rend_cache_failure_clean(time(NULL));
931 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
933 // Test with one old intro point and one new one
934 rend_cache_failure_purge();
935 failure = rend_cache_failure_entry_new();
936 ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
937 ip_one->created_ts = time(NULL) - 7*60;
938 digestmap_set(failure->intro_failures, key_one, ip_one);
939 ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
940 ip_two->created_ts = time(NULL) - 2*60;
941 digestmap_set(failure->intro_failures, key_two, ip_two);
942 strmap_set_lc(rend_cache_failure, "foo1", failure);
943 rend_cache_failure_clean(time(NULL));
944 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1);
945 tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1);
947 done:
948 rend_cache_free_all();
951 static void
952 test_rend_cache_failure_remove(void *data)
954 rend_service_descriptor_t *desc;
955 (void)data;
957 rend_cache_init();
959 // Test that it deals well with a NULL desc
960 rend_cache_failure_remove(NULL);
962 // Test a descriptor that isn't in the cache
963 desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
964 desc->pk = pk_generate(0);
965 rend_cache_failure_remove(desc);
967 // There seems to not exist any way of getting rend_cache_failure_remove()
968 // to fail because of a problem with rend_get_service_id from here
969 rend_cache_free_all();
971 rend_service_descriptor_free(desc);
972 /* done: */
973 /* (void)0; */
976 static void
977 test_rend_cache_free_all(void *data)
979 rend_cache_failure_t *failure;
980 rend_cache_entry_t *one;
981 rend_service_descriptor_t *desc_one;
983 (void)data;
985 rend_cache_init();
987 failure = rend_cache_failure_entry_new();
988 strmap_set_lc(rend_cache_failure, "foo1", failure);
990 one = tor_malloc_zero(sizeof(rend_cache_entry_t));
991 desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
992 one->parsed = desc_one;
993 desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST;
994 desc_one->pk = pk_generate(0);
995 strmap_set_lc(rend_cache, "foo1", one);
997 rend_cache_free_all();
999 tt_assert(!rend_cache);
1000 tt_assert(!rend_cache_v2_dir);
1001 tt_assert(!rend_cache_failure);
1002 tt_assert(!rend_cache_total_allocation);
1004 done:
1005 rend_cache_free_all();
1008 static void
1009 test_rend_cache_entry_free(void *data)
1011 (void)data;
1012 rend_cache_entry_t *e;
1014 // Handles NULL correctly
1015 rend_cache_entry_free(NULL);
1017 // Handles NULL descriptor correctly
1018 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1019 rend_cache_entry_free(e);
1021 // Handles non-NULL descriptor correctly
1022 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1023 e->desc = (char *)malloc(10);
1024 rend_cache_entry_free(e);
1026 /* done: */
1027 /* (void)0; */
1030 static void
1031 test_rend_cache_purge(void *data)
1033 (void)data;
1035 // Deals with a NULL rend_cache
1036 rend_cache_purge();
1037 tt_assert(rend_cache);
1038 tt_assert(strmap_size(rend_cache) == 0);
1040 // Deals with existing rend_cache
1041 rend_cache_free_all();
1042 rend_cache_init();
1043 tt_assert(rend_cache);
1044 tt_assert(strmap_size(rend_cache) == 0);
1046 rend_cache_purge();
1047 tt_assert(rend_cache);
1048 tt_assert(strmap_size(rend_cache) == 0);
1050 done:
1051 rend_cache_free_all();
1054 static void
1055 test_rend_cache_failure_intro_add(void *data)
1057 (void)data;
1058 rend_cache_failure_t *fail_entry;
1059 rend_cache_failure_intro_t *entry;
1060 const char identity[DIGEST_LEN] = "foo1";
1062 rend_cache_init();
1064 // Adds non-existing entry
1065 cache_failure_intro_add((const uint8_t *) identity, "foo2",
1066 INTRO_POINT_FAILURE_TIMEOUT);
1067 fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
1068 tt_assert(fail_entry);
1069 tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
1070 entry = digestmap_get(fail_entry->intro_failures, identity);
1071 tt_assert(entry);
1073 // Adds existing entry
1074 cache_failure_intro_add((const uint8_t *) identity, "foo2",
1075 INTRO_POINT_FAILURE_TIMEOUT);
1076 fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
1077 tt_assert(fail_entry);
1078 tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
1079 entry = digestmap_get(fail_entry->intro_failures, identity);
1080 tt_assert(entry);
1082 done:
1083 rend_cache_free_all();
1086 static void
1087 test_rend_cache_intro_failure_note(void *data)
1089 (void)data;
1090 rend_cache_failure_t *fail_entry;
1091 rend_cache_failure_intro_t *entry;
1092 const char key[DIGEST_LEN] = "foo1";
1094 rend_cache_init();
1096 // Test not found
1097 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT,
1098 (const uint8_t *) key, "foo2");
1099 fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
1100 tt_assert(fail_entry);
1101 tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
1102 entry = digestmap_get(fail_entry->intro_failures, key);
1103 tt_assert(entry);
1104 tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT);
1106 // Test found
1107 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE,
1108 (const uint8_t *) key, "foo2");
1109 tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE);
1111 done:
1112 rend_cache_free_all();
1115 #define NS_SUBMODULE clean_v2_descs_as_dir
1116 NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id));
1118 static int
1119 NS(hid_serv_responsible_for_desc_id)(const char *id)
1121 (void)id;
1122 return hid_serv_responsible_for_desc_id_response;
1125 static void
1126 test_rend_cache_clean_v2_descs_as_dir(void *data)
1128 rend_cache_entry_t *e;
1129 time_t now;
1130 rend_service_descriptor_t *desc;
1131 now = time(NULL);
1132 const char key[DIGEST_LEN] = "abcde";
1134 (void)data;
1136 NS_MOCK(hid_serv_responsible_for_desc_id);
1137 rend_cache_init();
1139 // Test running with an empty cache
1140 rend_cache_clean_v2_descs_as_dir(now, 0);
1141 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
1143 // Test with only one new entry
1144 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1145 e->last_served = now;
1146 desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
1147 desc->timestamp = now;
1148 desc->pk = pk_generate(0);
1149 e->parsed = desc;
1150 digestmap_set(rend_cache_v2_dir, key, e);
1152 hid_serv_responsible_for_desc_id_response = 1;
1153 rend_cache_clean_v2_descs_as_dir(now, 0);
1154 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1);
1156 // Test with one old entry
1157 desc->timestamp = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000);
1158 rend_cache_clean_v2_descs_as_dir(now, 0);
1159 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
1161 // Test with one entry that is not under the responsibility of this
1162 // hidden service
1163 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1164 e->last_served = now;
1165 desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
1166 desc->timestamp = now;
1167 desc->pk = pk_generate(0);
1168 e->parsed = desc;
1169 digestmap_set(rend_cache_v2_dir, key, e);
1171 hid_serv_responsible_for_desc_id_response = 0;
1172 rend_cache_clean_v2_descs_as_dir(now, 0);
1173 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
1175 // Test with one entry that has an old last served
1176 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1177 e->last_served = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000);
1178 desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
1179 desc->timestamp = now;
1180 desc->pk = pk_generate(0);
1181 e->parsed = desc;
1182 digestmap_set(rend_cache_v2_dir, key, e);
1184 hid_serv_responsible_for_desc_id_response = 1;
1185 rend_cache_clean_v2_descs_as_dir(now, 0);
1186 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
1188 // Test a run through asking for a large force_remove
1189 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1190 e->last_served = now;
1191 desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
1192 desc->timestamp = now;
1193 desc->pk = pk_generate(0);
1194 e->parsed = desc;
1195 digestmap_set(rend_cache_v2_dir, key, e);
1197 hid_serv_responsible_for_desc_id_response = 1;
1198 rend_cache_clean_v2_descs_as_dir(now, 20000);
1199 tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1);
1201 done:
1202 NS_UNMOCK(hid_serv_responsible_for_desc_id);
1203 rend_cache_free_all();
1206 #undef NS_SUBMODULE
1208 static void
1209 test_rend_cache_entry_allocation(void *data)
1211 (void)data;
1213 size_t ret;
1214 rend_cache_entry_t *e = NULL;
1216 // Handles a null argument
1217 ret = rend_cache_entry_allocation(NULL);
1218 tt_int_op(ret, OP_EQ, 0);
1220 // Handles a non-null argument
1221 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1222 ret = rend_cache_entry_allocation(e);
1223 tt_int_op(ret, OP_GT, sizeof(rend_cache_entry_t));
1225 done:
1226 tor_free(e);
1229 static void
1230 test_rend_cache_failure_intro_entry_free(void *data)
1232 (void)data;
1233 rend_cache_failure_intro_t *entry;
1235 // Handles a null argument
1236 rend_cache_failure_intro_entry_free(NULL);
1238 // Handles a non-null argument
1239 entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
1240 rend_cache_failure_intro_entry_free(entry);
1243 static void
1244 test_rend_cache_failure_purge(void *data)
1246 (void)data;
1248 // Handles a null failure cache
1249 strmap_free(rend_cache_failure, rend_cache_failure_entry_free_);
1250 rend_cache_failure = NULL;
1252 rend_cache_failure_purge();
1254 tt_ptr_op(rend_cache_failure, OP_NE, NULL);
1255 tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
1257 done:
1258 rend_cache_free_all();
1261 static void
1262 test_rend_cache_validate_intro_point_failure(void *data)
1264 (void)data;
1265 rend_service_descriptor_t *desc = NULL;
1266 char *service_id = NULL;
1267 rend_intro_point_t *intro = NULL;
1268 const char *identity = NULL;
1269 rend_cache_failure_t *failure;
1270 rend_cache_failure_intro_t *ip;
1272 rend_cache_init();
1274 create_descriptor(&desc, &service_id, 3);
1275 desc->timestamp = time(NULL) + RECENT_TIME;
1277 intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0);
1278 identity = intro->extend_info->identity_digest;
1280 failure = rend_cache_failure_entry_new();
1281 ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
1282 digestmap_set(failure->intro_failures, identity, ip);
1283 strmap_set_lc(rend_cache_failure, service_id, failure);
1285 // Test when we have an intro point in our cache
1286 validate_intro_point_failure(desc, service_id);
1287 tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2);
1289 done:
1290 rend_cache_free_all();
1291 rend_service_descriptor_free(desc);
1292 tor_free(service_id);
1295 struct testcase_t rend_cache_tests[] = {
1296 { "init", test_rend_cache_init, 0, NULL, NULL },
1297 { "decrement_allocation", test_rend_cache_decrement_allocation, 0,
1298 NULL, NULL },
1299 { "increment_allocation", test_rend_cache_increment_allocation, 0,
1300 NULL, NULL },
1301 { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL },
1302 { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0,
1303 NULL, NULL },
1304 { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL },
1305 { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL },
1306 { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0,
1307 NULL, NULL },
1308 { "free_all", test_rend_cache_free_all, 0, NULL, NULL },
1309 { "purge", test_rend_cache_purge, 0, NULL, NULL },
1310 { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL },
1311 { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL },
1312 { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL },
1313 { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL },
1314 { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0,
1315 NULL, NULL },
1316 { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0,
1317 NULL, NULL },
1318 { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL },
1319 { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL },
1320 { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL },
1321 { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL },
1322 { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0,
1323 NULL, NULL },
1324 { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0,
1325 NULL, NULL },
1326 { "store_v2_desc_as_client_with_different_time",
1327 test_rend_cache_store_v2_desc_as_client_with_different_time, 0,
1328 NULL, NULL },
1329 { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0,
1330 NULL, NULL },
1331 { "store_v2_desc_as_dir_with_different_time",
1332 test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL },
1333 { "store_v2_desc_as_dir_with_different_content",
1334 test_rend_cache_store_v2_desc_as_dir_with_different_content, 0,
1335 NULL, NULL },
1336 { "validate_intro_point_failure",
1337 test_rend_cache_validate_intro_point_failure, 0, NULL, NULL },
1338 END_OF_TESTCASES