test_util.c 37 KB

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