test_replay.c 9.5 KB

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