1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2012, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #define CONTROL_PRIVATE
8 #define MEMPOOL_PRIVATE
24 struct timeval start
, end
;
39 test_eq(0L, tv_udiff(&start
, &end
));
43 test_eq(2000L, tv_udiff(&start
, &end
));
47 test_eq(1002000L, tv_udiff(&start
, &end
));
51 test_eq(995000L, tv_udiff(&start
, &end
));
55 test_eq(-1005000L, tv_udiff(&start
, &end
));
59 /* The test values here are confirmed to be correct on a platform
60 * with a working timegm. */
61 a_time
.tm_year
= 2003-1900;
67 test_eq((time_t) 1062224095UL, tor_timegm(&a_time
));
68 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
69 test_eq((time_t) 1093846495UL, tor_timegm(&a_time
));
70 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
72 test_eq((time_t) 1076393695UL, tor_timegm(&a_time
));
75 test_eq((time_t) 1073715295UL, tor_timegm(&a_time
));
76 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
78 test_eq((time_t) -1, tor_timegm(&a_time
));
79 a_time
.tm_mon
= -1; /* Wrong month */
81 test_eq((time_t) -1, tor_timegm(&a_time
));
83 /* Test {format,parse}_rfc1123_time */
85 format_rfc1123_time(timestr
, 0);
86 test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr
);
87 format_rfc1123_time(timestr
, (time_t)1091580502UL);
88 test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr
);
91 i
= parse_rfc1123_time(timestr
, &t_res
);
93 test_eq(t_res
, (time_t)1091580502UL);
94 /* The timezone doesn't matter */
96 test_eq(0, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
97 test_eq(t_res
, (time_t)1091580502UL);
98 test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
99 test_eq(-1, parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
100 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
101 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
102 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
103 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
104 test_eq(-1, parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
105 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
108 /* This fails, I imagine it's important and should be fixed? */
109 test_eq(-1, parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
110 /* Why is this string valid (ie. the test fails because it doesn't
112 test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
115 /* Test parse_iso_time */
118 i
= parse_iso_time("", &t_res
);
121 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
124 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
128 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
130 test_eq(t_res
, (time_t)1091580502UL);
132 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
134 test_eq(t_res
, (time_t)1091580502UL);
135 test_eq(-1, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res
));
136 test_eq(-1, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res
));
137 test_eq(-1, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res
));
138 test_eq(-1, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res
));
139 test_eq(-1, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res
));
140 test_eq(-1, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res
));
141 test_eq(-1, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res
));
142 test_eq(-1, parse_iso_time("2011-03-30 23:59", &t_res
));
144 /* Test tor_gettimeofday */
147 end
.tv_usec
= 999990;
151 tor_gettimeofday(&start
);
152 /* now make sure time works. */
153 tor_gettimeofday(&end
);
154 /* We might've timewarped a little. */
155 tt_int_op(tv_udiff(&start
, &end
), >=, -5000);
157 /* Test format_iso_time */
159 tv
.tv_sec
= (time_t)1326296338;
161 format_iso_time(timestr
, tv
.tv_sec
);
162 test_streq("2012-01-11 15:38:58", timestr
);
163 /* The output of format_local_iso_time will vary by timezone, and setting
164 our timezone for testing purposes would be a nontrivial flaky pain.
165 Skip this test for now.
166 format_local_iso_time(timestr, tv.tv_sec);
167 test_streq("2012-01-11 10:38:58", timestr);
169 format_iso_time_nospace(timestr
, tv
.tv_sec
);
170 test_streq("2012-01-11T15:38:58", timestr
);
171 test_eq(strlen(timestr
), ISO_TIME_LEN
);
172 format_iso_time_nospace_usec(timestr
, &tv
);
173 test_streq("2012-01-11T15:38:58.003060", timestr
);
174 test_eq(strlen(timestr
), ISO_TIME_USEC_LEN
);
181 test_util_parse_http_time(void *arg
)
184 char b
[ISO_TIME_LEN
+1];
188 format_iso_time(b, tor_timegm(&a_time)); \
189 tt_str_op(b, ==, (s)); \
193 /* Test parse_http_time */
195 test_eq(-1, parse_http_time("", &a_time
));
196 test_eq(-1, parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
197 test_eq(-1, parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
198 test_eq(-1, parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
199 test_eq(-1, parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
200 test_eq(-1, parse_http_time("Sunday, August the third", &a_time
));
201 test_eq(-1, parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
203 test_eq(0, parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
204 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
205 T("1994-08-04 00:48:22");
206 test_eq(0, parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
207 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
208 T("1994-08-04 00:48:22");
209 test_eq(0, parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
210 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
211 T("1994-08-04 00:48:22");
212 test_eq(0, parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
213 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
214 T("1994-08-04 00:48:22");
215 test_eq(0, parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
216 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
217 T("1994-08-04 00:48:22");
218 test_eq(0, parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
219 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
220 T("1994-08-04 00:48:22");
221 test_eq(0, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
222 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
223 T("1994-08-04 00:48:22");
224 test_eq(0, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
225 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
226 T("1994-08-04 00:48:22");
227 test_eq(0, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
228 test_eq((time_t)775961302UL, tor_timegm(&a_time
));
229 T("1994-08-04 00:48:22");
230 test_eq(0, parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
231 test_eq((time_t)1325376000UL, tor_timegm(&a_time
));
232 T("2012-01-01 00:00:00");
233 test_eq(0, parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
234 test_eq((time_t)1356912000UL, tor_timegm(&a_time
));
235 T("2012-12-31 00:00:00");
236 test_eq(-1, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
237 test_eq(-1, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
238 test_eq(-1, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
239 test_eq(-1, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
240 test_eq(-1, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
241 test_eq(-1, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
242 test_eq(-1, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
243 test_eq(-1, parse_http_time("2011-03-30 23:59", &a_time
));
251 test_util_config_line(void)
254 char *k
=NULL
, *v
=NULL
;
257 /* Test parse_config_line_from_str */
258 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
260 "k3 \n" "\n" " \n" "#comment\n"
261 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
262 "kseven \"a quoted 'string\"\n"
263 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
264 "k9 a line that\\\n spans two lines.\n\n"
265 "k10 more than\\\n one contin\\\nuation\n"
266 "k11 \\\ncontinuation at the start\n"
267 "k12 line with a\\\n#comment\n embedded\n"
268 "k13\\\ncontinuation at the very start\n"
269 "k14 a line that has a comment and # ends with a slash \\\n"
270 "k15 this should be the next new line\n"
271 "k16 a line that has a comment and # ends without a slash \n"
272 "k17 this should be the next new line\n"
276 str
= parse_config_line_from_str(str
, &k
, &v
);
279 tor_free(k
); tor_free(v
);
280 test_assert(!strcmpstart(str
, "key value with"));
282 str
= parse_config_line_from_str(str
, &k
, &v
);
283 test_streq(k
, "key");
284 test_streq(v
, "value with spaces");
285 tor_free(k
); tor_free(v
);
286 test_assert(!strcmpstart(str
, "keykey"));
288 str
= parse_config_line_from_str(str
, &k
, &v
);
289 test_streq(k
, "keykey");
290 test_streq(v
, "val");
291 tor_free(k
); tor_free(v
);
292 test_assert(!strcmpstart(str
, "k2\n"));
294 str
= parse_config_line_from_str(str
, &k
, &v
);
297 tor_free(k
); tor_free(v
);
298 test_assert(!strcmpstart(str
, "k3 \n"));
300 str
= parse_config_line_from_str(str
, &k
, &v
);
303 tor_free(k
); tor_free(v
);
304 test_assert(!strcmpstart(str
, "#comment"));
306 str
= parse_config_line_from_str(str
, &k
, &v
);
309 tor_free(k
); tor_free(v
);
310 test_assert(!strcmpstart(str
, "k5#abc"));
312 str
= parse_config_line_from_str(str
, &k
, &v
);
315 tor_free(k
); tor_free(v
);
316 test_assert(!strcmpstart(str
, "k6"));
318 str
= parse_config_line_from_str(str
, &k
, &v
);
320 test_streq(v
, "val");
321 tor_free(k
); tor_free(v
);
322 test_assert(!strcmpstart(str
, "kseven"));
324 str
= parse_config_line_from_str(str
, &k
, &v
);
325 test_streq(k
, "kseven");
326 test_streq(v
, "a quoted \'string");
327 tor_free(k
); tor_free(v
);
328 test_assert(!strcmpstart(str
, "k8 "));
330 str
= parse_config_line_from_str(str
, &k
, &v
);
332 test_streq(v
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
333 tor_free(k
); tor_free(v
);
335 str
= parse_config_line_from_str(str
, &k
, &v
);
337 test_streq(v
, "a line that spans two lines.");
338 tor_free(k
); tor_free(v
);
340 str
= parse_config_line_from_str(str
, &k
, &v
);
341 test_streq(k
, "k10");
342 test_streq(v
, "more than one continuation");
343 tor_free(k
); tor_free(v
);
345 str
= parse_config_line_from_str(str
, &k
, &v
);
346 test_streq(k
, "k11");
347 test_streq(v
, "continuation at the start");
348 tor_free(k
); tor_free(v
);
350 str
= parse_config_line_from_str(str
, &k
, &v
);
351 test_streq(k
, "k12");
352 test_streq(v
, "line with a embedded");
353 tor_free(k
); tor_free(v
);
355 str
= parse_config_line_from_str(str
, &k
, &v
);
356 test_streq(k
, "k13");
357 test_streq(v
, "continuation at the very start");
358 tor_free(k
); tor_free(v
);
360 str
= parse_config_line_from_str(str
, &k
, &v
);
361 test_streq(k
, "k14");
362 test_streq(v
, "a line that has a comment and" );
363 tor_free(k
); tor_free(v
);
365 str
= parse_config_line_from_str(str
, &k
, &v
);
366 test_streq(k
, "k15");
367 test_streq(v
, "this should be the next new line");
368 tor_free(k
); tor_free(v
);
370 str
= parse_config_line_from_str(str
, &k
, &v
);
371 test_streq(k
, "k16");
372 test_streq(v
, "a line that has a comment and" );
373 tor_free(k
); tor_free(v
);
375 str
= parse_config_line_from_str(str
, &k
, &v
);
376 test_streq(k
, "k17");
377 test_streq(v
, "this should be the next new line");
378 tor_free(k
); tor_free(v
);
388 test_util_config_line_quotes(void)
394 char *k
=NULL
, *v
=NULL
;
397 /* Test parse_config_line_from_str */
398 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
399 "kTrailingGarbage \"quoted value\"trailing garbage\n"
401 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
403 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
405 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
409 str
= parse_config_line_from_str(str
, &k
, &v
);
410 test_streq(k
, "kTrailingSpace");
411 test_streq(v
, "quoted value");
412 tor_free(k
); tor_free(v
);
414 str
= parse_config_line_from_str(str
, &k
, &v
);
415 test_eq_ptr(str
, NULL
);
416 tor_free(k
); tor_free(v
);
420 str
= parse_config_line_from_str(str
, &k
, &v
);
421 test_eq_ptr(str
, NULL
);
422 tor_free(k
); tor_free(v
);
426 str
= parse_config_line_from_str(str
, &k
, &v
);
427 test_eq_ptr(str
, NULL
);
428 tor_free(k
); tor_free(v
);
432 str
= parse_config_line_from_str(str
, &k
, &v
);
433 test_eq_ptr(str
, NULL
);
434 tor_free(k
); tor_free(v
);
442 test_util_config_line_comment_character(void)
445 char *k
=NULL
, *v
=NULL
;
448 /* Test parse_config_line_from_str */
449 strlcpy(buf
, "k1 \"# in quotes\"\n"
450 "k2 some value # some comment\n"
451 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
455 str
= parse_config_line_from_str(str
, &k
, &v
);
457 test_streq(v
, "# in quotes");
458 tor_free(k
); tor_free(v
);
460 str
= parse_config_line_from_str(str
, &k
, &v
);
462 test_streq(v
, "some value");
463 tor_free(k
); tor_free(v
);
465 test_streq(str
, "k3 /home/user/myTorNetwork#2\n");
468 str
= parse_config_line_from_str(str
, &k
, &v
);
470 test_streq(v
, "/home/user/myTorNetwork#2");
471 tor_free(k
); tor_free(v
);
482 test_util_config_line_escaped_content(void)
490 char *k
=NULL
, *v
=NULL
;
493 /* Test parse_config_line_from_str */
494 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
495 "HexadecimalUpper \"\\x2A\"\n"
496 "HexadecimalUpperX \"\\X2A\"\n"
500 "CarriageReturn \"\\r\"\n"
501 "DoubleQuote \"\\\"\"\n"
502 "SimpleQuote \"\\'\"\n"
503 "Backslash \"\\\\\"\n"
504 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
507 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
510 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
513 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
516 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
519 strlcpy(buf6
, "BrokenEscape \"\\"
524 str
= parse_config_line_from_str(str
, &k
, &v
);
525 test_streq(k
, "HexadecimalLower");
527 tor_free(k
); tor_free(v
);
529 str
= parse_config_line_from_str(str
, &k
, &v
);
530 test_streq(k
, "HexadecimalUpper");
532 tor_free(k
); tor_free(v
);
534 str
= parse_config_line_from_str(str
, &k
, &v
);
535 test_streq(k
, "HexadecimalUpperX");
537 tor_free(k
); tor_free(v
);
539 str
= parse_config_line_from_str(str
, &k
, &v
);
540 test_streq(k
, "Octal");
542 tor_free(k
); tor_free(v
);
544 str
= parse_config_line_from_str(str
, &k
, &v
);
545 test_streq(k
, "Newline");
547 tor_free(k
); tor_free(v
);
549 str
= parse_config_line_from_str(str
, &k
, &v
);
550 test_streq(k
, "Tab");
552 tor_free(k
); tor_free(v
);
554 str
= parse_config_line_from_str(str
, &k
, &v
);
555 test_streq(k
, "CarriageReturn");
557 tor_free(k
); tor_free(v
);
559 str
= parse_config_line_from_str(str
, &k
, &v
);
560 test_streq(k
, "DoubleQuote");
562 tor_free(k
); tor_free(v
);
564 str
= parse_config_line_from_str(str
, &k
, &v
);
565 test_streq(k
, "SimpleQuote");
567 tor_free(k
); tor_free(v
);
569 str
= parse_config_line_from_str(str
, &k
, &v
);
570 test_streq(k
, "Backslash");
572 tor_free(k
); tor_free(v
);
574 str
= parse_config_line_from_str(str
, &k
, &v
);
575 test_streq(k
, "Mix");
576 test_streq(v
, "This is a \"star\":\t'*'\nAnd second line");
577 tor_free(k
); tor_free(v
);
582 str
= parse_config_line_from_str(str
, &k
, &v
);
583 test_eq_ptr(str
, NULL
);
584 tor_free(k
); tor_free(v
);
588 str
= parse_config_line_from_str(str
, &k
, &v
);
589 test_eq_ptr(str
, NULL
);
590 tor_free(k
); tor_free(v
);
594 str
= parse_config_line_from_str(str
, &k
, &v
);
595 test_eq_ptr(str
, NULL
);
596 tor_free(k
); tor_free(v
);
601 str
= parse_config_line_from_str(str
, &k
, &v
);
602 test_eq_ptr(str
, NULL
);
603 tor_free(k
); tor_free(v
);
608 str
= parse_config_line_from_str(str
, &k
, &v
);
609 test_eq_ptr(str
, NULL
);
610 tor_free(k
); tor_free(v
);
619 test_util_expand_filename(void)
623 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
625 str
= expand_filename("");
629 str
= expand_filename("/normal/path");
630 test_streq("/normal/path", str
);
633 str
= expand_filename("/normal/trailing/path/");
634 test_streq("/normal/trailing/path/", str
);
637 str
= expand_filename("~");
638 test_streq("/home/itv/", str
);
641 str
= expand_filename("$HOME/nodice");
642 test_streq("$HOME/nodice", str
);
645 str
= expand_filename("~/");
646 test_streq("/home/itv/", str
);
649 str
= expand_filename("~/foobarqux");
650 test_streq("/home/itv/foobarqux", str
);
653 str
= expand_filename("~/../../etc/passwd");
654 test_streq("/home/itv/../../etc/passwd", str
);
657 str
= expand_filename("~/trailing/");
658 test_streq("/home/itv/trailing/", str
);
660 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
661 have to somehow inject/fake the get_user_homedir call) */
663 /* $HOME ending in a trailing slash */
664 setenv("HOME", "/home/itv/", 1);
666 str
= expand_filename("~");
667 test_streq("/home/itv/", str
);
670 str
= expand_filename("~/");
671 test_streq("/home/itv/", str
);
674 str
= expand_filename("~/foo");
675 test_streq("/home/itv/foo", str
);
678 /* Try with empty $HOME */
680 setenv("HOME", "", 1);
682 str
= expand_filename("~");
683 test_streq("/", str
);
686 str
= expand_filename("~/");
687 test_streq("/", str
);
690 str
= expand_filename("~/foobar");
691 test_streq("/foobar", str
);
694 /* Try with $HOME unset */
698 str
= expand_filename("~");
699 test_streq("/", str
);
702 str
= expand_filename("~/");
703 test_streq("/", str
);
706 str
= expand_filename("~/foobar");
707 test_streq("/foobar", str
);
715 /** Test basic string functionality. */
717 test_util_strmisc(void)
723 /* Test strl operations */
724 test_eq(5, strlcpy(buf
, "Hello", 0));
725 test_eq(5, strlcpy(buf
, "Hello", 10));
726 test_streq(buf
, "Hello");
727 test_eq(5, strlcpy(buf
, "Hello", 6));
728 test_streq(buf
, "Hello");
729 test_eq(5, strlcpy(buf
, "Hello", 5));
730 test_streq(buf
, "Hell");
731 strlcpy(buf
, "Hello", sizeof(buf
));
732 test_eq(10, strlcat(buf
, "Hello", 5));
734 /* Test strstrip() */
735 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
736 tor_strstrip(buf
, ",!");
737 test_streq(buf
, "Testing 1 2 3");
738 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
739 tor_strstrip(buf
, "!? ");
740 test_streq(buf
, "Testing123");
741 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
742 tor_strstrip(buf
, "!? ");
743 test_streq(buf
, "Testing123");
745 /* Test parse_long */
746 /* Empty/zero input */
747 test_eq(0L, tor_parse_long("",10,0,100,&i
,NULL
));
749 test_eq(0L, tor_parse_long("0",10,0,100,&i
,NULL
));
752 test_eq(10L, tor_parse_long("10",10,0,100,&i
,NULL
));
754 test_eq(10L, tor_parse_long("10",10,0,10,&i
,NULL
));
756 test_eq(10L, tor_parse_long("10",10,10,100,&i
,NULL
));
758 test_eq(-50L, tor_parse_long("-50",10,-100,100,&i
,NULL
));
760 test_eq(-50L, tor_parse_long("-50",10,-100,0,&i
,NULL
));
762 test_eq(-50L, tor_parse_long("-50",10,-50,0,&i
,NULL
));
765 test_eq(0L, tor_parse_long("10m",10,0,100,&i
,NULL
));
767 test_eq(0L, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
769 test_eq(10L, tor_parse_long("10m",10,0,100,&i
,&cp
));
772 test_eq(-50L, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
774 test_streq(cp
, " plus garbage");
776 test_eq(0L, tor_parse_long("10",10,50,100,&i
,NULL
));
778 test_eq(0L, tor_parse_long("-50",10,0,100,&i
,NULL
));
780 /* Base different than 10 */
781 test_eq(2L, tor_parse_long("10",2,0,100,NULL
,NULL
));
782 test_eq(0L, tor_parse_long("2",2,0,100,NULL
,NULL
));
783 test_eq(0L, tor_parse_long("10",-2,0,100,NULL
,NULL
));
784 test_eq(68284L, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
785 test_eq(68284L, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
787 /* Test parse_ulong */
788 test_eq(0UL, tor_parse_ulong("",10,0,100,NULL
,NULL
));
789 test_eq(0UL, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
790 test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
791 test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
792 test_eq(10UL, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
793 test_eq(10UL, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
794 test_eq(0UL, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
795 test_eq(50UL, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
796 test_eq(0UL, tor_parse_ulong("-50",10,-100,100,NULL
,NULL
));
798 /* Test parse_uint64 */
799 test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
801 test_streq(cp
, " x");
802 test_assert(U64_LITERAL(12345678901) ==
803 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
806 test_assert(U64_LITERAL(0) ==
807 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
811 /* Test parse_double */
812 double d
= tor_parse_double("10", 0, UINT64_MAX
,&i
,NULL
);
814 test_assert(DBL_TO_U64(d
) == 10);
815 d
= tor_parse_double("0", 0, UINT64_MAX
,&i
,NULL
);
817 test_assert(DBL_TO_U64(d
) == 0);
818 d
= tor_parse_double(" ", 0, UINT64_MAX
,&i
,NULL
);
820 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,NULL
);
822 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,&cp
);
824 d
= tor_parse_double("-.0", 0, UINT64_MAX
,&i
,NULL
);
826 test_assert(DBL_TO_U64(d
) == 0);
827 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
833 /* Test tor_parse_* where we overflow/underflow the underlying type. */
834 /* This string should overflow 64-bit ints. */
835 #define TOOBIG "100000000000000000000000000"
836 test_eq(0L, tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
838 test_eq(0L, tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
840 test_eq(0UL, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
842 test_eq(U64_LITERAL(0), tor_parse_uint64(TOOBIG
, 10,
843 0, UINT64_MAX
, &i
, NULL
));
848 /* Returning -1 when there's not enough room in the output buffer */
849 test_eq(-1, tor_snprintf(buf
, 0, "Foo"));
850 test_eq(-1, tor_snprintf(buf
, 2, "Foo"));
851 test_eq(-1, tor_snprintf(buf
, 3, "Foo"));
852 test_neq(-1, tor_snprintf(buf
, 4, "Foo"));
853 /* Always NUL-terminate the output */
854 tor_snprintf(buf
, 5, "abcdef");
856 tor_snprintf(buf
, 10, "abcdef");
859 tor_snprintf(buf
, sizeof(buf
), "x!"U64_FORMAT
"!x",
860 U64_PRINTF_ARG(U64_LITERAL(12345678901)));
861 test_streq("x!12345678901!x", buf
);
863 /* Test str{,case}cmpstart */
864 test_assert(strcmpstart("abcdef", "abcdef")==0);
865 test_assert(strcmpstart("abcdef", "abc")==0);
866 test_assert(strcmpstart("abcdef", "abd")<0);
867 test_assert(strcmpstart("abcdef", "abb")>0);
868 test_assert(strcmpstart("ab", "abb")<0);
869 test_assert(strcmpstart("ab", "")==0);
870 test_assert(strcmpstart("ab", "ab ")<0);
871 test_assert(strcasecmpstart("abcdef", "abCdEF")==0);
872 test_assert(strcasecmpstart("abcDeF", "abc")==0);
873 test_assert(strcasecmpstart("abcdef", "Abd")<0);
874 test_assert(strcasecmpstart("Abcdef", "abb")>0);
875 test_assert(strcasecmpstart("ab", "Abb")<0);
876 test_assert(strcasecmpstart("ab", "")==0);
877 test_assert(strcasecmpstart("ab", "ab ")<0);
879 /* Test str{,case}cmpend */
880 test_assert(strcmpend("abcdef", "abcdef")==0);
881 test_assert(strcmpend("abcdef", "def")==0);
882 test_assert(strcmpend("abcdef", "deg")<0);
883 test_assert(strcmpend("abcdef", "dee")>0);
884 test_assert(strcmpend("ab", "aab")>0);
885 test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
886 test_assert(strcasecmpend("abcdef", "dEF")==0);
887 test_assert(strcasecmpend("abcdef", "Deg")<0);
888 test_assert(strcasecmpend("abcDef", "dee")>0);
889 test_assert(strcasecmpend("AB", "abb")<0);
891 /* Test digest_is_zero */
894 test_assert(tor_digest_is_zero(buf
));
896 test_assert(!tor_digest_is_zero(buf
));
898 /* Test mem_is_zero */
901 test_assert(tor_mem_is_zero(buf
, 10));
902 test_assert(tor_mem_is_zero(buf
, 20));
903 test_assert(tor_mem_is_zero(buf
, 128));
904 test_assert(!tor_mem_is_zero(buf
, 129));
906 test_assert(!tor_mem_is_zero(buf
, 128));
908 test_assert(!tor_mem_is_zero(buf
, 10));
911 test_assert(NULL
== escaped(NULL
));
912 test_streq("\"\"", escaped(""));
913 test_streq("\"abcd\"", escaped("abcd"));
914 test_streq("\"\\\\ \\n\\r\\t\\\"\\'\"", escaped("\\ \n\r\t\"'"));
915 test_streq("\"unnecessary \\'backslashes\\'\"",
916 escaped("unnecessary \'backslashes\'"));
917 /* Non-printable characters appear as octal */
918 test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
919 test_streq("\"z\\336\\255 ;foo\"", escaped("z\xde\xad\x20;foo"));
921 /* Test strndup and memdup */
923 const char *s
= "abcdefghijklmnopqrstuvwxyz";
924 cp
= tor_strndup(s
, 30);
925 test_streq(cp
, s
); /* same string, */
926 test_neq(cp
, s
); /* but different pointers. */
929 cp
= tor_strndup(s
, 5);
930 test_streq(cp
, "abcde");
933 s
= "a\0b\0c\0d\0e\0";
934 cp
= tor_memdup(s
,10);
935 test_memeq(cp
, s
, 10); /* same ram, */
936 test_neq(cp
, s
); /* but different pointers. */
940 /* Test str-foo functions */
941 cp
= tor_strdup("abcdef");
942 test_assert(tor_strisnonupper(cp
));
944 test_assert(!tor_strisnonupper(cp
));
946 test_streq(cp
, "ABCDEF");
948 test_streq(cp
, "abcdef");
949 test_assert(tor_strisnonupper(cp
));
950 test_assert(tor_strisprint(cp
));
952 test_assert(!tor_strisprint(cp
));
955 /* Test memmem and memstr */
957 const char *haystack
= "abcde";
958 test_assert(!tor_memmem(haystack
, 5, "ef", 2));
959 test_eq_ptr(tor_memmem(haystack
, 5, "cd", 2), haystack
+ 2);
960 test_eq_ptr(tor_memmem(haystack
, 5, "cde", 3), haystack
+ 2);
961 test_assert(!tor_memmem(haystack
, 4, "cde", 3));
962 haystack
= "ababcad";
963 test_eq_ptr(tor_memmem(haystack
, 7, "abc", 3), haystack
+ 2);
965 test_eq_ptr(tor_memstr(haystack
, 7, "abc"), haystack
+ 2);
966 test_eq_ptr(tor_memstr(haystack
, 7, "cad"), haystack
+ 4);
967 test_assert(!tor_memstr(haystack
, 6, "cad"));
968 test_assert(!tor_memstr(haystack
, 7, "cadd"));
969 test_assert(!tor_memstr(haystack
, 7, "fe"));
970 test_assert(!tor_memstr(haystack
, 7, "ababcade"));
973 /* Test wrap_string */
975 smartlist_t
*sl
= smartlist_new();
977 "This is a test of string wrapping functionality: woot. "
978 "a functionality? w00t w00t...!",
980 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
982 "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n"
983 "a\nfunctional\nity? w00t\nw00t...!\n");
985 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
988 wrap_string(sl
, "This is a test of string wrapping functionality: woot.",
990 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
992 "### This is a\n# test of string\n# wrapping\n# functionality:\n"
995 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
998 wrap_string(sl
, "A test of string wrapping...", 6, "### ", "# ");
999 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1001 "### A\n# test\n# of\n# stri\n# ng\n# wrap\n# ping\n# ...\n");
1003 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1004 smartlist_clear(sl
);
1006 wrap_string(sl
, "Wrapping test", 6, "#### ", "# ");
1007 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1008 test_streq(cp
, "#### W\n# rapp\n# ing\n# test\n");
1010 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1011 smartlist_clear(sl
);
1013 wrap_string(sl
, "Small test", 6, "### ", "#### ");
1014 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1015 test_streq(cp
, "### Sm\n#### a\n#### l\n#### l\n#### t\n#### e"
1016 "\n#### s\n#### t\n");
1018 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1019 smartlist_clear(sl
);
1021 wrap_string(sl
, "First null", 6, NULL
, "> ");
1022 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1023 test_streq(cp
, "First\n> null\n");
1025 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1026 smartlist_clear(sl
);
1028 wrap_string(sl
, "Second null", 6, "> ", NULL
);
1029 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1030 test_streq(cp
, "> Seco\nnd\nnull\n");
1032 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1033 smartlist_clear(sl
);
1035 wrap_string(sl
, "Both null", 6, NULL
, NULL
);
1036 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
1037 test_streq(cp
, "Both\nnull\n");
1039 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
1042 /* Can't test prefixes that have the same length as the line width, because
1043 the function has an assert */
1048 char binary_data
[68];
1050 for (i
= 0; i
< sizeof(binary_data
); ++i
)
1052 test_streq(hex_str(binary_data
, 0), "");
1053 test_streq(hex_str(binary_data
, 1), "00");
1054 test_streq(hex_str(binary_data
, 17), "000102030405060708090A0B0C0D0E0F10");
1055 test_streq(hex_str(binary_data
, 32),
1056 "000102030405060708090A0B0C0D0E0F"
1057 "101112131415161718191A1B1C1D1E1F");
1058 test_streq(hex_str(binary_data
, 34),
1059 "000102030405060708090A0B0C0D0E0F"
1060 "101112131415161718191A1B1C1D1E1F");
1061 /* Repeat these tests for shorter strings after longer strings
1062 have been tried, to make sure we're correctly terminating strings */
1063 test_streq(hex_str(binary_data
, 1), "00");
1064 test_streq(hex_str(binary_data
, 0), "");
1067 /* Test strcmp_opt */
1068 tt_int_op(strcmp_opt("", "foo"), <, 0);
1069 tt_int_op(strcmp_opt("", ""), ==, 0);
1070 tt_int_op(strcmp_opt("foo", ""), >, 0);
1072 tt_int_op(strcmp_opt(NULL
, ""), <, 0);
1073 tt_int_op(strcmp_opt(NULL
, NULL
), ==, 0);
1074 tt_int_op(strcmp_opt("", NULL
), >, 0);
1076 tt_int_op(strcmp_opt(NULL
, "foo"), <, 0);
1077 tt_int_op(strcmp_opt("foo", NULL
), >, 0);
1079 /* Test strcmp_len */
1080 tt_int_op(strcmp_len("foo", "bar", 3), >, 0);
1081 tt_int_op(strcmp_len("foo", "bar", 2), <, 0); /* First len, then lexical */
1082 tt_int_op(strcmp_len("foo2", "foo1", 4), >, 0);
1083 tt_int_op(strcmp_len("foo2", "foo1", 3), <, 0); /* Really stop at len */
1084 tt_int_op(strcmp_len("foo2", "foo", 3), ==, 0); /* Really stop at len */
1085 tt_int_op(strcmp_len("blah", "", 4), >, 0);
1086 tt_int_op(strcmp_len("blah", "", 0), ==, 0);
1093 test_util_pow2(void)
1095 /* Test tor_log2(). */
1096 test_eq(tor_log2(64), 6);
1097 test_eq(tor_log2(65), 6);
1098 test_eq(tor_log2(63), 5);
1099 test_eq(tor_log2(1), 0);
1100 test_eq(tor_log2(2), 1);
1101 test_eq(tor_log2(3), 1);
1102 test_eq(tor_log2(4), 2);
1103 test_eq(tor_log2(5), 2);
1104 test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
1105 test_eq(tor_log2(UINT64_MAX
), 63);
1107 /* Test round_to_power_of_2 */
1108 test_eq(round_to_power_of_2(120), 128);
1109 test_eq(round_to_power_of_2(128), 128);
1110 test_eq(round_to_power_of_2(130), 128);
1111 test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
1112 U64_LITERAL(1)<<55);
1113 test_eq(round_to_power_of_2(0), 2);
1119 /** mutex for thread test to stop the threads hitting data at the same time. */
1120 static tor_mutex_t
*_thread_test_mutex
= NULL
;
1121 /** mutexes for the thread test to make sure that the threads have to
1122 * interleave somewhat. */
1123 static tor_mutex_t
*_thread_test_start1
= NULL
,
1124 *_thread_test_start2
= NULL
;
1125 /** Shared strmap for the thread test. */
1126 static strmap_t
*_thread_test_strmap
= NULL
;
1127 /** The name of thread1 for the thread test */
1128 static char *_thread1_name
= NULL
;
1129 /** The name of thread2 for the thread test */
1130 static char *_thread2_name
= NULL
;
1132 static void _thread_test_func(void* _s
) ATTR_NORETURN
;
1134 /** How many iterations have the threads in the unit test run? */
1135 static int t1_count
= 0, t2_count
= 0;
1137 /** Helper function for threading unit tests: This function runs in a
1138 * subthread. It grabs its own mutex (start1 or start2) to make sure that it
1139 * should start, then it repeatedly alters _test_thread_strmap protected by
1140 * _thread_test_mutex. */
1142 _thread_test_func(void* _s
)
1149 if (!strcmp(s
, "thread 1")) {
1150 m
= _thread_test_start1
;
1151 cp
= &_thread1_name
;
1154 m
= _thread_test_start2
;
1155 cp
= &_thread2_name
;
1159 tor_snprintf(buf
, sizeof(buf
), "%lu", tor_get_thread_id());
1160 *cp
= tor_strdup(buf
);
1162 tor_mutex_acquire(m
);
1164 for (i
=0; i
<10000; ++i
) {
1165 tor_mutex_acquire(_thread_test_mutex
);
1166 strmap_set(_thread_test_strmap
, "last to run", *cp
);
1168 tor_mutex_release(_thread_test_mutex
);
1170 tor_mutex_acquire(_thread_test_mutex
);
1171 strmap_set(_thread_test_strmap
, s
, *cp
);
1172 tor_mutex_release(_thread_test_mutex
);
1174 tor_mutex_release(m
);
1179 /** Run unit tests for threading logic. */
1181 test_util_threads(void)
1183 char *s1
= NULL
, *s2
= NULL
;
1184 int done
= 0, timedout
= 0;
1189 tv
.tv_usec
=100*1000;
1191 #ifndef TOR_IS_MULTITHREADED
1192 /* Skip this test if we aren't threading. We should be threading most
1193 * everywhere by now. */
1197 _thread_test_mutex
= tor_mutex_new();
1198 _thread_test_start1
= tor_mutex_new();
1199 _thread_test_start2
= tor_mutex_new();
1200 _thread_test_strmap
= strmap_new();
1201 s1
= tor_strdup("thread 1");
1202 s2
= tor_strdup("thread 2");
1203 tor_mutex_acquire(_thread_test_start1
);
1204 tor_mutex_acquire(_thread_test_start2
);
1205 spawn_func(_thread_test_func
, s1
);
1206 spawn_func(_thread_test_func
, s2
);
1207 tor_mutex_release(_thread_test_start2
);
1208 tor_mutex_release(_thread_test_start1
);
1209 started
= time(NULL
);
1211 tor_mutex_acquire(_thread_test_mutex
);
1212 strmap_assert_ok(_thread_test_strmap
);
1213 if (strmap_get(_thread_test_strmap
, "thread 1") &&
1214 strmap_get(_thread_test_strmap
, "thread 2")) {
1216 } else if (time(NULL
) > started
+ 150) {
1217 timedout
= done
= 1;
1219 tor_mutex_release(_thread_test_mutex
);
1221 /* Prevent the main thread from starving the worker threads. */
1222 select(0, NULL
, NULL
, NULL
, &tv
);
1225 tor_mutex_acquire(_thread_test_start1
);
1226 tor_mutex_release(_thread_test_start1
);
1227 tor_mutex_acquire(_thread_test_start2
);
1228 tor_mutex_release(_thread_test_start2
);
1230 tor_mutex_free(_thread_test_mutex
);
1233 printf("\nTimed out: %d %d", t1_count
, t2_count
);
1234 test_assert(strmap_get(_thread_test_strmap
, "thread 1"));
1235 test_assert(strmap_get(_thread_test_strmap
, "thread 2"));
1236 test_assert(!timedout
);
1239 /* different thread IDs. */
1240 test_assert(strcmp(strmap_get(_thread_test_strmap
, "thread 1"),
1241 strmap_get(_thread_test_strmap
, "thread 2")));
1242 test_assert(!strcmp(strmap_get(_thread_test_strmap
, "thread 1"),
1243 strmap_get(_thread_test_strmap
, "last to run")) ||
1244 !strcmp(strmap_get(_thread_test_strmap
, "thread 2"),
1245 strmap_get(_thread_test_strmap
, "last to run")));
1250 tor_free(_thread1_name
);
1251 tor_free(_thread2_name
);
1252 if (_thread_test_strmap
)
1253 strmap_free(_thread_test_strmap
, NULL
);
1254 if (_thread_test_start1
)
1255 tor_mutex_free(_thread_test_start1
);
1256 if (_thread_test_start2
)
1257 tor_mutex_free(_thread_test_start2
);
1260 /** Run unit tests for compression functions */
1262 test_util_gzip(void)
1264 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
1267 tor_zlib_state_t
*state
= NULL
;
1269 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
1270 test_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
1271 if (is_gzip_supported()) {
1272 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1275 test_assert(len1
< strlen(buf1
));
1276 test_assert(detect_compression_method(buf2
, len1
) == GZIP_METHOD
);
1278 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
1279 GZIP_METHOD
, 1, LOG_INFO
));
1281 test_eq(strlen(buf1
) + 1, len2
);
1282 test_streq(buf1
, buf3
);
1288 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1291 test_assert(detect_compression_method(buf2
, len1
) == ZLIB_METHOD
);
1293 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
1294 ZLIB_METHOD
, 1, LOG_INFO
));
1296 test_eq(strlen(buf1
) + 1, len2
);
1297 test_streq(buf1
, buf3
);
1299 /* Check whether we can uncompress concatenated, compressed strings. */
1301 buf2
= tor_realloc(buf2
, len1
*2);
1302 memcpy(buf2
+len1
, buf2
, len1
);
1303 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
*2,
1304 ZLIB_METHOD
, 1, LOG_INFO
));
1305 test_eq((strlen(buf1
)+1)*2, len2
);
1307 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
1308 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
1309 (strlen(buf1
)+1)*2);
1315 /* Check whether we can uncompress partial strings. */
1317 tor_strdup("String with low redundancy that won't be compressed much.");
1318 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1321 /* when we allow an incomplete string, we should succeed.*/
1322 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
1323 ZLIB_METHOD
, 0, LOG_INFO
));
1324 tt_assert(len2
> 5);
1326 tt_assert(!strcmpstart(buf1
, buf3
));
1328 /* when we demand a complete string, this must fail. */
1330 tt_assert(tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
1331 ZLIB_METHOD
, 1, LOG_INFO
));
1334 /* Now, try streaming compression. */
1338 state
= tor_zlib_new(1, ZLIB_METHOD
);
1340 cp1
= buf1
= tor_malloc(1024);
1342 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
1344 test_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0)
1346 test_eq(0, len2
); /* Make sure we compressed it all. */
1347 test_assert(cp1
> buf1
);
1351 test_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1)
1354 test_assert(cp1
> cp2
); /* Make sure we really added something. */
1356 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
1357 ZLIB_METHOD
, 1, LOG_WARN
));
1358 test_streq(buf3
, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
1363 tor_zlib_free(state
);
1369 /** Run unit tests for mmap() wrapper functionality. */
1371 test_util_mmap(void)
1373 char *fname1
= tor_strdup(get_fname("mapped_1"));
1374 char *fname2
= tor_strdup(get_fname("mapped_2"));
1375 char *fname3
= tor_strdup(get_fname("mapped_3"));
1376 const size_t buflen
= 17000;
1377 char *buf
= tor_malloc(17000);
1378 tor_mmap_t
*mapping
= NULL
;
1380 crypto_rand(buf
, buflen
);
1382 mapping
= tor_mmap_file(fname1
);
1383 test_assert(! mapping
);
1385 write_str_to_file(fname1
, "Short file.", 1);
1387 mapping
= tor_mmap_file(fname1
);
1388 test_assert(mapping
);
1389 test_eq(mapping
->size
, strlen("Short file."));
1390 test_streq(mapping
->data
, "Short file.");
1392 tor_munmap_file(mapping
);
1394 test_assert(unlink(fname1
) == 0);
1396 /* make sure we can unlink. */
1397 test_assert(unlink(fname1
) == 0);
1398 test_streq(mapping
->data
, "Short file.");
1399 tor_munmap_file(mapping
);
1403 /* Now a zero-length file. */
1404 write_str_to_file(fname1
, "", 1);
1405 mapping
= tor_mmap_file(fname1
);
1406 test_eq(mapping
, NULL
);
1407 test_eq(ERANGE
, errno
);
1410 /* Make sure that we fail to map a no-longer-existent file. */
1411 mapping
= tor_mmap_file(fname1
);
1412 test_assert(! mapping
);
1414 /* Now try a big file that stretches across a few pages and isn't aligned */
1415 write_bytes_to_file(fname2
, buf
, buflen
, 1);
1416 mapping
= tor_mmap_file(fname2
);
1417 test_assert(mapping
);
1418 test_eq(mapping
->size
, buflen
);
1419 test_memeq(mapping
->data
, buf
, buflen
);
1420 tor_munmap_file(mapping
);
1423 /* Now try a big aligned file. */
1424 write_bytes_to_file(fname3
, buf
, 16384, 1);
1425 mapping
= tor_mmap_file(fname3
);
1426 test_assert(mapping
);
1427 test_eq(mapping
->size
, 16384);
1428 test_memeq(mapping
->data
, buf
, 16384);
1429 tor_munmap_file(mapping
);
1443 tor_munmap_file(mapping
);
1446 /** Run unit tests for escaping/unescaping data for use by controllers. */
1448 test_util_control_formats(void)
1452 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
1455 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
1457 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
1458 test_eq(sz
, strlen(out
));
1465 test_util_sscanf(void)
1467 unsigned u1
, u2
, u3
;
1468 char s1
[20], s2
[10], s3
[10], ch
;
1471 /* Simple tests (malformed patterns, literal matching, ...) */
1472 test_eq(-1, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
1473 test_eq(-1, tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
1474 test_eq(-1, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
1475 test_eq(-1, tor_sscanf("prettylongstring", "%999999s", s1
));
1477 /* GCC thinks these two are illegal. */
1478 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
1479 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
1481 /* No '%'-strings: always "success" */
1482 test_eq(0, tor_sscanf("hello world", "hello world"));
1483 test_eq(0, tor_sscanf("hello world", "good bye"));
1485 test_eq(0, tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
1486 test_eq(0, tor_sscanf(" 3 hello", "%u", &u1
));
1487 test_eq(0, tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
1488 test_eq(1, tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
1490 /* Numbers (ie. %u) */
1491 test_eq(0, tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
1492 test_eq(1, tor_sscanf("12345", "%u", &u1
));
1493 test_eq(12345u, u1
);
1494 test_eq(1, tor_sscanf("12346 ", "%u", &u1
));
1495 test_eq(12346u, u1
);
1496 test_eq(0, tor_sscanf(" 12347", "%u", &u1
));
1497 test_eq(1, tor_sscanf(" 12348", " %u", &u1
));
1498 test_eq(12348u, u1
);
1499 test_eq(1, tor_sscanf("0", "%u", &u1
));
1501 test_eq(1, tor_sscanf("0000", "%u", &u2
));
1503 test_eq(0, tor_sscanf("", "%u", &u1
)); /* absent number */
1504 test_eq(0, tor_sscanf("A", "%u", &u1
)); /* bogus number */
1505 test_eq(0, tor_sscanf("-1", "%u", &u1
)); /* negative number */
1506 test_eq(1, tor_sscanf("4294967295", "%u", &u1
)); /* UINT32_MAX should work */
1507 test_eq(4294967295u, u1
);
1508 test_eq(0, tor_sscanf("4294967296", "%u", &u1
)); /* But not at 32 bits */
1509 test_eq(1, tor_sscanf("4294967296", "%9u", &u1
)); /* but parsing only 9... */
1510 test_eq(429496729u, u1
);
1512 /* Numbers with size (eg. %2u) */
1513 test_eq(0, tor_sscanf("-1", "%2u", &u1
));
1514 test_eq(2, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
1517 test_eq(1, tor_sscanf("123456", "%8u", &u1
));
1518 test_eq(123456u, u1
);
1519 test_eq(1, tor_sscanf("123457 ", "%8u", &u1
));
1520 test_eq(123457u, u1
);
1521 test_eq(0, tor_sscanf(" 123456", "%8u", &u1
));
1522 test_eq(3, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
1526 test_eq(3, tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
1530 /* %u does not match space.*/
1531 test_eq(2, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
1534 /* %u does not match negative numbers. */
1535 test_eq(2, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
1538 /* Arbitrary amounts of 0-padding are okay */
1539 test_eq(3, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
1546 test_eq(3, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
1547 test_eq(0x1234, u1
);
1548 test_eq(0x2ABCDEF, u2
);
1550 /* Width works on %x */
1551 test_eq(3, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
1552 test_eq(0xf00d, u1
);
1553 test_eq(0xcafe, u2
);
1556 /* Literal '%' (ie. '%%') */
1557 test_eq(1, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
1559 test_eq(0, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
1560 test_eq(1, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
1561 test_eq(2, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
1563 test_streq(s1
, "fresh");
1564 test_eq(1, tor_sscanf("% boo", "%% %3s", s1
));
1565 test_streq("boo", s1
);
1567 /* Strings (ie. %s) */
1568 test_eq(2, tor_sscanf("hello", "%3s%7s", s1
, s2
));
1569 test_streq(s1
, "hel");
1570 test_streq(s2
, "lo");
1571 test_eq(2, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
1572 test_streq(s3
, "WD");
1574 test_eq(2, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
1575 test_streq(s3
, "WD4");
1577 test_eq(2, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
1579 test_streq(s1
, "trombones");
1580 test_eq(1, tor_sscanf("prettylongstring", "%999s", s1
));
1581 test_streq(s1
, "prettylongstring");
1582 /* %s doesn't eat spaces */
1583 test_eq(2, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
1584 test_streq(s1
, "hello");
1585 test_streq(s2
, "world");
1586 test_eq(2, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
1587 test_streq(s1
, "bye");
1589 test_eq(3, tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
1590 test_streq(s1
, "hi");
1594 test_eq(3, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
1595 test_eq(4, tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
1603 test_util_path_is_relative(void)
1605 /* OS-independent tests */
1606 test_eq(1, path_is_relative(""));
1607 test_eq(1, path_is_relative("dir"));
1608 test_eq(1, path_is_relative("dir/"));
1609 test_eq(1, path_is_relative("./dir"));
1610 test_eq(1, path_is_relative("../dir"));
1612 test_eq(0, path_is_relative("/"));
1613 test_eq(0, path_is_relative("/dir"));
1614 test_eq(0, path_is_relative("/dir/"));
1618 /* I don't have Windows so I can't test this, hence the "#ifdef
1619 0". These are tests that look useful, so please try to get them
1620 running and uncomment if it all works as it should */
1621 test_eq(1, path_is_relative("dir"));
1622 test_eq(1, path_is_relative("dir\\"));
1623 test_eq(1, path_is_relative("dir\\a:"));
1624 test_eq(1, path_is_relative("dir\\a:\\"));
1625 test_eq(1, path_is_relative("http:\\dir"));
1627 test_eq(0, path_is_relative("\\dir"));
1628 test_eq(0, path_is_relative("a:\\dir"));
1629 test_eq(0, path_is_relative("z:\\dir"));
1636 /** Run unittests for memory pool allocator */
1638 test_util_mempool(void)
1640 mp_pool_t
*pool
= NULL
;
1641 smartlist_t
*allocated
= NULL
;
1644 pool
= mp_pool_new(1, 100);
1646 test_assert(pool
->new_chunk_capacity
>= 100);
1647 test_assert(pool
->item_alloc_size
>= sizeof(void*)+1);
1648 mp_pool_destroy(pool
);
1651 pool
= mp_pool_new(241, 2500);
1653 test_assert(pool
->new_chunk_capacity
>= 10);
1654 test_assert(pool
->item_alloc_size
>= sizeof(void*)+241);
1655 test_eq(pool
->item_alloc_size
& 0x03, 0);
1656 test_assert(pool
->new_chunk_capacity
< 60);
1658 allocated
= smartlist_new();
1659 for (i
= 0; i
< 20000; ++i
) {
1660 if (smartlist_len(allocated
) < 20 || crypto_rand_int(2)) {
1661 void *m
= mp_pool_get(pool
);
1662 memset(m
, 0x09, 241);
1663 smartlist_add(allocated
, m
);
1664 //printf("%d: %p\n", i, m);
1665 //mp_pool_assert_ok(pool);
1667 int idx
= crypto_rand_int(smartlist_len(allocated
));
1668 void *m
= smartlist_get(allocated
, idx
);
1669 //printf("%d: free %p\n", i, m);
1670 smartlist_del(allocated
, idx
);
1672 //mp_pool_assert_ok(pool);
1674 if (crypto_rand_int(777)==0)
1675 mp_pool_clean(pool
, 1, 1);
1678 mp_pool_assert_ok(pool
);
1683 SMARTLIST_FOREACH(allocated
, void *, m
, mp_pool_release(m
));
1684 mp_pool_assert_ok(pool
);
1685 mp_pool_clean(pool
, 0, 0);
1686 mp_pool_assert_ok(pool
);
1687 smartlist_free(allocated
);
1691 mp_pool_destroy(pool
);
1694 /** Run unittests for memory area allocator */
1696 test_util_memarea(void)
1698 memarea_t
*area
= memarea_new();
1699 char *p1
, *p2
, *p3
, *p1_orig
;
1700 void *malloced_ptr
= NULL
;
1705 p1_orig
= p1
= memarea_alloc(area
,64);
1706 p2
= memarea_alloc_zero(area
,52);
1707 p3
= memarea_alloc(area
,11);
1709 test_assert(memarea_owns_ptr(area
, p1
));
1710 test_assert(memarea_owns_ptr(area
, p2
));
1711 test_assert(memarea_owns_ptr(area
, p3
));
1712 /* Make sure we left enough space. */
1713 test_assert(p1
+64 <= p2
);
1714 test_assert(p2
+52 <= p3
);
1715 /* Make sure we aligned. */
1716 test_eq(((uintptr_t)p1
) % sizeof(void*), 0);
1717 test_eq(((uintptr_t)p2
) % sizeof(void*), 0);
1718 test_eq(((uintptr_t)p3
) % sizeof(void*), 0);
1719 test_assert(!memarea_owns_ptr(area
, p3
+8192));
1720 test_assert(!memarea_owns_ptr(area
, p3
+30));
1721 test_assert(tor_mem_is_zero(p2
, 52));
1722 /* Make sure we don't overalign. */
1723 p1
= memarea_alloc(area
, 1);
1724 p2
= memarea_alloc(area
, 1);
1725 test_eq(p1
+sizeof(void*), p2
);
1727 malloced_ptr
= tor_malloc(64);
1728 test_assert(!memarea_owns_ptr(area
, malloced_ptr
));
1729 tor_free(malloced_ptr
);
1732 /* memarea_memdup */
1734 malloced_ptr
= tor_malloc(64);
1735 crypto_rand((char*)malloced_ptr
, 64);
1736 p1
= memarea_memdup(area
, malloced_ptr
, 64);
1737 test_assert(p1
!= malloced_ptr
);
1738 test_memeq(p1
, malloced_ptr
, 64);
1739 tor_free(malloced_ptr
);
1742 /* memarea_strdup. */
1743 p1
= memarea_strdup(area
,"");
1744 p2
= memarea_strdup(area
, "abcd");
1748 test_streq(p2
, "abcd");
1750 /* memarea_strndup. */
1752 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
1753 /* (From Turandot, act 3.) */
1754 size_t len
= strlen(s
);
1755 p1
= memarea_strndup(area
, s
, 1000);
1756 p2
= memarea_strndup(area
, s
, 10);
1758 test_assert(p2
>= p1
+ len
+ 1);
1759 test_memeq(s
, p2
, 10);
1760 test_eq(p2
[10], '\0');
1761 p3
= memarea_strndup(area
, s
, len
);
1763 p3
= memarea_strndup(area
, s
, len
-1);
1764 test_memeq(s
, p3
, len
-1);
1765 test_eq(p3
[len
-1], '\0');
1768 memarea_clear(area
);
1769 p1
= memarea_alloc(area
, 1);
1770 test_eq(p1
, p1_orig
);
1771 memarea_clear(area
);
1773 /* Check for running over an area's size. */
1774 for (i
= 0; i
< 512; ++i
) {
1775 p1
= memarea_alloc(area
, crypto_rand_int(5)+1);
1776 test_assert(memarea_owns_ptr(area
, p1
));
1778 memarea_assert_ok(area
);
1779 /* Make sure we can allocate a too-big object. */
1780 p1
= memarea_alloc_zero(area
, 9000);
1781 p2
= memarea_alloc_zero(area
, 16);
1782 test_assert(memarea_owns_ptr(area
, p1
));
1783 test_assert(memarea_owns_ptr(area
, p2
));
1786 memarea_drop_all(area
);
1787 tor_free(malloced_ptr
);
1790 /** Run unit tests for utility functions to get file names relative to
1791 * the data directory. */
1793 test_util_datadir(void)
1797 char *temp_dir
= NULL
;
1799 temp_dir
= get_datadir_fname(NULL
);
1800 f
= get_datadir_fname("state");
1801 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
1804 f
= get_datadir_fname2("cache", "thingy");
1805 tor_snprintf(buf
, sizeof(buf
),
1806 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
1809 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
1810 tor_snprintf(buf
, sizeof(buf
),
1811 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
1814 f
= get_datadir_fname_suffix("cache", ".foo");
1815 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
1825 test_util_strtok(void)
1832 for (i
= 0; i
< 3; i
++) {
1833 const char *pad1
="", *pad2
="";
1846 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
1847 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
1848 test_assert(NULL
== tor_strtok_r_impl(buf
, " ", &cp1
));
1849 test_assert(NULL
== tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
1851 tor_snprintf(buf
, sizeof(buf
),
1852 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
1853 tor_snprintf(buf2
, sizeof(buf2
),
1854 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
1855 /* -- "Year's End", Richard Wilbur */
1857 test_streq("Graved", tor_strtok_r_impl(buf
, " ", &cp1
));
1858 test_streq("they", tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
1859 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
1860 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
1861 test_streq("on", S1());
1862 test_streq("the", S1());
1863 test_streq("dark", S1());
1864 test_streq("seemed", S2());
1865 test_streq("their", S2());
1866 test_streq("own", S2());
1867 test_streq("in", S1());
1868 test_streq("gestures", S1());
1869 test_streq("of", S1());
1870 test_streq("most", S2());
1871 test_streq("perfect", S2());
1872 test_streq("descent", S1());
1873 test_streq("monument", S2());
1874 test_eq_ptr(NULL
, S1());
1875 test_eq_ptr(NULL
, S2());
1879 test_eq_ptr(NULL
, tor_strtok_r_impl(buf
, " ", &cp1
));
1880 test_eq_ptr(NULL
, tor_strtok_r_impl(buf
, "!", &cp1
));
1882 strlcpy(buf
, "Howdy!", sizeof(buf
));
1883 test_streq("Howdy", tor_strtok_r_impl(buf
, "!", &cp1
));
1884 test_eq_ptr(NULL
, tor_strtok_r_impl(NULL
, "!", &cp1
));
1886 strlcpy(buf
, " ", sizeof(buf
));
1887 test_eq_ptr(NULL
, tor_strtok_r_impl(buf
, " ", &cp1
));
1888 strlcpy(buf
, " ", sizeof(buf
));
1889 test_eq_ptr(NULL
, tor_strtok_r_impl(buf
, " ", &cp1
));
1891 strlcpy(buf
, "something ", sizeof(buf
));
1892 test_streq("something", tor_strtok_r_impl(buf
, " ", &cp1
));
1893 test_eq_ptr(NULL
, tor_strtok_r_impl(NULL
, ";", &cp1
));
1899 test_util_find_str_at_start_of_line(void *ptr
)
1901 const char *long_string
=
1902 "howdy world. how are you? i hope it's fine.\n"
1905 char *line2
= strchr(long_string
,'\n')+1;
1906 char *line3
= strchr(line2
,'\n')+1;
1907 const char *short_string
= "hello kitty\n"
1909 char *short_line2
= strchr(short_string
,'\n')+1;
1913 test_eq_ptr(long_string
, find_str_at_start_of_line(long_string
, ""));
1914 test_eq_ptr(NULL
, find_str_at_start_of_line(short_string
, "nonsense"));
1915 test_eq_ptr(NULL
, find_str_at_start_of_line(long_string
, "nonsense"));
1916 test_eq_ptr(NULL
, find_str_at_start_of_line(long_string
, "\n"));
1917 test_eq_ptr(NULL
, find_str_at_start_of_line(long_string
, "how "));
1918 test_eq_ptr(NULL
, find_str_at_start_of_line(long_string
, "kitty"));
1919 test_eq_ptr(long_string
, find_str_at_start_of_line(long_string
, "h"));
1920 test_eq_ptr(long_string
, find_str_at_start_of_line(long_string
, "how"));
1921 test_eq_ptr(line2
, find_str_at_start_of_line(long_string
, "he"));
1922 test_eq_ptr(line2
, find_str_at_start_of_line(long_string
, "hell"));
1923 test_eq_ptr(line2
, find_str_at_start_of_line(long_string
, "hello k"));
1924 test_eq_ptr(line2
, find_str_at_start_of_line(long_string
, "hello kitty\n"));
1925 test_eq_ptr(line2
, find_str_at_start_of_line(long_string
, "hello kitty\nt"));
1926 test_eq_ptr(line3
, find_str_at_start_of_line(long_string
, "third"));
1927 test_eq_ptr(line3
, find_str_at_start_of_line(long_string
, "third line"));
1928 test_eq_ptr(NULL
, find_str_at_start_of_line(long_string
, "third line\n"));
1929 test_eq_ptr(short_line2
, find_str_at_start_of_line(short_string
,
1936 test_util_string_is_C_identifier(void *ptr
)
1940 test_eq(1, string_is_C_identifier("string_is_C_identifier"));
1941 test_eq(1, string_is_C_identifier("_string_is_C_identifier"));
1942 test_eq(1, string_is_C_identifier("_"));
1943 test_eq(1, string_is_C_identifier("i"));
1944 test_eq(1, string_is_C_identifier("_____"));
1945 test_eq(1, string_is_C_identifier("__00__"));
1946 test_eq(1, string_is_C_identifier("__init__"));
1947 test_eq(1, string_is_C_identifier("_0"));
1948 test_eq(1, string_is_C_identifier("_0string_is_C_identifier"));
1949 test_eq(1, string_is_C_identifier("_0"));
1951 test_eq(0, string_is_C_identifier("0_string_is_C_identifier"));
1952 test_eq(0, string_is_C_identifier("0"));
1953 test_eq(0, string_is_C_identifier(""));
1954 test_eq(0, string_is_C_identifier(";"));
1955 test_eq(0, string_is_C_identifier("i;"));
1956 test_eq(0, string_is_C_identifier("_;"));
1957 test_eq(0, string_is_C_identifier("Ã"));
1958 test_eq(0, string_is_C_identifier("ñ"));
1965 test_util_asprintf(void *ptr
)
1967 #define LOREMIPSUM \
1968 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
1969 char *cp
=NULL
, *cp2
=NULL
;
1974 r
= tor_asprintf(&cp
, "simple string 100%% safe");
1976 test_streq("simple string 100% safe", cp
);
1977 test_eq(strlen(cp
), r
);
1980 r
= tor_asprintf(&cp
, "%s", "");
1983 test_eq(strlen(cp
), r
);
1986 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
1988 test_streq("I like numbers--1, 2, etc.", cp
);
1989 test_eq(strlen(cp
), r
);
1992 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
1994 test_eq(strlen(cp2
), r
);
1995 test_streq("First=101, Second=202", cp2
);
1996 test_assert(cp
!= cp2
);
2000 /* Glass-box test: a string exactly 128 characters long. */
2001 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
2004 test_assert(cp
[128] == '\0');
2005 test_streq("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
, cp
);
2008 /* String longer than 128 characters */
2009 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
2010 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
2012 test_eq(strlen(cp
), r
);
2013 test_streq("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
, cp
);
2021 test_util_listdir(void *ptr
)
2023 smartlist_t
*dir_contents
= NULL
;
2024 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
2028 fname1
= tor_strdup(get_fname("hopscotch"));
2029 fname2
= tor_strdup(get_fname("mumblety-peg"));
2030 fname3
= tor_strdup(get_fname(".hidden-file"));
2031 dir1
= tor_strdup(get_fname("some-directory"));
2032 dirname
= tor_strdup(get_fname(NULL
));
2034 test_eq(0, write_str_to_file(fname1
, "X\n", 0));
2035 test_eq(0, write_str_to_file(fname2
, "Y\n", 0));
2036 test_eq(0, write_str_to_file(fname3
, "Z\n", 0));
2040 r
= mkdir(dir1
, 0700);
2043 fprintf(stderr
, "Can't create directory %s:", dir1
);
2048 dir_contents
= tor_listdir(dirname
);
2049 test_assert(dir_contents
);
2050 /* make sure that each filename is listed. */
2051 test_assert(smartlist_string_isin_case(dir_contents
, "hopscotch"));
2052 test_assert(smartlist_string_isin_case(dir_contents
, "mumblety-peg"));
2053 test_assert(smartlist_string_isin_case(dir_contents
, ".hidden-file"));
2054 test_assert(smartlist_string_isin_case(dir_contents
, "some-directory"));
2056 test_assert(!smartlist_string_isin(dir_contents
, "."));
2057 test_assert(!smartlist_string_isin(dir_contents
, ".."));
2064 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
2065 smartlist_free(dir_contents
);
2070 test_util_parent_dir(void *ptr
)
2075 #define T(output,expect_ok,input) \
2078 cp = tor_strdup(input); \
2079 ok = get_parent_directory(cp); \
2080 tt_int_op(expect_ok, ==, ok); \
2082 tt_str_op(output, ==, cp); \
2086 T("/home/wombat", 0, "/home/wombat/knish");
2087 T("/home/wombat", 0, "/home/wombat/knish/");
2088 T("/home/wombat", 0, "/home/wombat/knish///");
2089 T("./home/wombat", 0, "./home/wombat/knish/");
2091 T("/", 0, "/home//");
2092 T(".", 0, "./wombat");
2093 T(".", 0, "./wombat/");
2094 T(".", 0, "./wombat//");
2095 T("wombat", 0, "wombat/foo");
2096 T("wombat/..", 0, "wombat/../foo");
2097 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
2098 T("wombat/.", 0, "wombat/./foo");
2099 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
2100 T("wombat", 0, "wombat/..//");
2101 T("wombat", 0, "wombat/foo/");
2102 T("wombat", 0, "wombat/.foo");
2103 T("wombat", 0, "wombat/.foo/");
2105 T("wombat", -1, "");
2107 T("wombat", 0, "wombat/knish");
2118 test_util_load_win_lib(void *ptr
)
2120 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
2131 clear_hex_errno(char *hex_errno
)
2133 memset(hex_errno
, '\0', HEX_ERRNO_SIZE
+ 1);
2137 test_util_exit_status(void *ptr
)
2139 /* Leave an extra byte for a \0 so we can do string comparison */
2140 char hex_errno
[HEX_ERRNO_SIZE
+ 1];
2145 clear_hex_errno(hex_errno
);
2146 n
= format_helper_exit_status(0, 0, hex_errno
);
2147 test_streq("0/0\n", hex_errno
);
2148 test_eq(n
, strlen(hex_errno
));
2150 clear_hex_errno(hex_errno
);
2151 n
= format_helper_exit_status(0, 0x7FFFFFFF, hex_errno
);
2152 test_streq("0/7FFFFFFF\n", hex_errno
);
2153 test_eq(n
, strlen(hex_errno
));
2155 clear_hex_errno(hex_errno
);
2156 n
= format_helper_exit_status(0xFF, -0x80000000, hex_errno
);
2157 test_streq("FF/-80000000\n", hex_errno
);
2158 test_eq(n
, strlen(hex_errno
));
2160 clear_hex_errno(hex_errno
);
2161 n
= format_helper_exit_status(0x7F, 0, hex_errno
);
2162 test_streq("7F/0\n", hex_errno
);
2163 test_eq(n
, strlen(hex_errno
));
2165 clear_hex_errno(hex_errno
);
2166 n
= format_helper_exit_status(0x08, -0x242, hex_errno
);
2167 test_streq("8/-242\n", hex_errno
);
2168 test_eq(n
, strlen(hex_errno
));
2175 /** Check that fgets waits until a full line, and not return a partial line, on
2176 * a EAGAIN with a non-blocking pipe */
2178 test_util_fgets_eagain(void *ptr
)
2180 int test_pipe
[2] = {-1, -1};
2184 FILE *test_stream
= NULL
;
2189 /* Set up a pipe to test on */
2190 retval
= pipe(test_pipe
);
2191 tt_int_op(retval
, >=, 0);
2193 /* Set up the read-end to be non-blocking */
2194 retval
= fcntl(test_pipe
[0], F_SETFL
, O_NONBLOCK
);
2195 tt_int_op(retval
, >=, 0);
2197 /* Open it as a stdio stream */
2198 test_stream
= fdopen(test_pipe
[0], "r");
2199 tt_ptr_op(test_stream
, !=, NULL
);
2201 /* Send in a partial line */
2202 retlen
= write(test_pipe
[1], "A", 1);
2203 tt_int_op(retlen
, ==, 1);
2204 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2205 tt_want(retptr
== NULL
);
2206 tt_int_op(errno
, ==, EAGAIN
);
2208 /* Send in the rest */
2209 retlen
= write(test_pipe
[1], "B\n", 2);
2210 tt_int_op(retlen
, ==, 2);
2211 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2212 tt_ptr_op(retptr
, ==, buf
);
2213 tt_str_op(buf
, ==, "AB\n");
2215 /* Send in a full line */
2216 retlen
= write(test_pipe
[1], "CD\n", 3);
2217 tt_int_op(retlen
, ==, 3);
2218 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2219 tt_ptr_op(retptr
, ==, buf
);
2220 tt_str_op(buf
, ==, "CD\n");
2222 /* Send in a partial line */
2223 retlen
= write(test_pipe
[1], "E", 1);
2224 tt_int_op(retlen
, ==, 1);
2225 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2226 tt_ptr_op(retptr
, ==, NULL
);
2227 tt_int_op(errno
, ==, EAGAIN
);
2229 /* Send in the rest */
2230 retlen
= write(test_pipe
[1], "F\n", 2);
2231 tt_int_op(retlen
, ==, 2);
2232 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2233 tt_ptr_op(retptr
, ==, buf
);
2234 tt_str_op(buf
, ==, "EF\n");
2236 /* Send in a full line and close */
2237 retlen
= write(test_pipe
[1], "GH", 2);
2238 tt_int_op(retlen
, ==, 2);
2239 retval
= close(test_pipe
[1]);
2241 tt_int_op(retval
, ==, 0);
2242 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2243 tt_ptr_op(retptr
, ==, buf
);
2244 tt_str_op(buf
, ==, "GH");
2247 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
2248 tt_ptr_op(retptr
, ==, NULL
);
2249 tt_int_op(feof(test_stream
), >, 0);
2252 if (test_stream
!= NULL
)
2253 fclose(test_stream
);
2254 if (test_pipe
[0] != -1)
2255 close(test_pipe
[0]);
2256 if (test_pipe
[1] != -1)
2257 close(test_pipe
[1]);
2261 /** Helper function for testing tor_spawn_background */
2263 run_util_spawn_background(const char *argv
[], const char *expected_out
,
2264 const char *expected_err
, int expected_exit
,
2265 int expected_status
)
2267 int retval
, exit_code
;
2269 process_handle_t
*process_handle
=NULL
;
2270 char stdout_buf
[100], stderr_buf
[100];
2273 /* Start the program */
2275 status
= tor_spawn_background(NULL
, argv
, NULL
, &process_handle
);
2277 status
= tor_spawn_background(argv
[0], argv
, NULL
, &process_handle
);
2280 test_eq(expected_status
, status
);
2281 if (status
== PROCESS_STATUS_ERROR
)
2284 test_assert(process_handle
!= NULL
);
2285 test_eq(expected_status
, process_handle
->status
);
2288 test_assert(process_handle
->stdout_pipe
!= INVALID_HANDLE_VALUE
);
2289 test_assert(process_handle
->stderr_pipe
!= INVALID_HANDLE_VALUE
);
2291 test_assert(process_handle
->stdout_pipe
> 0);
2292 test_assert(process_handle
->stderr_pipe
> 0);
2296 pos
= tor_read_all_from_process_stdout(process_handle
, stdout_buf
,
2297 sizeof(stdout_buf
) - 1);
2298 tt_assert(pos
>= 0);
2299 stdout_buf
[pos
] = '\0';
2300 test_eq(strlen(expected_out
), pos
);
2301 test_streq(expected_out
, stdout_buf
);
2303 /* Check it terminated correctly */
2304 retval
= tor_get_exit_code(process_handle
, 1, &exit_code
);
2305 test_eq(PROCESS_EXIT_EXITED
, retval
);
2306 test_eq(expected_exit
, exit_code
);
2307 // TODO: Make test-child exit with something other than 0
2310 pos
= tor_read_all_from_process_stderr(process_handle
, stderr_buf
,
2311 sizeof(stderr_buf
) - 1);
2312 test_assert(pos
>= 0);
2313 stderr_buf
[pos
] = '\0';
2314 test_streq(expected_err
, stderr_buf
);
2315 test_eq(strlen(expected_err
), pos
);
2319 tor_process_handle_destroy(process_handle
, 1);
2322 /** Check that we can launch a process and read the output */
2324 test_util_spawn_background_ok(void *ptr
)
2327 const char *argv
[] = {"test-child.exe", "--test", NULL
};
2328 const char *expected_out
= "OUT\r\n--test\r\nSLEEPING\r\nDONE\r\n";
2329 const char *expected_err
= "ERR\r\n";
2331 const char *argv
[] = {BUILDDIR
"/src/test/test-child", "--test", NULL
};
2332 const char *expected_out
= "OUT\n--test\nSLEEPING\nDONE\n";
2333 const char *expected_err
= "ERR\n";
2338 run_util_spawn_background(argv
, expected_out
, expected_err
, 0,
2339 PROCESS_STATUS_RUNNING
);
2342 /** Check that failing to find the executable works as expected */
2344 test_util_spawn_background_fail(void *ptr
)
2347 #define BUILDDIR "."
2349 const char *argv
[] = {BUILDDIR
"/src/test/no-such-file", "--test", NULL
};
2350 const char *expected_err
= "";
2351 char expected_out
[1024];
2354 const int expected_status
= PROCESS_STATUS_ERROR
;
2356 /* TODO: Once we can signal failure to exec, set this to be
2357 * PROCESS_STATUS_ERROR */
2358 const int expected_status
= PROCESS_STATUS_RUNNING
;
2363 tor_snprintf(code
, sizeof(code
), "%x/%x",
2364 9 /* CHILD_STATE_FAILEXEC */ , ENOENT
);
2365 tor_snprintf(expected_out
, sizeof(expected_out
),
2366 "ERR: Failed to spawn background process - code %s\n", code
);
2368 run_util_spawn_background(argv
, expected_out
, expected_err
, 255,
2372 /** Test that reading from a handle returns a partial read rather than
2375 test_util_spawn_background_partial_read(void *ptr
)
2377 const int expected_exit
= 0;
2378 const int expected_status
= PROCESS_STATUS_RUNNING
;
2380 int retval
, exit_code
;
2382 process_handle_t
*process_handle
=NULL
;
2384 char stdout_buf
[100], stderr_buf
[100];
2386 const char *argv
[] = {"test-child.exe", "--test", NULL
};
2387 const char *expected_out
[] = { "OUT\r\n--test\r\nSLEEPING\r\n",
2390 const char *expected_err
= "ERR\r\n";
2392 const char *argv
[] = {BUILDDIR
"/src/test/test-child", "--test", NULL
};
2393 const char *expected_out
[] = { "OUT\n--test\nSLEEPING\n",
2396 const char *expected_err
= "ERR\n";
2399 int expected_out_ctr
;
2402 /* Start the program */
2404 status
= tor_spawn_background(NULL
, argv
, NULL
, &process_handle
);
2406 status
= tor_spawn_background(argv
[0], argv
, NULL
, &process_handle
);
2408 test_eq(expected_status
, status
);
2409 test_assert(process_handle
);
2410 test_eq(expected_status
, process_handle
->status
);
2413 for (expected_out_ctr
= 0; expected_out
[expected_out_ctr
] != NULL
;) {
2415 pos
= tor_read_all_handle(process_handle
->stdout_pipe
, stdout_buf
,
2416 sizeof(stdout_buf
) - 1, NULL
);
2418 /* Check that we didn't read the end of file last time */
2420 pos
= tor_read_all_handle(process_handle
->stdout_handle
, stdout_buf
,
2421 sizeof(stdout_buf
) - 1, NULL
, &eof
);
2423 log_info(LD_GENERAL
, "tor_read_all_handle() returned %d", (int)pos
);
2425 /* We would have blocked, keep on trying */
2429 test_assert(pos
> 0);
2430 stdout_buf
[pos
] = '\0';
2431 test_streq(expected_out
[expected_out_ctr
], stdout_buf
);
2432 test_eq(strlen(expected_out
[expected_out_ctr
]), pos
);
2436 /* The process should have exited without writing more */
2438 pos
= tor_read_all_handle(process_handle
->stdout_pipe
, stdout_buf
,
2439 sizeof(stdout_buf
) - 1,
2444 /* We should have got all the data, but maybe not the EOF flag */
2445 pos
= tor_read_all_handle(process_handle
->stdout_handle
, stdout_buf
,
2446 sizeof(stdout_buf
) - 1,
2447 process_handle
, &eof
);
2451 /* Otherwise, we got the EOF on the last read */
2454 /* Check it terminated correctly */
2455 retval
= tor_get_exit_code(process_handle
, 1, &exit_code
);
2456 test_eq(PROCESS_EXIT_EXITED
, retval
);
2457 test_eq(expected_exit
, exit_code
);
2459 // TODO: Make test-child exit with something other than 0
2462 pos
= tor_read_all_from_process_stderr(process_handle
, stderr_buf
,
2463 sizeof(stderr_buf
) - 1);
2464 test_assert(pos
>= 0);
2465 stderr_buf
[pos
] = '\0';
2466 test_streq(expected_err
, stderr_buf
);
2467 test_eq(strlen(expected_err
), pos
);
2470 tor_process_handle_destroy(process_handle
, 1);
2474 * Test for format_hex_number_for_helper_exit_status()
2478 test_util_format_hex_number(void *ptr
)
2481 char buf
[HEX_ERRNO_SIZE
+ 1];
2490 #if UINT_MAX >= 0xffffffff
2491 {"31BC421D", 0x31bc421d},
2492 {"FFFFFFFF", 0xffffffff},
2499 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
2500 len
= format_hex_number_for_helper_exit_status(test_data
[i
].x
,
2501 buf
, HEX_ERRNO_SIZE
);
2504 test_streq(buf
, test_data
[i
].str
);
2512 * Test that we can properly format q Windows command line
2515 test_util_join_win_cmdline(void *ptr
)
2517 /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
2518 * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
2519 * will try to only generate simple cases for the child process to parse;
2520 * i.e. we never embed quoted strings in arguments. */
2522 const char *argvs
[][4] = {
2523 {"a", "bb", "CCC", NULL
}, // Normal
2524 {NULL
, NULL
, NULL
, NULL
}, // Empty argument list
2525 {"", NULL
, NULL
, NULL
}, // Empty argument
2526 {"\"a", "b\"b", "CCC\"", NULL
}, // Quotes
2527 {"a\tbc", "dd dd", "E", NULL
}, // Whitespace
2528 {"a\\\\\\b", "de fg", "H", NULL
}, // Backslashes
2529 {"a\\\"b", "\\c", "D\\", NULL
}, // Backslashes before quote
2530 {"a\\\\b c", "d", "E", NULL
}, // Backslashes not before quote
2531 { NULL
} // Terminator
2534 const char *cmdlines
[] = {
2538 "\\\"a b\\\"b CCC\\\"",
2539 "\"a\tbc\" \"dd dd\" E",
2540 "a\\\\\\b \"de fg\" H",
2541 "a\\\\\\\"b \\c D\\",
2551 for (i
=0; cmdlines
[i
]!=NULL
; i
++) {
2552 log_info(LD_GENERAL
, "Joining argvs[%d], expecting <%s>", i
, cmdlines
[i
]);
2553 joined_argv
= tor_join_win_cmdline(argvs
[i
]);
2554 test_streq(cmdlines
[i
], joined_argv
);
2555 tor_free(joined_argv
);
2562 #define MAX_SPLIT_LINE_COUNT 4
2563 struct split_lines_test_t
{
2564 const char *orig_line
; // Line to be split (may contain \0's)
2565 int orig_length
; // Length of orig_line
2566 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
2570 * Test that we properly split a buffer into lines
2573 test_util_split_lines(void *ptr
)
2575 /* Test cases. orig_line of last test case must be NULL.
2576 * The last element of split_line[i] must be NULL. */
2577 struct split_lines_test_t tests
[] = {
2579 {"foo", 3, {"foo", NULL
}},
2580 {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL
}},
2581 {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL
}},
2582 {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL
}},
2583 {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL
}},
2584 {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL
}},
2585 {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL
}},
2586 {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL
}},
2587 {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL
}},
2588 {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL
}},
2593 char *orig_line
=NULL
;
2594 smartlist_t
*sl
=NULL
;
2598 for (i
=0; tests
[i
].orig_line
; i
++) {
2599 sl
= smartlist_new();
2600 /* Allocate space for string and trailing NULL */
2601 orig_line
= tor_memdup(tests
[i
].orig_line
, tests
[i
].orig_length
+ 1);
2602 tor_split_lines(sl
, orig_line
, tests
[i
].orig_length
);
2605 log_info(LD_GENERAL
, "Splitting test %d of length %d",
2606 i
, tests
[i
].orig_length
);
2607 SMARTLIST_FOREACH_BEGIN(sl
, const char *, line
) {
2608 /* Check we have not got too many lines */
2609 test_assert(j
< MAX_SPLIT_LINE_COUNT
);
2610 /* Check that there actually should be a line here */
2611 test_assert(tests
[i
].split_line
[j
] != NULL
);
2612 log_info(LD_GENERAL
, "Line %d of test %d, should be <%s>",
2613 j
, i
, tests
[i
].split_line
[j
]);
2614 /* Check that the line is as expected */
2615 test_streq(line
, tests
[i
].split_line
[j
]);
2617 } SMARTLIST_FOREACH_END(line
);
2618 /* Check that we didn't miss some lines */
2619 test_eq_ptr(NULL
, tests
[i
].split_line
[j
]);
2620 tor_free(orig_line
);
2626 tor_free(orig_line
);
2631 test_util_di_ops(void)
2637 const char *a
; int want_sign
; const char *b
;
2639 { "Foo", EQ
, "Foo" },
2640 { "foo", GT
, "bar", },
2641 { "foobar", EQ
,"foobar" },
2642 { "foobar", LT
, "foobaw" },
2643 { "foobar", GT
, "f00bar" },
2644 { "foobar", GT
, "boobar" },
2651 for (i
= 0; examples
[i
].a
; ++i
) {
2652 size_t len
= strlen(examples
[i
].a
);
2653 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
2654 test_eq(len
, strlen(examples
[i
].b
));
2655 /* We do all of the operations, with operands in both orders. */
2656 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
2657 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
2658 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
2659 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
2660 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
2661 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
2663 /* Check for correctness of cmp1 */
2664 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
2666 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
2668 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
2671 /* Check for consistency of everything else with cmp1 */
2673 test_eq(neq1
, neq2
);
2674 test_eq(cmp1
, -cmp2
);
2675 test_eq(eq1
, cmp1
== 0);
2676 test_eq(neq1
, !eq1
);
2684 * Test counting high bits
2687 test_util_n_bits_set(void *ptr
)
2690 test_eq(0, n_bits_set_u8(0));
2691 test_eq(1, n_bits_set_u8(1));
2692 test_eq(3, n_bits_set_u8(7));
2693 test_eq(1, n_bits_set_u8(8));
2694 test_eq(2, n_bits_set_u8(129));
2695 test_eq(8, n_bits_set_u8(255));
2701 * Test LHS whitespace (and comment) eater
2704 test_util_eat_whitespace(void *ptr
)
2706 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
2712 /* Try one leading ws */
2713 strcpy(str
, "fuubaar");
2714 for (i
= 0; i
< sizeof(ws
); ++i
) {
2716 test_eq_ptr(str
+ 1, eat_whitespace(str
));
2717 test_eq_ptr(str
+ 1, eat_whitespace_eos(str
, str
+ strlen(str
)));
2718 test_eq_ptr(str
+ 1, eat_whitespace_no_nl(str
));
2719 test_eq_ptr(str
+ 1, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2722 test_eq_ptr(str
+ 1, eat_whitespace(str
));
2723 test_eq_ptr(str
+ 1, eat_whitespace_eos(str
, str
+ strlen(str
)));
2724 test_eq_ptr(str
, eat_whitespace_no_nl(str
));
2725 test_eq_ptr(str
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2729 test_eq_ptr(str
, eat_whitespace(str
));
2730 test_eq_ptr(str
, eat_whitespace_eos(str
, str
));
2731 test_eq_ptr(str
, eat_whitespace_no_nl(str
));
2732 test_eq_ptr(str
, eat_whitespace_eos_no_nl(str
, str
));
2735 strcpy(str
, " \t\r\n");
2736 test_eq_ptr(str
+ strlen(str
), eat_whitespace(str
));
2737 test_eq_ptr(str
+ strlen(str
), eat_whitespace_eos(str
, str
+ strlen(str
)));
2738 test_eq_ptr(str
+ strlen(str
) - 1,
2739 eat_whitespace_no_nl(str
));
2740 test_eq_ptr(str
+ strlen(str
) - 1,
2741 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2743 strcpy(str
, " \t\r ");
2744 test_eq_ptr(str
+ strlen(str
), eat_whitespace(str
));
2745 test_eq_ptr(str
+ strlen(str
),
2746 eat_whitespace_eos(str
, str
+ strlen(str
)));
2747 test_eq_ptr(str
+ strlen(str
), eat_whitespace_no_nl(str
));
2748 test_eq_ptr(str
+ strlen(str
),
2749 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2752 strcpy(str
, "fuubaar");
2753 for (i
= 0; i
< sizeof(ws
); ++i
)
2755 test_eq_ptr(str
+ sizeof(ws
), eat_whitespace(str
));
2756 test_eq_ptr(str
+ sizeof(ws
), eat_whitespace_eos(str
, str
+ strlen(str
)));
2757 test_eq_ptr(str
+ sizeof(ws
), eat_whitespace_no_nl(str
));
2758 test_eq_ptr(str
+ sizeof(ws
),
2759 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2762 strcpy(str
, "# Comment \n No Comment");
2763 test_streq("No Comment", eat_whitespace(str
));
2764 test_streq("No Comment", eat_whitespace_eos(str
, str
+ strlen(str
)));
2765 test_eq_ptr(str
, eat_whitespace_no_nl(str
));
2766 test_eq_ptr(str
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2768 /* Eat comment & ws mix */
2769 strcpy(str
, " # \t Comment \n\t\nNo Comment");
2770 test_streq("No Comment", eat_whitespace(str
));
2771 test_streq("No Comment", eat_whitespace_eos(str
, str
+ strlen(str
)));
2772 test_eq_ptr(str
+ 1, eat_whitespace_no_nl(str
));
2773 test_eq_ptr(str
+ 1, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2775 /* Eat entire comment */
2776 strcpy(str
, "#Comment");
2777 test_eq_ptr(str
+ strlen(str
), eat_whitespace(str
));
2778 test_eq_ptr(str
+ strlen(str
), eat_whitespace_eos(str
, str
+ strlen(str
)));
2779 test_eq_ptr(str
, eat_whitespace_no_nl(str
));
2780 test_eq_ptr(str
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2782 /* Blank line, then comment */
2783 strcpy(str
, " \t\n # Comment");
2784 test_eq_ptr(str
+ strlen(str
), eat_whitespace(str
));
2785 test_eq_ptr(str
+ strlen(str
), eat_whitespace_eos(str
, str
+ strlen(str
)));
2786 test_eq_ptr(str
+ 2, eat_whitespace_no_nl(str
));
2787 test_eq_ptr(str
+ 2, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
2793 /** Return a newly allocated smartlist containing the lines of text in
2794 * <b>lines</b>. The returned strings are heap-allocated, and must be
2795 * freed by the caller.
2797 * XXXX? Move to container.[hc] ? */
2798 static smartlist_t
*
2799 smartlist_new_from_text_lines(const char *lines
)
2801 smartlist_t
*sl
= smartlist_new();
2804 smartlist_split_string(sl
, lines
, "\n", 0, 0);
2806 last_line
= smartlist_pop_last(sl
);
2807 if (last_line
!= NULL
&& *last_line
!= '\0') {
2808 smartlist_add(sl
, last_line
);
2814 /** Test smartlist_new_from_text_lines */
2816 test_util_sl_new_from_text_lines(void *ptr
)
2820 { /* Normal usage */
2821 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
2822 int sl_len
= smartlist_len(sl
);
2824 tt_want_int_op(sl_len
, ==, 3);
2826 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), ==, "foo");
2827 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), ==, "bar");
2828 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), ==, "baz");
2830 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
2834 { /* No final newline */
2835 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
2836 int sl_len
= smartlist_len(sl
);
2838 tt_want_int_op(sl_len
, ==, 3);
2840 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), ==, "foo");
2841 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), ==, "bar");
2842 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), ==, "baz");
2844 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
2849 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
2850 int sl_len
= smartlist_len(sl
);
2852 tt_want_int_op(sl_len
, ==, 1);
2854 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), ==, "foo");
2856 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
2860 { /* No text at all */
2861 smartlist_t
*sl
= smartlist_new_from_text_lines("");
2862 int sl_len
= smartlist_len(sl
);
2864 tt_want_int_op(sl_len
, ==, 0);
2866 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
2872 test_util_envnames(void *ptr
)
2876 tt_assert(environment_variable_names_equal("abc", "abc"));
2877 tt_assert(environment_variable_names_equal("abc", "abc="));
2878 tt_assert(environment_variable_names_equal("abc", "abc=def"));
2879 tt_assert(environment_variable_names_equal("abc=def", "abc"));
2880 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
2882 tt_assert(environment_variable_names_equal("abc", "abc"));
2883 tt_assert(environment_variable_names_equal("abc", "abc="));
2884 tt_assert(environment_variable_names_equal("abc", "abc=def"));
2885 tt_assert(environment_variable_names_equal("abc=def", "abc"));
2886 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
2888 tt_assert(!environment_variable_names_equal("abc", "abcd"));
2889 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
2890 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
2891 tt_assert(!environment_variable_names_equal("abc=", "def"));
2892 tt_assert(!environment_variable_names_equal("abc=", "def="));
2893 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
2895 tt_assert(!environment_variable_names_equal("", "a=def"));
2896 /* A bit surprising. */
2897 tt_assert(environment_variable_names_equal("", "=def"));
2898 tt_assert(environment_variable_names_equal("=y", "=x"));
2904 /** Test process_environment_make */
2906 test_util_make_environment(void *ptr
)
2908 const char *env_vars_string
=
2909 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
2910 "HOME=/home/foozer\n";
2911 const char expected_windows_env_block
[] =
2912 "HOME=/home/foozer\000"
2913 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
2915 size_t expected_windows_env_block_len
=
2916 sizeof(expected_windows_env_block
) - 1;
2918 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
2919 smartlist_t
*env_vars_sorted
= smartlist_new();
2920 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
2922 process_environment_t
*env
;
2926 env
= process_environment_make(env_vars
);
2928 /* Check that the Windows environment block is correct. */
2929 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
2930 expected_windows_env_block_len
));
2932 /* Now for the Unixoid environment block. We don't care which order
2933 * these environment variables are in, so we sort both lists first. */
2935 smartlist_add_all(env_vars_sorted
, env_vars
);
2939 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
2940 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
2944 smartlist_sort_strings(env_vars_sorted
);
2945 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
2947 tt_want_int_op(smartlist_len(env_vars_sorted
), ==,
2948 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
2950 int len
= smartlist_len(env_vars_sorted
);
2953 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
2954 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
2957 for (i
= 0; i
< len
; ++i
) {
2958 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), ==,
2959 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
2964 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
2965 smartlist_free(env_vars_sorted
);
2967 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
2968 smartlist_free(env_vars
);
2970 process_environment_free(env
);
2973 /** Test set_environment_variable_in_smartlist */
2975 test_util_set_env_var_in_sl(void *ptr
)
2977 /* The environment variables in these strings are in arbitrary
2978 * order; we sort the resulting lists before comparing them.
2980 * (They *will not* end up in the order shown in
2981 * expected_resulting_env_vars_string.) */
2983 const char *base_env_vars_string
=
2984 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
2985 "HOME=/home/foozer\n"
2994 const char *new_env_vars_string
=
2999 const char *expected_resulting_env_vars_string
=
3000 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
3001 "HOME=/home/foozer\n"
3011 smartlist_t
*merged_env_vars
=
3012 smartlist_new_from_text_lines(base_env_vars_string
);
3013 smartlist_t
*new_env_vars
=
3014 smartlist_new_from_text_lines(new_env_vars_string
);
3015 smartlist_t
*expected_resulting_env_vars
=
3016 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
3018 /* Elements of merged_env_vars are heap-allocated, and must be
3019 * freed. Some of them are (or should) be freed by
3020 * set_environment_variable_in_smartlist.
3022 * Elements of new_env_vars are heap-allocated, but are copied into
3023 * merged_env_vars, so they are not freed separately at the end of
3026 * Elements of expected_resulting_env_vars are heap-allocated, and
3031 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
3032 set_environment_variable_in_smartlist(merged_env_vars
,
3037 smartlist_sort_strings(merged_env_vars
);
3038 smartlist_sort_strings(expected_resulting_env_vars
);
3040 tt_want_int_op(smartlist_len(merged_env_vars
), ==,
3041 smartlist_len(expected_resulting_env_vars
));
3043 int len
= smartlist_len(merged_env_vars
);
3046 if (smartlist_len(expected_resulting_env_vars
) < len
) {
3047 len
= smartlist_len(expected_resulting_env_vars
);
3050 for (i
= 0; i
< len
; ++i
) {
3051 tt_want_str_op(smartlist_get(merged_env_vars
, i
), ==,
3052 smartlist_get(expected_resulting_env_vars
, i
));
3057 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
3058 smartlist_free(merged_env_vars
);
3060 smartlist_free(new_env_vars
);
3062 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
3063 smartlist_free(expected_resulting_env_vars
);
3066 #define UTIL_LEGACY(name) \
3067 { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
3069 #define UTIL_TEST(name, flags) \
3070 { #name, test_util_ ## name, flags, NULL, NULL }
3072 struct testcase_t util_tests
[] = {
3074 UTIL_TEST(parse_http_time
, 0),
3075 UTIL_LEGACY(config_line
),
3076 UTIL_LEGACY(config_line_quotes
),
3077 UTIL_LEGACY(config_line_comment_character
),
3078 UTIL_LEGACY(config_line_escaped_content
),
3080 UTIL_LEGACY(expand_filename
),
3082 UTIL_LEGACY(strmisc
),
3085 UTIL_LEGACY(datadir
),
3086 UTIL_LEGACY(mempool
),
3087 UTIL_LEGACY(memarea
),
3088 UTIL_LEGACY(control_formats
),
3090 UTIL_LEGACY(threads
),
3091 UTIL_LEGACY(sscanf
),
3092 UTIL_LEGACY(path_is_relative
),
3093 UTIL_LEGACY(strtok
),
3094 UTIL_LEGACY(di_ops
),
3095 UTIL_TEST(find_str_at_start_of_line
, 0),
3096 UTIL_TEST(string_is_C_identifier
, 0),
3097 UTIL_TEST(asprintf
, 0),
3098 UTIL_TEST(listdir
, 0),
3099 UTIL_TEST(parent_dir
, 0),
3101 UTIL_TEST(load_win_lib
, 0),
3103 UTIL_TEST(exit_status
, 0),
3105 UTIL_TEST(fgets_eagain
, TT_SKIP
),
3107 UTIL_TEST(spawn_background_ok
, 0),
3108 UTIL_TEST(spawn_background_fail
, 0),
3109 UTIL_TEST(spawn_background_partial_read
, 0),
3110 UTIL_TEST(format_hex_number
, 0),
3111 UTIL_TEST(join_win_cmdline
, 0),
3112 UTIL_TEST(split_lines
, 0),
3113 UTIL_TEST(n_bits_set
, 0),
3114 UTIL_TEST(eat_whitespace
, 0),
3115 UTIL_TEST(sl_new_from_text_lines
, 0),
3116 UTIL_TEST(envnames
, 0),
3117 UTIL_TEST(make_environment
, 0),
3118 UTIL_TEST(set_env_var_in_sl
, 0),