test_replay.c (9754B)
1 /* Copyright (c) 2012-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #define REPLAYCACHE_PRIVATE 5 6 #include "orconfig.h" 7 #include "core/or/or.h" 8 #include "feature/hs_common/replaycache.h" 9 #include "test/test.h" 10 11 static const char *test_buffer = 12 "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed do eiusmod" 13 " tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim" 14 " veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea" 15 " commodo consequat. Duis aute irure dolor in reprehenderit in voluptate" 16 " velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint" 17 " occaecat cupidatat non proident, sunt in culpa qui officia deserunt" 18 " mollit anim id est laborum."; 19 20 static const char *test_buffer_2 = 21 "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis" 22 " praesentium voluptatum deleniti atque corrupti quos dolores et quas" 23 " molestias excepturi sint occaecati cupiditate non provident, similique" 24 " sunt in culpa qui officia deserunt mollitia animi, id est laborum et" 25 " dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio." 26 " Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil" 27 " impedit quo minus id quod maxime placeat facere possimus, omnis voluptas" 28 " assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut" 29 " officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates" 30 " repudiandae sint et molestiae non recusandae. Itaque earum rerum hic" 31 " tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias" 32 " consequatur aut perferendis doloribus asperiores repellat."; 33 34 static void 35 test_replaycache_alloc(void *arg) 36 { 37 replaycache_t *r = NULL; 38 39 (void)arg; 40 r = replaycache_new(600, 300); 41 tt_ptr_op(r, OP_NE, NULL); 42 43 done: 44 if (r) replaycache_free(r); 45 46 return; 47 } 48 49 static void 50 test_replaycache_badalloc(void *arg) 51 { 52 replaycache_t *r = NULL; 53 54 /* Negative horizon should fail */ 55 (void)arg; 56 r = replaycache_new(-600, 300); 57 tt_ptr_op(r, OP_EQ, NULL); 58 /* Negative interval should get adjusted to zero */ 59 r = replaycache_new(600, -300); 60 tt_ptr_op(r, OP_NE, NULL); 61 tt_int_op(r->scrub_interval,OP_EQ, 0); 62 replaycache_free(r); 63 /* Negative horizon and negative interval should still fail */ 64 r = replaycache_new(-600, -300); 65 tt_ptr_op(r, OP_EQ, NULL); 66 67 done: 68 if (r) replaycache_free(r); 69 70 return; 71 } 72 73 static void 74 test_replaycache_free_null(void *arg) 75 { 76 (void)arg; 77 replaycache_free_(NULL); 78 /* Assert that we're here without horrible death */ 79 tt_assert(1); 80 81 done: 82 return; 83 } 84 85 static void 86 test_replaycache_miss(void *arg) 87 { 88 replaycache_t *r = NULL; 89 int result; 90 91 (void)arg; 92 r = replaycache_new(600, 300); 93 tt_ptr_op(r, OP_NE, NULL); 94 95 result = 96 replaycache_add_and_test_internal(1200, r, test_buffer, 97 strlen(test_buffer), NULL); 98 tt_int_op(result,OP_EQ, 0); 99 100 /* make sure a different buffer misses as well */ 101 result = 102 replaycache_add_and_test_internal(1200, NULL, test_buffer_2, 103 strlen(test_buffer_2), NULL); 104 tt_int_op(result,OP_EQ, 0); 105 106 /* poke the bad-parameter error case too */ 107 result = 108 replaycache_add_and_test_internal(1200, NULL, test_buffer, 109 strlen(test_buffer), NULL); 110 tt_int_op(result,OP_EQ, 0); 111 112 done: 113 if (r) replaycache_free(r); 114 115 return; 116 } 117 118 static void 119 test_replaycache_hit(void *arg) 120 { 121 replaycache_t *r = NULL; 122 int result; 123 124 (void)arg; 125 r = replaycache_new(600, 300); 126 tt_ptr_op(r, OP_NE, NULL); 127 128 result = 129 replaycache_add_and_test_internal(1200, r, test_buffer, 130 strlen(test_buffer), NULL); 131 tt_int_op(result,OP_EQ, 0); 132 133 result = 134 replaycache_add_and_test_internal(1300, r, test_buffer, 135 strlen(test_buffer), NULL); 136 tt_int_op(result,OP_EQ, 1); 137 138 /* make sure a different buffer misses then hits as well */ 139 140 result = 141 replaycache_add_and_test_internal(1200, r, test_buffer_2, 142 strlen(test_buffer_2), NULL); 143 tt_int_op(result,OP_EQ, 0); 144 145 result = 146 replaycache_add_and_test_internal(1300, r, test_buffer_2, 147 strlen(test_buffer_2), NULL); 148 tt_int_op(result,OP_EQ, 1); 149 150 done: 151 if (r) replaycache_free(r); 152 153 return; 154 } 155 156 static void 157 test_replaycache_age(void *arg) 158 { 159 replaycache_t *r = NULL; 160 int result; 161 162 (void)arg; 163 r = replaycache_new(600, 300); 164 tt_ptr_op(r, OP_NE, NULL); 165 166 result = 167 replaycache_add_and_test_internal(1200, r, test_buffer, 168 strlen(test_buffer), NULL); 169 tt_int_op(result,OP_EQ, 0); 170 171 result = 172 replaycache_add_and_test_internal(1300, r, test_buffer, 173 strlen(test_buffer), NULL); 174 tt_int_op(result,OP_EQ, 1); 175 176 result = 177 replaycache_add_and_test_internal(3000, r, test_buffer, 178 strlen(test_buffer), NULL); 179 tt_int_op(result,OP_EQ, 0); 180 181 done: 182 if (r) replaycache_free(r); 183 184 return; 185 } 186 187 static void 188 test_replaycache_elapsed(void *arg) 189 { 190 replaycache_t *r = NULL; 191 int result; 192 time_t elapsed; 193 194 (void)arg; 195 r = replaycache_new(600, 300); 196 tt_ptr_op(r, OP_NE, NULL); 197 198 result = 199 replaycache_add_and_test_internal(1200, r, test_buffer, 200 strlen(test_buffer), NULL); 201 tt_int_op(result,OP_EQ, 0); 202 203 result = 204 replaycache_add_and_test_internal(1300, r, test_buffer, 205 strlen(test_buffer), &elapsed); 206 tt_int_op(result,OP_EQ, 1); 207 tt_int_op(elapsed,OP_EQ, 100); 208 209 done: 210 if (r) replaycache_free(r); 211 212 return; 213 } 214 215 static void 216 test_replaycache_noexpire(void *arg) 217 { 218 replaycache_t *r = NULL; 219 int result; 220 221 (void)arg; 222 r = replaycache_new(0, 0); 223 tt_ptr_op(r, OP_NE, NULL); 224 225 result = 226 replaycache_add_and_test_internal(1200, r, test_buffer, 227 strlen(test_buffer), NULL); 228 tt_int_op(result,OP_EQ, 0); 229 230 result = 231 replaycache_add_and_test_internal(1300, r, test_buffer, 232 strlen(test_buffer), NULL); 233 tt_int_op(result,OP_EQ, 1); 234 235 result = 236 replaycache_add_and_test_internal(3000, r, test_buffer, 237 strlen(test_buffer), NULL); 238 tt_int_op(result,OP_EQ, 1); 239 240 done: 241 if (r) replaycache_free(r); 242 243 return; 244 } 245 246 static void 247 test_replaycache_scrub(void *arg) 248 { 249 replaycache_t *r = NULL; 250 int result; 251 252 (void)arg; 253 r = replaycache_new(600, 300); 254 tt_ptr_op(r, OP_NE, NULL); 255 256 /* Set up like in test_replaycache_hit() */ 257 result = 258 replaycache_add_and_test_internal(100, r, test_buffer, 259 strlen(test_buffer), NULL); 260 tt_int_op(result,OP_EQ, 0); 261 262 result = 263 replaycache_add_and_test_internal(200, r, test_buffer, 264 strlen(test_buffer), NULL); 265 tt_int_op(result,OP_EQ, 1); 266 267 /* 268 * Poke a few replaycache_scrub_if_needed_internal() error cases that 269 * can't happen through replaycache_add_and_test_internal() 270 */ 271 272 /* Null cache */ 273 replaycache_scrub_if_needed_internal(300, NULL); 274 /* Assert we're still here */ 275 tt_assert(1); 276 277 /* Make sure we hit the aging-out case too */ 278 replaycache_scrub_if_needed_internal(1500, r); 279 /* Assert that we aged it */ 280 tt_int_op(digest256map_size(r->digests_seen),OP_EQ, 0); 281 282 done: 283 if (r) replaycache_free(r); 284 285 return; 286 } 287 288 static void 289 test_replaycache_future(void *arg) 290 { 291 replaycache_t *r = NULL; 292 int result; 293 time_t elapsed = 0; 294 295 (void)arg; 296 r = replaycache_new(600, 300); 297 tt_ptr_op(r, OP_NE, NULL); 298 299 /* Set up like in test_replaycache_hit() */ 300 result = 301 replaycache_add_and_test_internal(100, r, test_buffer, 302 strlen(test_buffer), &elapsed); 303 tt_int_op(result,OP_EQ, 0); 304 /* elapsed should still be 0, since it wasn't written */ 305 tt_int_op(elapsed,OP_EQ, 0); 306 307 result = 308 replaycache_add_and_test_internal(200, r, test_buffer, 309 strlen(test_buffer), &elapsed); 310 tt_int_op(result,OP_EQ, 1); 311 /* elapsed should be the time since the last hit */ 312 tt_int_op(elapsed,OP_EQ, 100); 313 314 /* 315 * Now let's turn the clock back to get coverage on the cache entry from the 316 * future not-supposed-to-happen case. 317 */ 318 result = 319 replaycache_add_and_test_internal(150, r, test_buffer, 320 strlen(test_buffer), &elapsed); 321 /* We should still get a hit */ 322 tt_int_op(result,OP_EQ, 1); 323 /* ...but it shouldn't let us see a negative elapsed time */ 324 tt_int_op(elapsed,OP_EQ, 0); 325 326 done: 327 if (r) replaycache_free(r); 328 329 return; 330 } 331 332 static void 333 test_replaycache_realtime(void *arg) 334 { 335 replaycache_t *r = NULL; 336 /* 337 * Negative so we fail if replaycache_add_test_and_elapsed() doesn't 338 * write to elapsed. 339 */ 340 time_t elapsed = -1; 341 int result; 342 343 /* Test the realtime as well as *_internal() entry points */ 344 (void)arg; 345 r = replaycache_new(600, 300); 346 tt_ptr_op(r, OP_NE, NULL); 347 348 /* This should miss */ 349 result = 350 replaycache_add_and_test(r, test_buffer, strlen(test_buffer)); 351 tt_int_op(result,OP_EQ, 0); 352 353 /* This should hit */ 354 result = 355 replaycache_add_and_test(r, test_buffer, strlen(test_buffer)); 356 tt_int_op(result,OP_EQ, 1); 357 358 /* This should hit and return a small elapsed time */ 359 result = 360 replaycache_add_test_and_elapsed(r, test_buffer, 361 strlen(test_buffer), &elapsed); 362 tt_int_op(result,OP_EQ, 1); 363 tt_assert(elapsed >= 0); 364 tt_assert(elapsed <= 5); 365 366 /* Scrub it to exercise that entry point too */ 367 replaycache_scrub_if_needed(r); 368 369 done: 370 if (r) replaycache_free(r); 371 return; 372 } 373 374 #define REPLAYCACHE_LEGACY(name) \ 375 { #name, test_replaycache_ ## name , 0, NULL, NULL } 376 377 struct testcase_t replaycache_tests[] = { 378 REPLAYCACHE_LEGACY(alloc), 379 REPLAYCACHE_LEGACY(badalloc), 380 REPLAYCACHE_LEGACY(free_null), 381 REPLAYCACHE_LEGACY(miss), 382 REPLAYCACHE_LEGACY(hit), 383 REPLAYCACHE_LEGACY(age), 384 REPLAYCACHE_LEGACY(elapsed), 385 REPLAYCACHE_LEGACY(noexpire), 386 REPLAYCACHE_LEGACY(scrub), 387 REPLAYCACHE_LEGACY(future), 388 REPLAYCACHE_LEGACY(realtime), 389 END_OF_TESTCASES 390 };