1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2010, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #define CONTROL_PRIVATE
8 #define MEMPOOL_PRIVATE
19 struct timeval start
, end
;
21 char timestr
[RFC1123_TIME_LEN
+1];
31 test_eq(0L, tv_udiff(&start
, &end
));
35 test_eq(2000L, tv_udiff(&start
, &end
));
39 test_eq(1002000L, tv_udiff(&start
, &end
));
43 test_eq(995000L, tv_udiff(&start
, &end
));
47 test_eq(-1005000L, tv_udiff(&start
, &end
));
53 /* The test values here are confirmed to be correct on a platform
54 * with a working timegm. */
55 a_time
.tm_year
= 2003-1900;
61 test_eq((time_t) 1062224095UL, tor_timegm(&a_time
));
62 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
63 test_eq((time_t) 1093846495UL, tor_timegm(&a_time
));
64 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
66 test_eq((time_t) 1076393695UL, tor_timegm(&a_time
));
68 format_rfc1123_time(timestr
, 0);
69 test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr
);
70 format_rfc1123_time(timestr
, (time_t)1091580502UL);
71 test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr
);
74 i
= parse_rfc1123_time(timestr
, &t_res
);
76 test_eq(t_res
, (time_t)1091580502UL);
77 test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
79 tor_gettimeofday(&start
);
80 /* now make sure time works. */
81 tor_gettimeofday(&end
);
82 /* We might've timewarped a little. */
83 tt_int_op(tv_udiff(&start
, &end
), >=, -5000);
90 test_util_config_line(void)
93 char *k
=NULL
, *v
=NULL
;
96 /* Test parse_config_line_from_str */
97 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
99 "k3 \n" "\n" " \n" "#comment\n"
100 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
101 "kseven \"a quoted 'string\"\n"
102 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
106 str
= parse_config_line_from_str(str
, &k
, &v
);
109 tor_free(k
); tor_free(v
);
110 test_assert(!strcmpstart(str
, "key value with"));
112 str
= parse_config_line_from_str(str
, &k
, &v
);
113 test_streq(k
, "key");
114 test_streq(v
, "value with spaces");
115 tor_free(k
); tor_free(v
);
116 test_assert(!strcmpstart(str
, "keykey"));
118 str
= parse_config_line_from_str(str
, &k
, &v
);
119 test_streq(k
, "keykey");
120 test_streq(v
, "val");
121 tor_free(k
); tor_free(v
);
122 test_assert(!strcmpstart(str
, "k2\n"));
124 str
= parse_config_line_from_str(str
, &k
, &v
);
127 tor_free(k
); tor_free(v
);
128 test_assert(!strcmpstart(str
, "k3 \n"));
130 str
= parse_config_line_from_str(str
, &k
, &v
);
133 tor_free(k
); tor_free(v
);
134 test_assert(!strcmpstart(str
, "#comment"));
136 str
= parse_config_line_from_str(str
, &k
, &v
);
139 tor_free(k
); tor_free(v
);
140 test_assert(!strcmpstart(str
, "k5#abc"));
142 str
= parse_config_line_from_str(str
, &k
, &v
);
145 tor_free(k
); tor_free(v
);
146 test_assert(!strcmpstart(str
, "k6"));
148 str
= parse_config_line_from_str(str
, &k
, &v
);
150 test_streq(v
, "val");
151 tor_free(k
); tor_free(v
);
152 test_assert(!strcmpstart(str
, "kseven"));
154 str
= parse_config_line_from_str(str
, &k
, &v
);
155 test_streq(k
, "kseven");
156 test_streq(v
, "a quoted \'string");
157 tor_free(k
); tor_free(v
);
158 test_assert(!strcmpstart(str
, "k8 "));
160 str
= parse_config_line_from_str(str
, &k
, &v
);
162 test_streq(v
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
163 tor_free(k
); tor_free(v
);
170 /** Test basic string functionality. */
172 test_util_strmisc(void)
178 /* Tests for corner cases of strl operations */
179 test_eq(5, strlcpy(buf
, "Hello", 0));
180 strlcpy(buf
, "Hello", sizeof(buf
));
181 test_eq(10, strlcat(buf
, "Hello", 5));
183 /* Test tor_strstrip() */
184 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
185 tor_strstrip(buf
, ",!");
186 test_streq(buf
, "Testing 1 2 3");
187 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
188 tor_strstrip(buf
, "!? ");
189 test_streq(buf
, "Testing123");
191 /* Test tor_parse_long. */
192 test_eq(10L, tor_parse_long("10",10,0,100,NULL
,NULL
));
193 test_eq(0L, tor_parse_long("10",10,50,100,NULL
,NULL
));
194 test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL
,NULL
));
196 /* Test tor_parse_ulong */
197 test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
198 test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
200 /* Test tor_parse_uint64. */
201 test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
203 test_streq(cp
, " x");
204 test_assert(U64_LITERAL(12345678901) ==
205 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
208 test_assert(U64_LITERAL(0) ==
209 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
213 /* Test tor_parse_double. */
214 double d
= tor_parse_double("10", 0, UINT64_MAX
,&i
,NULL
);
216 test_assert(DBL_TO_U64(d
) == 10);
217 d
= tor_parse_double("0", 0, UINT64_MAX
,&i
,NULL
);
219 test_assert(DBL_TO_U64(d
) == 0);
220 d
= tor_parse_double(" ", 0, UINT64_MAX
,&i
,NULL
);
222 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,NULL
);
224 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,&cp
);
226 d
= tor_parse_double("-.0", 0, UINT64_MAX
,&i
,NULL
);
230 /* Test failing snprintf cases */
231 test_eq(-1, tor_snprintf(buf
, 0, "Foo"));
232 test_eq(-1, tor_snprintf(buf
, 2, "Foo"));
234 /* Test printf with uint64 */
235 tor_snprintf(buf
, sizeof(buf
), "x!"U64_FORMAT
"!x",
236 U64_PRINTF_ARG(U64_LITERAL(12345678901)));
237 test_streq(buf
, "x!12345678901!x");
239 /* Test for strcmpstart and strcmpend. */
240 test_assert(strcmpstart("abcdef", "abcdef")==0);
241 test_assert(strcmpstart("abcdef", "abc")==0);
242 test_assert(strcmpstart("abcdef", "abd")<0);
243 test_assert(strcmpstart("abcdef", "abb")>0);
244 test_assert(strcmpstart("ab", "abb")<0);
246 test_assert(strcmpend("abcdef", "abcdef")==0);
247 test_assert(strcmpend("abcdef", "def")==0);
248 test_assert(strcmpend("abcdef", "deg")<0);
249 test_assert(strcmpend("abcdef", "dee")>0);
250 test_assert(strcmpend("ab", "abb")<0);
252 test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
253 test_assert(strcasecmpend("abcdef", "dEF")==0);
254 test_assert(strcasecmpend("abcDEf", "deg")<0);
255 test_assert(strcasecmpend("abcdef", "DEE")>0);
256 test_assert(strcasecmpend("ab", "abB")<0);
258 /* Test mem_is_zero */
261 test_assert(tor_digest_is_zero(buf
));
262 test_assert(tor_mem_is_zero(buf
, 10));
263 test_assert(tor_mem_is_zero(buf
, 20));
264 test_assert(tor_mem_is_zero(buf
, 128));
265 test_assert(!tor_mem_is_zero(buf
, 129));
267 test_assert(!tor_mem_is_zero(buf
, 128));
269 test_assert(!tor_mem_is_zero(buf
, 10));
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
));
278 /* Test strndup and memdup */
280 const char *s
= "abcdefghijklmnopqrstuvwxyz";
281 cp
= tor_strndup(s
, 30);
282 test_streq(cp
, s
); /* same string, */
283 test_neq(cp
, s
); /* but different pointers. */
286 cp
= tor_strndup(s
, 5);
287 test_streq(cp
, "abcde");
290 s
= "a\0b\0c\0d\0e\0";
291 cp
= tor_memdup(s
,10);
292 test_memeq(cp
, s
, 10); /* same ram, */
293 test_neq(cp
, s
); /* but different pointers. */
297 /* Test str-foo functions */
298 cp
= tor_strdup("abcdef");
299 test_assert(tor_strisnonupper(cp
));
301 test_assert(!tor_strisnonupper(cp
));
303 test_streq(cp
, "ABCDEF");
304 test_assert(tor_strisprint(cp
));
306 test_assert(!tor_strisprint(cp
));
309 /* Test eat_whitespace. */
311 const char *s
= " \n a";
312 test_eq_ptr(eat_whitespace(s
), s
+4);
314 test_eq_ptr(eat_whitespace(s
), s
);
316 test_eq_ptr(eat_whitespace(s
), s
+5);
319 /* Test memmem and memstr */
321 const char *haystack
= "abcde";
322 tor_assert(!tor_memmem(haystack
, 5, "ef", 2));
323 test_eq_ptr(tor_memmem(haystack
, 5, "cd", 2), haystack
+ 2);
324 test_eq_ptr(tor_memmem(haystack
, 5, "cde", 3), haystack
+ 2);
325 haystack
= "ababcad";
326 test_eq_ptr(tor_memmem(haystack
, 7, "abc", 3), haystack
+ 2);
327 test_eq_ptr(tor_memstr(haystack
, 7, "abc"), haystack
+ 2);
328 test_assert(!tor_memstr(haystack
, 7, "fe"));
329 test_assert(!tor_memstr(haystack
, 7, "longerthantheoriginal"));
332 /* Test wrap_string */
334 smartlist_t
*sl
= smartlist_create();
335 wrap_string(sl
, "This is a test of string wrapping functionality: woot.",
337 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
339 "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
341 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
344 wrap_string(sl
, "This is a test of string wrapping functionality: woot.",
346 cp
= smartlist_join_strings(sl
, "", 0, NULL
);
348 "### This is a\n# test of string\n# wrapping\n# functionality:\n"
352 SMARTLIST_FOREACH(sl
, char *, cp
, tor_free(cp
));
362 /* Test tor_log2(). */
363 test_eq(tor_log2(64), 6);
364 test_eq(tor_log2(65), 6);
365 test_eq(tor_log2(63), 5);
366 test_eq(tor_log2(1), 0);
367 test_eq(tor_log2(2), 1);
368 test_eq(tor_log2(3), 1);
369 test_eq(tor_log2(4), 2);
370 test_eq(tor_log2(5), 2);
371 test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
372 test_eq(tor_log2(UINT64_MAX
), 63);
374 /* Test round_to_power_of_2 */
375 test_eq(round_to_power_of_2(120), 128);
376 test_eq(round_to_power_of_2(128), 128);
377 test_eq(round_to_power_of_2(130), 128);
378 test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
380 test_eq(round_to_power_of_2(0), 2);
386 /** mutex for thread test to stop the threads hitting data at the same time. */
387 static tor_mutex_t
*_thread_test_mutex
= NULL
;
388 /** mutexes for the thread test to make sure that the threads have to
389 * interleave somewhat. */
390 static tor_mutex_t
*_thread_test_start1
= NULL
,
391 *_thread_test_start2
= NULL
;
392 /** Shared strmap for the thread test. */
393 static strmap_t
*_thread_test_strmap
= NULL
;
394 /** The name of thread1 for the thread test */
395 static char *_thread1_name
= NULL
;
396 /** The name of thread2 for the thread test */
397 static char *_thread2_name
= NULL
;
399 static void _thread_test_func(void* _s
) ATTR_NORETURN
;
401 /** How many iterations have the threads in the unit test run? */
402 static int t1_count
= 0, t2_count
= 0;
404 /** Helper function for threading unit tests: This function runs in a
405 * subthread. It grabs its own mutex (start1 or start2) to make sure that it
406 * should start, then it repeatedly alters _test_thread_strmap protected by
407 * _thread_test_mutex. */
409 _thread_test_func(void* _s
)
416 if (!strcmp(s
, "thread 1")) {
417 m
= _thread_test_start1
;
421 m
= _thread_test_start2
;
426 tor_snprintf(buf
, sizeof(buf
), "%lu", tor_get_thread_id());
427 *cp
= tor_strdup(buf
);
429 tor_mutex_acquire(m
);
431 for (i
=0; i
<10000; ++i
) {
432 tor_mutex_acquire(_thread_test_mutex
);
433 strmap_set(_thread_test_strmap
, "last to run", *cp
);
435 tor_mutex_release(_thread_test_mutex
);
437 tor_mutex_acquire(_thread_test_mutex
);
438 strmap_set(_thread_test_strmap
, s
, *cp
);
439 tor_mutex_release(_thread_test_mutex
);
441 tor_mutex_release(m
);
446 /** Run unit tests for threading logic. */
448 test_util_threads(void)
450 char *s1
= NULL
, *s2
= NULL
;
451 int done
= 0, timedout
= 0;
458 #ifndef TOR_IS_MULTITHREADED
459 /* Skip this test if we aren't threading. We should be threading most
460 * everywhere by now. */
464 _thread_test_mutex
= tor_mutex_new();
465 _thread_test_start1
= tor_mutex_new();
466 _thread_test_start2
= tor_mutex_new();
467 _thread_test_strmap
= strmap_new();
468 s1
= tor_strdup("thread 1");
469 s2
= tor_strdup("thread 2");
470 tor_mutex_acquire(_thread_test_start1
);
471 tor_mutex_acquire(_thread_test_start2
);
472 spawn_func(_thread_test_func
, s1
);
473 spawn_func(_thread_test_func
, s2
);
474 tor_mutex_release(_thread_test_start2
);
475 tor_mutex_release(_thread_test_start1
);
476 started
= time(NULL
);
478 tor_mutex_acquire(_thread_test_mutex
);
479 strmap_assert_ok(_thread_test_strmap
);
480 if (strmap_get(_thread_test_strmap
, "thread 1") &&
481 strmap_get(_thread_test_strmap
, "thread 2")) {
483 } else if (time(NULL
) > started
+ 25) {
486 tor_mutex_release(_thread_test_mutex
);
488 /* Prevent the main thread from starving the worker threads. */
489 select(0, NULL
, NULL
, NULL
, &tv
);
492 tor_mutex_acquire(_thread_test_start1
);
493 tor_mutex_release(_thread_test_start1
);
494 tor_mutex_acquire(_thread_test_start2
);
495 tor_mutex_release(_thread_test_start2
);
497 tor_mutex_free(_thread_test_mutex
);
500 printf("\nTimed out: %d %d", t1_count
, t2_count
);
501 test_assert(strmap_get(_thread_test_strmap
, "thread 1"));
502 test_assert(strmap_get(_thread_test_strmap
, "thread 2"));
503 test_assert(!timedout
);
506 /* different thread IDs. */
507 test_assert(strcmp(strmap_get(_thread_test_strmap
, "thread 1"),
508 strmap_get(_thread_test_strmap
, "thread 2")));
509 test_assert(!strcmp(strmap_get(_thread_test_strmap
, "thread 1"),
510 strmap_get(_thread_test_strmap
, "last to run")) ||
511 !strcmp(strmap_get(_thread_test_strmap
, "thread 2"),
512 strmap_get(_thread_test_strmap
, "last to run")));
517 tor_free(_thread1_name
);
518 tor_free(_thread2_name
);
519 if (_thread_test_strmap
)
520 strmap_free(_thread_test_strmap
, NULL
);
521 if (_thread_test_start1
)
522 tor_mutex_free(_thread_test_start1
);
523 if (_thread_test_start2
)
524 tor_mutex_free(_thread_test_start2
);
527 /** Run unit tests for compression functions */
531 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
534 tor_zlib_state_t
*state
= NULL
;
536 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
537 test_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
538 if (is_gzip_supported()) {
539 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
542 test_assert(!memcmp(buf2
, "\037\213", 2)); /* Gzip magic. */
543 test_assert(detect_compression_method(buf2
, len1
) == GZIP_METHOD
);
545 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
546 GZIP_METHOD
, 1, LOG_INFO
));
548 test_streq(buf1
,buf3
);
554 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
557 test_assert(!memcmp(buf2
, "\x78\xDA", 2)); /* deflate magic. */
558 test_assert(detect_compression_method(buf2
, len1
) == ZLIB_METHOD
);
560 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
561 ZLIB_METHOD
, 1, LOG_INFO
));
563 test_streq(buf1
,buf3
);
565 /* Check whether we can uncompress concatenated, compressed strings. */
567 buf2
= tor_realloc(buf2
, len1
*2);
568 memcpy(buf2
+len1
, buf2
, len1
);
569 test_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
*2,
570 ZLIB_METHOD
, 1, LOG_INFO
));
571 test_eq(len2
, (strlen(buf1
)+1)*2);
573 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
574 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
581 /* Check whether we can uncompress partial strings. */
583 tor_strdup("String with low redundancy that won't be compressed much.");
584 test_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
587 /* when we allow an incomplete string, we should succeed.*/
588 tor_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
589 ZLIB_METHOD
, 0, LOG_INFO
));
591 tor_assert(len2
> 5);
592 tor_assert(!strcmpstart(buf1
, buf3
));
594 /* when we demand a complete string, this must fail. */
596 tor_assert(tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
597 ZLIB_METHOD
, 1, LOG_INFO
));
600 /* Now, try streaming compression. */
604 state
= tor_zlib_new(1, ZLIB_METHOD
);
606 cp1
= buf1
= tor_malloc(1024);
608 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
610 test_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0)
612 test_eq(len2
, 0); /* Make sure we compressed it all. */
613 test_assert(cp1
> buf1
);
617 test_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1)
620 test_assert(cp1
> cp2
); /* Make sure we really added something. */
622 tor_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
623 ZLIB_METHOD
, 1, LOG_WARN
));
624 test_streq(buf3
, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
628 tor_zlib_free(state
);
634 /** Run unit tests for mmap() wrapper functionality. */
638 char *fname1
= tor_strdup(get_fname("mapped_1"));
639 char *fname2
= tor_strdup(get_fname("mapped_2"));
640 char *fname3
= tor_strdup(get_fname("mapped_3"));
641 const size_t buflen
= 17000;
642 char *buf
= tor_malloc(17000);
643 tor_mmap_t
*mapping
= NULL
;
645 crypto_rand(buf
, buflen
);
647 mapping
= tor_mmap_file(fname1
);
648 test_assert(! mapping
);
650 write_str_to_file(fname1
, "Short file.", 1);
651 write_bytes_to_file(fname2
, buf
, buflen
, 1);
652 write_bytes_to_file(fname3
, buf
, 16384, 1);
654 mapping
= tor_mmap_file(fname1
);
655 test_assert(mapping
);
656 test_eq(mapping
->size
, strlen("Short file."));
657 test_streq(mapping
->data
, "Short file.");
659 tor_munmap_file(mapping
);
661 test_assert(unlink(fname1
) == 0);
663 /* make sure we can unlink. */
664 test_assert(unlink(fname1
) == 0);
665 test_streq(mapping
->data
, "Short file.");
666 tor_munmap_file(mapping
);
670 /* Now a zero-length file. */
671 write_str_to_file(fname1
, "", 1);
672 mapping
= tor_mmap_file(fname1
);
673 test_eq(mapping
, NULL
);
674 test_eq(ERANGE
, errno
);
677 /* Make sure that we fail to map a no-longer-existent file. */
678 mapping
= tor_mmap_file(fname1
);
679 test_assert(mapping
== NULL
);
681 /* Now try a big file that stretches across a few pages and isn't aligned */
682 mapping
= tor_mmap_file(fname2
);
683 test_assert(mapping
);
684 test_eq(mapping
->size
, buflen
);
685 test_memeq(mapping
->data
, buf
, buflen
);
686 tor_munmap_file(mapping
);
689 /* Now try a big aligned file. */
690 mapping
= tor_mmap_file(fname3
);
691 test_assert(mapping
);
692 test_eq(mapping
->size
, 16384);
693 test_memeq(mapping
->data
, buf
, 16384);
694 tor_munmap_file(mapping
);
708 tor_munmap_file(mapping
);
711 /** Run unit tests for escaping/unescaping data for use by controllers. */
713 test_util_control_formats(void)
717 "..This is a test\r\nof the emergency \nbroadcast\r\n..system.\r\nZ.\r\n";
720 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
722 ".This is a test\nof the emergency \nbroadcast\n.system.\nZ.\n");
723 test_eq(sz
, strlen(out
));
730 test_util_sscanf(void)
733 char s1
[10], s2
[10], s3
[10], ch
;
736 r
= tor_sscanf("hello world", "hello world"); /* String match: success */
738 r
= tor_sscanf("hello world 3", "hello worlb %u", &u1
); /* String fail */
740 r
= tor_sscanf("12345", "%u", &u1
); /* Simple number */
743 r
= tor_sscanf("", "%u", &u1
); /* absent number */
745 r
= tor_sscanf("A", "%u", &u1
); /* bogus number */
747 r
= tor_sscanf("4294967295", "%u", &u1
); /* UINT32_MAX should work. */
749 test_eq(u1
, 4294967295u);
750 r
= tor_sscanf("4294967296", "%u", &u1
); /* Always say -1 at 32 bits. */
752 r
= tor_sscanf("123456", "%2u%u", &u1
, &u2
); /* Width */
756 r
= tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
); /* separators */
761 r
= tor_sscanf("12:3:045", "%2u:%2u:%3u", &u1
, &u2
, &u3
); /* 0s */
766 /* %u does not match space.*/
767 r
= tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
);
769 /* %u does not match negative numbers. */
770 r
= tor_sscanf("12:3:-4", "%2u:%2u:%3u", &u1
, &u2
, &u3
);
772 /* Arbitrary amounts of 0-padding are okay */
773 r
= tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1
, &u2
, &u3
);
779 r
= tor_sscanf("99% fresh", "%3u%% fresh", &u1
); /* percents are scannable.*/
783 r
= tor_sscanf("hello", "%s", s1
); /* %s needs a number. */
786 r
= tor_sscanf("hello", "%3s%7s", s1
, s2
); /* %s matches characters. */
788 test_streq(s1
, "hel");
789 test_streq(s2
, "lo");
790 r
= tor_sscanf("WD40", "%2s%u", s3
, &u1
); /* %s%u */
792 test_streq(s3
, "WD");
794 r
= tor_sscanf("76trombones", "%6u%9s", &u1
, s1
); /* %u%s */
797 test_streq(s1
, "trombones");
798 r
= tor_sscanf("hello world", "%9s %9s", s1
, s2
); /* %s doesn't eat space. */
800 test_streq(s1
, "hello");
801 test_streq(s2
, "world");
802 r
= tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
); /* %s can be empty. */
804 test_streq(s1
, "hi");
808 r
= tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
);
810 r
= tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
);
817 /** Run unittests for memory pool allocator */
819 test_util_mempool(void)
821 mp_pool_t
*pool
= NULL
;
822 smartlist_t
*allocated
= NULL
;
825 pool
= mp_pool_new(1, 100);
827 test_assert(pool
->new_chunk_capacity
>= 100);
828 test_assert(pool
->item_alloc_size
>= sizeof(void*)+1);
829 mp_pool_destroy(pool
);
832 pool
= mp_pool_new(241, 2500);
834 test_assert(pool
->new_chunk_capacity
>= 10);
835 test_assert(pool
->item_alloc_size
>= sizeof(void*)+241);
836 test_eq(pool
->item_alloc_size
& 0x03, 0);
837 test_assert(pool
->new_chunk_capacity
< 60);
839 allocated
= smartlist_create();
840 for (i
= 0; i
< 20000; ++i
) {
841 if (smartlist_len(allocated
) < 20 || crypto_rand_int(2)) {
842 void *m
= mp_pool_get(pool
);
843 memset(m
, 0x09, 241);
844 smartlist_add(allocated
, m
);
845 //printf("%d: %p\n", i, m);
846 //mp_pool_assert_ok(pool);
848 int idx
= crypto_rand_int(smartlist_len(allocated
));
849 void *m
= smartlist_get(allocated
, idx
);
850 //printf("%d: free %p\n", i, m);
851 smartlist_del(allocated
, idx
);
853 //mp_pool_assert_ok(pool);
855 if (crypto_rand_int(777)==0)
856 mp_pool_clean(pool
, 1, 1);
859 mp_pool_assert_ok(pool
);
864 SMARTLIST_FOREACH(allocated
, void *, m
, mp_pool_release(m
));
865 mp_pool_assert_ok(pool
);
866 mp_pool_clean(pool
, 0, 0);
867 mp_pool_assert_ok(pool
);
868 smartlist_free(allocated
);
872 mp_pool_destroy(pool
);
875 /** Run unittests for memory area allocator */
877 test_util_memarea(void)
879 memarea_t
*area
= memarea_new();
880 char *p1
, *p2
, *p3
, *p1_orig
;
881 void *malloced_ptr
= NULL
;
886 p1_orig
= p1
= memarea_alloc(area
,64);
887 p2
= memarea_alloc_zero(area
,52);
888 p3
= memarea_alloc(area
,11);
890 test_assert(memarea_owns_ptr(area
, p1
));
891 test_assert(memarea_owns_ptr(area
, p2
));
892 test_assert(memarea_owns_ptr(area
, p3
));
893 /* Make sure we left enough space. */
894 test_assert(p1
+64 <= p2
);
895 test_assert(p2
+52 <= p3
);
896 /* Make sure we aligned. */
897 test_eq(((uintptr_t)p1
) % sizeof(void*), 0);
898 test_eq(((uintptr_t)p2
) % sizeof(void*), 0);
899 test_eq(((uintptr_t)p3
) % sizeof(void*), 0);
900 test_assert(!memarea_owns_ptr(area
, p3
+8192));
901 test_assert(!memarea_owns_ptr(area
, p3
+30));
902 test_assert(tor_mem_is_zero(p2
, 52));
903 /* Make sure we don't overalign. */
904 p1
= memarea_alloc(area
, 1);
905 p2
= memarea_alloc(area
, 1);
906 test_eq(p1
+sizeof(void*), p2
);
908 malloced_ptr
= tor_malloc(64);
909 test_assert(!memarea_owns_ptr(area
, malloced_ptr
));
910 tor_free(malloced_ptr
);
915 malloced_ptr
= tor_malloc(64);
916 crypto_rand((char*)malloced_ptr
, 64);
917 p1
= memarea_memdup(area
, malloced_ptr
, 64);
918 test_assert(p1
!= malloced_ptr
);
919 test_memeq(p1
, malloced_ptr
, 64);
920 tor_free(malloced_ptr
);
923 /* memarea_strdup. */
924 p1
= memarea_strdup(area
,"");
925 p2
= memarea_strdup(area
, "abcd");
929 test_streq(p2
, "abcd");
931 /* memarea_strndup. */
933 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
934 /* (From Turandot, act 3.) */
935 size_t len
= strlen(s
);
936 p1
= memarea_strndup(area
, s
, 1000);
937 p2
= memarea_strndup(area
, s
, 10);
939 test_assert(p2
>= p1
+ len
+ 1);
940 test_memeq(s
, p2
, 10);
941 test_eq(p2
[10], '\0');
942 p3
= memarea_strndup(area
, s
, len
);
944 p3
= memarea_strndup(area
, s
, len
-1);
945 test_memeq(s
, p3
, len
-1);
946 test_eq(p3
[len
-1], '\0');
950 p1
= memarea_alloc(area
, 1);
951 test_eq(p1
, p1_orig
);
954 /* Check for running over an area's size. */
955 for (i
= 0; i
< 512; ++i
) {
956 p1
= memarea_alloc(area
, crypto_rand_int(5)+1);
957 test_assert(memarea_owns_ptr(area
, p1
));
959 memarea_assert_ok(area
);
960 /* Make sure we can allocate a too-big object. */
961 p1
= memarea_alloc_zero(area
, 9000);
962 p2
= memarea_alloc_zero(area
, 16);
963 test_assert(memarea_owns_ptr(area
, p1
));
964 test_assert(memarea_owns_ptr(area
, p2
));
967 memarea_drop_all(area
);
968 tor_free(malloced_ptr
);
971 /** Run unit tests for utility functions to get file names relative to
972 * the data directory. */
974 test_util_datadir(void)
978 char *temp_dir
= NULL
;
980 temp_dir
= get_datadir_fname(NULL
);
981 f
= get_datadir_fname("state");
982 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
985 f
= get_datadir_fname2("cache", "thingy");
986 tor_snprintf(buf
, sizeof(buf
),
987 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
990 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
991 tor_snprintf(buf
, sizeof(buf
),
992 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
995 f
= get_datadir_fname_suffix("cache", ".foo");
996 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
1006 test_util_strtok(void)
1011 strlcpy(buf
, "Graved on the dark in gestures of descent", sizeof(buf
));
1012 strlcpy(buf2
, "they.seemed;their!own;most.perfect;monument", sizeof(buf2
));
1013 /* -- "Year's End", Richard Wilbur */
1015 test_streq("Graved", tor_strtok_r_impl(buf
, " ", &cp1
));
1016 test_streq("they", tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
1017 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
1018 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
1019 test_streq("on", S1());
1020 test_streq("the", S1());
1021 test_streq("dark", S1());
1022 test_streq("seemed", S2());
1023 test_streq("their", S2());
1024 test_streq("own", S2());
1025 test_streq("in", S1());
1026 test_streq("gestures", S1());
1027 test_streq("of", S1());
1028 test_streq("most", S2());
1029 test_streq("perfect", S2());
1030 test_streq("descent", S1());
1031 test_streq("monument", S2());
1032 test_assert(NULL
== S1());
1033 test_assert(NULL
== S2());
1039 test_util_find_str_at_start_of_line(void *ptr
)
1041 const char *long_string
=
1042 "hello world. hello world. hello hello. howdy.\n"
1043 "hello hello world\n";
1047 /* not-found case. */
1048 tt_assert(! find_str_at_start_of_line(long_string
, "fred"));
1050 /* not-found case where haystack doesn't end with \n */
1051 tt_assert(! find_str_at_start_of_line("foobar\nbaz", "fred"));
1053 /* start-of-string case */
1054 tt_assert(long_string
==
1055 find_str_at_start_of_line(long_string
, "hello world."));
1057 /* start-of-line case */
1058 tt_assert(strchr(long_string
,'\n')+1 ==
1059 find_str_at_start_of_line(long_string
, "hello hello"));
1065 test_util_asprintf(void *ptr
)
1067 #define LOREMIPSUM \
1068 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
1069 char *cp
=NULL
, *cp2
=NULL
;
1074 r
= tor_asprintf(&cp
, "%s", "");
1076 tt_int_op(r
, ==, strlen(cp
));
1077 tt_str_op(cp
, ==, "");
1079 /* Short string with some printing in it. */
1080 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
1082 tt_int_op(r
, ==, strlen(cp2
));
1083 tt_str_op(cp2
, ==, "First=101, Second=202");
1084 tt_assert(cp
!= cp2
);
1088 /* Glass-box test: a string exactly 128 characters long. */
1089 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
1091 tt_int_op(r
, ==, 128);
1092 tt_assert(cp
[128] == '\0');
1094 "Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
);
1097 /* String longer than 128 characters */
1098 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
1099 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
1101 tt_int_op(r
, ==, strlen(cp
));
1102 tt_str_op(cp
, ==, "1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
);
1109 #define UTIL_LEGACY(name) \
1110 { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
1112 #define UTIL_TEST(name, flags) \
1113 { #name, test_util_ ## name, flags, NULL, NULL }
1115 struct testcase_t util_tests
[] = {
1117 UTIL_LEGACY(config_line
),
1118 UTIL_LEGACY(strmisc
),
1121 UTIL_LEGACY(datadir
),
1122 UTIL_LEGACY(mempool
),
1123 UTIL_LEGACY(memarea
),
1124 UTIL_LEGACY(control_formats
),
1126 UTIL_LEGACY(threads
),
1127 UTIL_LEGACY(sscanf
),
1128 UTIL_LEGACY(strtok
),
1129 UTIL_TEST(find_str_at_start_of_line
, 0),
1130 UTIL_TEST(asprintf
, 0),