test_util.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2010, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define CONTROL_PRIVATE
  7. #define MEMPOOL_PRIVATE
  8. #include "or.h"
  9. #include "test.h"
  10. #include "mempool.h"
  11. #include "memarea.h"
  12. static void
  13. test_util_time(void)
  14. {
  15. struct timeval start, end;
  16. struct tm a_time;
  17. char timestr[RFC1123_TIME_LEN+1];
  18. time_t t_res;
  19. int i;
  20. start.tv_sec = 5;
  21. start.tv_usec = 5000;
  22. end.tv_sec = 5;
  23. end.tv_usec = 5000;
  24. test_eq(0L, tv_udiff(&start, &end));
  25. end.tv_usec = 7000;
  26. test_eq(2000L, tv_udiff(&start, &end));
  27. end.tv_sec = 6;
  28. test_eq(1002000L, tv_udiff(&start, &end));
  29. end.tv_usec = 0;
  30. test_eq(995000L, tv_udiff(&start, &end));
  31. end.tv_sec = 4;
  32. test_eq(-1005000L, tv_udiff(&start, &end));
  33. end.tv_usec = 999990;
  34. start.tv_sec = 1;
  35. start.tv_usec = 500;
  36. /* The test values here are confirmed to be correct on a platform
  37. * with a working timegm. */
  38. a_time.tm_year = 2003-1900;
  39. a_time.tm_mon = 7;
  40. a_time.tm_mday = 30;
  41. a_time.tm_hour = 6;
  42. a_time.tm_min = 14;
  43. a_time.tm_sec = 55;
  44. test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
  45. a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
  46. test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
  47. a_time.tm_mon = 1; /* Try a leap year, in feb. */
  48. a_time.tm_mday = 10;
  49. test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
  50. format_rfc1123_time(timestr, 0);
  51. test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
  52. format_rfc1123_time(timestr, (time_t)1091580502UL);
  53. test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
  54. t_res = 0;
  55. i = parse_rfc1123_time(timestr, &t_res);
  56. test_eq(i,0);
  57. test_eq(t_res, (time_t)1091580502UL);
  58. test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
  59. tor_gettimeofday(&start);
  60. /* now make sure time works. */
  61. tor_gettimeofday(&end);
  62. /* We might've timewarped a little. */
  63. tt_int_op(tv_udiff(&start, &end), >=, -5000);
  64. done:
  65. ;
  66. }
  67. static void
  68. test_util_config_line(void)
  69. {
  70. char buf[1024];
  71. char *k=NULL, *v=NULL;
  72. const char *str;
  73. /* Test parse_config_line_from_str */
  74. strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
  75. "k2\n"
  76. "k3 \n" "\n" " \n" "#comment\n"
  77. "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
  78. "kseven \"a quoted 'string\"\n"
  79. "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
  80. , sizeof(buf));
  81. str = buf;
  82. str = parse_config_line_from_str(str, &k, &v);
  83. test_streq(k, "k");
  84. test_streq(v, "v");
  85. tor_free(k); tor_free(v);
  86. test_assert(!strcmpstart(str, "key value with"));
  87. str = parse_config_line_from_str(str, &k, &v);
  88. test_streq(k, "key");
  89. test_streq(v, "value with spaces");
  90. tor_free(k); tor_free(v);
  91. test_assert(!strcmpstart(str, "keykey"));
  92. str = parse_config_line_from_str(str, &k, &v);
  93. test_streq(k, "keykey");
  94. test_streq(v, "val");
  95. tor_free(k); tor_free(v);
  96. test_assert(!strcmpstart(str, "k2\n"));
  97. str = parse_config_line_from_str(str, &k, &v);
  98. test_streq(k, "k2");
  99. test_streq(v, "");
  100. tor_free(k); tor_free(v);
  101. test_assert(!strcmpstart(str, "k3 \n"));
  102. str = parse_config_line_from_str(str, &k, &v);
  103. test_streq(k, "k3");
  104. test_streq(v, "");
  105. tor_free(k); tor_free(v);
  106. test_assert(!strcmpstart(str, "#comment"));
  107. str = parse_config_line_from_str(str, &k, &v);
  108. test_streq(k, "k4");
  109. test_streq(v, "");
  110. tor_free(k); tor_free(v);
  111. test_assert(!strcmpstart(str, "k5#abc"));
  112. str = parse_config_line_from_str(str, &k, &v);
  113. test_streq(k, "k5");
  114. test_streq(v, "");
  115. tor_free(k); tor_free(v);
  116. test_assert(!strcmpstart(str, "k6"));
  117. str = parse_config_line_from_str(str, &k, &v);
  118. test_streq(k, "k6");
  119. test_streq(v, "val");
  120. tor_free(k); tor_free(v);
  121. test_assert(!strcmpstart(str, "kseven"));
  122. str = parse_config_line_from_str(str, &k, &v);
  123. test_streq(k, "kseven");
  124. test_streq(v, "a quoted \'string");
  125. tor_free(k); tor_free(v);
  126. test_assert(!strcmpstart(str, "k8 "));
  127. str = parse_config_line_from_str(str, &k, &v);
  128. test_streq(k, "k8");
  129. test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
  130. tor_free(k); tor_free(v);
  131. test_streq(str, "");
  132. done:
  133. tor_free(k);
  134. tor_free(v);
  135. }
  136. /** Test basic string functionality. */
  137. static void
  138. test_util_strmisc(void)
  139. {
  140. char buf[1024];
  141. int i;
  142. char *cp;
  143. /* Tests for corner cases of strl operations */
  144. test_eq(5, strlcpy(buf, "Hello", 0));
  145. strlcpy(buf, "Hello", sizeof(buf));
  146. test_eq(10, strlcat(buf, "Hello", 5));
  147. /* Test tor_strstrip() */
  148. strlcpy(buf, "Testing 1 2 3", sizeof(buf));
  149. tor_strstrip(buf, ",!");
  150. test_streq(buf, "Testing 1 2 3");
  151. strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
  152. tor_strstrip(buf, "!? ");
  153. test_streq(buf, "Testing123");
  154. /* Test tor_parse_long. */
  155. test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
  156. test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
  157. test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
  158. /* Test tor_parse_ulong */
  159. test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
  160. test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
  161. /* Test tor_parse_uint64. */
  162. test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
  163. test_assert(i == 1);
  164. test_streq(cp, " x");
  165. test_assert(U64_LITERAL(12345678901) ==
  166. tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
  167. test_assert(i == 1);
  168. test_streq(cp, "");
  169. test_assert(U64_LITERAL(0) ==
  170. tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
  171. test_assert(i == 0);
  172. {
  173. /* Test tor_parse_double. */
  174. double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
  175. test_assert(i == 1);
  176. test_assert(DBL_TO_U64(d) == 10);
  177. d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
  178. test_assert(i == 1);
  179. test_assert(DBL_TO_U64(d) == 0);
  180. d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
  181. test_assert(i == 0);
  182. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
  183. test_assert(i == 0);
  184. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
  185. test_assert(i == 1);
  186. d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
  187. test_assert(i == 1);
  188. }
  189. /* Test failing snprintf cases */
  190. test_eq(-1, tor_snprintf(buf, 0, "Foo"));
  191. test_eq(-1, tor_snprintf(buf, 2, "Foo"));
  192. /* Test printf with uint64 */
  193. tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
  194. U64_PRINTF_ARG(U64_LITERAL(12345678901)));
  195. test_streq(buf, "x!12345678901!x");
  196. /* Test for strcmpstart and strcmpend. */
  197. test_assert(strcmpstart("abcdef", "abcdef")==0);
  198. test_assert(strcmpstart("abcdef", "abc")==0);
  199. test_assert(strcmpstart("abcdef", "abd")<0);
  200. test_assert(strcmpstart("abcdef", "abb")>0);
  201. test_assert(strcmpstart("ab", "abb")<0);
  202. test_assert(strcmpend("abcdef", "abcdef")==0);
  203. test_assert(strcmpend("abcdef", "def")==0);
  204. test_assert(strcmpend("abcdef", "deg")<0);
  205. test_assert(strcmpend("abcdef", "dee")>0);
  206. test_assert(strcmpend("ab", "abb")<0);
  207. test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
  208. test_assert(strcasecmpend("abcdef", "dEF")==0);
  209. test_assert(strcasecmpend("abcDEf", "deg")<0);
  210. test_assert(strcasecmpend("abcdef", "DEE")>0);
  211. test_assert(strcasecmpend("ab", "abB")<0);
  212. /* Test mem_is_zero */
  213. memset(buf,0,128);
  214. buf[128] = 'x';
  215. test_assert(tor_digest_is_zero(buf));
  216. test_assert(tor_mem_is_zero(buf, 10));
  217. test_assert(tor_mem_is_zero(buf, 20));
  218. test_assert(tor_mem_is_zero(buf, 128));
  219. test_assert(!tor_mem_is_zero(buf, 129));
  220. buf[60] = (char)255;
  221. test_assert(!tor_mem_is_zero(buf, 128));
  222. buf[0] = (char)1;
  223. test_assert(!tor_mem_is_zero(buf, 10));
  224. /* Test 'escaped' */
  225. test_streq("\"\"", escaped(""));
  226. test_streq("\"abcd\"", escaped("abcd"));
  227. test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
  228. test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
  229. test_assert(NULL == escaped(NULL));
  230. /* Test strndup and memdup */
  231. {
  232. const char *s = "abcdefghijklmnopqrstuvwxyz";
  233. cp = tor_strndup(s, 30);
  234. test_streq(cp, s); /* same string, */
  235. test_neq(cp, s); /* but different pointers. */
  236. tor_free(cp);
  237. cp = tor_strndup(s, 5);
  238. test_streq(cp, "abcde");
  239. tor_free(cp);
  240. s = "a\0b\0c\0d\0e\0";
  241. cp = tor_memdup(s,10);
  242. test_memeq(cp, s, 10); /* same ram, */
  243. test_neq(cp, s); /* but different pointers. */
  244. tor_free(cp);
  245. }
  246. /* Test str-foo functions */
  247. cp = tor_strdup("abcdef");
  248. test_assert(tor_strisnonupper(cp));
  249. cp[3] = 'D';
  250. test_assert(!tor_strisnonupper(cp));
  251. tor_strupper(cp);
  252. test_streq(cp, "ABCDEF");
  253. test_assert(tor_strisprint(cp));
  254. cp[3] = 3;
  255. test_assert(!tor_strisprint(cp));
  256. tor_free(cp);
  257. /* Test eat_whitespace. */
  258. {
  259. const char *s = " \n a";
  260. test_eq_ptr(eat_whitespace(s), s+4);
  261. s = "abcd";
  262. test_eq_ptr(eat_whitespace(s), s);
  263. s = "#xyz\nab";
  264. test_eq_ptr(eat_whitespace(s), s+5);
  265. }
  266. /* Test memmem and memstr */
  267. {
  268. const char *haystack = "abcde";
  269. tor_assert(!tor_memmem(haystack, 5, "ef", 2));
  270. test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
  271. test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
  272. haystack = "ababcad";
  273. test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
  274. test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
  275. test_assert(!tor_memstr(haystack, 7, "fe"));
  276. test_assert(!tor_memstr(haystack, 7, "longerthantheoriginal"));
  277. }
  278. /* Test wrap_string */
  279. {
  280. smartlist_t *sl = smartlist_create();
  281. wrap_string(sl, "This is a test of string wrapping functionality: woot.",
  282. 10, "", "");
  283. cp = smartlist_join_strings(sl, "", 0, NULL);
  284. test_streq(cp,
  285. "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
  286. tor_free(cp);
  287. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  288. smartlist_clear(sl);
  289. wrap_string(sl, "This is a test of string wrapping functionality: woot.",
  290. 16, "### ", "# ");
  291. cp = smartlist_join_strings(sl, "", 0, NULL);
  292. test_streq(cp,
  293. "### This is a\n# test of string\n# wrapping\n# functionality:\n"
  294. "# woot.\n");
  295. tor_free(cp);
  296. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  297. smartlist_free(sl);
  298. }
  299. done:
  300. ;
  301. }
  302. static void
  303. test_util_pow2(void)
  304. {
  305. /* Test tor_log2(). */
  306. test_eq(tor_log2(64), 6);
  307. test_eq(tor_log2(65), 6);
  308. test_eq(tor_log2(63), 5);
  309. test_eq(tor_log2(1), 0);
  310. test_eq(tor_log2(2), 1);
  311. test_eq(tor_log2(3), 1);
  312. test_eq(tor_log2(4), 2);
  313. test_eq(tor_log2(5), 2);
  314. test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
  315. test_eq(tor_log2(UINT64_MAX), 63);
  316. /* Test round_to_power_of_2 */
  317. test_eq(round_to_power_of_2(120), 128);
  318. test_eq(round_to_power_of_2(128), 128);
  319. test_eq(round_to_power_of_2(130), 128);
  320. test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
  321. U64_LITERAL(1)<<55);
  322. test_eq(round_to_power_of_2(0), 2);
  323. done:
  324. ;
  325. }
  326. /** mutex for thread test to stop the threads hitting data at the same time. */
  327. static tor_mutex_t *_thread_test_mutex = NULL;
  328. /** mutexes for the thread test to make sure that the threads have to
  329. * interleave somewhat. */
  330. static tor_mutex_t *_thread_test_start1 = NULL,
  331. *_thread_test_start2 = NULL;
  332. /** Shared strmap for the thread test. */
  333. static strmap_t *_thread_test_strmap = NULL;
  334. /** The name of thread1 for the thread test */
  335. static char *_thread1_name = NULL;
  336. /** The name of thread2 for the thread test */
  337. static char *_thread2_name = NULL;
  338. static void _thread_test_func(void* _s) ATTR_NORETURN;
  339. /** How many iterations have the threads in the unit test run? */
  340. static int t1_count = 0, t2_count = 0;
  341. /** Helper function for threading unit tests: This function runs in a
  342. * subthread. It grabs its own mutex (start1 or start2) to make sure that it
  343. * should start, then it repeatedly alters _test_thread_strmap protected by
  344. * _thread_test_mutex. */
  345. static void
  346. _thread_test_func(void* _s)
  347. {
  348. char *s = _s;
  349. int i, *count;
  350. tor_mutex_t *m;
  351. char buf[64];
  352. char **cp;
  353. if (!strcmp(s, "thread 1")) {
  354. m = _thread_test_start1;
  355. cp = &_thread1_name;
  356. count = &t1_count;
  357. } else {
  358. m = _thread_test_start2;
  359. cp = &_thread2_name;
  360. count = &t2_count;
  361. }
  362. tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
  363. *cp = tor_strdup(buf);
  364. tor_mutex_acquire(m);
  365. for (i=0; i<10000; ++i) {
  366. tor_mutex_acquire(_thread_test_mutex);
  367. strmap_set(_thread_test_strmap, "last to run", *cp);
  368. ++*count;
  369. tor_mutex_release(_thread_test_mutex);
  370. }
  371. tor_mutex_acquire(_thread_test_mutex);
  372. strmap_set(_thread_test_strmap, s, *cp);
  373. tor_mutex_release(_thread_test_mutex);
  374. tor_mutex_release(m);
  375. spawn_exit();
  376. }
  377. /** Run unit tests for threading logic. */
  378. static void
  379. test_util_threads(void)
  380. {
  381. char *s1 = NULL, *s2 = NULL;
  382. int done = 0, timedout = 0;
  383. time_t started;
  384. #ifndef TOR_IS_MULTITHREADED
  385. /* Skip this test if we aren't threading. We should be threading most
  386. * everywhere by now. */
  387. if (1)
  388. return;
  389. #endif
  390. _thread_test_mutex = tor_mutex_new();
  391. _thread_test_start1 = tor_mutex_new();
  392. _thread_test_start2 = tor_mutex_new();
  393. _thread_test_strmap = strmap_new();
  394. s1 = tor_strdup("thread 1");
  395. s2 = tor_strdup("thread 2");
  396. tor_mutex_acquire(_thread_test_start1);
  397. tor_mutex_acquire(_thread_test_start2);
  398. spawn_func(_thread_test_func, s1);
  399. spawn_func(_thread_test_func, s2);
  400. tor_mutex_release(_thread_test_start2);
  401. tor_mutex_release(_thread_test_start1);
  402. started = time(NULL);
  403. while (!done) {
  404. tor_mutex_acquire(_thread_test_mutex);
  405. strmap_assert_ok(_thread_test_strmap);
  406. if (strmap_get(_thread_test_strmap, "thread 1") &&
  407. strmap_get(_thread_test_strmap, "thread 2")) {
  408. done = 1;
  409. } else if (time(NULL) > started + 25) {
  410. timedout = done = 1;
  411. }
  412. tor_mutex_release(_thread_test_mutex);
  413. }
  414. tor_mutex_free(_thread_test_mutex);
  415. tor_mutex_acquire(_thread_test_start1);
  416. tor_mutex_release(_thread_test_start1);
  417. tor_mutex_acquire(_thread_test_start2);
  418. tor_mutex_release(_thread_test_start2);
  419. if (timedout) {
  420. printf("\nTimed out: %d %d", t1_count, t2_count);
  421. test_assert(strmap_get(_thread_test_strmap, "thread 1"));
  422. test_assert(strmap_get(_thread_test_strmap, "thread 2"));
  423. test_assert(!timedout);
  424. }
  425. /* different thread IDs. */
  426. test_assert(strcmp(strmap_get(_thread_test_strmap, "thread 1"),
  427. strmap_get(_thread_test_strmap, "thread 2")));
  428. test_assert(!strcmp(strmap_get(_thread_test_strmap, "thread 1"),
  429. strmap_get(_thread_test_strmap, "last to run")) ||
  430. !strcmp(strmap_get(_thread_test_strmap, "thread 2"),
  431. strmap_get(_thread_test_strmap, "last to run")));
  432. done:
  433. tor_free(s1);
  434. tor_free(s2);
  435. tor_free(_thread1_name);
  436. tor_free(_thread2_name);
  437. if (_thread_test_strmap)
  438. strmap_free(_thread_test_strmap, NULL);
  439. if (_thread_test_start1)
  440. tor_mutex_free(_thread_test_start1);
  441. if (_thread_test_start2)
  442. tor_mutex_free(_thread_test_start2);
  443. }
  444. /** Run unit tests for compression functions */
  445. static void
  446. test_util_gzip(void)
  447. {
  448. char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
  449. const char *ccp2;
  450. size_t len1, len2;
  451. tor_zlib_state_t *state = NULL;
  452. buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
  453. test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
  454. if (is_gzip_supported()) {
  455. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  456. GZIP_METHOD));
  457. test_assert(buf2);
  458. test_assert(!memcmp(buf2, "\037\213", 2)); /* Gzip magic. */
  459. test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
  460. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  461. GZIP_METHOD, 1, LOG_INFO));
  462. test_assert(buf3);
  463. test_streq(buf1,buf3);
  464. tor_free(buf2);
  465. tor_free(buf3);
  466. }
  467. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  468. ZLIB_METHOD));
  469. test_assert(buf2);
  470. test_assert(!memcmp(buf2, "\x78\xDA", 2)); /* deflate magic. */
  471. test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
  472. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  473. ZLIB_METHOD, 1, LOG_INFO));
  474. test_assert(buf3);
  475. test_streq(buf1,buf3);
  476. /* Check whether we can uncompress concatenated, compressed strings. */
  477. tor_free(buf3);
  478. buf2 = tor_realloc(buf2, len1*2);
  479. memcpy(buf2+len1, buf2, len1);
  480. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
  481. ZLIB_METHOD, 1, LOG_INFO));
  482. test_eq(len2, (strlen(buf1)+1)*2);
  483. test_memeq(buf3,
  484. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
  485. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
  486. (strlen(buf1)+1)*2);
  487. tor_free(buf1);
  488. tor_free(buf2);
  489. tor_free(buf3);
  490. /* Check whether we can uncompress partial strings. */
  491. buf1 =
  492. tor_strdup("String with low redundancy that won't be compressed much.");
  493. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  494. ZLIB_METHOD));
  495. tor_assert(len1>16);
  496. /* when we allow an incomplete string, we should succeed.*/
  497. tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  498. ZLIB_METHOD, 0, LOG_INFO));
  499. buf3[len2]='\0';
  500. tor_assert(len2 > 5);
  501. tor_assert(!strcmpstart(buf1, buf3));
  502. /* when we demand a complete string, this must fail. */
  503. tor_free(buf3);
  504. tor_assert(tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  505. ZLIB_METHOD, 1, LOG_INFO));
  506. tor_assert(!buf3);
  507. /* Now, try streaming compression. */
  508. tor_free(buf1);
  509. tor_free(buf2);
  510. tor_free(buf3);
  511. state = tor_zlib_new(1, ZLIB_METHOD);
  512. tor_assert(state);
  513. cp1 = buf1 = tor_malloc(1024);
  514. len1 = 1024;
  515. ccp2 = "ABCDEFGHIJABCDEFGHIJ";
  516. len2 = 21;
  517. test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
  518. == TOR_ZLIB_OK);
  519. test_eq(len2, 0); /* Make sure we compressed it all. */
  520. test_assert(cp1 > buf1);
  521. len2 = 0;
  522. cp2 = cp1;
  523. test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
  524. == TOR_ZLIB_DONE);
  525. test_eq(len2, 0);
  526. test_assert(cp1 > cp2); /* Make sure we really added something. */
  527. tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
  528. ZLIB_METHOD, 1, LOG_WARN));
  529. test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
  530. done:
  531. if (state)
  532. tor_zlib_free(state);
  533. tor_free(buf2);
  534. tor_free(buf3);
  535. tor_free(buf1);
  536. }
  537. /** Run unit tests for mmap() wrapper functionality. */
  538. static void
  539. test_util_mmap(void)
  540. {
  541. char *fname1 = tor_strdup(get_fname("mapped_1"));
  542. char *fname2 = tor_strdup(get_fname("mapped_2"));
  543. char *fname3 = tor_strdup(get_fname("mapped_3"));
  544. const size_t buflen = 17000;
  545. char *buf = tor_malloc(17000);
  546. tor_mmap_t *mapping = NULL;
  547. crypto_rand(buf, buflen);
  548. mapping = tor_mmap_file(fname1);
  549. test_assert(! mapping);
  550. write_str_to_file(fname1, "Short file.", 1);
  551. write_bytes_to_file(fname2, buf, buflen, 1);
  552. write_bytes_to_file(fname3, buf, 16384, 1);
  553. mapping = tor_mmap_file(fname1);
  554. test_assert(mapping);
  555. test_eq(mapping->size, strlen("Short file."));
  556. test_streq(mapping->data, "Short file.");
  557. #ifdef MS_WINDOWS
  558. tor_munmap_file(mapping);
  559. mapping = NULL;
  560. test_assert(unlink(fname1) == 0);
  561. #else
  562. /* make sure we can unlink. */
  563. test_assert(unlink(fname1) == 0);
  564. test_streq(mapping->data, "Short file.");
  565. tor_munmap_file(mapping);
  566. mapping = NULL;
  567. #endif
  568. /* Now a zero-length file. */
  569. write_str_to_file(fname1, "", 1);
  570. mapping = tor_mmap_file(fname1);
  571. test_eq(mapping, NULL);
  572. test_eq(ERANGE, errno);
  573. unlink(fname1);
  574. /* Make sure that we fail to map a no-longer-existent file. */
  575. mapping = tor_mmap_file(fname1);
  576. test_assert(mapping == NULL);
  577. /* Now try a big file that stretches across a few pages and isn't aligned */
  578. mapping = tor_mmap_file(fname2);
  579. test_assert(mapping);
  580. test_eq(mapping->size, buflen);
  581. test_memeq(mapping->data, buf, buflen);
  582. tor_munmap_file(mapping);
  583. mapping = NULL;
  584. /* Now try a big aligned file. */
  585. mapping = tor_mmap_file(fname3);
  586. test_assert(mapping);
  587. test_eq(mapping->size, 16384);
  588. test_memeq(mapping->data, buf, 16384);
  589. tor_munmap_file(mapping);
  590. mapping = NULL;
  591. done:
  592. unlink(fname1);
  593. unlink(fname2);
  594. unlink(fname3);
  595. tor_free(fname1);
  596. tor_free(fname2);
  597. tor_free(fname3);
  598. tor_free(buf);
  599. if (mapping)
  600. tor_munmap_file(mapping);
  601. }
  602. /** Run unit tests for escaping/unescaping data for use by controllers. */
  603. static void
  604. test_util_control_formats(void)
  605. {
  606. char *out = NULL;
  607. const char *inp =
  608. "..This is a test\r\nof the emergency \nbroadcast\r\n..system.\r\nZ.\r\n";
  609. size_t sz;
  610. sz = read_escaped_data(inp, strlen(inp), &out);
  611. test_streq(out,
  612. ".This is a test\nof the emergency \nbroadcast\n.system.\nZ.\n");
  613. test_eq(sz, strlen(out));
  614. done:
  615. tor_free(out);
  616. }
  617. static void
  618. test_util_sscanf(void)
  619. {
  620. unsigned u1, u2, u3;
  621. char s1[10], s2[10], s3[10], ch;
  622. int r;
  623. r = tor_sscanf("hello world", "hello world"); /* String match: success */
  624. test_eq(r, 0);
  625. r = tor_sscanf("hello world 3", "hello worlb %u", &u1); /* String fail */
  626. test_eq(r, 0);
  627. r = tor_sscanf("12345", "%u", &u1); /* Simple number */
  628. test_eq(r, 1);
  629. test_eq(u1, 12345u);
  630. r = tor_sscanf("", "%u", &u1); /* absent number */
  631. test_eq(r, 0);
  632. r = tor_sscanf("A", "%u", &u1); /* bogus number */
  633. test_eq(r, 0);
  634. r = tor_sscanf("4294967295", "%u", &u1); /* UINT32_MAX should work. */
  635. test_eq(r, 1);
  636. test_eq(u1, 4294967295u);
  637. r = tor_sscanf("4294967296", "%u", &u1); /* Always say -1 at 32 bits. */
  638. test_eq(r, 0);
  639. r = tor_sscanf("123456", "%2u%u", &u1, &u2); /* Width */
  640. test_eq(r, 2);
  641. test_eq(u1, 12u);
  642. test_eq(u2, 3456u);
  643. r = tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3); /* separators */
  644. test_eq(r, 3);
  645. test_eq(u1, 12u);
  646. test_eq(u2, 3u);
  647. test_eq(u3, 456u);
  648. r = tor_sscanf("12:3:045", "%2u:%2u:%3u", &u1, &u2, &u3); /* 0s */
  649. test_eq(r, 3);
  650. test_eq(u1, 12u);
  651. test_eq(u2, 3u);
  652. test_eq(u3, 45u);
  653. /* %u does not match space.*/
  654. r = tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3);
  655. test_eq(r, 2);
  656. /* %u does not match negative numbers. */
  657. r = tor_sscanf("12:3:-4", "%2u:%2u:%3u", &u1, &u2, &u3);
  658. test_eq(r, 2);
  659. /* Arbitrary amounts of 0-padding are okay */
  660. r = tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1, &u2, &u3);
  661. test_eq(r, 3);
  662. test_eq(u1, 12u);
  663. test_eq(u2, 3u);
  664. test_eq(u3, 99u);
  665. r = tor_sscanf("99% fresh", "%3u%% fresh", &u1); /* percents are scannable.*/
  666. test_eq(r, 1);
  667. test_eq(u1, 99);
  668. r = tor_sscanf("hello", "%s", s1); /* %s needs a number. */
  669. test_eq(r, -1);
  670. r = tor_sscanf("hello", "%3s%7s", s1, s2); /* %s matches characters. */
  671. test_eq(r, 2);
  672. test_streq(s1, "hel");
  673. test_streq(s2, "lo");
  674. r = tor_sscanf("WD40", "%2s%u", s3, &u1); /* %s%u */
  675. test_eq(r, 2);
  676. test_streq(s3, "WD");
  677. test_eq(u1, 40);
  678. r = tor_sscanf("76trombones", "%6u%9s", &u1, s1); /* %u%s */
  679. test_eq(r, 2);
  680. test_eq(u1, 76);
  681. test_streq(s1, "trombones");
  682. r = tor_sscanf("hello world", "%9s %9s", s1, s2); /* %s doesn't eat space. */
  683. test_eq(r, 2);
  684. test_streq(s1, "hello");
  685. test_streq(s2, "world");
  686. r = tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3); /* %s can be empty. */
  687. test_eq(r, 3);
  688. test_streq(s1, "hi");
  689. test_streq(s2, "");
  690. test_streq(s3, "");
  691. r = tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
  692. test_eq(r, 3);
  693. r = tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
  694. test_eq(r, 4);
  695. done:
  696. ;
  697. }
  698. /** Run unittests for memory pool allocator */
  699. static void
  700. test_util_mempool(void)
  701. {
  702. mp_pool_t *pool = NULL;
  703. smartlist_t *allocated = NULL;
  704. int i;
  705. pool = mp_pool_new(1, 100);
  706. test_assert(pool);
  707. test_assert(pool->new_chunk_capacity >= 100);
  708. test_assert(pool->item_alloc_size >= sizeof(void*)+1);
  709. mp_pool_destroy(pool);
  710. pool = NULL;
  711. pool = mp_pool_new(241, 2500);
  712. test_assert(pool);
  713. test_assert(pool->new_chunk_capacity >= 10);
  714. test_assert(pool->item_alloc_size >= sizeof(void*)+241);
  715. test_eq(pool->item_alloc_size & 0x03, 0);
  716. test_assert(pool->new_chunk_capacity < 60);
  717. allocated = smartlist_create();
  718. for (i = 0; i < 20000; ++i) {
  719. if (smartlist_len(allocated) < 20 || crypto_rand_int(2)) {
  720. void *m = mp_pool_get(pool);
  721. memset(m, 0x09, 241);
  722. smartlist_add(allocated, m);
  723. //printf("%d: %p\n", i, m);
  724. //mp_pool_assert_ok(pool);
  725. } else {
  726. int idx = crypto_rand_int(smartlist_len(allocated));
  727. void *m = smartlist_get(allocated, idx);
  728. //printf("%d: free %p\n", i, m);
  729. smartlist_del(allocated, idx);
  730. mp_pool_release(m);
  731. //mp_pool_assert_ok(pool);
  732. }
  733. if (crypto_rand_int(777)==0)
  734. mp_pool_clean(pool, 1, 1);
  735. if (i % 777)
  736. mp_pool_assert_ok(pool);
  737. }
  738. done:
  739. if (allocated) {
  740. SMARTLIST_FOREACH(allocated, void *, m, mp_pool_release(m));
  741. mp_pool_assert_ok(pool);
  742. mp_pool_clean(pool, 0, 0);
  743. mp_pool_assert_ok(pool);
  744. smartlist_free(allocated);
  745. }
  746. if (pool)
  747. mp_pool_destroy(pool);
  748. }
  749. /** Run unittests for memory area allocator */
  750. static void
  751. test_util_memarea(void)
  752. {
  753. memarea_t *area = memarea_new();
  754. char *p1, *p2, *p3, *p1_orig;
  755. void *malloced_ptr = NULL;
  756. int i;
  757. test_assert(area);
  758. p1_orig = p1 = memarea_alloc(area,64);
  759. p2 = memarea_alloc_zero(area,52);
  760. p3 = memarea_alloc(area,11);
  761. test_assert(memarea_owns_ptr(area, p1));
  762. test_assert(memarea_owns_ptr(area, p2));
  763. test_assert(memarea_owns_ptr(area, p3));
  764. /* Make sure we left enough space. */
  765. test_assert(p1+64 <= p2);
  766. test_assert(p2+52 <= p3);
  767. /* Make sure we aligned. */
  768. test_eq(((uintptr_t)p1) % sizeof(void*), 0);
  769. test_eq(((uintptr_t)p2) % sizeof(void*), 0);
  770. test_eq(((uintptr_t)p3) % sizeof(void*), 0);
  771. test_assert(!memarea_owns_ptr(area, p3+8192));
  772. test_assert(!memarea_owns_ptr(area, p3+30));
  773. test_assert(tor_mem_is_zero(p2, 52));
  774. /* Make sure we don't overalign. */
  775. p1 = memarea_alloc(area, 1);
  776. p2 = memarea_alloc(area, 1);
  777. test_eq(p1+sizeof(void*), p2);
  778. {
  779. malloced_ptr = tor_malloc(64);
  780. test_assert(!memarea_owns_ptr(area, malloced_ptr));
  781. tor_free(malloced_ptr);
  782. }
  783. /* memarea_memdup */
  784. {
  785. malloced_ptr = tor_malloc(64);
  786. crypto_rand((char*)malloced_ptr, 64);
  787. p1 = memarea_memdup(area, malloced_ptr, 64);
  788. test_assert(p1 != malloced_ptr);
  789. test_memeq(p1, malloced_ptr, 64);
  790. tor_free(malloced_ptr);
  791. }
  792. /* memarea_strdup. */
  793. p1 = memarea_strdup(area,"");
  794. p2 = memarea_strdup(area, "abcd");
  795. test_assert(p1);
  796. test_assert(p2);
  797. test_streq(p1, "");
  798. test_streq(p2, "abcd");
  799. /* memarea_strndup. */
  800. {
  801. const char *s = "Ad ogni porta batte la morte e grida: il nome!";
  802. /* (From Turandot, act 3.) */
  803. size_t len = strlen(s);
  804. p1 = memarea_strndup(area, s, 1000);
  805. p2 = memarea_strndup(area, s, 10);
  806. test_streq(p1, s);
  807. test_assert(p2 >= p1 + len + 1);
  808. test_memeq(s, p2, 10);
  809. test_eq(p2[10], '\0');
  810. p3 = memarea_strndup(area, s, len);
  811. test_streq(p3, s);
  812. p3 = memarea_strndup(area, s, len-1);
  813. test_memeq(s, p3, len-1);
  814. test_eq(p3[len-1], '\0');
  815. }
  816. memarea_clear(area);
  817. p1 = memarea_alloc(area, 1);
  818. test_eq(p1, p1_orig);
  819. memarea_clear(area);
  820. /* Check for running over an area's size. */
  821. for (i = 0; i < 512; ++i) {
  822. p1 = memarea_alloc(area, crypto_rand_int(5)+1);
  823. test_assert(memarea_owns_ptr(area, p1));
  824. }
  825. memarea_assert_ok(area);
  826. /* Make sure we can allocate a too-big object. */
  827. p1 = memarea_alloc_zero(area, 9000);
  828. p2 = memarea_alloc_zero(area, 16);
  829. test_assert(memarea_owns_ptr(area, p1));
  830. test_assert(memarea_owns_ptr(area, p2));
  831. done:
  832. memarea_drop_all(area);
  833. tor_free(malloced_ptr);
  834. }
  835. /** Run unit tests for utility functions to get file names relative to
  836. * the data directory. */
  837. static void
  838. test_util_datadir(void)
  839. {
  840. char buf[1024];
  841. char *f = NULL;
  842. char *temp_dir = NULL;
  843. temp_dir = get_datadir_fname(NULL);
  844. f = get_datadir_fname("state");
  845. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
  846. test_streq(f, buf);
  847. tor_free(f);
  848. f = get_datadir_fname2("cache", "thingy");
  849. tor_snprintf(buf, sizeof(buf),
  850. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
  851. test_streq(f, buf);
  852. tor_free(f);
  853. f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
  854. tor_snprintf(buf, sizeof(buf),
  855. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
  856. test_streq(f, buf);
  857. tor_free(f);
  858. f = get_datadir_fname_suffix("cache", ".foo");
  859. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
  860. temp_dir);
  861. test_streq(f, buf);
  862. done:
  863. tor_free(f);
  864. tor_free(temp_dir);
  865. }
  866. static void
  867. test_util_strtok(void)
  868. {
  869. char buf[128];
  870. char buf2[128];
  871. char *cp1, *cp2;
  872. strlcpy(buf, "Graved on the dark in gestures of descent", sizeof(buf));
  873. strlcpy(buf2, "they.seemed;their!own;most.perfect;monument", sizeof(buf2));
  874. /* -- "Year's End", Richard Wilbur */
  875. test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
  876. test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  877. #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
  878. #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
  879. test_streq("on", S1());
  880. test_streq("the", S1());
  881. test_streq("dark", S1());
  882. test_streq("seemed", S2());
  883. test_streq("their", S2());
  884. test_streq("own", S2());
  885. test_streq("in", S1());
  886. test_streq("gestures", S1());
  887. test_streq("of", S1());
  888. test_streq("most", S2());
  889. test_streq("perfect", S2());
  890. test_streq("descent", S1());
  891. test_streq("monument", S2());
  892. test_assert(NULL == S1());
  893. test_assert(NULL == S2());
  894. done:
  895. ;
  896. }
  897. static void
  898. test_util_find_str_at_start_of_line(void *ptr)
  899. {
  900. const char *long_string =
  901. "hello world. hello world. hello hello. howdy.\n"
  902. "hello hello world\n";
  903. (void)ptr;
  904. /* not-found case. */
  905. tt_assert(! find_str_at_start_of_line(long_string, "fred"));
  906. /* not-found case where haystack doesn't end with \n */
  907. tt_assert(! find_str_at_start_of_line("foobar\nbaz", "fred"));
  908. /* start-of-string case */
  909. tt_assert(long_string ==
  910. find_str_at_start_of_line(long_string, "hello world."));
  911. /* start-of-line case */
  912. tt_assert(strchr(long_string,'\n')+1 ==
  913. find_str_at_start_of_line(long_string, "hello hello"));
  914. done:
  915. ;
  916. }
  917. #define UTIL_LEGACY(name) \
  918. { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
  919. #define UTIL_TEST(name, flags) \
  920. { #name, test_util_ ## name, flags, NULL, NULL }
  921. struct testcase_t util_tests[] = {
  922. UTIL_LEGACY(time),
  923. UTIL_LEGACY(config_line),
  924. UTIL_LEGACY(strmisc),
  925. UTIL_LEGACY(pow2),
  926. UTIL_LEGACY(gzip),
  927. UTIL_LEGACY(datadir),
  928. UTIL_LEGACY(mempool),
  929. UTIL_LEGACY(memarea),
  930. UTIL_LEGACY(control_formats),
  931. UTIL_LEGACY(mmap),
  932. UTIL_LEGACY(threads),
  933. UTIL_LEGACY(sscanf),
  934. UTIL_LEGACY(strtok),
  935. UTIL_TEST(find_str_at_start_of_line, 0),
  936. END_OF_TESTCASES
  937. };