1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2015, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 #define CONTROL_PRIVATE
9 #define MEMPOOL_PRIVATE
15 #ifdef ENABLE_MEMPOOLS
17 #endif /* ENABLE_MEMPOOLS */
19 #include "util_process.h"
27 /* XXXX this is a minimal wrapper to make the unit tests compile with the
28 * changed tor_timegm interface. */
30 tor_timegm_wrapper(const struct tm
*tm
)
33 if (tor_timegm(tm
, &t
) < 0)
38 #define tor_timegm tor_timegm_wrapper
41 test_util_read_until_eof_impl(const char *fname
, size_t file_len
,
44 char *fifo_name
= NULL
;
45 char *test_str
= NULL
;
51 fifo_name
= tor_strdup(get_fname(fname
));
52 test_str
= tor_malloc(file_len
);
53 crypto_rand(test_str
, file_len
);
55 r
= write_bytes_to_file(fifo_name
, test_str
, file_len
, 1);
56 tt_int_op(r
, OP_EQ
, 0);
58 fd
= open(fifo_name
, O_RDONLY
|O_BINARY
);
59 tt_int_op(fd
, OP_GE
, 0);
60 str
= read_file_to_str_until_eof(fd
, read_limit
, &sz
);
61 tt_assert(str
!= NULL
);
63 if (read_limit
< file_len
)
64 tt_int_op(sz
, OP_EQ
, read_limit
);
66 tt_int_op(sz
, OP_EQ
, file_len
);
68 tt_mem_op(test_str
, OP_EQ
, str
, sz
);
69 tt_int_op(str
[sz
], OP_EQ
, '\0');
81 test_util_read_file_eof_tiny_limit(void *arg
)
84 // purposely set limit shorter than what we wrote to the FIFO to
85 // test the maximum, and that it puts the NUL in the right spot
87 test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
91 test_util_read_file_eof_one_loop_a(void *arg
)
94 test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
98 test_util_read_file_eof_one_loop_b(void *arg
)
101 test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
105 test_util_read_file_eof_two_loops(void *arg
)
108 // write more than 1024 bytes to the FIFO to test two passes through
109 // the loop in the method; if the re-alloc size is changed this
110 // should be updated as well.
112 test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
116 test_util_read_file_eof_two_loops_b(void *arg
)
120 test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
124 test_util_read_file_eof_zero_bytes(void *arg
)
128 test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
131 /* Test the basic expected behaviour for write_chunks_to_file.
132 * NOTE: This will need to be updated if we ever change the tempfile location
135 test_util_write_chunks_to_file(void *arg
)
138 char *tempname
= NULL
;
143 /* These should be two different sizes to ensure the data is different
144 * between the data file and the temp file's 'known string' */
145 int temp_str_len
= 1024;
146 int data_str_len
= 512;
147 char *data_str
= tor_malloc(data_str_len
);
148 char *temp_str
= tor_malloc(temp_str_len
);
150 smartlist_t
*chunks
= smartlist_new();
151 sized_chunk_t c
= {data_str
, data_str_len
/2};
152 sized_chunk_t c2
= {data_str
+ data_str_len
/2, data_str_len
/2};
155 crypto_rand(temp_str
, temp_str_len
);
156 crypto_rand(data_str
, data_str_len
);
158 // Ensure it can write multiple chunks
160 smartlist_add(chunks
, &c
);
161 smartlist_add(chunks
, &c2
);
164 * Check if it writes using a tempfile
166 fname
= tor_strdup(get_fname("write_chunks_with_tempfile"));
167 tor_asprintf(&tempname
, "%s.tmp", fname
);
169 // write a known string to a file where the tempfile will be
170 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
171 tt_int_op(r
, OP_EQ
, 0);
173 // call write_chunks_to_file
174 r
= write_chunks_to_file(fname
, chunks
, 1, 0);
175 tt_int_op(r
, OP_EQ
, 0);
177 // assert the file has been written (expected size)
178 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
179 tt_assert(str
!= NULL
);
180 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
181 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
184 // assert that the tempfile is removed (should not leave artifacts)
185 str
= read_file_to_str(tempname
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
186 tt_assert(str
== NULL
);
188 // Remove old testfile for second test
190 tt_int_op(r
, OP_EQ
, 0);
195 * Check if it skips using a tempfile with flags
197 fname
= tor_strdup(get_fname("write_chunks_with_no_tempfile"));
198 tor_asprintf(&tempname
, "%s.tmp", fname
);
200 // write a known string to a file where the tempfile will be
201 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
202 tt_int_op(r
, OP_EQ
, 0);
204 // call write_chunks_to_file with no_tempfile = true
205 r
= write_chunks_to_file(fname
, chunks
, 1, 1);
206 tt_int_op(r
, OP_EQ
, 0);
208 // assert the file has been written (expected size)
209 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
210 tt_assert(str
!= NULL
);
211 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
212 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
215 // assert the tempfile still contains the known string
216 str
= read_file_to_str(tempname
, RFTS_BIN
, &st
);
217 tt_assert(str
!= NULL
);
218 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, temp_str_len
);
219 tt_mem_op(temp_str
, OP_EQ
, str
, temp_str_len
);
224 smartlist_free(chunks
);
232 #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
233 /** test the minimum set of struct tm fields needed for a unique epoch value
234 * this is also the set we use to test tor_timegm */
235 #define TM_EQUAL(a, b) \
237 _TFE(a, b, tm_year); \
238 _TFE(a, b, tm_mon ); \
239 _TFE(a, b, tm_mday); \
240 _TFE(a, b, tm_hour); \
241 _TFE(a, b, tm_min ); \
242 _TFE(a, b, tm_sec ); \
246 test_util_time(void *arg
)
248 struct timeval start
, end
;
249 struct tm a_time
, b_time
;
259 start
.tv_usec
= 5000;
264 tt_int_op(0L,OP_EQ
, tv_udiff(&start
, &end
));
268 tt_int_op(2000L,OP_EQ
, tv_udiff(&start
, &end
));
272 tt_int_op(1002000L,OP_EQ
, tv_udiff(&start
, &end
));
276 tt_int_op(995000L,OP_EQ
, tv_udiff(&start
, &end
));
280 tt_int_op(-1005000L,OP_EQ
, tv_udiff(&start
, &end
));
282 /* Test tor_timegm & tor_gmtime_r */
284 /* The test values here are confirmed to be correct on a platform
285 * with a working timegm & gmtime_r. */
287 /* Start with known-zero a_time and b_time.
288 * This avoids passing uninitialised values to TM_EQUAL in a_time.
289 * Zeroing may not be needed for b_time, as long as tor_gmtime_r
290 * never reads the existing values in the structure.
291 * But we really don't want intermittently failing tests. */
292 memset(&a_time
, 0, sizeof(struct tm
));
293 memset(&b_time
, 0, sizeof(struct tm
));
295 a_time
.tm_year
= 2003-1900;
301 t_res
= 1062224095UL;
302 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
303 tor_gmtime_r(&t_res
, &b_time
);
304 TM_EQUAL(a_time
, b_time
);
306 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
307 t_res
= 1093846495UL;
308 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
309 tor_gmtime_r(&t_res
, &b_time
);
310 TM_EQUAL(a_time
, b_time
);
312 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
314 t_res
= 1076393695UL;
315 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
316 tor_gmtime_r(&t_res
, &b_time
);
317 TM_EQUAL(a_time
, b_time
);
320 t_res
= 1073715295UL;
321 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
322 tor_gmtime_r(&t_res
, &b_time
);
323 TM_EQUAL(a_time
, b_time
);
325 /* Test tor_timegm out of range */
329 /* Wrong year < 1970 */
330 a_time
.tm_year
= 1969-1900;
331 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
333 a_time
.tm_year
= -1-1900;
334 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
336 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
337 a_time
.tm_year
= -1*(1 << 16);
338 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
340 /* one of the smallest tm_year values my 64 bit system supports:
341 * t_res = -9223372036854775LL without clamping */
342 a_time
.tm_year
= -292275055-1900;
343 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
345 a_time
.tm_year
= INT32_MIN
;
346 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
350 a_time
.tm_year
= -1*(1 << 48);
351 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
353 /* while unlikely, the system's gmtime(_r) could return
354 * a "correct" retrospective gregorian negative year value,
355 * which I'm pretty sure is:
356 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
357 * 730485 is the number of days in two millenia, including leap days */
358 a_time
.tm_year
= -292277022657-1900;
359 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
361 a_time
.tm_year
= INT64_MIN
;
362 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
365 /* Wrong year >= INT32_MAX - 1900 */
366 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
367 a_time
.tm_year
= INT32_MAX
-1900;
368 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
370 a_time
.tm_year
= INT32_MAX
;
371 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
375 /* one of the largest tm_year values my 64 bit system supports */
376 a_time
.tm_year
= 292278994-1900;
377 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
379 /* while unlikely, the system's gmtime(_r) could return
380 * a "correct" proleptic gregorian year value,
381 * which I'm pretty sure is:
382 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
383 * 730485 is the number of days in two millenia, including leap days */
384 a_time
.tm_year
= 292277026596-1900;
385 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
387 a_time
.tm_year
= INT64_MAX
-1900;
388 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
390 a_time
.tm_year
= INT64_MAX
;
391 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
395 a_time
.tm_year
= 2007-1900; /* restore valid year */
397 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
398 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
400 a_time
.tm_mon
= -1; /* Wrong month */
401 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
404 a_time
.tm_mon
= 6; /* Try July */
405 a_time
.tm_mday
= 32; /* Wrong day */
406 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
408 a_time
.tm_mon
= 5; /* Try June */
409 a_time
.tm_mday
= 31; /* Wrong day */
410 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
412 a_time
.tm_year
= 2008-1900; /* Try a leap year */
413 a_time
.tm_mon
= 1; /* in feb. */
414 a_time
.tm_mday
= 30; /* Wrong day */
415 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
417 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
418 a_time
.tm_mon
= 1; /* in feb. */
419 a_time
.tm_mday
= 29; /* Wrong day */
420 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
422 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
423 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
426 a_time
.tm_mday
= 3; /* restore valid month day */
428 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
429 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
431 a_time
.tm_hour
= -1; /* Wrong hour */
432 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
435 a_time
.tm_hour
= 22; /* restore valid hour */
437 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
438 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
440 a_time
.tm_min
= -1; /* Wrong minute */
441 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
444 a_time
.tm_min
= 37; /* restore valid minute */
446 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
447 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
449 a_time
.tm_sec
= -1; /* Wrong second */
450 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
452 /* Test tor_gmtime_r out of range */
454 /* time_t < 0 yields a year clamped to 1 or 1970,
455 * depending on whether the implementation of the system gmtime(_r)
456 * sets struct tm (1) or not (1970) */
458 tor_gmtime_r(&t_res
, &b_time
);
459 tt_assert(b_time
.tm_year
== (1970-1900) ||
460 b_time
.tm_year
== (1969-1900));
462 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
463 t_res
= -1*(1 << 30);
464 tor_gmtime_r(&t_res
, &b_time
);
465 tt_assert(b_time
.tm_year
== (1970-1900) ||
466 b_time
.tm_year
== (1935-1900));
469 tor_gmtime_r(&t_res
, &b_time
);
470 tt_assert(b_time
.tm_year
== (1970-1900) ||
471 b_time
.tm_year
== (1901-1900));
474 #if SIZEOF_TIME_T == 8
476 /* one of the smallest tm_year values my 64 bit system supports:
477 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
478 t_res
= -9223372036854775LL;
479 tor_gmtime_r(&t_res
, &b_time
);
480 tt_assert(b_time
.tm_year
== (1970-1900) ||
481 b_time
.tm_year
== (1-1900));
483 /* while unlikely, the system's gmtime(_r) could return
484 * a "correct" retrospective gregorian negative year value,
485 * which I'm pretty sure is:
486 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
487 * 730485 is the number of days in two millenia, including leap days
488 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
490 tor_gmtime_r(&t_res
, &b_time
);
491 tt_assert(b_time
.tm_year
== (1970-1900) ||
492 b_time
.tm_year
== (1-1900));
496 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
497 * depending on whether the implementation of the system gmtime(_r)
498 * sets struct tm (9999) or not (2037) */
499 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
502 tor_gmtime_r(&t_res
, &b_time
);
503 tt_assert(b_time
.tm_year
== (2021-1900));
506 tor_gmtime_r(&t_res
, &b_time
);
507 tt_assert(b_time
.tm_year
== (2037-1900) ||
508 b_time
.tm_year
== (2038-1900));
512 #if SIZEOF_TIME_T == 8
514 /* one of the largest tm_year values my 64 bit system supports:
515 * b_time.tm_year == (292278994L-1900L) without clamping */
516 t_res
= 9223372036854775LL;
517 tor_gmtime_r(&t_res
, &b_time
);
518 tt_assert(b_time
.tm_year
== (2037-1900) ||
519 b_time
.tm_year
== (9999-1900));
521 /* while unlikely, the system's gmtime(_r) could return
522 * a "correct" proleptic gregorian year value,
523 * which I'm pretty sure is:
524 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
525 * 730485 is the number of days in two millenia, including leap days
526 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
528 tor_gmtime_r(&t_res
, &b_time
);
529 tt_assert(b_time
.tm_year
== (2037-1900) ||
530 b_time
.tm_year
== (9999-1900));
534 /* Test {format,parse}_rfc1123_time */
536 format_rfc1123_time(timestr
, 0);
537 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
538 format_rfc1123_time(timestr
, (time_t)1091580502UL);
539 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
542 i
= parse_rfc1123_time(timestr
, &t_res
);
543 tt_int_op(0,OP_EQ
, i
);
544 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
545 /* The timezone doesn't matter */
548 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
549 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
551 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
553 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
555 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
557 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
559 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
561 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
563 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
565 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
568 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
570 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
572 /* Test parse_iso_time */
575 i
= parse_iso_time("", &t_res
);
576 tt_int_op(-1,OP_EQ
, i
);
578 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
579 tt_int_op(-1,OP_EQ
, i
);
581 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
582 tt_int_op(-1,OP_EQ
, i
);
585 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
586 tt_int_op(0,OP_EQ
, i
);
587 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
589 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
590 tt_int_op(0,OP_EQ
, i
);
591 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
592 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
593 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
594 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
595 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
596 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
597 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
598 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
599 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
600 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
601 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
602 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
604 /* Test tor_gettimeofday */
607 end
.tv_usec
= 999990;
611 tor_gettimeofday(&start
);
612 /* now make sure time works. */
613 tor_gettimeofday(&end
);
614 /* We might've timewarped a little. */
615 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
617 /* Test format_iso_time */
619 tv
.tv_sec
= (time_t)1326296338;
621 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
622 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
623 /* The output of format_local_iso_time will vary by timezone, and setting
624 our timezone for testing purposes would be a nontrivial flaky pain.
625 Skip this test for now.
626 format_local_iso_time(timestr, tv.tv_sec);
627 test_streq("2012-01-11 10:38:58", timestr);
629 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
630 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
631 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
632 format_iso_time_nospace_usec(timestr
, &tv
);
633 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
634 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
641 test_util_parse_http_time(void *arg
)
644 char b
[ISO_TIME_LEN
+1];
648 format_iso_time(b, tor_timegm(&a_time)); \
649 tt_str_op(b, OP_EQ, (s)); \
653 /* Test parse_http_time */
656 parse_http_time("", &a_time
));
658 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
660 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
662 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
664 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
666 parse_http_time("Sunday, August the third", &a_time
));
668 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
671 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
672 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
673 T("1994-08-04 00:48:22");
675 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
676 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
677 T("1994-08-04 00:48:22");
679 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
680 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
681 T("1994-08-04 00:48:22");
683 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
684 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
685 T("1994-08-04 00:48:22");
687 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
688 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
689 T("1994-08-04 00:48:22");
691 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
692 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
693 T("1994-08-04 00:48:22");
694 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
695 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
696 T("1994-08-04 00:48:22");
697 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
698 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
699 T("1994-08-04 00:48:22");
700 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
701 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
702 T("1994-08-04 00:48:22");
703 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
704 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
705 T("2012-01-01 00:00:00");
706 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
707 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
708 T("2012-12-31 00:00:00");
709 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
710 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
711 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
712 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
713 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
714 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
715 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
716 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
724 test_util_config_line(void *arg
)
727 char *k
=NULL
, *v
=NULL
;
730 /* Test parse_config_line_from_str */
732 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
734 "k3 \n" "\n" " \n" "#comment\n"
735 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
736 "kseven \"a quoted 'string\"\n"
737 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
738 "k9 a line that\\\n spans two lines.\n\n"
739 "k10 more than\\\n one contin\\\nuation\n"
740 "k11 \\\ncontinuation at the start\n"
741 "k12 line with a\\\n#comment\n embedded\n"
742 "k13\\\ncontinuation at the very start\n"
743 "k14 a line that has a comment and # ends with a slash \\\n"
744 "k15 this should be the next new line\n"
745 "k16 a line that has a comment and # ends without a slash \n"
746 "k17 this should be the next new line\n"
750 str
= parse_config_line_from_str(str
, &k
, &v
);
751 tt_str_op(k
,OP_EQ
, "k");
752 tt_str_op(v
,OP_EQ
, "v");
753 tor_free(k
); tor_free(v
);
754 tt_assert(!strcmpstart(str
, "key value with"));
756 str
= parse_config_line_from_str(str
, &k
, &v
);
757 tt_str_op(k
,OP_EQ
, "key");
758 tt_str_op(v
,OP_EQ
, "value with spaces");
759 tor_free(k
); tor_free(v
);
760 tt_assert(!strcmpstart(str
, "keykey"));
762 str
= parse_config_line_from_str(str
, &k
, &v
);
763 tt_str_op(k
,OP_EQ
, "keykey");
764 tt_str_op(v
,OP_EQ
, "val");
765 tor_free(k
); tor_free(v
);
766 tt_assert(!strcmpstart(str
, "k2\n"));
768 str
= parse_config_line_from_str(str
, &k
, &v
);
769 tt_str_op(k
,OP_EQ
, "k2");
770 tt_str_op(v
,OP_EQ
, "");
771 tor_free(k
); tor_free(v
);
772 tt_assert(!strcmpstart(str
, "k3 \n"));
774 str
= parse_config_line_from_str(str
, &k
, &v
);
775 tt_str_op(k
,OP_EQ
, "k3");
776 tt_str_op(v
,OP_EQ
, "");
777 tor_free(k
); tor_free(v
);
778 tt_assert(!strcmpstart(str
, "#comment"));
780 str
= parse_config_line_from_str(str
, &k
, &v
);
781 tt_str_op(k
,OP_EQ
, "k4");
782 tt_str_op(v
,OP_EQ
, "");
783 tor_free(k
); tor_free(v
);
784 tt_assert(!strcmpstart(str
, "k5#abc"));
786 str
= parse_config_line_from_str(str
, &k
, &v
);
787 tt_str_op(k
,OP_EQ
, "k5");
788 tt_str_op(v
,OP_EQ
, "");
789 tor_free(k
); tor_free(v
);
790 tt_assert(!strcmpstart(str
, "k6"));
792 str
= parse_config_line_from_str(str
, &k
, &v
);
793 tt_str_op(k
,OP_EQ
, "k6");
794 tt_str_op(v
,OP_EQ
, "val");
795 tor_free(k
); tor_free(v
);
796 tt_assert(!strcmpstart(str
, "kseven"));
798 str
= parse_config_line_from_str(str
, &k
, &v
);
799 tt_str_op(k
,OP_EQ
, "kseven");
800 tt_str_op(v
,OP_EQ
, "a quoted \'string");
801 tor_free(k
); tor_free(v
);
802 tt_assert(!strcmpstart(str
, "k8 "));
804 str
= parse_config_line_from_str(str
, &k
, &v
);
805 tt_str_op(k
,OP_EQ
, "k8");
806 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
807 tor_free(k
); tor_free(v
);
809 str
= parse_config_line_from_str(str
, &k
, &v
);
810 tt_str_op(k
,OP_EQ
, "k9");
811 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
812 tor_free(k
); tor_free(v
);
814 str
= parse_config_line_from_str(str
, &k
, &v
);
815 tt_str_op(k
,OP_EQ
, "k10");
816 tt_str_op(v
,OP_EQ
, "more than one continuation");
817 tor_free(k
); tor_free(v
);
819 str
= parse_config_line_from_str(str
, &k
, &v
);
820 tt_str_op(k
,OP_EQ
, "k11");
821 tt_str_op(v
,OP_EQ
, "continuation at the start");
822 tor_free(k
); tor_free(v
);
824 str
= parse_config_line_from_str(str
, &k
, &v
);
825 tt_str_op(k
,OP_EQ
, "k12");
826 tt_str_op(v
,OP_EQ
, "line with a embedded");
827 tor_free(k
); tor_free(v
);
829 str
= parse_config_line_from_str(str
, &k
, &v
);
830 tt_str_op(k
,OP_EQ
, "k13");
831 tt_str_op(v
,OP_EQ
, "continuation at the very start");
832 tor_free(k
); tor_free(v
);
834 str
= parse_config_line_from_str(str
, &k
, &v
);
835 tt_str_op(k
,OP_EQ
, "k14");
836 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
837 tor_free(k
); tor_free(v
);
839 str
= parse_config_line_from_str(str
, &k
, &v
);
840 tt_str_op(k
,OP_EQ
, "k15");
841 tt_str_op(v
,OP_EQ
, "this should be the next new line");
842 tor_free(k
); tor_free(v
);
844 str
= parse_config_line_from_str(str
, &k
, &v
);
845 tt_str_op(k
,OP_EQ
, "k16");
846 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
847 tor_free(k
); tor_free(v
);
849 str
= parse_config_line_from_str(str
, &k
, &v
);
850 tt_str_op(k
,OP_EQ
, "k17");
851 tt_str_op(v
,OP_EQ
, "this should be the next new line");
852 tor_free(k
); tor_free(v
);
854 tt_str_op(str
,OP_EQ
, "");
862 test_util_config_line_quotes(void *arg
)
868 char *k
=NULL
, *v
=NULL
;
871 /* Test parse_config_line_from_str */
873 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
874 "kTrailingGarbage \"quoted value\"trailing garbage\n"
876 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
878 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
880 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
884 str
= parse_config_line_from_str(str
, &k
, &v
);
885 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
886 tt_str_op(v
,OP_EQ
, "quoted value");
887 tor_free(k
); tor_free(v
);
889 str
= parse_config_line_from_str(str
, &k
, &v
);
890 tt_ptr_op(str
,OP_EQ
, NULL
);
891 tor_free(k
); tor_free(v
);
895 str
= parse_config_line_from_str(str
, &k
, &v
);
896 tt_ptr_op(str
,OP_EQ
, NULL
);
897 tor_free(k
); tor_free(v
);
901 str
= parse_config_line_from_str(str
, &k
, &v
);
902 tt_ptr_op(str
,OP_EQ
, NULL
);
903 tor_free(k
); tor_free(v
);
907 str
= parse_config_line_from_str(str
, &k
, &v
);
908 tt_ptr_op(str
,OP_EQ
, NULL
);
909 tor_free(k
); tor_free(v
);
917 test_util_config_line_comment_character(void *arg
)
920 char *k
=NULL
, *v
=NULL
;
923 /* Test parse_config_line_from_str */
925 strlcpy(buf
, "k1 \"# in quotes\"\n"
926 "k2 some value # some comment\n"
927 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
931 str
= parse_config_line_from_str(str
, &k
, &v
);
932 tt_str_op(k
,OP_EQ
, "k1");
933 tt_str_op(v
,OP_EQ
, "# in quotes");
934 tor_free(k
); tor_free(v
);
936 str
= parse_config_line_from_str(str
, &k
, &v
);
937 tt_str_op(k
,OP_EQ
, "k2");
938 tt_str_op(v
,OP_EQ
, "some value");
939 tor_free(k
); tor_free(v
);
941 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
944 str
= parse_config_line_from_str(str
, &k
, &v
);
946 test_streq(v
, "/home/user/myTorNetwork#2");
947 tor_free(k
); tor_free(v
);
958 test_util_config_line_escaped_content(void *arg
)
966 char *k
=NULL
, *v
=NULL
;
969 /* Test parse_config_line_from_str */
971 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
972 "HexadecimalUpper \"\\x2A\"\n"
973 "HexadecimalUpperX \"\\X2A\"\n"
977 "CarriageReturn \"\\r\"\n"
978 "DoubleQuote \"\\\"\"\n"
979 "SimpleQuote \"\\'\"\n"
980 "Backslash \"\\\\\"\n"
981 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
984 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
987 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
990 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
993 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
996 strlcpy(buf6
, "BrokenEscape \"\\"
1001 str
= parse_config_line_from_str(str
, &k
, &v
);
1002 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1003 tt_str_op(v
,OP_EQ
, "*");
1004 tor_free(k
); tor_free(v
);
1006 str
= parse_config_line_from_str(str
, &k
, &v
);
1007 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1008 tt_str_op(v
,OP_EQ
, "*");
1009 tor_free(k
); tor_free(v
);
1011 str
= parse_config_line_from_str(str
, &k
, &v
);
1012 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1013 tt_str_op(v
,OP_EQ
, "*");
1014 tor_free(k
); tor_free(v
);
1016 str
= parse_config_line_from_str(str
, &k
, &v
);
1017 tt_str_op(k
,OP_EQ
, "Octal");
1018 tt_str_op(v
,OP_EQ
, "*");
1019 tor_free(k
); tor_free(v
);
1021 str
= parse_config_line_from_str(str
, &k
, &v
);
1022 tt_str_op(k
,OP_EQ
, "Newline");
1023 tt_str_op(v
,OP_EQ
, "\n");
1024 tor_free(k
); tor_free(v
);
1026 str
= parse_config_line_from_str(str
, &k
, &v
);
1027 tt_str_op(k
,OP_EQ
, "Tab");
1028 tt_str_op(v
,OP_EQ
, "\t");
1029 tor_free(k
); tor_free(v
);
1031 str
= parse_config_line_from_str(str
, &k
, &v
);
1032 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1033 tt_str_op(v
,OP_EQ
, "\r");
1034 tor_free(k
); tor_free(v
);
1036 str
= parse_config_line_from_str(str
, &k
, &v
);
1037 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1038 tt_str_op(v
,OP_EQ
, "\"");
1039 tor_free(k
); tor_free(v
);
1041 str
= parse_config_line_from_str(str
, &k
, &v
);
1042 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1043 tt_str_op(v
,OP_EQ
, "'");
1044 tor_free(k
); tor_free(v
);
1046 str
= parse_config_line_from_str(str
, &k
, &v
);
1047 tt_str_op(k
,OP_EQ
, "Backslash");
1048 tt_str_op(v
,OP_EQ
, "\\");
1049 tor_free(k
); tor_free(v
);
1051 str
= parse_config_line_from_str(str
, &k
, &v
);
1052 tt_str_op(k
,OP_EQ
, "Mix");
1053 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1054 tor_free(k
); tor_free(v
);
1055 tt_str_op(str
,OP_EQ
, "");
1059 str
= parse_config_line_from_str(str
, &k
, &v
);
1060 tt_ptr_op(str
,OP_EQ
, NULL
);
1061 tor_free(k
); tor_free(v
);
1065 str
= parse_config_line_from_str(str
, &k
, &v
);
1066 tt_ptr_op(str
,OP_EQ
, NULL
);
1067 tor_free(k
); tor_free(v
);
1071 str
= parse_config_line_from_str(str
, &k
, &v
);
1072 tt_ptr_op(str
,OP_EQ
, NULL
);
1073 tor_free(k
); tor_free(v
);
1078 str
= parse_config_line_from_str(str
, &k
, &v
);
1079 tt_ptr_op(str
, OP_EQ
, NULL
);
1080 tor_free(k
); tor_free(v
);
1085 str
= parse_config_line_from_str(str
, &k
, &v
);
1086 tt_ptr_op(str
,OP_EQ
, NULL
);
1087 tor_free(k
); tor_free(v
);
1096 test_util_expand_filename(void *arg
)
1101 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
1103 str
= expand_filename("");
1104 tt_str_op("",OP_EQ
, str
);
1107 str
= expand_filename("/normal/path");
1108 tt_str_op("/normal/path",OP_EQ
, str
);
1111 str
= expand_filename("/normal/trailing/path/");
1112 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
1115 str
= expand_filename("~");
1116 tt_str_op("/home/itv/",OP_EQ
, str
);
1119 str
= expand_filename("$HOME/nodice");
1120 tt_str_op("$HOME/nodice",OP_EQ
, str
);
1123 str
= expand_filename("~/");
1124 tt_str_op("/home/itv/",OP_EQ
, str
);
1127 str
= expand_filename("~/foobarqux");
1128 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
1131 str
= expand_filename("~/../../etc/passwd");
1132 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
1135 str
= expand_filename("~/trailing/");
1136 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
1138 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
1139 have to somehow inject/fake the get_user_homedir call) */
1141 /* $HOME ending in a trailing slash */
1142 setenv("HOME", "/home/itv/", 1);
1144 str
= expand_filename("~");
1145 tt_str_op("/home/itv/",OP_EQ
, str
);
1148 str
= expand_filename("~/");
1149 tt_str_op("/home/itv/",OP_EQ
, str
);
1152 str
= expand_filename("~/foo");
1153 tt_str_op("/home/itv/foo",OP_EQ
, str
);
1156 /* Try with empty $HOME */
1158 setenv("HOME", "", 1);
1160 str
= expand_filename("~");
1161 tt_str_op("/",OP_EQ
, str
);
1164 str
= expand_filename("~/");
1165 tt_str_op("/",OP_EQ
, str
);
1168 str
= expand_filename("~/foobar");
1169 tt_str_op("/foobar",OP_EQ
, str
);
1172 /* Try with $HOME unset */
1176 str
= expand_filename("~");
1177 tt_str_op("/",OP_EQ
, str
);
1180 str
= expand_filename("~/");
1181 tt_str_op("/",OP_EQ
, str
);
1184 str
= expand_filename("~/foobar");
1185 tt_str_op("/foobar",OP_EQ
, str
);
1193 /** Test tor_escape_str_for_pt_args(). */
1195 test_util_escape_string_socks(void *arg
)
1197 char *escaped_string
= NULL
;
1199 /** Simple backslash escape. */
1201 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
1202 tt_assert(escaped_string
);
1203 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
1204 tor_free(escaped_string
);
1206 /** Simple semicolon escape. */
1207 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
1208 tt_assert(escaped_string
);
1209 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
1210 tor_free(escaped_string
);
1212 /** Empty string. */
1213 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
1214 tt_assert(escaped_string
);
1215 tt_str_op(escaped_string
,OP_EQ
, "");
1216 tor_free(escaped_string
);
1218 /** Escape all characters. */
1219 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
1220 tt_assert(escaped_string
);
1221 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
1222 tor_free(escaped_string
);
1224 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
1225 tt_assert(escaped_string
);
1226 tt_str_op(escaped_string
,OP_EQ
, "\\;");
1227 tor_free(escaped_string
);
1230 tor_free(escaped_string
);
1234 test_util_string_is_key_value(void *ptr
)
1237 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
1238 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
1239 tt_assert(string_is_key_value(LOG_WARN
, "key="));
1240 tt_assert(string_is_key_value(LOG_WARN
, "x="));
1241 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
1242 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
1243 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
1244 tt_assert(!string_is_key_value(LOG_WARN
, "="));
1247 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
1252 /** Test basic string functionality. */
1254 test_util_strmisc(void *arg
)
1258 char *cp
, *cp_tmp
= NULL
;
1260 /* Test strl operations */
1262 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
1263 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
1264 tt_str_op(buf
,OP_EQ
, "Hello");
1265 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
1266 tt_str_op(buf
,OP_EQ
, "Hello");
1267 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
1268 tt_str_op(buf
,OP_EQ
, "Hell");
1269 strlcpy(buf
, "Hello", sizeof(buf
));
1270 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
1272 /* Test strstrip() */
1273 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
1274 tor_strstrip(buf
, ",!");
1275 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
1276 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
1277 tor_strstrip(buf
, "!? ");
1278 tt_str_op(buf
,OP_EQ
, "Testing123");
1279 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
1280 tor_strstrip(buf
, "!? ");
1281 tt_str_op(buf
,OP_EQ
, "Testing123");
1283 /* Test parse_long */
1284 /* Empty/zero input */
1285 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
1286 tt_int_op(0,OP_EQ
, i
);
1287 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
1288 tt_int_op(1,OP_EQ
, i
);
1290 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
1291 tt_int_op(1,OP_EQ
, i
);
1292 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
1293 tt_int_op(1,OP_EQ
, i
);
1294 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
1295 tt_int_op(1,OP_EQ
, i
);
1296 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
1297 tt_int_op(1,OP_EQ
, i
);
1298 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
1299 tt_int_op(1,OP_EQ
, i
);
1300 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
1301 tt_int_op(1,OP_EQ
, i
);
1303 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
1304 tt_int_op(0,OP_EQ
, i
);
1305 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
1306 tt_int_op(0,OP_EQ
, i
);
1307 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
1308 tt_int_op(1,OP_EQ
, i
);
1309 tt_str_op(cp
,OP_EQ
, "m");
1310 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
1311 tt_int_op(1,OP_EQ
, i
);
1312 tt_str_op(cp
,OP_EQ
, " plus garbage");
1314 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
1315 tt_int_op(0,OP_EQ
, i
);
1316 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
1317 tt_int_op(0,OP_EQ
, i
);
1318 /* Base different than 10 */
1319 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
1320 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
1321 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
1322 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
1323 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
1324 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
1325 tt_int_op(i
,OP_EQ
, 0);
1327 /* Test parse_ulong */
1328 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
1329 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
1330 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
1331 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
1332 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
1333 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
1334 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
1335 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
1336 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,-100,100,NULL
,NULL
));
1337 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
1338 tt_int_op(0,OP_EQ
, i
);
1340 /* Test parse_uint64 */
1341 tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
1342 tt_int_op(1,OP_EQ
, i
);
1343 tt_str_op(cp
,OP_EQ
, " x");
1344 tt_assert(U64_LITERAL(12345678901) ==
1345 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
1346 tt_int_op(1,OP_EQ
, i
);
1347 tt_str_op(cp
,OP_EQ
, "");
1348 tt_assert(U64_LITERAL(0) ==
1349 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
1350 tt_int_op(0,OP_EQ
, i
);
1351 tt_assert(U64_LITERAL(0) ==
1352 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
1353 tt_int_op(0,OP_EQ
, i
);
1356 /* Test parse_double */
1357 double d
= tor_parse_double("10", 0, UINT64_MAX
,&i
,NULL
);
1358 tt_int_op(1,OP_EQ
, i
);
1359 tt_assert(DBL_TO_U64(d
) == 10);
1360 d
= tor_parse_double("0", 0, UINT64_MAX
,&i
,NULL
);
1361 tt_int_op(1,OP_EQ
, i
);
1362 tt_assert(DBL_TO_U64(d
) == 0);
1363 d
= tor_parse_double(" ", 0, UINT64_MAX
,&i
,NULL
);
1364 tt_int_op(0,OP_EQ
, i
);
1365 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,NULL
);
1366 tt_int_op(0,OP_EQ
, i
);
1367 d
= tor_parse_double(".0a", 0, UINT64_MAX
,&i
,&cp
);
1368 tt_int_op(1,OP_EQ
, i
);
1369 d
= tor_parse_double("-.0", 0, UINT64_MAX
,&i
,NULL
);
1370 tt_int_op(1,OP_EQ
, i
);
1371 tt_assert(DBL_TO_U64(d
) == 0);
1372 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
1373 tt_int_op(1,OP_EQ
, i
);
1374 tt_int_op(-10.0,OP_EQ
, d
);
1378 /* Test tor_parse_* where we overflow/underflow the underlying type. */
1379 /* This string should overflow 64-bit ints. */
1380 #define TOOBIG "100000000000000000000000000"
1381 tt_int_op(0L, OP_EQ
,
1382 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
1383 tt_int_op(i
,OP_EQ
, 0);
1385 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
1386 tt_int_op(i
,OP_EQ
, 0);
1387 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
1388 tt_int_op(i
,OP_EQ
, 0);
1389 tt_u64_op(U64_LITERAL(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
1390 0, UINT64_MAX
, &i
, NULL
));
1391 tt_int_op(i
,OP_EQ
, 0);
1395 /* Returning -1 when there's not enough room in the output buffer */
1396 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
1397 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
1398 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
1399 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
1400 /* Always NUL-terminate the output */
1401 tor_snprintf(buf
, 5, "abcdef");
1402 tt_int_op(0,OP_EQ
, buf
[4]);
1403 tor_snprintf(buf
, 10, "abcdef");
1404 tt_int_op(0,OP_EQ
, buf
[6]);
1406 tor_snprintf(buf
, sizeof(buf
), "x!"U64_FORMAT
"!x",
1407 U64_PRINTF_ARG(U64_LITERAL(12345678901)));
1408 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
1410 /* Test str{,case}cmpstart */
1411 tt_assert(strcmpstart("abcdef", "abcdef")==0);
1412 tt_assert(strcmpstart("abcdef", "abc")==0);
1413 tt_assert(strcmpstart("abcdef", "abd")<0);
1414 tt_assert(strcmpstart("abcdef", "abb")>0);
1415 tt_assert(strcmpstart("ab", "abb")<0);
1416 tt_assert(strcmpstart("ab", "")==0);
1417 tt_assert(strcmpstart("ab", "ab ")<0);
1418 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
1419 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
1420 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
1421 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
1422 tt_assert(strcasecmpstart("ab", "Abb")<0);
1423 tt_assert(strcasecmpstart("ab", "")==0);
1424 tt_assert(strcasecmpstart("ab", "ab ")<0);
1426 /* Test str{,case}cmpend */
1427 tt_assert(strcmpend("abcdef", "abcdef")==0);
1428 tt_assert(strcmpend("abcdef", "def")==0);
1429 tt_assert(strcmpend("abcdef", "deg")<0);
1430 tt_assert(strcmpend("abcdef", "dee")>0);
1431 tt_assert(strcmpend("ab", "aab")>0);
1432 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
1433 tt_assert(strcasecmpend("abcdef", "dEF")==0);
1434 tt_assert(strcasecmpend("abcdef", "Deg")<0);
1435 tt_assert(strcasecmpend("abcDef", "dee")>0);
1436 tt_assert(strcasecmpend("AB", "abb")<0);
1438 /* Test digest_is_zero */
1441 tt_assert(tor_digest_is_zero(buf
));
1443 tt_assert(!tor_digest_is_zero(buf
));
1445 /* Test mem_is_zero */
1448 tt_assert(tor_mem_is_zero(buf
, 10));
1449 tt_assert(tor_mem_is_zero(buf
, 20));
1450 tt_assert(tor_mem_is_zero(buf
, 128));
1451 tt_assert(!tor_mem_is_zero(buf
, 129));
1452 buf
[60] = (char)255;
1453 tt_assert(!tor_mem_is_zero(buf
, 128));
1455 tt_assert(!tor_mem_is_zero(buf
, 10));
1457 /* Test 'escaped' */
1458 tt_assert(NULL
== escaped(NULL
));
1459 tt_str_op("\"\"",OP_EQ
, escaped(""));
1460 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
1461 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
1462 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
1463 escaped("unnecessary \'backslashes\'"));
1464 /* Non-printable characters appear as octal */
1465 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
1466 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
1468 /* Test strndup and memdup */
1470 const char *s
= "abcdefghijklmnopqrstuvwxyz";
1471 cp_tmp
= tor_strndup(s
, 30);
1472 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
1473 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
1476 cp_tmp
= tor_strndup(s
, 5);
1477 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
1480 s
= "a\0b\0c\0d\0e\0";
1481 cp_tmp
= tor_memdup(s
,10);
1482 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
1483 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
1487 /* Test str-foo functions */
1488 cp_tmp
= tor_strdup("abcdef");
1489 tt_assert(tor_strisnonupper(cp_tmp
));
1491 tt_assert(!tor_strisnonupper(cp_tmp
));
1492 tor_strupper(cp_tmp
);
1493 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
1494 tor_strlower(cp_tmp
);
1495 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
1496 tt_assert(tor_strisnonupper(cp_tmp
));
1497 tt_assert(tor_strisprint(cp_tmp
));
1499 tt_assert(!tor_strisprint(cp_tmp
));
1502 /* Test memmem and memstr */
1504 const char *haystack
= "abcde";
1505 tt_assert(!tor_memmem(haystack
, 5, "ef", 2));
1506 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
1507 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
1508 tt_assert(!tor_memmem(haystack
, 4, "cde", 3));
1509 haystack
= "ababcad";
1510 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
1511 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
1512 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
1513 tt_assert(!tor_memmem(haystack
, 7, "dadad", 5));
1514 tt_assert(!tor_memmem(haystack
, 7, "abcdefghij", 10));
1516 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
1517 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
1518 tt_assert(!tor_memstr(haystack
, 6, "cad"));
1519 tt_assert(!tor_memstr(haystack
, 7, "cadd"));
1520 tt_assert(!tor_memstr(haystack
, 7, "fe"));
1521 tt_assert(!tor_memstr(haystack
, 7, "ababcade"));
1526 char binary_data
[68];
1528 for (i
= 0; i
< sizeof(binary_data
); ++i
)
1530 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
1531 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
1532 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
1533 "000102030405060708090A0B0C0D0E0F10");
1534 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
1535 "000102030405060708090A0B0C0D0E0F"
1536 "101112131415161718191A1B1C1D1E1F");
1537 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
1538 "000102030405060708090A0B0C0D0E0F"
1539 "101112131415161718191A1B1C1D1E1F");
1540 /* Repeat these tests for shorter strings after longer strings
1541 have been tried, to make sure we're correctly terminating strings */
1542 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
1543 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
1546 /* Test strcmp_opt */
1547 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
1548 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
1549 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
1551 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
1552 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
1553 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
1555 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
1556 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
1558 /* Test strcmp_len */
1559 tt_int_op(strcmp_len("foo", "bar", 3), OP_GT
, 0);
1560 tt_int_op(strcmp_len("foo", "bar", 2), OP_LT
, 0);
1561 tt_int_op(strcmp_len("foo2", "foo1", 4), OP_GT
, 0);
1562 tt_int_op(strcmp_len("foo2", "foo1", 3), OP_LT
, 0); /* Really stop at len */
1563 tt_int_op(strcmp_len("foo2", "foo", 3), OP_EQ
, 0); /* Really stop at len */
1564 tt_int_op(strcmp_len("blah", "", 4), OP_GT
, 0);
1565 tt_int_op(strcmp_len("blah", "", 0), OP_EQ
, 0);
1572 test_util_pow2(void *arg
)
1574 /* Test tor_log2(). */
1576 tt_int_op(tor_log2(64),OP_EQ
, 6);
1577 tt_int_op(tor_log2(65),OP_EQ
, 6);
1578 tt_int_op(tor_log2(63),OP_EQ
, 5);
1579 /* incorrect mathematically, but as specified: */
1580 tt_int_op(tor_log2(0),OP_EQ
, 0);
1581 tt_int_op(tor_log2(1),OP_EQ
, 0);
1582 tt_int_op(tor_log2(2),OP_EQ
, 1);
1583 tt_int_op(tor_log2(3),OP_EQ
, 1);
1584 tt_int_op(tor_log2(4),OP_EQ
, 2);
1585 tt_int_op(tor_log2(5),OP_EQ
, 2);
1586 tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),OP_EQ
, 55);
1587 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
1589 /* Test round_to_power_of_2 */
1590 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
1591 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
1592 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
1593 tt_u64_op(round_to_power_of_2(U64_LITERAL(40000000000000000)), OP_EQ
,
1594 U64_LITERAL(1)<<55);
1595 tt_u64_op(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)), OP_EQ
,
1596 U64_LITERAL(1)<<63);
1597 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
1598 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
1599 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
1600 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
1601 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
1602 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
1603 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
1604 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
1610 /** Run unit tests for compression functions */
1612 test_util_gzip(void *arg
)
1614 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
1617 tor_zlib_state_t
*state
= NULL
;
1620 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
1621 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
1622 if (is_gzip_supported()) {
1623 tt_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1626 tt_assert(len1
< strlen(buf1
));
1627 tt_assert(detect_compression_method(buf2
, len1
) == GZIP_METHOD
);
1629 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
1630 GZIP_METHOD
, 1, LOG_INFO
));
1632 tt_int_op(strlen(buf1
) + 1,OP_EQ
, len2
);
1633 tt_str_op(buf1
,OP_EQ
, buf3
);
1639 tt_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1642 tt_assert(detect_compression_method(buf2
, len1
) == ZLIB_METHOD
);
1644 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
,
1645 ZLIB_METHOD
, 1, LOG_INFO
));
1647 tt_int_op(strlen(buf1
) + 1,OP_EQ
, len2
);
1648 tt_str_op(buf1
,OP_EQ
, buf3
);
1650 /* Check whether we can uncompress concatenated, compressed strings. */
1652 buf2
= tor_reallocarray(buf2
, len1
, 2);
1653 memcpy(buf2
+len1
, buf2
, len1
);
1654 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
*2,
1655 ZLIB_METHOD
, 1, LOG_INFO
));
1656 tt_int_op((strlen(buf1
)+1)*2,OP_EQ
, len2
);
1657 tt_mem_op(buf3
,OP_EQ
,
1658 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
1659 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
1660 (strlen(buf1
)+1)*2);
1666 /* Check whether we can uncompress partial strings. */
1668 tor_strdup("String with low redundancy that won't be compressed much.");
1669 tt_assert(!tor_gzip_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1,
1672 /* when we allow an incomplete string, we should succeed.*/
1673 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
1674 ZLIB_METHOD
, 0, LOG_INFO
));
1675 tt_assert(len2
> 5);
1677 tt_assert(!strcmpstart(buf1
, buf3
));
1679 /* when we demand a complete string, this must fail. */
1681 tt_assert(tor_gzip_uncompress(&buf3
, &len2
, buf2
, len1
-16,
1682 ZLIB_METHOD
, 1, LOG_INFO
));
1685 /* Now, try streaming compression. */
1689 state
= tor_zlib_new(1, ZLIB_METHOD
, HIGH_COMPRESSION
);
1691 cp1
= buf1
= tor_malloc(1024);
1693 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
1695 tt_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0)
1697 tt_int_op(0,OP_EQ
, len2
); /* Make sure we compressed it all. */
1698 tt_assert(cp1
> buf1
);
1702 tt_assert(tor_zlib_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1)
1704 tt_int_op(0,OP_EQ
, len2
);
1705 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
1707 tt_assert(!tor_gzip_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
1708 ZLIB_METHOD
, 1, LOG_WARN
));
1709 /* Make sure it compressed right. */
1710 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
1711 tt_int_op(21,OP_EQ
, len2
);
1715 tor_zlib_free(state
);
1721 /** Run unit tests for mmap() wrapper functionality. */
1723 test_util_mmap(void *arg
)
1725 char *fname1
= tor_strdup(get_fname("mapped_1"));
1726 char *fname2
= tor_strdup(get_fname("mapped_2"));
1727 char *fname3
= tor_strdup(get_fname("mapped_3"));
1728 const size_t buflen
= 17000;
1729 char *buf
= tor_malloc(17000);
1730 tor_mmap_t
*mapping
= NULL
;
1733 crypto_rand(buf
, buflen
);
1735 mapping
= tor_mmap_file(fname1
);
1736 tt_assert(! mapping
);
1738 write_str_to_file(fname1
, "Short file.", 1);
1740 mapping
= tor_mmap_file(fname1
);
1742 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
1743 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
1745 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
1747 tt_assert(unlink(fname1
) == 0);
1749 /* make sure we can unlink. */
1750 tt_assert(unlink(fname1
) == 0);
1751 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
1752 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
1756 /* Now a zero-length file. */
1757 write_str_to_file(fname1
, "", 1);
1758 mapping
= tor_mmap_file(fname1
);
1759 tt_ptr_op(mapping
,OP_EQ
, NULL
);
1760 tt_int_op(ERANGE
,OP_EQ
, errno
);
1763 /* Make sure that we fail to map a no-longer-existent file. */
1764 mapping
= tor_mmap_file(fname1
);
1765 tt_assert(! mapping
);
1767 /* Now try a big file that stretches across a few pages and isn't aligned */
1768 write_bytes_to_file(fname2
, buf
, buflen
, 1);
1769 mapping
= tor_mmap_file(fname2
);
1771 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
1772 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
1773 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
1776 /* Now try a big aligned file. */
1777 write_bytes_to_file(fname3
, buf
, 16384, 1);
1778 mapping
= tor_mmap_file(fname3
);
1780 tt_int_op(mapping
->size
,OP_EQ
, 16384);
1781 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
1782 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
1795 tor_munmap_file(mapping
);
1798 /** Run unit tests for escaping/unescaping data for use by controllers. */
1800 test_util_control_formats(void *arg
)
1804 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
1808 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
1809 tt_str_op(out
,OP_EQ
,
1810 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
1811 tt_int_op(sz
,OP_EQ
, strlen(out
));
1817 #define test_feq(value1,value2) do { \
1818 double v1 = (value1), v2=(value2); \
1819 double tf_diff = v1-v2; \
1820 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
1821 if (tf_diff<0) tf_diff=-tf_diff; \
1822 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
1823 if (tf_diff<tf_tolerance) { \
1824 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
1826 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
1831 test_util_sscanf(void *arg
)
1833 unsigned u1
, u2
, u3
;
1835 char s1
[20], s2
[10], s3
[10], ch
;
1841 /* Simple tests (malformed patterns, literal matching, ...) */
1843 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
1845 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
1846 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
1847 tt_int_op(-1,OP_EQ
, tor_sscanf("prettylongstring", "%999999s", s1
));
1849 /* GCC thinks these two are illegal. */
1850 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
1851 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
1853 /* No '%'-strings: always "success" */
1854 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
1855 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
1858 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
1859 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
1861 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
1863 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
1865 /* Numbers (ie. %u) */
1867 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
1868 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
1869 tt_int_op(12345u,OP_EQ
, u1
);
1870 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
1871 tt_int_op(12346u,OP_EQ
, u1
);
1872 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
1873 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
1874 tt_int_op(12348u,OP_EQ
, u1
);
1875 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
1876 tt_int_op(0u,OP_EQ
, u1
);
1877 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
1878 tt_int_op(0u,OP_EQ
, u2
);
1879 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
1880 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
1881 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
1883 /* Numbers with size (eg. %2u) */
1884 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
1885 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
1886 tt_int_op(12u,OP_EQ
, u1
);
1887 tt_int_op(3456u,OP_EQ
, u2
);
1888 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
1889 tt_int_op(123456u,OP_EQ
, u1
);
1890 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
1891 tt_int_op(123457u,OP_EQ
, u1
);
1892 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
1893 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
1894 tt_int_op(12u,OP_EQ
, u1
);
1895 tt_int_op(3u,OP_EQ
, u2
);
1896 tt_int_op(456u,OP_EQ
, u3
);
1898 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
1899 tt_int_op(67u,OP_EQ
, u1
);
1900 tt_int_op(8u,OP_EQ
, u2
);
1901 tt_int_op(99u,OP_EQ
, u3
);
1902 /* %u does not match space.*/
1903 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
1904 tt_int_op(12u,OP_EQ
, u1
);
1905 tt_int_op(3u,OP_EQ
, u2
);
1906 /* %u does not match negative numbers. */
1907 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
1908 tt_int_op(67u,OP_EQ
, u1
);
1909 tt_int_op(8u,OP_EQ
, u2
);
1910 /* Arbitrary amounts of 0-padding are okay */
1911 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
1913 tt_int_op(12u,OP_EQ
, u1
);
1914 tt_int_op(3u,OP_EQ
, u2
);
1915 tt_int_op(99u,OP_EQ
, u3
);
1919 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
1920 tt_int_op(0x1234,OP_EQ
, u1
);
1921 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
1922 tt_int_op(0xFF,OP_EQ
, u3
);
1923 /* Width works on %x */
1924 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
1925 tt_int_op(0xf00d,OP_EQ
, u1
);
1926 tt_int_op(0xcafe,OP_EQ
, u2
);
1927 tt_int_op(444,OP_EQ
, u3
);
1929 /* Literal '%' (ie. '%%') */
1930 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
1931 tt_int_op(99,OP_EQ
, u1
);
1932 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
1933 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
1934 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
1935 tt_int_op(99,OP_EQ
, u1
);
1936 tt_str_op(s1
,OP_EQ
, "fresh");
1937 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
1938 tt_str_op("boo",OP_EQ
, s1
);
1940 /* Strings (ie. %s) */
1941 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
1942 tt_str_op(s1
,OP_EQ
, "hel");
1943 tt_str_op(s2
,OP_EQ
, "lo");
1944 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
1945 tt_str_op(s3
,OP_EQ
, "WD");
1946 tt_int_op(40,OP_EQ
, u1
);
1947 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
1948 tt_str_op(s3
,OP_EQ
, "WD4");
1949 tt_int_op(0,OP_EQ
, u1
);
1950 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
1951 tt_int_op(76,OP_EQ
, u1
);
1952 tt_str_op(s1
,OP_EQ
, "trombones");
1953 tt_int_op(1,OP_EQ
, tor_sscanf("prettylongstring", "%999s", s1
));
1954 tt_str_op(s1
,OP_EQ
, "prettylongstring");
1955 /* %s doesn't eat spaces */
1956 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
1957 tt_str_op(s1
,OP_EQ
, "hello");
1958 tt_str_op(s2
,OP_EQ
, "world");
1959 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
1960 tt_str_op(s1
,OP_EQ
, "bye");
1961 tt_str_op(s2
,OP_EQ
, "");
1963 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
1964 tt_str_op(s1
,OP_EQ
, "hi");
1965 tt_str_op(s2
,OP_EQ
, "");
1966 tt_str_op(s3
,OP_EQ
, "");
1968 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
1970 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
1971 tt_int_op(' ',OP_EQ
, ch
);
1973 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
1974 tt_int_op(r
,OP_EQ
, 3);
1975 tt_int_op(int1
,OP_EQ
, 12345);
1976 tt_int_op(lng1
,OP_EQ
, -67890);
1977 tt_int_op(int2
,OP_EQ
, -1);
1981 /* UINT32_MAX should work */
1982 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
1983 tt_int_op(4294967295U,OP_EQ
, u1
);
1985 /* But UINT32_MAX + 1 shouldn't work */
1986 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
1987 /* but parsing only 9... */
1988 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
1989 tt_int_op(429496729U,OP_EQ
, u1
);
1992 /* UINT32_MAX should work */
1993 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
1994 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
1996 /* But UINT32_MAX + 1 shouldn't work */
1997 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
2000 /* INT32_MIN and INT32_MAX should work */
2001 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
2002 tt_int_op(r
,OP_EQ
, 2);
2003 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
2004 tt_int_op(int2
,OP_EQ
, 2147483647);
2006 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
2007 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
2008 tt_int_op(r
,OP_EQ
, 0);
2010 r
= tor_sscanf("2147483648.", "%d.", &int1
);
2011 tt_int_op(r
,OP_EQ
, 0);
2013 /* and the first failure stops further processing */
2014 r
= tor_sscanf("-2147483648. 2147483648.",
2015 "%d. %d.", &int1
, &int2
);
2016 tt_int_op(r
,OP_EQ
, 1);
2018 r
= tor_sscanf("-2147483649. 2147483647.",
2019 "%d. %d.", &int1
, &int2
);
2020 tt_int_op(r
,OP_EQ
, 0);
2022 r
= tor_sscanf("2147483648. -2147483649.",
2023 "%d. %d.", &int1
, &int2
);
2024 tt_int_op(r
,OP_EQ
, 0);
2025 #elif SIZEOF_INT == 8
2027 /* UINT64_MAX should work */
2028 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
2029 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
2031 /* But UINT64_MAX + 1 shouldn't work */
2032 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
2033 /* but parsing only 19... */
2034 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
2035 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
2038 /* UINT64_MAX should work */
2039 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
2040 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
2042 /* But UINT64_MAX + 1 shouldn't work */
2043 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
2046 /* INT64_MIN and INT64_MAX should work */
2047 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
2048 "%d. %d.", &int1
, &int2
);
2049 tt_int_op(r
,OP_EQ
, 2);
2050 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
2051 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
2053 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
2054 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
2055 tt_int_op(r
,OP_EQ
, 0);
2057 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
2058 tt_int_op(r
,OP_EQ
, 0);
2060 /* and the first failure stops further processing */
2061 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
2062 "%d. %d.", &int1
, &int2
);
2063 tt_int_op(r
,OP_EQ
, 1);
2065 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
2066 "%d. %d.", &int1
, &int2
);
2067 tt_int_op(r
,OP_EQ
, 0);
2069 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
2070 "%d. %d.", &int1
, &int2
);
2071 tt_int_op(r
,OP_EQ
, 0);
2074 #if SIZEOF_LONG == 4
2076 /* UINT32_MAX should work */
2077 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
2078 tt_int_op(4294967295UL,OP_EQ
, ulng
);
2080 /* But UINT32_MAX + 1 shouldn't work */
2081 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
2082 /* but parsing only 9... */
2083 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
2084 tt_int_op(429496729UL,OP_EQ
, ulng
);
2087 /* UINT32_MAX should work */
2088 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
2089 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
2091 /* But UINT32_MAX + 1 shouldn't work */
2092 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
2095 /* INT32_MIN and INT32_MAX should work */
2096 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
2097 tt_int_op(r
,OP_EQ
, 2);
2098 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
2099 tt_int_op(lng2
,OP_EQ
, 2147483647L);
2101 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
2102 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
2103 tt_int_op(r
,OP_EQ
, 0);
2105 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
2106 tt_int_op(r
,OP_EQ
, 0);
2108 /* and the first failure stops further processing */
2109 r
= tor_sscanf("-2147483648. 2147483648.",
2110 "%ld. %ld.", &lng1
, &lng2
);
2111 tt_int_op(r
,OP_EQ
, 1);
2113 r
= tor_sscanf("-2147483649. 2147483647.",
2114 "%ld. %ld.", &lng1
, &lng2
);
2115 tt_int_op(r
,OP_EQ
, 0);
2117 r
= tor_sscanf("2147483648. -2147483649.",
2118 "%ld. %ld.", &lng1
, &lng2
);
2119 tt_int_op(r
,OP_EQ
, 0);
2120 #elif SIZEOF_LONG == 8
2122 /* UINT64_MAX should work */
2123 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
2124 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
2126 /* But UINT64_MAX + 1 shouldn't work */
2127 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
2128 /* but parsing only 19... */
2129 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
2130 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
2133 /* UINT64_MAX should work */
2134 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
2135 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
2137 /* But UINT64_MAX + 1 shouldn't work */
2138 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
2141 /* INT64_MIN and INT64_MAX should work */
2142 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
2143 "%ld. %ld.", &lng1
, &lng2
);
2144 tt_int_op(r
,OP_EQ
, 2);
2145 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
2146 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
2148 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
2149 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
2150 tt_int_op(r
,OP_EQ
, 0);
2152 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
2153 tt_int_op(r
,OP_EQ
, 0);
2155 /* and the first failure stops further processing */
2156 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
2157 "%ld. %ld.", &lng1
, &lng2
);
2158 tt_int_op(r
,OP_EQ
, 1);
2160 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
2161 "%ld. %ld.", &lng1
, &lng2
);
2162 tt_int_op(r
,OP_EQ
, 0);
2164 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
2165 "%ld. %ld.", &lng1
, &lng2
);
2166 tt_int_op(r
,OP_EQ
, 0);
2169 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
2170 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
2171 tt_int_op(r
,OP_EQ
, 4);
2172 test_feq(d1
, 123.456);
2173 test_feq(d2
, .000007);
2174 test_feq(d3
, -900123123.2000787);
2181 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
2182 #define tt_ci_char_op(a,op,b) tt_char_op(tolower(a),op,tolower(b))
2184 #ifndef HAVE_STRNLEN
2186 strnlen(const char *s
, size_t len
)
2188 const char *p
= memchr(s
, 0, len
);
2196 test_util_format_time_interval(void *arg
)
2198 /* use the same sized buffer and integers as tor uses */
2199 #define DBUF_SIZE 64
2200 char dbuf
[DBUF_SIZE
];
2202 long sec
, min
, hour
, day
;
2204 /* we don't care about the exact spelling of the
2205 * second(s), minute(s), hour(s), day(s) labels */
2206 #define LABEL_SIZE 21
2208 char label_s
[LABEL_SIZE
];
2209 char label_m
[LABEL_SIZE
];
2210 char label_h
[LABEL_SIZE
];
2211 char label_d
[LABEL_SIZE
];
2213 #define TL_ T_ " " L_
2219 /* In these tests, we're not picky about
2220 * spelling or abbreviations */
2222 /* seconds: 0, 1, 9, 10, 59 */
2224 /* ignore exact spelling of "second(s)"*/
2225 format_time_interval(dbuf
, sizeof(dbuf
), 0);
2226 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2227 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2228 tt_int_op(r
,OP_EQ
, 2);
2229 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2230 tt_int_op(sec
,OP_EQ
, 0);
2232 format_time_interval(dbuf
, sizeof(dbuf
), 1);
2233 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2234 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2235 tt_int_op(r
,OP_EQ
, 2);
2236 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2237 tt_int_op(sec
,OP_EQ
, 1);
2239 format_time_interval(dbuf
, sizeof(dbuf
), 10);
2240 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2241 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2242 tt_int_op(r
,OP_EQ
, 2);
2243 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2244 tt_int_op(sec
,OP_EQ
, 10);
2246 format_time_interval(dbuf
, sizeof(dbuf
), 59);
2247 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2248 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2249 tt_int_op(r
,OP_EQ
, 2);
2250 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2251 tt_int_op(sec
,OP_EQ
, 59);
2253 /* negative seconds are reported as their absolute value */
2255 format_time_interval(dbuf
, sizeof(dbuf
), -4);
2256 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2257 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2258 tt_int_op(r
,OP_EQ
, 2);
2259 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2260 tt_int_op(sec
,OP_EQ
, 4);
2261 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2263 format_time_interval(dbuf
, sizeof(dbuf
), -32);
2264 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2265 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
2266 tt_int_op(r
,OP_EQ
, 2);
2267 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2268 tt_int_op(sec
,OP_EQ
, 32);
2269 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2271 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
2273 /* ignore trailing "0 second(s)", if present */
2274 format_time_interval(dbuf
, sizeof(dbuf
), 60);
2275 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2276 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
2277 tt_int_op(r
,OP_EQ
, 2);
2278 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2279 tt_int_op(min
,OP_EQ
, 1);
2280 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2282 /* ignore exact spelling of "minute(s)," and "second(s)" */
2283 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 1);
2284 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2285 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2286 &min
, label_m
, &sec
, label_s
);
2287 tt_int_op(r
,OP_EQ
, 4);
2288 tt_int_op(min
,OP_EQ
, 1);
2289 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2290 tt_int_op(sec
,OP_EQ
, 1);
2291 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2292 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2294 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
2295 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2296 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2297 &min
, label_m
, &sec
, label_s
);
2298 tt_int_op(r
,OP_EQ
, 4);
2299 tt_int_op(min
,OP_EQ
, 1);
2300 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2301 tt_int_op(sec
,OP_EQ
, 59);
2302 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2304 /* ignore trailing "0 second(s)", if present */
2305 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
2306 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2307 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
2308 tt_int_op(r
,OP_EQ
, 2);
2309 tt_int_op(min
,OP_EQ
, 2);
2310 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2312 /* ignore exact spelling of "minute(s)," and "second(s)" */
2313 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
2314 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2315 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2316 &min
, label_m
, &sec
, label_s
);
2317 tt_int_op(r
,OP_EQ
, 4);
2318 tt_int_op(min
,OP_EQ
, 2);
2319 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2320 tt_int_op(sec
,OP_EQ
, 1);
2321 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2323 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
2324 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2325 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2326 &min
, label_m
, &sec
, label_s
);
2327 tt_int_op(r
,OP_EQ
, 4);
2328 tt_int_op(min
,OP_EQ
, 59);
2329 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2330 tt_int_op(sec
,OP_EQ
, 59);
2331 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2333 /* negative minutes are reported as their absolute value */
2335 /* ignore trailing "0 second(s)", if present */
2336 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
2337 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2338 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
2339 tt_int_op(r
,OP_EQ
, 2);
2340 tt_int_op(min
,OP_EQ
, 3);
2341 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2343 /* ignore exact spelling of "minute(s)," and "second(s)" */
2344 format_time_interval(dbuf
, sizeof(dbuf
), -96);
2345 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2346 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2347 &min
, label_m
, &sec
, label_s
);
2348 tt_int_op(r
,OP_EQ
, 4);
2349 tt_int_op(min
,OP_EQ
, 1);
2350 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2351 tt_int_op(sec
,OP_EQ
, 36);
2352 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2354 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
2355 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2356 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2357 &min
, label_m
, &sec
, label_s
);
2358 tt_int_op(r
,OP_EQ
, 4);
2359 tt_int_op(min
,OP_EQ
, 46);
2360 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2361 tt_int_op(sec
,OP_EQ
, 55);
2362 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
2364 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
2365 /* always ignore trailing seconds, if present */
2367 /* ignore trailing "0 minute(s)" etc., if present */
2368 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
2369 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2370 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
2371 tt_int_op(r
,OP_EQ
, 2);
2372 tt_int_op(hour
,OP_EQ
, 1);
2373 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2375 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
2376 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2377 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
2378 tt_int_op(r
,OP_EQ
, 2);
2379 tt_int_op(hour
,OP_EQ
, 1);
2380 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2382 /* ignore exact spelling of "hour(s)," etc. */
2383 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
2384 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2385 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2386 &hour
, label_h
, &min
, label_m
);
2387 tt_int_op(r
,OP_EQ
, 4);
2388 tt_int_op(hour
,OP_EQ
, 1);
2389 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2390 tt_int_op(min
,OP_EQ
, 1);
2391 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2393 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
2394 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2395 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2396 &hour
, label_h
, &min
, label_m
);
2397 tt_int_op(r
,OP_EQ
, 4);
2398 tt_int_op(hour
,OP_EQ
, 23);
2399 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2400 tt_int_op(min
,OP_EQ
, 59);
2401 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2403 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
2404 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2405 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2406 &hour
, label_h
, &min
, label_m
);
2407 tt_int_op(r
,OP_EQ
, 4);
2408 tt_int_op(hour
,OP_EQ
, 23);
2409 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2410 tt_int_op(min
,OP_EQ
, 59);
2411 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2413 /* negative hours are reported as their absolute value */
2415 /* ignore exact spelling of "hour(s)," etc., if present */
2416 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
2417 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2418 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
2419 tt_int_op(r
,OP_EQ
, 2);
2420 tt_int_op(hour
,OP_EQ
, 2);
2421 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2423 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
2424 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2425 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2426 &hour
, label_h
, &min
, label_m
);
2427 tt_int_op(r
,OP_EQ
, 4);
2428 tt_int_op(hour
,OP_EQ
, 21);
2429 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2430 tt_int_op(min
,OP_EQ
, 3);
2431 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2433 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
2434 /* always ignore trailing seconds, if present */
2436 /* ignore trailing "0 hours(s)" etc., if present */
2437 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
2438 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2439 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
2440 tt_int_op(r
,OP_EQ
, 2);
2441 tt_int_op(day
,OP_EQ
, 1);
2442 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2444 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
2445 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2446 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
2447 tt_int_op(r
,OP_EQ
, 2);
2448 tt_int_op(day
,OP_EQ
, 1);
2449 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2451 /* ignore exact spelling of "days(s)," etc. */
2452 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
2453 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2454 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2455 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2457 /* ignore 0 hours(s), if present */
2458 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2459 &day
, label_d
, &min
, label_m
);
2461 tt_assert(r
== 4 || r
== 6);
2462 tt_int_op(day
,OP_EQ
, 1);
2463 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2465 tt_int_op(hour
,OP_EQ
, 0);
2466 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2468 tt_int_op(min
,OP_EQ
, 1);
2469 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2471 /* ignore trailing "0 minutes(s)" etc., if present */
2472 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
2473 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2474 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
2475 &day
, label_d
, &hour
, label_h
);
2476 tt_int_op(r
,OP_EQ
, 4);
2477 tt_int_op(day
,OP_EQ
, 1);
2478 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2479 tt_int_op(hour
,OP_EQ
, 1);
2480 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2482 /* negative days are reported as their absolute value */
2484 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
2485 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2486 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2487 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2488 tt_int_op(r
,OP_EQ
, 6);
2489 tt_int_op(day
,OP_EQ
, 253);
2490 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2491 tt_int_op(hour
,OP_EQ
, 21);
2492 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2493 tt_int_op(min
,OP_EQ
, 23);
2494 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2496 /* periods > 1 year are reported in days (warn?) */
2498 /* ignore exact spelling of "days(s)," etc., if present */
2499 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
2500 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2501 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2502 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2503 tt_int_op(r
,OP_EQ
, 6);
2504 tt_int_op(day
,OP_EQ
, 8780);
2505 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2506 tt_int_op(hour
,OP_EQ
, 11);
2507 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2508 tt_int_op(min
,OP_EQ
, 59);
2509 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2511 /* negative periods > 1 year are reported in days (warn?) */
2513 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
2514 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2515 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2516 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2517 tt_int_op(r
,OP_EQ
, 6);
2518 tt_int_op(day
,OP_EQ
, 16516);
2519 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2520 tt_int_op(hour
,OP_EQ
, 9);
2521 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2522 tt_int_op(min
,OP_EQ
, 2);
2523 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2525 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
2527 /* We can try INT32_MIN/MAX */
2528 /* Always ignore second(s) */
2531 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
2532 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2533 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2534 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2535 tt_int_op(r
,OP_EQ
, 6);
2536 tt_int_op(day
,OP_EQ
, 24855);
2537 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2538 tt_int_op(hour
,OP_EQ
, 3);
2539 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2540 tt_int_op(min
,OP_EQ
, 14);
2541 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2542 /* and 7 seconds - ignored */
2544 /* INT32_MIN: check that we get the absolute value of interval,
2545 * which doesn't actually fit in int32_t.
2546 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
2547 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
2548 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2549 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2550 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2551 tt_int_op(r
,OP_EQ
, 6);
2552 tt_int_op(day
,OP_EQ
, 24855);
2553 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2554 tt_int_op(hour
,OP_EQ
, 3);
2555 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2556 tt_int_op(min
,OP_EQ
, 14);
2557 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2558 /* and 7 or 8 seconds - ignored */
2562 #if SIZEOF_LONG == 8
2564 /* We can try INT64_MIN/MAX */
2565 /* Always ignore second(s) */
2568 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
2569 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2570 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2571 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2572 tt_int_op(r
,OP_EQ
, 6);
2573 tt_int_op(day
,OP_EQ
, 106751991167300L);
2574 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2575 tt_int_op(hour
,OP_EQ
, 15);
2576 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2577 tt_int_op(min
,OP_EQ
, 30);
2578 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2579 /* and 7 seconds - ignored */
2581 /* INT64_MIN: check that we get the absolute value of interval,
2582 * which doesn't actually fit in int64_t.
2583 * We expect INT64_MAX */
2584 format_time_interval(dbuf
, sizeof(dbuf
),
2585 -9223372036854775807L - 1L);
2586 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
2587 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
2588 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
2589 tt_int_op(r
,OP_EQ
, 6);
2590 tt_int_op(day
,OP_EQ
, 106751991167300L);
2591 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
2592 tt_int_op(hour
,OP_EQ
, 15);
2593 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
2594 tt_int_op(min
,OP_EQ
, 30);
2595 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
2596 /* and 7 or 8 seconds - ignored */
2605 #undef tt_ci_char_op
2613 test_util_path_is_relative(void *arg
)
2615 /* OS-independent tests */
2617 tt_int_op(1,OP_EQ
, path_is_relative(""));
2618 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
2619 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
2620 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
2621 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
2623 tt_int_op(0,OP_EQ
, path_is_relative("/"));
2624 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
2625 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
2629 /* I don't have Windows so I can't test this, hence the "#ifdef
2630 0". These are tests that look useful, so please try to get them
2631 running and uncomment if it all works as it should */
2632 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
2633 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
2634 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
2635 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
2636 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
2638 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
2639 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
2640 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
2647 #ifdef ENABLE_MEMPOOLS
2649 /** Run unittests for memory pool allocator */
2651 test_util_mempool(void *arg
)
2653 mp_pool_t
*pool
= NULL
;
2654 smartlist_t
*allocated
= NULL
;
2658 pool
= mp_pool_new(1, 100);
2660 tt_assert(pool
->new_chunk_capacity
>= 100);
2661 tt_assert(pool
->item_alloc_size
>= sizeof(void*)+1);
2662 mp_pool_destroy(pool
);
2665 pool
= mp_pool_new(241, 2500);
2667 tt_assert(pool
->new_chunk_capacity
>= 10);
2668 tt_assert(pool
->item_alloc_size
>= sizeof(void*)+241);
2669 tt_int_op(pool
->item_alloc_size
& 0x03,OP_EQ
, 0);
2670 tt_assert(pool
->new_chunk_capacity
< 60);
2672 allocated
= smartlist_new();
2673 for (i
= 0; i
< 20000; ++i
) {
2674 if (smartlist_len(allocated
) < 20 || crypto_rand_int(2)) {
2675 void *m
= mp_pool_get(pool
);
2676 memset(m
, 0x09, 241);
2677 smartlist_add(allocated
, m
);
2678 //printf("%d: %p\n", i, m);
2679 //mp_pool_assert_ok(pool);
2681 int idx
= crypto_rand_int(smartlist_len(allocated
));
2682 void *m
= smartlist_get(allocated
, idx
);
2683 //printf("%d: free %p\n", i, m);
2684 smartlist_del(allocated
, idx
);
2686 //mp_pool_assert_ok(pool);
2688 if (crypto_rand_int(777)==0)
2689 mp_pool_clean(pool
, 1, 1);
2692 mp_pool_assert_ok(pool
);
2697 SMARTLIST_FOREACH(allocated
, void *, m
, mp_pool_release(m
));
2698 mp_pool_assert_ok(pool
);
2699 mp_pool_clean(pool
, 0, 0);
2700 mp_pool_assert_ok(pool
);
2701 smartlist_free(allocated
);
2705 mp_pool_destroy(pool
);
2708 #endif /* ENABLE_MEMPOOLS */
2710 /** Run unittests for memory area allocator */
2712 test_util_memarea(void *arg
)
2714 memarea_t
*area
= memarea_new();
2715 char *p1
, *p2
, *p3
, *p1_orig
;
2716 void *malloced_ptr
= NULL
;
2722 p1_orig
= p1
= memarea_alloc(area
,64);
2723 p2
= memarea_alloc_zero(area
,52);
2724 p3
= memarea_alloc(area
,11);
2726 tt_assert(memarea_owns_ptr(area
, p1
));
2727 tt_assert(memarea_owns_ptr(area
, p2
));
2728 tt_assert(memarea_owns_ptr(area
, p3
));
2729 /* Make sure we left enough space. */
2730 tt_assert(p1
+64 <= p2
);
2731 tt_assert(p2
+52 <= p3
);
2732 /* Make sure we aligned. */
2733 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
2734 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
2735 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
2736 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
2737 tt_assert(!memarea_owns_ptr(area
, p3
+30));
2738 tt_assert(tor_mem_is_zero(p2
, 52));
2739 /* Make sure we don't overalign. */
2740 p1
= memarea_alloc(area
, 1);
2741 p2
= memarea_alloc(area
, 1);
2742 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
2744 malloced_ptr
= tor_malloc(64);
2745 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
2746 tor_free(malloced_ptr
);
2749 /* memarea_memdup */
2751 malloced_ptr
= tor_malloc(64);
2752 crypto_rand((char*)malloced_ptr
, 64);
2753 p1
= memarea_memdup(area
, malloced_ptr
, 64);
2754 tt_assert(p1
!= malloced_ptr
);
2755 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
2756 tor_free(malloced_ptr
);
2759 /* memarea_strdup. */
2760 p1
= memarea_strdup(area
,"");
2761 p2
= memarea_strdup(area
, "abcd");
2764 tt_str_op(p1
,OP_EQ
, "");
2765 tt_str_op(p2
,OP_EQ
, "abcd");
2767 /* memarea_strndup. */
2769 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
2770 /* (From Turandot, act 3.) */
2771 size_t len
= strlen(s
);
2772 p1
= memarea_strndup(area
, s
, 1000);
2773 p2
= memarea_strndup(area
, s
, 10);
2774 tt_str_op(p1
,OP_EQ
, s
);
2775 tt_assert(p2
>= p1
+ len
+ 1);
2776 tt_mem_op(s
,OP_EQ
, p2
, 10);
2777 tt_int_op(p2
[10],OP_EQ
, '\0');
2778 p3
= memarea_strndup(area
, s
, len
);
2779 tt_str_op(p3
,OP_EQ
, s
);
2780 p3
= memarea_strndup(area
, s
, len
-1);
2781 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
2782 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
2785 memarea_clear(area
);
2786 p1
= memarea_alloc(area
, 1);
2787 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
2788 memarea_clear(area
);
2790 /* Check for running over an area's size. */
2791 for (i
= 0; i
< 512; ++i
) {
2792 p1
= memarea_alloc(area
, crypto_rand_int(5)+1);
2793 tt_assert(memarea_owns_ptr(area
, p1
));
2795 memarea_assert_ok(area
);
2796 /* Make sure we can allocate a too-big object. */
2797 p1
= memarea_alloc_zero(area
, 9000);
2798 p2
= memarea_alloc_zero(area
, 16);
2799 tt_assert(memarea_owns_ptr(area
, p1
));
2800 tt_assert(memarea_owns_ptr(area
, p2
));
2803 memarea_drop_all(area
);
2804 tor_free(malloced_ptr
);
2807 /** Run unit tests for utility functions to get file names relative to
2808 * the data directory. */
2810 test_util_datadir(void *arg
)
2814 char *temp_dir
= NULL
;
2817 temp_dir
= get_datadir_fname(NULL
);
2818 f
= get_datadir_fname("state");
2819 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
2820 tt_str_op(f
,OP_EQ
, buf
);
2822 f
= get_datadir_fname2("cache", "thingy");
2823 tor_snprintf(buf
, sizeof(buf
),
2824 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
2825 tt_str_op(f
,OP_EQ
, buf
);
2827 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
2828 tor_snprintf(buf
, sizeof(buf
),
2829 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
2830 tt_str_op(f
,OP_EQ
, buf
);
2832 f
= get_datadir_fname_suffix("cache", ".foo");
2833 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
2835 tt_str_op(f
,OP_EQ
, buf
);
2843 test_util_strtok(void *arg
)
2851 for (i
= 0; i
< 3; i
++) {
2852 const char *pad1
="", *pad2
="";
2865 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
2866 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
2867 tt_assert(NULL
== tor_strtok_r_impl(buf
, " ", &cp1
));
2868 tt_assert(NULL
== tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
2870 tor_snprintf(buf
, sizeof(buf
),
2871 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
2872 tor_snprintf(buf2
, sizeof(buf2
),
2873 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
2874 /* -- "Year's End", Richard Wilbur */
2876 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
2877 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
2878 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
2879 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
2880 tt_str_op("on",OP_EQ
, S1());
2881 tt_str_op("the",OP_EQ
, S1());
2882 tt_str_op("dark",OP_EQ
, S1());
2883 tt_str_op("seemed",OP_EQ
, S2());
2884 tt_str_op("their",OP_EQ
, S2());
2885 tt_str_op("own",OP_EQ
, S2());
2886 tt_str_op("in",OP_EQ
, S1());
2887 tt_str_op("gestures",OP_EQ
, S1());
2888 tt_str_op("of",OP_EQ
, S1());
2889 tt_str_op("most",OP_EQ
, S2());
2890 tt_str_op("perfect",OP_EQ
, S2());
2891 tt_str_op("descent",OP_EQ
, S1());
2892 tt_str_op("monument",OP_EQ
, S2());
2893 tt_ptr_op(NULL
,OP_EQ
, S1());
2894 tt_ptr_op(NULL
,OP_EQ
, S2());
2898 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
2899 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
2901 strlcpy(buf
, "Howdy!", sizeof(buf
));
2902 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
2903 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
2905 strlcpy(buf
, " ", sizeof(buf
));
2906 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
2907 strlcpy(buf
, " ", sizeof(buf
));
2908 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
2910 strlcpy(buf
, "something ", sizeof(buf
));
2911 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
2912 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
2918 test_util_find_str_at_start_of_line(void *ptr
)
2920 const char *long_string
=
2921 "howdy world. how are you? i hope it's fine.\n"
2924 char *line2
= strchr(long_string
,'\n')+1;
2925 char *line3
= strchr(line2
,'\n')+1;
2926 const char *short_string
= "hello kitty\n"
2928 char *short_line2
= strchr(short_string
,'\n')+1;
2932 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
2933 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
2934 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
2935 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
2936 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
2937 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
2938 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
2939 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
2940 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
2941 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
2942 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
2943 tt_ptr_op(line2
,OP_EQ
,
2944 find_str_at_start_of_line(long_string
, "hello kitty\n"));
2945 tt_ptr_op(line2
,OP_EQ
,
2946 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
2947 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
2948 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
2949 tt_ptr_op(NULL
, OP_EQ
,
2950 find_str_at_start_of_line(long_string
, "third line\n"));
2951 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
2958 test_util_string_is_C_identifier(void *ptr
)
2962 tt_int_op(1,OP_EQ
, string_is_C_identifier("string_is_C_identifier"));
2963 tt_int_op(1,OP_EQ
, string_is_C_identifier("_string_is_C_identifier"));
2964 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
2965 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
2966 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
2967 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
2968 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
2969 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
2970 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
2971 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
2973 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
2974 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
2975 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
2976 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
2977 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
2978 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
2979 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
2980 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
2987 test_util_asprintf(void *ptr
)
2989 #define LOREMIPSUM \
2990 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
2991 char *cp
=NULL
, *cp2
=NULL
;
2996 r
= tor_asprintf(&cp
, "simple string 100%% safe");
2998 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
2999 tt_int_op(strlen(cp
),OP_EQ
, r
);
3003 r
= tor_asprintf(&cp
, "%s", "");
3005 tt_str_op("",OP_EQ
, cp
);
3006 tt_int_op(strlen(cp
),OP_EQ
, r
);
3010 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
3012 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
3013 tt_int_op(strlen(cp
),OP_EQ
, r
);
3014 /* don't free cp; next test uses it. */
3017 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
3019 tt_int_op(strlen(cp2
),OP_EQ
, r
);
3020 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
3021 tt_assert(cp
!= cp2
);
3025 /* Glass-box test: a string exactly 128 characters long. */
3026 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
3028 tt_int_op(128,OP_EQ
, r
);
3029 tt_int_op(cp
[128], OP_EQ
, '\0');
3030 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
3033 /* String longer than 128 characters */
3034 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
3035 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
3037 tt_int_op(strlen(cp
),OP_EQ
, r
);
3038 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
3046 test_util_listdir(void *ptr
)
3048 smartlist_t
*dir_contents
= NULL
;
3049 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
3053 fname1
= tor_strdup(get_fname("hopscotch"));
3054 fname2
= tor_strdup(get_fname("mumblety-peg"));
3055 fname3
= tor_strdup(get_fname(".hidden-file"));
3056 dir1
= tor_strdup(get_fname("some-directory"));
3057 dirname
= tor_strdup(get_fname(NULL
));
3059 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
3060 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
3061 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
3065 r
= mkdir(dir1
, 0700);
3068 fprintf(stderr
, "Can't create directory %s:", dir1
);
3073 dir_contents
= tor_listdir(dirname
);
3074 tt_assert(dir_contents
);
3075 /* make sure that each filename is listed. */
3076 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
3077 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
3078 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
3079 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
3081 tt_assert(!smartlist_contains_string(dir_contents
, "."));
3082 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
3091 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
3092 smartlist_free(dir_contents
);
3097 test_util_parent_dir(void *ptr
)
3102 #define T(output,expect_ok,input) \
3105 cp = tor_strdup(input); \
3106 ok = get_parent_directory(cp); \
3107 tt_int_op(expect_ok, OP_EQ, ok); \
3109 tt_str_op(output, OP_EQ, cp); \
3113 T("/home/wombat", 0, "/home/wombat/knish");
3114 T("/home/wombat", 0, "/home/wombat/knish/");
3115 T("/home/wombat", 0, "/home/wombat/knish///");
3116 T("./home/wombat", 0, "./home/wombat/knish/");
3118 T("/", 0, "/home//");
3119 T(".", 0, "./wombat");
3120 T(".", 0, "./wombat/");
3121 T(".", 0, "./wombat//");
3122 T("wombat", 0, "wombat/foo");
3123 T("wombat/..", 0, "wombat/../foo");
3124 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
3125 T("wombat/.", 0, "wombat/./foo");
3126 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
3127 T("wombat", 0, "wombat/..//");
3128 T("wombat", 0, "wombat/foo/");
3129 T("wombat", 0, "wombat/.foo");
3130 T("wombat", 0, "wombat/.foo/");
3132 T("wombat", -1, "");
3134 T("wombat", 0, "wombat/knish");
3144 test_util_ftruncate(void *ptr
)
3149 const char *message
= "Hello world";
3150 const char *message2
= "Hola mundo";
3155 fname
= get_fname("ftruncate");
3157 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
3158 tt_int_op(fd
, OP_GE
, 0);
3160 /* Make the file be there. */
3161 tt_int_op(strlen(message
), OP_EQ
, write_all(fd
, message
, strlen(message
),0));
3162 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
3163 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3164 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
3166 /* Truncate and see if it got truncated */
3167 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
3168 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
3169 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3170 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
3172 /* Replace, and see if it got replaced */
3173 tt_int_op(strlen(message2
), OP_EQ
,
3174 write_all(fd
, message2
, strlen(message2
), 0));
3175 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
3176 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3177 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
3182 buf
= read_file_to_str(fname
, 0, NULL
);
3183 tt_str_op(message2
, OP_EQ
, buf
);
3193 test_util_load_win_lib(void *ptr
)
3195 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
3207 clear_hex_errno(char *hex_errno
)
3209 memset(hex_errno
, '\0', HEX_ERRNO_SIZE
+ 1);
3213 test_util_exit_status(void *ptr
)
3215 /* Leave an extra byte for a \0 so we can do string comparison */
3216 char hex_errno
[HEX_ERRNO_SIZE
+ 1];
3221 clear_hex_errno(hex_errno
);
3222 tt_str_op("",OP_EQ
, hex_errno
);
3224 clear_hex_errno(hex_errno
);
3225 n
= format_helper_exit_status(0, 0, hex_errno
);
3226 tt_str_op("0/0\n",OP_EQ
, hex_errno
);
3227 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3231 clear_hex_errno(hex_errno
);
3232 n
= format_helper_exit_status(0, 0x7FFFFFFF, hex_errno
);
3233 tt_str_op("0/7FFFFFFF\n",OP_EQ
, hex_errno
);
3234 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3236 clear_hex_errno(hex_errno
);
3237 n
= format_helper_exit_status(0xFF, -0x80000000, hex_errno
);
3238 tt_str_op("FF/-80000000\n",OP_EQ
, hex_errno
);
3239 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3240 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
3242 #elif SIZEOF_INT == 8
3244 clear_hex_errno(hex_errno
);
3245 n
= format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno
);
3246 tt_str_op("0/7FFFFFFFFFFFFFFF\n",OP_EQ
, hex_errno
);
3247 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3249 clear_hex_errno(hex_errno
);
3250 n
= format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno
);
3251 tt_str_op("FF/-8000000000000000\n",OP_EQ
, hex_errno
);
3252 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3253 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
3257 clear_hex_errno(hex_errno
);
3258 n
= format_helper_exit_status(0x7F, 0, hex_errno
);
3259 tt_str_op("7F/0\n",OP_EQ
, hex_errno
);
3260 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3262 clear_hex_errno(hex_errno
);
3263 n
= format_helper_exit_status(0x08, -0x242, hex_errno
);
3264 tt_str_op("8/-242\n",OP_EQ
, hex_errno
);
3265 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
3267 clear_hex_errno(hex_errno
);
3268 tt_str_op("",OP_EQ
, hex_errno
);
3276 /* Check that fgets with a non-blocking pipe returns partial lines and sets
3277 * EAGAIN, returns full lines and sets no error, and returns NULL on EOF and
3280 test_util_fgets_eagain(void *ptr
)
3282 int test_pipe
[2] = {-1, -1};
3286 FILE *test_stream
= NULL
;
3287 char buf
[4] = { 0 };
3293 /* Set up a pipe to test on */
3294 retval
= pipe(test_pipe
);
3295 tt_int_op(retval
, OP_EQ
, 0);
3297 /* Set up the read-end to be non-blocking */
3298 retval
= fcntl(test_pipe
[0], F_SETFL
, O_NONBLOCK
);
3299 tt_int_op(retval
, OP_EQ
, 0);
3301 /* Open it as a stdio stream */
3302 test_stream
= fdopen(test_pipe
[0], "r");
3303 tt_ptr_op(test_stream
, OP_NE
, NULL
);
3305 /* Send in a partial line */
3306 retlen
= write(test_pipe
[1], "A", 1);
3307 tt_int_op(retlen
, OP_EQ
, 1);
3308 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3309 tt_int_op(errno
, OP_EQ
, EAGAIN
);
3310 tt_ptr_op(retptr
, OP_EQ
, buf
);
3311 tt_str_op(buf
, OP_EQ
, "A");
3314 /* Send in the rest */
3315 retlen
= write(test_pipe
[1], "B\n", 2);
3316 tt_int_op(retlen
, OP_EQ
, 2);
3317 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3318 tt_int_op(errno
, OP_EQ
, 0);
3319 tt_ptr_op(retptr
, OP_EQ
, buf
);
3320 tt_str_op(buf
, OP_EQ
, "B\n");
3323 /* Send in a full line */
3324 retlen
= write(test_pipe
[1], "CD\n", 3);
3325 tt_int_op(retlen
, OP_EQ
, 3);
3326 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3327 tt_int_op(errno
, OP_EQ
, 0);
3328 tt_ptr_op(retptr
, OP_EQ
, buf
);
3329 tt_str_op(buf
, OP_EQ
, "CD\n");
3332 /* Send in a partial line */
3333 retlen
= write(test_pipe
[1], "E", 1);
3334 tt_int_op(retlen
, OP_EQ
, 1);
3335 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3336 tt_int_op(errno
, OP_EQ
, EAGAIN
);
3337 tt_ptr_op(retptr
, OP_EQ
, buf
);
3338 tt_str_op(buf
, OP_EQ
, "E");
3341 /* Send in the rest */
3342 retlen
= write(test_pipe
[1], "F\n", 2);
3343 tt_int_op(retlen
, OP_EQ
, 2);
3344 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3345 tt_int_op(errno
, OP_EQ
, 0);
3346 tt_ptr_op(retptr
, OP_EQ
, buf
);
3347 tt_str_op(buf
, OP_EQ
, "F\n");
3350 /* Send in a full line and close */
3351 retlen
= write(test_pipe
[1], "GH", 2);
3352 tt_int_op(retlen
, OP_EQ
, 2);
3353 retval
= close(test_pipe
[1]);
3354 tt_int_op(retval
, OP_EQ
, 0);
3356 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3357 tt_int_op(errno
, OP_EQ
, 0);
3358 tt_ptr_op(retptr
, OP_EQ
, buf
);
3359 tt_str_op(buf
, OP_EQ
, "GH");
3363 retptr
= fgets(buf
, sizeof(buf
), test_stream
);
3364 tt_int_op(errno
, OP_EQ
, 0);
3365 tt_ptr_op(retptr
, OP_EQ
, NULL
);
3366 retval
= feof(test_stream
);
3367 tt_int_op(retval
, OP_NE
, 0);
3370 /* Check that buf is unchanged according to C99 and C11 */
3371 tt_str_op(buf
, OP_EQ
, "GH");
3374 if (test_stream
!= NULL
)
3375 fclose(test_stream
);
3376 if (test_pipe
[0] != -1)
3377 close(test_pipe
[0]);
3378 if (test_pipe
[1] != -1)
3379 close(test_pipe
[1]);
3384 * Test for format_hex_number_sigsafe()
3388 test_util_format_hex_number(void *ptr
)
3400 {"7FFFFFFF", 0x7fffffff},
3401 {"FFFFFFFF", 0xffffffff},
3402 #if UINT_MAX >= 0xffffffff
3403 {"31BC421D", 0x31bc421d},
3404 {"FFFFFFFF", 0xffffffff},
3411 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
3412 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
3413 tt_int_op(len
,OP_NE
, 0);
3414 tt_int_op(len
,OP_EQ
, strlen(buf
));
3415 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
3418 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
3419 tt_str_op(buf
,OP_EQ
, "FFFF");
3420 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
3421 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
3428 * Test for format_hex_number_sigsafe()
3432 test_util_format_dec_number(void *ptr
)
3443 {"12345678", 12345678},
3444 {"99999999", 99999999},
3445 {"100000000", 100000000},
3446 {"4294967295", 4294967295u},
3447 #if UINT_MAX > 0xffffffff
3448 {"18446744073709551615", 18446744073709551615u },
3455 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
3456 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
3457 tt_int_op(len
,OP_NE
, 0);
3458 tt_int_op(len
,OP_EQ
, strlen(buf
));
3459 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
3461 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
3462 (int)(strlen(test_data
[i
].str
) + 1));
3463 tt_int_op(len
,OP_EQ
, strlen(buf
));
3464 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
3467 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
3468 tt_str_op(buf
,OP_EQ
, "7331");
3469 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
3470 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
3471 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
3478 * Test that we can properly format a Windows command line
3481 test_util_join_win_cmdline(void *ptr
)
3483 /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
3484 * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
3485 * will try to only generate simple cases for the child process to parse;
3486 * i.e. we never embed quoted strings in arguments. */
3488 const char *argvs
[][4] = {
3489 {"a", "bb", "CCC", NULL
}, // Normal
3490 {NULL
, NULL
, NULL
, NULL
}, // Empty argument list
3491 {"", NULL
, NULL
, NULL
}, // Empty argument
3492 {"\"a", "b\"b", "CCC\"", NULL
}, // Quotes
3493 {"a\tbc", "dd dd", "E", NULL
}, // Whitespace
3494 {"a\\\\\\b", "de fg", "H", NULL
}, // Backslashes
3495 {"a\\\"b", "\\c", "D\\", NULL
}, // Backslashes before quote
3496 {"a\\\\b c", "d", "E", NULL
}, // Backslashes not before quote
3497 { NULL
} // Terminator
3500 const char *cmdlines
[] = {
3504 "\\\"a b\\\"b CCC\\\"",
3505 "\"a\tbc\" \"dd dd\" E",
3506 "a\\\\\\b \"de fg\" H",
3507 "a\\\\\\\"b \\c D\\",
3513 char *joined_argv
= NULL
;
3517 for (i
=0; cmdlines
[i
]!=NULL
; i
++) {
3518 log_info(LD_GENERAL
, "Joining argvs[%d], expecting <%s>", i
, cmdlines
[i
]);
3519 joined_argv
= tor_join_win_cmdline(argvs
[i
]);
3520 tt_str_op(cmdlines
[i
],OP_EQ
, joined_argv
);
3521 tor_free(joined_argv
);
3525 tor_free(joined_argv
);
3528 #define MAX_SPLIT_LINE_COUNT 4
3529 struct split_lines_test_t
{
3530 const char *orig_line
; // Line to be split (may contain \0's)
3531 int orig_length
; // Length of orig_line
3532 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
3536 * Test that we properly split a buffer into lines
3539 test_util_split_lines(void *ptr
)
3541 /* Test cases. orig_line of last test case must be NULL.
3542 * The last element of split_line[i] must be NULL. */
3543 struct split_lines_test_t tests
[] = {
3545 {"foo", 3, {"foo", NULL
}},
3546 {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL
}},
3547 {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL
}},
3548 {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL
}},
3549 {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL
}},
3550 {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL
}},
3551 {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL
}},
3552 {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL
}},
3553 {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL
}},
3554 {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL
}},
3559 char *orig_line
=NULL
;
3560 smartlist_t
*sl
=NULL
;
3564 for (i
=0; tests
[i
].orig_line
; i
++) {
3565 sl
= smartlist_new();
3566 /* Allocate space for string and trailing NULL */
3567 orig_line
= tor_memdup(tests
[i
].orig_line
, tests
[i
].orig_length
+ 1);
3568 tor_split_lines(sl
, orig_line
, tests
[i
].orig_length
);
3571 log_info(LD_GENERAL
, "Splitting test %d of length %d",
3572 i
, tests
[i
].orig_length
);
3573 SMARTLIST_FOREACH_BEGIN(sl
, const char *, line
) {
3574 /* Check we have not got too many lines */
3575 tt_int_op(MAX_SPLIT_LINE_COUNT
, OP_GT
, j
);
3576 /* Check that there actually should be a line here */
3577 tt_assert(tests
[i
].split_line
[j
] != NULL
);
3578 log_info(LD_GENERAL
, "Line %d of test %d, should be <%s>",
3579 j
, i
, tests
[i
].split_line
[j
]);
3580 /* Check that the line is as expected */
3581 tt_str_op(line
,OP_EQ
, tests
[i
].split_line
[j
]);
3583 } SMARTLIST_FOREACH_END(line
);
3584 /* Check that we didn't miss some lines */
3585 tt_ptr_op(NULL
,OP_EQ
, tests
[i
].split_line
[j
]);
3586 tor_free(orig_line
);
3592 tor_free(orig_line
);
3597 test_util_di_ops(void *arg
)
3603 const char *a
; int want_sign
; const char *b
;
3605 { "Foo", EQ
, "Foo" },
3606 { "foo", GT
, "bar", },
3607 { "foobar", EQ
,"foobar" },
3608 { "foobar", LT
, "foobaw" },
3609 { "foobar", GT
, "f00bar" },
3610 { "foobar", GT
, "boobar" },
3618 for (i
= 0; examples
[i
].a
; ++i
) {
3619 size_t len
= strlen(examples
[i
].a
);
3620 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
3621 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
3622 /* We do all of the operations, with operands in both orders. */
3623 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
3624 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
3625 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
3626 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
3627 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
3628 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
3630 /* Check for correctness of cmp1 */
3631 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
3632 TT_DIE(("Assertion failed."));
3633 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
3634 TT_DIE(("Assertion failed."));
3635 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
3636 TT_DIE(("Assertion failed."));
3638 /* Check for consistency of everything else with cmp1 */
3639 tt_int_op(eq1
,OP_EQ
, eq2
);
3640 tt_int_op(neq1
,OP_EQ
, neq2
);
3641 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
3642 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
3643 tt_int_op(neq1
,OP_EQ
, !eq1
);
3651 /* exhaustively test tor_memeq and tor_memcmp
3652 * against each possible single-byte numeric difference
3653 * some arithmetic bugs only appear with certain bit patterns */
3654 for (z
= 0; z
< 256; z
++) {
3655 for (i
= 0; i
< 256; i
++) {
3658 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
3659 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
3661 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
3667 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
3668 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
3669 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
3670 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
3671 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
3672 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
3673 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
3674 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
3675 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
3682 * Test counting high bits
3685 test_util_n_bits_set(void *ptr
)
3688 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
3689 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
3690 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
3691 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
3692 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
3693 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
3699 * Test LHS whitespace (and comment) eater
3702 test_util_eat_whitespace(void *ptr
)
3704 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
3710 /* Try one leading ws */
3711 strlcpy(str
, "fuubaar", sizeof(str
));
3712 for (i
= 0; i
< sizeof(ws
); ++i
) {
3714 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
3715 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
3716 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
3717 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3720 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
3721 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
3722 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
3723 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3726 strlcpy(str
, "", sizeof(str
));
3727 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
3728 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
3729 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
3730 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
3733 strlcpy(str
, " \t\r\n", sizeof(str
));
3734 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
3735 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
3736 eat_whitespace_eos(str
, str
+ strlen(str
)));
3737 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
3738 eat_whitespace_no_nl(str
));
3739 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
3740 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3742 strlcpy(str
, " \t\r ", sizeof(str
));
3743 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
3744 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
3745 eat_whitespace_eos(str
, str
+ strlen(str
)));
3746 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
3747 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
3748 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3751 strlcpy(str
, "fuubaar", sizeof(str
));
3752 for (i
= 0; i
< sizeof(ws
); ++i
)
3754 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
3755 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
3756 eat_whitespace_eos(str
, str
+ strlen(str
)));
3757 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
3758 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
3759 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3762 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
3763 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
3764 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
3765 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
3766 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3768 /* Eat comment & ws mix */
3769 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
3770 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
3771 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
3772 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
3773 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3775 /* Eat entire comment */
3776 strlcpy(str
, "#Comment", sizeof(str
));
3777 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
3778 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
3779 eat_whitespace_eos(str
, str
+ strlen(str
)));
3780 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
3781 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3783 /* Blank line, then comment */
3784 strlcpy(str
, " \t\n # Comment", sizeof(str
));
3785 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
3786 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
3787 eat_whitespace_eos(str
, str
+ strlen(str
)));
3788 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
3789 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
3795 /** Return a newly allocated smartlist containing the lines of text in
3796 * <b>lines</b>. The returned strings are heap-allocated, and must be
3797 * freed by the caller.
3799 * XXXX? Move to container.[hc] ? */
3800 static smartlist_t
*
3801 smartlist_new_from_text_lines(const char *lines
)
3803 smartlist_t
*sl
= smartlist_new();
3806 smartlist_split_string(sl
, lines
, "\n", 0, 0);
3808 last_line
= smartlist_pop_last(sl
);
3809 if (last_line
!= NULL
&& *last_line
!= '\0') {
3810 smartlist_add(sl
, last_line
);
3812 tor_free(last_line
);
3818 /** Test smartlist_new_from_text_lines */
3820 test_util_sl_new_from_text_lines(void *ptr
)
3824 { /* Normal usage */
3825 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
3826 int sl_len
= smartlist_len(sl
);
3828 tt_want_int_op(sl_len
, OP_EQ
, 3);
3830 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
3831 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
3832 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
3834 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
3838 { /* No final newline */
3839 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
3840 int sl_len
= smartlist_len(sl
);
3842 tt_want_int_op(sl_len
, OP_EQ
, 3);
3844 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
3845 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
3846 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
3848 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
3853 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
3854 int sl_len
= smartlist_len(sl
);
3856 tt_want_int_op(sl_len
, OP_EQ
, 1);
3858 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
3860 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
3864 { /* No text at all */
3865 smartlist_t
*sl
= smartlist_new_from_text_lines("");
3866 int sl_len
= smartlist_len(sl
);
3868 tt_want_int_op(sl_len
, OP_EQ
, 0);
3870 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
3876 test_util_envnames(void *ptr
)
3880 tt_assert(environment_variable_names_equal("abc", "abc"));
3881 tt_assert(environment_variable_names_equal("abc", "abc="));
3882 tt_assert(environment_variable_names_equal("abc", "abc=def"));
3883 tt_assert(environment_variable_names_equal("abc=def", "abc"));
3884 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
3886 tt_assert(environment_variable_names_equal("abc", "abc"));
3887 tt_assert(environment_variable_names_equal("abc", "abc="));
3888 tt_assert(environment_variable_names_equal("abc", "abc=def"));
3889 tt_assert(environment_variable_names_equal("abc=def", "abc"));
3890 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
3892 tt_assert(!environment_variable_names_equal("abc", "abcd"));
3893 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
3894 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
3895 tt_assert(!environment_variable_names_equal("abc=", "def"));
3896 tt_assert(!environment_variable_names_equal("abc=", "def="));
3897 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
3899 tt_assert(!environment_variable_names_equal("", "a=def"));
3900 /* A bit surprising. */
3901 tt_assert(environment_variable_names_equal("", "=def"));
3902 tt_assert(environment_variable_names_equal("=y", "=x"));
3908 /** Test process_environment_make */
3910 test_util_make_environment(void *ptr
)
3912 const char *env_vars_string
=
3913 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
3914 "HOME=/home/foozer\n";
3915 const char expected_windows_env_block
[] =
3916 "HOME=/home/foozer\000"
3917 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
3919 size_t expected_windows_env_block_len
=
3920 sizeof(expected_windows_env_block
) - 1;
3922 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
3923 smartlist_t
*env_vars_sorted
= smartlist_new();
3924 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
3926 process_environment_t
*env
;
3930 env
= process_environment_make(env_vars
);
3932 /* Check that the Windows environment block is correct. */
3933 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
3934 expected_windows_env_block_len
));
3936 /* Now for the Unixoid environment block. We don't care which order
3937 * these environment variables are in, so we sort both lists first. */
3939 smartlist_add_all(env_vars_sorted
, env_vars
);
3943 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
3944 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
3948 smartlist_sort_strings(env_vars_sorted
);
3949 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
3951 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
3952 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
3954 int len
= smartlist_len(env_vars_sorted
);
3957 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
3958 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
3961 for (i
= 0; i
< len
; ++i
) {
3962 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
3963 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
3968 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
3969 smartlist_free(env_vars_sorted
);
3971 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
3972 smartlist_free(env_vars
);
3974 process_environment_free(env
);
3977 /** Test set_environment_variable_in_smartlist */
3979 test_util_set_env_var_in_sl(void *ptr
)
3981 /* The environment variables in these strings are in arbitrary
3982 * order; we sort the resulting lists before comparing them.
3984 * (They *will not* end up in the order shown in
3985 * expected_resulting_env_vars_string.) */
3987 const char *base_env_vars_string
=
3988 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
3989 "HOME=/home/foozer\n"
3998 const char *new_env_vars_string
=
4003 const char *expected_resulting_env_vars_string
=
4004 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4005 "HOME=/home/foozer\n"
4015 smartlist_t
*merged_env_vars
=
4016 smartlist_new_from_text_lines(base_env_vars_string
);
4017 smartlist_t
*new_env_vars
=
4018 smartlist_new_from_text_lines(new_env_vars_string
);
4019 smartlist_t
*expected_resulting_env_vars
=
4020 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
4022 /* Elements of merged_env_vars are heap-allocated, and must be
4023 * freed. Some of them are (or should) be freed by
4024 * set_environment_variable_in_smartlist.
4026 * Elements of new_env_vars are heap-allocated, but are copied into
4027 * merged_env_vars, so they are not freed separately at the end of
4030 * Elements of expected_resulting_env_vars are heap-allocated, and
4035 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
4036 set_environment_variable_in_smartlist(merged_env_vars
,
4041 smartlist_sort_strings(merged_env_vars
);
4042 smartlist_sort_strings(expected_resulting_env_vars
);
4044 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
4045 smartlist_len(expected_resulting_env_vars
));
4047 int len
= smartlist_len(merged_env_vars
);
4050 if (smartlist_len(expected_resulting_env_vars
) < len
) {
4051 len
= smartlist_len(expected_resulting_env_vars
);
4054 for (i
= 0; i
< len
; ++i
) {
4055 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
4056 smartlist_get(expected_resulting_env_vars
, i
));
4061 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
4062 smartlist_free(merged_env_vars
);
4064 smartlist_free(new_env_vars
);
4066 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
4067 smartlist_free(expected_resulting_env_vars
);
4071 test_util_weak_random(void *arg
)
4077 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
4079 for (i
= 1; i
<= 256; ++i
) {
4080 for (j
=0;j
<100;++j
) {
4081 int r
= tor_weak_random_range(&rng
, i
);
4082 tt_int_op(0, OP_LE
, r
);
4083 tt_int_op(r
, OP_LT
, i
);
4087 memset(n
,0,sizeof(n
));
4088 for (j
=0;j
<8192;++j
) {
4089 n
[tor_weak_random_range(&rng
, 16)]++;
4093 tt_int_op(n
[i
], OP_GT
, 0);
4099 test_util_mathlog(void *arg
)
4104 d
= tor_mathlog(2.718281828);
4105 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
4106 d
= tor_mathlog(10);
4107 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
4113 test_util_round_to_next_multiple_of(void *arg
)
4117 tt_u64_op(round_uint64_to_next_multiple_of(0,1), ==, 0);
4118 tt_u64_op(round_uint64_to_next_multiple_of(0,7), ==, 0);
4120 tt_u64_op(round_uint64_to_next_multiple_of(99,1), ==, 99);
4121 tt_u64_op(round_uint64_to_next_multiple_of(99,7), ==, 105);
4122 tt_u64_op(round_uint64_to_next_multiple_of(99,9), ==, 99);
4124 tt_i64_op(round_int64_to_next_multiple_of(0,1), ==, 0);
4125 tt_i64_op(round_int64_to_next_multiple_of(0,7), ==, 0);
4127 tt_i64_op(round_int64_to_next_multiple_of(99,1), ==, 99);
4128 tt_i64_op(round_int64_to_next_multiple_of(99,7), ==, 105);
4129 tt_i64_op(round_int64_to_next_multiple_of(99,9), ==, 99);
4131 tt_i64_op(round_int64_to_next_multiple_of(-99,1), ==, -99);
4132 tt_i64_op(round_int64_to_next_multiple_of(-99,7), ==, -98);
4133 tt_i64_op(round_int64_to_next_multiple_of(-99,9), ==, -99);
4135 tt_i64_op(round_int64_to_next_multiple_of(INT64_MIN
,2), ==, INT64_MIN
);
4136 tt_i64_op(round_int64_to_next_multiple_of(INT64_MAX
,2), ==,
4137 INT64_MAX
-INT64_MAX
%2);
4143 test_util_laplace(void *arg
)
4145 /* Sample values produced using Python's SciPy:
4147 * >>> from scipy.stats import laplace
4148 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
4149 ... loc = 24, scale = 24)
4150 * array([ nan, -inf, -69.88855213, 24. ,
4151 * 24.48486498, 117.88855213, inf, nan])
4153 const double mu
= 24.0, b
= 24.0;
4154 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
4157 tt_i64_op(INT64_MIN
, ==, sample_laplace_distribution(mu
, b
, 0.0));
4158 tt_i64_op(-69, ==, sample_laplace_distribution(mu
, b
, 0.01));
4159 tt_i64_op(24, ==, sample_laplace_distribution(mu
, b
, 0.5));
4160 tt_i64_op(24, ==, sample_laplace_distribution(mu
, b
, 0.51));
4161 tt_i64_op(117, ==, sample_laplace_distribution(mu
, b
, 0.99));
4163 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
4164 * ... loc = 0, scale = 50)
4165 * array([ -inf, -80.47189562, -34.65735903, 0. ,
4166 * 34.65735903, 80.47189562, 195.60115027])
4168 tt_i64_op(INT64_MIN
+ 20, ==,
4169 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
4170 tt_i64_op(-60, ==, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
4171 tt_i64_op(-14, ==, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
4172 tt_i64_op(20, ==, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
4173 tt_i64_op(54, ==, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
4174 tt_i64_op(100, ==, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
4175 tt_i64_op(215, ==, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
4182 test_util_strclear(void *arg
)
4184 static const char *vals
[] = { "", "a", "abcdef", "abcdefgh", NULL
};
4189 for (i
= 0; vals
[i
]; ++i
) {
4191 v
= tor_strdup(vals
[i
]);
4194 tt_assert(tor_mem_is_zero(v
, n
+1));
4201 #define UTIL_LEGACY(name) \
4202 { #name, test_util_ ## name , 0, NULL, NULL }
4204 #define UTIL_TEST(name, flags) \
4205 { #name, test_util_ ## name, flags, NULL, NULL }
4208 #define CAN_CHECK_CLOEXEC
4210 fd_is_cloexec(tor_socket_t fd
)
4212 int flags
= fcntl(fd
, F_GETFD
, 0);
4213 return (flags
& FD_CLOEXEC
) == FD_CLOEXEC
;
4218 #define CAN_CHECK_NONBLOCK
4220 fd_is_nonblocking(tor_socket_t fd
)
4222 int flags
= fcntl(fd
, F_GETFL
, 0);
4223 return (flags
& O_NONBLOCK
) == O_NONBLOCK
;
4228 test_util_socket(void *arg
)
4230 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
4231 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
4232 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
4233 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
4234 int n
= get_n_open_sockets();
4236 TT_BLATHER(("Starting with %d open sockets.", n
));
4240 fd1
= tor_open_socket_with_extensions(AF_INET
, SOCK_STREAM
, 0, 0, 0);
4241 fd2
= tor_open_socket_with_extensions(AF_INET
, SOCK_STREAM
, 0, 0, 1);
4242 tt_assert(SOCKET_OK(fd1
));
4243 tt_assert(SOCKET_OK(fd2
));
4244 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
4245 //fd3 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 1, 0);
4246 //fd4 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 1, 1);
4247 fd3
= tor_open_socket(AF_INET
, SOCK_STREAM
, 0);
4248 fd4
= tor_open_socket_nonblocking(AF_INET
, SOCK_STREAM
, 0);
4249 tt_assert(SOCKET_OK(fd3
));
4250 tt_assert(SOCKET_OK(fd4
));
4251 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
4253 #ifdef CAN_CHECK_CLOEXEC
4254 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
4255 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
4256 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
4257 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
4259 #ifdef CAN_CHECK_NONBLOCK
4260 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
4261 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
4262 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
4263 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
4266 tor_close_socket(fd1
);
4267 tor_close_socket(fd2
);
4268 fd1
= fd2
= TOR_INVALID_SOCKET
;
4269 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
4270 tor_close_socket(fd3
);
4271 tor_close_socket(fd4
);
4272 fd3
= fd4
= TOR_INVALID_SOCKET
;
4273 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
4277 tor_close_socket(fd1
);
4279 tor_close_socket(fd2
);
4281 tor_close_socket(fd3
);
4283 tor_close_socket(fd4
);
4286 /* Test for socketpair and ersatz_socketpair(). We test them both, since
4287 * the latter is a tolerably good way to exersize tor_accept_socket(). */
4289 test_util_socketpair(void *arg
)
4291 const int ersatz
= !strcmp(arg
, "1");
4292 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
4293 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
4294 int n
= get_n_open_sockets();
4295 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
4296 const int family
= AF_UNIX
;
4298 tt_int_op(0, OP_EQ
, tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
));
4299 tt_assert(SOCKET_OK(fds
[0]));
4300 tt_assert(SOCKET_OK(fds
[1]));
4301 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
4302 #ifdef CAN_CHECK_CLOEXEC
4303 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, 1);
4304 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, 1);
4306 #ifdef CAN_CHECK_NONBLOCK
4307 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
4308 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
4312 if (SOCKET_OK(fds
[0]))
4313 tor_close_socket(fds
[0]);
4314 if (SOCKET_OK(fds
[1]))
4315 tor_close_socket(fds
[1]);
4319 test_util_max_mem(void *arg
)
4321 size_t memory1
, memory2
;
4325 r
= get_total_system_memory(&memory1
);
4326 r2
= get_total_system_memory(&memory2
);
4327 tt_int_op(r
, OP_EQ
, r2
);
4328 tt_uint_op(memory2
, OP_EQ
, memory1
);
4330 TT_BLATHER(("System memory: "U64_FORMAT
, U64_PRINTF_ARG(memory1
)));
4333 /* You have at least a megabyte. */
4334 tt_uint_op(memory1
, OP_GT
, (1<<20));
4336 /* You do not have a petabyte. */
4337 #if SIZEOF_SIZE_T == SIZEOF_UINT64_T
4338 tt_u64_op(memory1
, OP_LT
, (U64_LITERAL(1)<<50));
4347 test_util_hostname_validation(void *arg
)
4351 // Lets try valid hostnames first.
4352 tt_assert(string_is_valid_hostname("torproject.org"));
4353 tt_assert(string_is_valid_hostname("ocw.mit.edu"));
4354 tt_assert(string_is_valid_hostname("i.4cdn.org"));
4355 tt_assert(string_is_valid_hostname("stanford.edu"));
4356 tt_assert(string_is_valid_hostname("multiple-words-with-hypens.jp"));
4358 // Subdomain name cannot start with '-'.
4359 tt_assert(!string_is_valid_hostname("-torproject.org"));
4360 tt_assert(!string_is_valid_hostname("subdomain.-domain.org"));
4361 tt_assert(!string_is_valid_hostname("-subdomain.domain.org"));
4363 // Hostnames cannot contain non-alphanumeric characters.
4364 tt_assert(!string_is_valid_hostname("%%domain.\\org."));
4365 tt_assert(!string_is_valid_hostname("***x.net"));
4366 tt_assert(!string_is_valid_hostname("___abc.org"));
4367 tt_assert(!string_is_valid_hostname("\xff\xffxyz.org"));
4368 tt_assert(!string_is_valid_hostname("word1 word2.net"));
4370 // XXX: do we allow single-label DNS names?
4377 test_util_ipv4_validation(void *arg
)
4381 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
4382 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
4384 tt_assert(!string_is_valid_ipv4_address("abcd"));
4385 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
4386 tt_assert(!string_is_valid_ipv4_address("8.8."));
4392 struct testcase_t util_tests
[] = {
4394 UTIL_TEST(parse_http_time
, 0),
4395 UTIL_LEGACY(config_line
),
4396 UTIL_LEGACY(config_line_quotes
),
4397 UTIL_LEGACY(config_line_comment_character
),
4398 UTIL_LEGACY(config_line_escaped_content
),
4400 UTIL_LEGACY(expand_filename
),
4402 UTIL_LEGACY(escape_string_socks
),
4403 UTIL_LEGACY(string_is_key_value
),
4404 UTIL_LEGACY(strmisc
),
4407 UTIL_LEGACY(datadir
),
4408 #ifdef ENABLE_MEMPOOLS
4409 UTIL_LEGACY(mempool
),
4411 UTIL_LEGACY(memarea
),
4412 UTIL_LEGACY(control_formats
),
4414 UTIL_LEGACY(sscanf
),
4415 UTIL_LEGACY(format_time_interval
),
4416 UTIL_LEGACY(path_is_relative
),
4417 UTIL_LEGACY(strtok
),
4418 UTIL_LEGACY(di_ops
),
4419 UTIL_TEST(round_to_next_multiple_of
, 0),
4420 UTIL_TEST(laplace
, 0),
4421 UTIL_TEST(strclear
, 0),
4422 UTIL_TEST(find_str_at_start_of_line
, 0),
4423 UTIL_TEST(string_is_C_identifier
, 0),
4424 UTIL_TEST(asprintf
, 0),
4425 UTIL_TEST(listdir
, 0),
4426 UTIL_TEST(parent_dir
, 0),
4427 UTIL_TEST(ftruncate
, 0),
4429 UTIL_TEST(load_win_lib
, 0),
4432 UTIL_TEST(exit_status
, 0),
4433 UTIL_TEST(fgets_eagain
, 0),
4435 UTIL_TEST(format_hex_number
, 0),
4436 UTIL_TEST(format_dec_number
, 0),
4437 UTIL_TEST(join_win_cmdline
, 0),
4438 UTIL_TEST(split_lines
, 0),
4439 UTIL_TEST(n_bits_set
, 0),
4440 UTIL_TEST(eat_whitespace
, 0),
4441 UTIL_TEST(sl_new_from_text_lines
, 0),
4442 UTIL_TEST(envnames
, 0),
4443 UTIL_TEST(make_environment
, 0),
4444 UTIL_TEST(set_env_var_in_sl
, 0),
4445 UTIL_TEST(read_file_eof_tiny_limit
, 0),
4446 UTIL_TEST(read_file_eof_one_loop_a
, 0),
4447 UTIL_TEST(read_file_eof_one_loop_b
, 0),
4448 UTIL_TEST(read_file_eof_two_loops
, 0),
4449 UTIL_TEST(read_file_eof_two_loops_b
, 0),
4450 UTIL_TEST(read_file_eof_zero_bytes
, 0),
4451 UTIL_TEST(write_chunks_to_file
, 0),
4452 UTIL_TEST(mathlog
, 0),
4453 UTIL_TEST(weak_random
, 0),
4454 UTIL_TEST(socket
, TT_FORK
),
4455 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
4457 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
4458 &passthrough_setup
, (void*)"1" },
4459 UTIL_TEST(max_mem
, 0),
4460 UTIL_TEST(hostname_validation
, 0),
4461 UTIL_TEST(ipv4_validation
, 0),