test_buffers.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2013, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #define BUFFERS_PRIVATE
  6. #include "or.h"
  7. #include "buffers.h"
  8. #include "ext_orport.h"
  9. #include "test.h"
  10. /** Run unit tests for buffers.c */
  11. static void
  12. test_buffers_basic(void *arg)
  13. {
  14. char str[256];
  15. char str2[256];
  16. buf_t *buf = NULL, *buf2 = NULL;
  17. const char *cp;
  18. int j;
  19. size_t r;
  20. (void) arg;
  21. /****
  22. * buf_new
  23. ****/
  24. if (!(buf = buf_new()))
  25. test_fail();
  26. //test_eq(buf_capacity(buf), 4096);
  27. test_eq(buf_datalen(buf), 0);
  28. /****
  29. * General pointer frobbing
  30. */
  31. for (j=0;j<256;++j) {
  32. str[j] = (char)j;
  33. }
  34. write_to_buf(str, 256, buf);
  35. write_to_buf(str, 256, buf);
  36. test_eq(buf_datalen(buf), 512);
  37. fetch_from_buf(str2, 200, buf);
  38. test_memeq(str, str2, 200);
  39. test_eq(buf_datalen(buf), 312);
  40. memset(str2, 0, sizeof(str2));
  41. fetch_from_buf(str2, 256, buf);
  42. test_memeq(str+200, str2, 56);
  43. test_memeq(str, str2+56, 200);
  44. test_eq(buf_datalen(buf), 56);
  45. memset(str2, 0, sizeof(str2));
  46. /* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
  47. * another 3584 bytes, we hit the end. */
  48. for (j=0;j<15;++j) {
  49. write_to_buf(str, 256, buf);
  50. }
  51. assert_buf_ok(buf);
  52. test_eq(buf_datalen(buf), 3896);
  53. fetch_from_buf(str2, 56, buf);
  54. test_eq(buf_datalen(buf), 3840);
  55. test_memeq(str+200, str2, 56);
  56. for (j=0;j<15;++j) {
  57. memset(str2, 0, sizeof(str2));
  58. fetch_from_buf(str2, 256, buf);
  59. test_memeq(str, str2, 256);
  60. }
  61. test_eq(buf_datalen(buf), 0);
  62. buf_free(buf);
  63. buf = NULL;
  64. /* Okay, now make sure growing can work. */
  65. buf = buf_new_with_capacity(16);
  66. //test_eq(buf_capacity(buf), 16);
  67. write_to_buf(str+1, 255, buf);
  68. //test_eq(buf_capacity(buf), 256);
  69. fetch_from_buf(str2, 254, buf);
  70. test_memeq(str+1, str2, 254);
  71. //test_eq(buf_capacity(buf), 256);
  72. assert_buf_ok(buf);
  73. write_to_buf(str, 32, buf);
  74. //test_eq(buf_capacity(buf), 256);
  75. assert_buf_ok(buf);
  76. write_to_buf(str, 256, buf);
  77. assert_buf_ok(buf);
  78. //test_eq(buf_capacity(buf), 512);
  79. test_eq(buf_datalen(buf), 33+256);
  80. fetch_from_buf(str2, 33, buf);
  81. test_eq(*str2, str[255]);
  82. test_memeq(str2+1, str, 32);
  83. //test_eq(buf_capacity(buf), 512);
  84. test_eq(buf_datalen(buf), 256);
  85. fetch_from_buf(str2, 256, buf);
  86. test_memeq(str, str2, 256);
  87. /* now try shrinking: case 1. */
  88. buf_free(buf);
  89. buf = buf_new_with_capacity(33668);
  90. for (j=0;j<67;++j) {
  91. write_to_buf(str,255, buf);
  92. }
  93. //test_eq(buf_capacity(buf), 33668);
  94. test_eq(buf_datalen(buf), 17085);
  95. for (j=0; j < 40; ++j) {
  96. fetch_from_buf(str2, 255,buf);
  97. test_memeq(str2, str, 255);
  98. }
  99. /* now try shrinking: case 2. */
  100. buf_free(buf);
  101. buf = buf_new_with_capacity(33668);
  102. for (j=0;j<67;++j) {
  103. write_to_buf(str,255, buf);
  104. }
  105. for (j=0; j < 20; ++j) {
  106. fetch_from_buf(str2, 255,buf);
  107. test_memeq(str2, str, 255);
  108. }
  109. for (j=0;j<80;++j) {
  110. write_to_buf(str,255, buf);
  111. }
  112. //test_eq(buf_capacity(buf),33668);
  113. for (j=0; j < 120; ++j) {
  114. fetch_from_buf(str2, 255,buf);
  115. test_memeq(str2, str, 255);
  116. }
  117. /* Move from buf to buf. */
  118. buf_free(buf);
  119. buf = buf_new_with_capacity(4096);
  120. buf2 = buf_new_with_capacity(4096);
  121. for (j=0;j<100;++j)
  122. write_to_buf(str, 255, buf);
  123. test_eq(buf_datalen(buf), 25500);
  124. for (j=0;j<100;++j) {
  125. r = 10;
  126. move_buf_to_buf(buf2, buf, &r);
  127. test_eq(r, 0);
  128. }
  129. test_eq(buf_datalen(buf), 24500);
  130. test_eq(buf_datalen(buf2), 1000);
  131. for (j=0;j<3;++j) {
  132. fetch_from_buf(str2, 255, buf2);
  133. test_memeq(str2, str, 255);
  134. }
  135. r = 8192; /*big move*/
  136. move_buf_to_buf(buf2, buf, &r);
  137. test_eq(r, 0);
  138. r = 30000; /* incomplete move */
  139. move_buf_to_buf(buf2, buf, &r);
  140. test_eq(r, 13692);
  141. for (j=0;j<97;++j) {
  142. fetch_from_buf(str2, 255, buf2);
  143. test_memeq(str2, str, 255);
  144. }
  145. buf_free(buf);
  146. buf_free(buf2);
  147. buf = buf2 = NULL;
  148. buf = buf_new_with_capacity(5);
  149. cp = "Testing. This is a moderately long Testing string.";
  150. for (j = 0; cp[j]; j++)
  151. write_to_buf(cp+j, 1, buf);
  152. test_eq(0, buf_find_string_offset(buf, "Testing", 7));
  153. test_eq(1, buf_find_string_offset(buf, "esting", 6));
  154. test_eq(1, buf_find_string_offset(buf, "est", 3));
  155. test_eq(39, buf_find_string_offset(buf, "ing str", 7));
  156. test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
  157. test_eq(32, buf_find_string_offset(buf, "ng ", 3));
  158. test_eq(43, buf_find_string_offset(buf, "string.", 7));
  159. test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
  160. test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
  161. test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
  162. buf_free(buf);
  163. buf = NULL;
  164. /* Try adding a string too long for any freelist. */
  165. {
  166. char *cp = tor_malloc_zero(65536);
  167. buf = buf_new();
  168. write_to_buf(cp, 65536, buf);
  169. tor_free(cp);
  170. tt_int_op(buf_datalen(buf), ==, 65536);
  171. buf_free(buf);
  172. buf = NULL;
  173. }
  174. done:
  175. if (buf)
  176. buf_free(buf);
  177. if (buf2)
  178. buf_free(buf2);
  179. }
  180. static void
  181. test_buffer_copy(void *arg)
  182. {
  183. generic_buffer_t *buf=NULL, *buf2=NULL;
  184. const char *s;
  185. size_t len;
  186. char b[256];
  187. int i;
  188. (void)arg;
  189. buf = generic_buffer_new();
  190. tt_assert(buf);
  191. /* Copy an empty buffer. */
  192. tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  193. tt_assert(buf2);
  194. tt_int_op(0, ==, generic_buffer_len(buf2));
  195. /* Now try with a short buffer. */
  196. s = "And now comes an act of enormous enormance!";
  197. len = strlen(s);
  198. generic_buffer_add(buf, s, len);
  199. tt_int_op(len, ==, generic_buffer_len(buf));
  200. /* Add junk to buf2 so we can test replacing.*/
  201. generic_buffer_add(buf2, "BLARG", 5);
  202. tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  203. tt_int_op(len, ==, generic_buffer_len(buf2));
  204. generic_buffer_get(buf2, b, len);
  205. test_mem_op(b, ==, s, len);
  206. /* Now free buf2 and retry so we can test allocating */
  207. generic_buffer_free(buf2);
  208. buf2 = NULL;
  209. tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  210. tt_int_op(len, ==, generic_buffer_len(buf2));
  211. generic_buffer_get(buf2, b, len);
  212. test_mem_op(b, ==, s, len);
  213. /* Clear buf for next test */
  214. generic_buffer_get(buf, b, len);
  215. tt_int_op(generic_buffer_len(buf),==,0);
  216. /* Okay, now let's try a bigger buffer. */
  217. s = "Quis autem vel eum iure reprehenderit qui in ea voluptate velit "
  218. "esse quam nihil molestiae consequatur, vel illum qui dolorem eum "
  219. "fugiat quo voluptas nulla pariatur?";
  220. len = strlen(s);
  221. for (i = 0; i < 256; ++i) {
  222. b[0]=i;
  223. generic_buffer_add(buf, b, 1);
  224. generic_buffer_add(buf, s, len);
  225. }
  226. tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  227. tt_int_op(generic_buffer_len(buf2), ==, generic_buffer_len(buf));
  228. for (i = 0; i < 256; ++i) {
  229. generic_buffer_get(buf2, b, len+1);
  230. tt_int_op((unsigned char)b[0],==,i);
  231. test_mem_op(b+1, ==, s, len);
  232. }
  233. done:
  234. if (buf)
  235. generic_buffer_free(buf);
  236. if (buf2)
  237. generic_buffer_free(buf2);
  238. }
  239. static void
  240. test_buffer_ext_or_cmd(void *arg)
  241. {
  242. ext_or_cmd_t *cmd = NULL;
  243. generic_buffer_t *buf = generic_buffer_new();
  244. char *tmp = NULL;
  245. (void) arg;
  246. /* Empty -- should give "not there. */
  247. tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  248. tt_ptr_op(NULL, ==, cmd);
  249. /* Three bytes: shouldn't work. */
  250. generic_buffer_add(buf, "\x00\x20\x00", 3);
  251. tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  252. tt_ptr_op(NULL, ==, cmd);
  253. tt_int_op(3, ==, generic_buffer_len(buf));
  254. /* 0020 0000: That's a nil command. It should work. */
  255. generic_buffer_add(buf, "\x00", 1);
  256. tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  257. tt_ptr_op(NULL, !=, cmd);
  258. tt_int_op(0x20, ==, cmd->cmd);
  259. tt_int_op(0, ==, cmd->len);
  260. tt_int_op(0, ==, generic_buffer_len(buf));
  261. ext_or_cmd_free(cmd);
  262. cmd = NULL;
  263. /* Now try a length-6 command with one byte missing. */
  264. generic_buffer_add(buf, "\x10\x21\x00\x06""abcde", 9);
  265. tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  266. tt_ptr_op(NULL, ==, cmd);
  267. generic_buffer_add(buf, "f", 1);
  268. tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  269. tt_ptr_op(NULL, !=, cmd);
  270. tt_int_op(0x1021, ==, cmd->cmd);
  271. tt_int_op(6, ==, cmd->len);
  272. test_mem_op("abcdef", ==, cmd->body, 6);
  273. tt_int_op(0, ==, generic_buffer_len(buf));
  274. ext_or_cmd_free(cmd);
  275. cmd = NULL;
  276. /* Now try a length-10 command with 4 extra bytes. */
  277. generic_buffer_add(buf, "\xff\xff\x00\x0a"
  278. "loremipsum\x10\x00\xff\xff", 18);
  279. tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  280. tt_ptr_op(NULL, !=, cmd);
  281. tt_int_op(0xffff, ==, cmd->cmd);
  282. tt_int_op(10, ==, cmd->len);
  283. test_mem_op("loremipsum", ==, cmd->body, 10);
  284. tt_int_op(4, ==, generic_buffer_len(buf));
  285. ext_or_cmd_free(cmd);
  286. cmd = NULL;
  287. /* Finally, let's try a maximum-length command. We already have the header
  288. * waiting. */
  289. tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  290. tmp = tor_malloc_zero(65535);
  291. generic_buffer_add(buf, tmp, 65535);
  292. tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
  293. tt_ptr_op(NULL, !=, cmd);
  294. tt_int_op(0x1000, ==, cmd->cmd);
  295. tt_int_op(0xffff, ==, cmd->len);
  296. test_mem_op(tmp, ==, cmd->body, 65535);
  297. tt_int_op(0, ==, generic_buffer_len(buf));
  298. ext_or_cmd_free(cmd);
  299. cmd = NULL;
  300. done:
  301. ext_or_cmd_free(cmd);
  302. generic_buffer_free(buf);
  303. tor_free(tmp);
  304. }
  305. struct testcase_t buffer_tests[] = {
  306. { "basic", test_buffers_basic, 0, NULL, NULL },
  307. { "copy", test_buffer_copy, 0, NULL, NULL },
  308. { "ext_or_cmd", test_buffer_ext_or_cmd, 0, NULL, NULL },
  309. END_OF_TESTCASES
  310. };