summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test.h9
-rw-r--r--src/test/test_addr.c8
-rw-r--r--src/test/test_dir.c2
-rw-r--r--src/test/test_util.c1520
-rw-r--r--src/test/tinytest.c50
-rw-r--r--src/test/tinytest.h18
-rw-r--r--src/test/tinytest_demo.c2
-rw-r--r--src/test/tinytest_macros.h78
8 files changed, 1357 insertions, 330 deletions
diff --git a/src/test/test.h b/src/test/test.h
index 0fcb02a41c..4d5117aea7 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -34,18 +34,17 @@
#define test_neq_ptr(expr1, expr2) tt_ptr_op((expr1), !=, (expr2))
#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2))
#define test_strneq(expr1, expr2) tt_str_op((expr1), !=, (expr2))
-#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2))
#define test_mem_op(expr1, op, expr2, len) \
tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \
const char *, \
- (memcmp(_val1, _val2, len) op 0), \
+ (memcmp(val1_, val2_, len) op 0), \
char *, "%s", \
{ size_t printlen = (len)*2+1; \
- _print = tor_malloc(printlen); \
- base16_encode(_print, printlen, _value, \
+ print_ = tor_malloc(printlen); \
+ base16_encode(print_, printlen, value_, \
(len)); }, \
- { tor_free(_print); }, \
+ { tor_free(print_); }, \
TT_EXIT_TEST_FUNCTION \
);
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index cf9c8f91d5..3838b8072b 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -73,17 +73,17 @@ test_addr_basic(void)
#define _test_op_ip6(a,op,b,e1,e2) \
STMT_BEGIN \
tt_assert_test_fmt_type(a,b,e1" "#op" "e2,struct in6_addr*, \
- (memcmp(_val1->s6_addr, _val2->s6_addr, 16) op 0), \
+ (memcmp(val1_->s6_addr, val2_->s6_addr, 16) op 0), \
char *, "%s", \
{ int i; char *cp; \
- cp = _print = tor_malloc(64); \
+ cp = print_ = tor_malloc(64); \
for (i=0;i<16;++i) { \
- tor_snprintf(cp, 3,"%02x", (unsigned)_value->s6_addr[i]);\
+ tor_snprintf(cp, 3,"%02x", (unsigned)value_->s6_addr[i]);\
cp += 2; \
if (i != 15) *cp++ = ':'; \
} \
}, \
- { tor_free(_print); }, \
+ { tor_free(print_); }, \
TT_EXIT_TEST_FUNCTION \
); \
STMT_END
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index fb2351957b..0ed54c33d0 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -305,7 +305,7 @@ test_dir_versions(void)
#define tt_versionstatus_op(vs1, op, vs2) \
tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
- (_val1 op _val2),"%d",TT_EXIT_TEST_FUNCTION)
+ (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
#define test_v_i_o(val, ver, lst) \
tt_versionstatus_op(val, ==, tor_version_is_obsolete(ver, lst))
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 508c15596d..9da4cb7994 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -24,6 +24,8 @@ test_util_time(void)
int i;
struct timeval tv;
+ /* Test tv_udiff */
+
start.tv_sec = 5;
start.tv_usec = 5000;
@@ -48,9 +50,8 @@ test_util_time(void)
test_eq(-1005000L, tv_udiff(&start, &end));
- end.tv_usec = 999990;
- start.tv_sec = 1;
- start.tv_usec = 500;
+
+ /* Test tor_timegm */
/* The test values here are confirmed to be correct on a platform
* with a working timegm. */
@@ -66,6 +67,18 @@ test_util_time(void)
a_time.tm_mon = 1; /* Try a leap year, in feb. */
a_time.tm_mday = 10;
test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
+ a_time.tm_mon = 0;
+ a_time.tm_mday = 10;
+ test_eq((time_t) 1073715295UL, tor_timegm(&a_time));
+ a_time.tm_mon = 12; /* Wrong month, it's 0-based */
+ a_time.tm_mday = 10;
+ test_eq((time_t) -1, tor_timegm(&a_time));
+ a_time.tm_mon = -1; /* Wrong month */
+ a_time.tm_mday = 10;
+ test_eq((time_t) -1, tor_timegm(&a_time));
+
+
+ /* Test {format,parse}_rfc1123_time */
format_rfc1123_time(timestr, 0);
test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
@@ -74,9 +87,66 @@ test_util_time(void)
t_res = 0;
i = parse_rfc1123_time(timestr, &t_res);
- test_eq(i,0);
+ test_eq(0,i);
+ test_eq(t_res, (time_t)1091580502UL);
+ /* The timezone doesn't matter */
+ t_res = 0;
+ test_eq(0, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
test_eq(t_res, (time_t)1091580502UL);
test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
+
+#if 0
+ /* This fails, I imagine it's important and should be fixed? */
+ test_eq(-1, parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res));
+ /* Why is this string valid (ie. the test fails because it doesn't
+ return -1)? */
+ test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res));
+#endif
+
+
+ /* Test parse_iso_time */
+
+ t_res = 0;
+ i = parse_iso_time("", &t_res);
+ test_eq(-1, i);
+ t_res = 0;
+ i = parse_iso_time("2004-08-32 00:48:22", &t_res);
+ test_eq(-1, i);
+ t_res = 0;
+ i = parse_iso_time("1969-08-03 00:48:22", &t_res);
+ test_eq(-1, i);
+
+ t_res = 0;
+ i = parse_iso_time("2004-08-04 00:48:22", &t_res);
+ test_eq(0,i);
+ test_eq(t_res, (time_t)1091580502UL);
+ t_res = 0;
+ i = parse_iso_time("2004-8-4 0:48:22", &t_res);
+ test_eq(0, i);
+ test_eq(t_res, (time_t)1091580502UL);
+ test_eq(-1, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res));
+ test_eq(-1, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res));
+ test_eq(-1, parse_iso_time("2011-03-30 23:59", &t_res));
+
+
+ /* Test tor_gettimeofday */
+
+ end.tv_sec = 4;
+ end.tv_usec = 999990;
+ start.tv_sec = 1;
+ start.tv_usec = 500;
tor_gettimeofday(&start);
/* now make sure time works. */
@@ -84,7 +154,9 @@ test_util_time(void)
/* We might've timewarped a little. */
tt_int_op(tv_udiff(&start, &end), >=, -5000);
- /* Now let's check some format_iso_time variants */
+
+ /* Test format_iso_time */
+
tv.tv_sec = (time_t)1326296338;
tv.tv_usec = 3060;
format_iso_time(timestr, tv.tv_sec);
@@ -243,6 +315,331 @@ test_util_config_line(void)
tor_free(v);
}
+static void
+test_util_config_line_quotes(void)
+{
+ char buf1[1024];
+ char buf2[128];
+ char buf3[128];
+ char buf4[128];
+ char *k=NULL, *v=NULL;
+ const char *str;
+
+ /* Test parse_config_line_from_str */
+ strlcpy(buf1, "kTrailingSpace \"quoted value\" \n"
+ "kTrailingGarbage \"quoted value\"trailing garbage\n"
+ , sizeof(buf1));
+ strlcpy(buf2, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
+ , sizeof(buf2));
+ strlcpy(buf3, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
+ , sizeof(buf3));
+ strlcpy(buf4, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
+ , sizeof(buf4));
+ str = buf1;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "kTrailingSpace");
+ test_streq(v, "quoted value");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ str = buf2;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ str = buf3;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ str = buf4;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ done:
+ tor_free(k);
+ tor_free(v);
+}
+
+static void
+test_util_config_line_comment_character(void)
+{
+ char buf[1024];
+ char *k=NULL, *v=NULL;
+ const char *str;
+
+ /* Test parse_config_line_from_str */
+ strlcpy(buf, "k1 \"# in quotes\"\n"
+ "k2 some value # some comment\n"
+ "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
+ , sizeof(buf));
+ str = buf;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k1");
+ test_streq(v, "# in quotes");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k2");
+ test_streq(v, "some value");
+ tor_free(k); tor_free(v);
+
+#if 0
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k3");
+ test_streq(v, "/home/user/myTorNetwork#2");
+ tor_free(k); tor_free(v);
+
+ test_streq(str, "");
+#endif
+
+ done:
+ tor_free(k);
+ tor_free(v);
+}
+
+static void
+test_util_config_line_escaped_content(void)
+{
+ char buf1[1024];
+ char buf2[128];
+ char buf3[128];
+ char buf4[128];
+ char buf5[128];
+ char buf6[128];
+ char *k=NULL, *v=NULL;
+ const char *str;
+
+ /* Test parse_config_line_from_str */
+ strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
+ "HexadecimalUpper \"\\x2A\"\n"
+ "HexadecimalUpperX \"\\X2A\"\n"
+ "Octal \"\\52\"\n"
+ "Newline \"\\n\"\n"
+ "Tab \"\\t\"\n"
+ "CarriageReturn \"\\r\"\n"
+ "DoubleQuote \"\\\"\"\n"
+ "SimpleQuote \"\\'\"\n"
+ "Backslash \"\\\\\"\n"
+ "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
+ , sizeof(buf1));
+
+ strlcpy(buf2, "BrokenEscapedContent \"\\a\"\n"
+ , sizeof(buf2));
+
+ strlcpy(buf3, "BrokenEscapedContent \"\\x\"\n"
+ , sizeof(buf3));
+
+ strlcpy(buf4, "BrokenOctal \"\\8\"\n"
+ , sizeof(buf4));
+
+ strlcpy(buf5, "BrokenHex \"\\xg4\"\n"
+ , sizeof(buf5));
+
+ strlcpy(buf6, "BrokenEscape \"\\"
+ , sizeof(buf6));
+
+ str = buf1;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "HexadecimalLower");
+ test_streq(v, "*");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "HexadecimalUpper");
+ test_streq(v, "*");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "HexadecimalUpperX");
+ test_streq(v, "*");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "Octal");
+ test_streq(v, "*");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "Newline");
+ test_streq(v, "\n");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "Tab");
+ test_streq(v, "\t");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "CarriageReturn");
+ test_streq(v, "\r");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "DoubleQuote");
+ test_streq(v, "\"");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "SimpleQuote");
+ test_streq(v, "'");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "Backslash");
+ test_streq(v, "\\");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "Mix");
+ test_streq(v, "This is a \"star\":\t'*'\nAnd second line");
+ tor_free(k); tor_free(v);
+
+ str = buf2;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ str = buf3;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ str = buf4;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+#if 0
+ str = buf5;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+#endif
+
+ str = buf6;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_eq_ptr(str, NULL);
+ tor_free(k); tor_free(v);
+
+ done:
+ tor_free(k);
+ tor_free(v);
+}
+
+#ifndef MS_WINDOWS
+static void
+test_util_expand_filename(void)
+{
+ char *str;
+
+ setenv("HOME", "/home/itv", 1); /* For "internal test value" */
+
+ str = expand_filename("");
+ test_streq("", str);
+ tor_free(str);
+
+ str = expand_filename("/normal/path");
+ test_streq("/normal/path", str);
+ tor_free(str);
+
+ str = expand_filename("/normal/trailing/path/");
+ test_streq("/normal/trailing/path/", str);
+ tor_free(str);
+
+ str = expand_filename("~");
+ test_streq("/home/itv/", str);
+ tor_free(str);
+
+ str = expand_filename("$HOME/nodice");
+ test_streq("$HOME/nodice", str);
+ tor_free(str);
+
+ str = expand_filename("~/");
+ test_streq("/home/itv/", str);
+ tor_free(str);
+
+ str = expand_filename("~/foobarqux");
+ test_streq("/home/itv/foobarqux", str);
+ tor_free(str);
+
+ str = expand_filename("~/../../etc/passwd");
+ test_streq("/home/itv/../../etc/passwd", str);
+ tor_free(str);
+
+ str = expand_filename("~/trailing/");
+ test_streq("/home/itv/trailing/", str);
+ tor_free(str);
+ /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
+ have to somehow inject/fake the get_user_homedir call) */
+
+ /* $HOME ending in a trailing slash */
+ setenv("HOME", "/home/itv/", 1);
+
+ str = expand_filename("~");
+ test_streq("/home/itv/", str);
+ tor_free(str);
+
+ str = expand_filename("~/");
+ test_streq("/home/itv/", str);
+ tor_free(str);
+
+ str = expand_filename("~/foo");
+ test_streq("/home/itv/foo", str);
+ tor_free(str);
+
+ /* Try with empty $HOME */
+
+ setenv("HOME", "", 1);
+
+ str = expand_filename("~");
+ test_streq("/", str);
+ tor_free(str);
+
+ str = expand_filename("~/");
+ test_streq("/", str);
+ tor_free(str);
+
+ str = expand_filename("~/foobar");
+ test_streq("/foobar", str);
+ tor_free(str);
+
+ /* Try with $HOME unset */
+
+ unsetenv("HOME");
+
+ str = expand_filename("~");
+ test_streq("/", str);
+ tor_free(str);
+
+ str = expand_filename("~/");
+ test_streq("/", str);
+ tor_free(str);
+
+ str = expand_filename("~/foobar");
+ test_streq("/foobar", str);
+ tor_free(str);
+
+ done:
+ tor_free(str);
+}
+#endif
+
/** Test basic string functionality. */
static void
test_util_strmisc(void)
@@ -251,90 +648,169 @@ test_util_strmisc(void)
int i;
char *cp;
- /* Tests for corner cases of strl operations */
+ /* Test strl operations */
test_eq(5, strlcpy(buf, "Hello", 0));
+ test_eq(5, strlcpy(buf, "Hello", 10));
+ test_streq(buf, "Hello");
+ test_eq(5, strlcpy(buf, "Hello", 6));
+ test_streq(buf, "Hello");
+ test_eq(5, strlcpy(buf, "Hello", 5));
+ test_streq(buf, "Hell");
strlcpy(buf, "Hello", sizeof(buf));
test_eq(10, strlcat(buf, "Hello", 5));
- /* Test tor_strstrip() */
+ /* Test strstrip() */
strlcpy(buf, "Testing 1 2 3", sizeof(buf));
tor_strstrip(buf, ",!");
test_streq(buf, "Testing 1 2 3");
strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
tor_strstrip(buf, "!? ");
test_streq(buf, "Testing123");
+ strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
+ tor_strstrip(buf, "!? ");
+ test_streq(buf, "Testing123");
- /* Test tor_parse_long. */
- test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
- test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
- test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
-
- /* Test tor_parse_ulong */
+ /* Test parse_long */
+ /* Empty/zero input */
+ test_eq(0L, tor_parse_long("",10,0,100,&i,NULL));
+ test_eq(0, i);
+ test_eq(0L, tor_parse_long("0",10,0,100,&i,NULL));
+ test_eq(1, i);
+ /* Normal cases */
+ test_eq(10L, tor_parse_long("10",10,0,100,&i,NULL));
+ test_eq(1, i);
+ test_eq(10L, tor_parse_long("10",10,0,10,&i,NULL));
+ test_eq(1, i);
+ test_eq(10L, tor_parse_long("10",10,10,100,&i,NULL));
+ test_eq(1, i);
+ test_eq(-50L, tor_parse_long("-50",10,-100,100,&i,NULL));
+ test_eq(1, i);
+ test_eq(-50L, tor_parse_long("-50",10,-100,0,&i,NULL));
+ test_eq(1, i);
+ test_eq(-50L, tor_parse_long("-50",10,-50,0,&i,NULL));
+ test_eq(1, i);
+ /* Extra garbage */
+ test_eq(0L, tor_parse_long("10m",10,0,100,&i,NULL));
+ test_eq(0, i);
+ test_eq(0L, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
+ test_eq(0, i);
+ test_eq(10L, tor_parse_long("10m",10,0,100,&i,&cp));
+ test_eq(1, i);
+ test_streq(cp, "m");
+ test_eq(-50L, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
+ test_eq(1, i);
+ test_streq(cp, " plus garbage");
+ /* Out of bounds */
+ test_eq(0L, tor_parse_long("10",10,50,100,&i,NULL));
+ test_eq(0, i);
+ test_eq(0L, tor_parse_long("-50",10,0,100,&i,NULL));
+ test_eq(0, i);
+ /* Base different than 10 */
+ test_eq(2L, tor_parse_long("10",2,0,100,NULL,NULL));
+ test_eq(0L, tor_parse_long("2",2,0,100,NULL,NULL));
+ test_eq(0L, tor_parse_long("10",-2,0,100,NULL,NULL));
+ test_eq(68284L, tor_parse_long("10abc",16,0,70000,NULL,NULL));
+ test_eq(68284L, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
+
+ /* Test parse_ulong */
+ test_eq(0UL, tor_parse_ulong("",10,0,100,NULL,NULL));
+ test_eq(0UL, tor_parse_ulong("0",10,0,100,NULL,NULL));
test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
+ test_eq(10UL, tor_parse_ulong("10",10,0,10,NULL,NULL));
+ test_eq(10UL, tor_parse_ulong("10",10,10,100,NULL,NULL));
+ test_eq(0UL, tor_parse_ulong("8",8,0,100,NULL,NULL));
+ test_eq(50UL, tor_parse_ulong("50",10,50,100,NULL,NULL));
+ test_eq(0UL, tor_parse_ulong("-50",10,-100,100,NULL,NULL));
- /* Test tor_parse_uint64. */
+ /* Test parse_uint64 */
test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
- test_assert(i == 1);
+ test_eq(1, i);
test_streq(cp, " x");
test_assert(U64_LITERAL(12345678901) ==
tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
- test_assert(i == 1);
+ test_eq(1, i);
test_streq(cp, "");
test_assert(U64_LITERAL(0) ==
tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
- test_assert(i == 0);
+ test_eq(0, i);
{
- /* Test tor_parse_double. */
+ /* Test parse_double */
double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
- test_assert(i == 1);
+ test_eq(1, i);
test_assert(DBL_TO_U64(d) == 10);
d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
- test_assert(i == 1);
+ test_eq(1, i);
test_assert(DBL_TO_U64(d) == 0);
d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
- test_assert(i == 0);
+ test_eq(0, i);
d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
- test_assert(i == 0);
+ test_eq(0, i);
d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
- test_assert(i == 1);
+ test_eq(1, i);
d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
- test_assert(i == 1);
+ test_eq(1, i);
+ test_assert(DBL_TO_U64(d) == 0);
+ d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
+ test_eq(1, i);
+ test_eq(-10.0, d);
}
- /* Test failing snprintf cases */
+ /* Test snprintf */
+ /* Returning -1 when there's not enough room in the output buffer */
test_eq(-1, tor_snprintf(buf, 0, "Foo"));
test_eq(-1, tor_snprintf(buf, 2, "Foo"));
-
- /* Test printf with uint64 */
+ test_eq(-1, tor_snprintf(buf, 3, "Foo"));
+ test_neq(-1, tor_snprintf(buf, 4, "Foo"));
+ /* Always NUL-terminate the output */
+ tor_snprintf(buf, 5, "abcdef");
+ test_eq(0, buf[4]);
+ tor_snprintf(buf, 10, "abcdef");
+ test_eq(0, buf[6]);
+ /* uint64 */
tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
U64_PRINTF_ARG(U64_LITERAL(12345678901)));
- test_streq(buf, "x!12345678901!x");
+ test_streq("x!12345678901!x", buf);
- /* Test for strcmpstart and strcmpend. */
+ /* Test str{,case}cmpstart */
test_assert(strcmpstart("abcdef", "abcdef")==0);
test_assert(strcmpstart("abcdef", "abc")==0);
test_assert(strcmpstart("abcdef", "abd")<0);
test_assert(strcmpstart("abcdef", "abb")>0);
test_assert(strcmpstart("ab", "abb")<0);
-
+ test_assert(strcmpstart("ab", "")==0);
+ test_assert(strcmpstart("ab", "ab ")<0);
+ test_assert(strcasecmpstart("abcdef", "abCdEF")==0);
+ test_assert(strcasecmpstart("abcDeF", "abc")==0);
+ test_assert(strcasecmpstart("abcdef", "Abd")<0);
+ test_assert(strcasecmpstart("Abcdef", "abb")>0);
+ test_assert(strcasecmpstart("ab", "Abb")<0);
+ test_assert(strcasecmpstart("ab", "")==0);
+ test_assert(strcasecmpstart("ab", "ab ")<0);
+
+ /* Test str{,case}cmpend */
test_assert(strcmpend("abcdef", "abcdef")==0);
test_assert(strcmpend("abcdef", "def")==0);
test_assert(strcmpend("abcdef", "deg")<0);
test_assert(strcmpend("abcdef", "dee")>0);
- test_assert(strcmpend("ab", "abb")<0);
-
+ test_assert(strcmpend("ab", "aab")>0);
test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
test_assert(strcasecmpend("abcdef", "dEF")==0);
- test_assert(strcasecmpend("abcDEf", "deg")<0);
- test_assert(strcasecmpend("abcdef", "DEE")>0);
- test_assert(strcasecmpend("ab", "abB")<0);
+ test_assert(strcasecmpend("abcdef", "Deg")<0);
+ test_assert(strcasecmpend("abcDef", "dee")>0);
+ test_assert(strcasecmpend("AB", "abb")<0);
+
+ /* Test digest_is_zero */
+ memset(buf,0,20);
+ buf[20] = 'x';
+ test_assert(tor_digest_is_zero(buf));
+ buf[19] = 'x';
+ test_assert(!tor_digest_is_zero(buf));
/* Test mem_is_zero */
memset(buf,0,128);
buf[128] = 'x';
- test_assert(tor_digest_is_zero(buf));
test_assert(tor_mem_is_zero(buf, 10));
test_assert(tor_mem_is_zero(buf, 20));
test_assert(tor_mem_is_zero(buf, 128));
@@ -345,11 +821,15 @@ test_util_strmisc(void)
test_assert(!tor_mem_is_zero(buf, 10));
/* Test 'escaped' */
+ test_assert(NULL == escaped(NULL));
test_streq("\"\"", escaped(""));
test_streq("\"abcd\"", escaped("abcd"));
- test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
- test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
- test_assert(NULL == escaped(NULL));
+ test_streq("\"\\\\ \\n\\r\\t\\\"\\'\"", escaped("\\ \n\r\t\"'"));
+ test_streq("\"unnecessary \\'backslashes\\'\"",
+ escaped("unnecessary \'backslashes\'"));
+ /* Non-printable characters appear as octal */
+ test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
+ test_streq("\"z\\336\\255 ;foo\"", escaped("z\xde\xad\x20;foo"));
/* Test strndup and memdup */
{
@@ -377,6 +857,9 @@ test_util_strmisc(void)
test_assert(!tor_strisnonupper(cp));
tor_strupper(cp);
test_streq(cp, "ABCDEF");
+ tor_strlower(cp);
+ test_streq(cp, "abcdef");
+ test_assert(tor_strisnonupper(cp));
test_assert(tor_strisprint(cp));
cp[3] = 3;
test_assert(!tor_strisprint(cp));
@@ -385,24 +868,32 @@ test_util_strmisc(void)
/* Test memmem and memstr */
{
const char *haystack = "abcde";
- tt_assert(!tor_memmem(haystack, 5, "ef", 2));
+ test_assert(!tor_memmem(haystack, 5, "ef", 2));
test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
+ test_assert(!tor_memmem(haystack, 4, "cde", 3));
haystack = "ababcad";
test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
+ /* memstr */
test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
+ test_eq_ptr(tor_memstr(haystack, 7, "cad"), haystack + 4);
+ test_assert(!tor_memstr(haystack, 6, "cad"));
+ test_assert(!tor_memstr(haystack, 7, "cadd"));
test_assert(!tor_memstr(haystack, 7, "fe"));
- test_assert(!tor_memstr(haystack, 7, "longerthantheoriginal"));
+ test_assert(!tor_memstr(haystack, 7, "ababcade"));
}
/* Test wrap_string */
{
smartlist_t *sl = smartlist_new();
- wrap_string(sl, "This is a test of string wrapping functionality: woot.",
+ wrap_string(sl,
+ "This is a test of string wrapping functionality: woot. "
+ "a functionality? w00t w00t...!",
10, "", "");
cp = smartlist_join_strings(sl, "", 0, NULL);
test_streq(cp,
- "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
+ "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n"
+ "a\nfunctional\nity? w00t\nw00t...!\n");
tor_free(cp);
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
@@ -413,15 +904,59 @@ test_util_strmisc(void)
test_streq(cp,
"### This is a\n# test of string\n# wrapping\n# functionality:\n"
"# woot.\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "A test of string wrapping...", 6, "### ", "# ");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "### A\n# test\n# of\n# stri\n# ng\n# wrap\n# ping\n# ...\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "Wrapping test", 6, "#### ", "# ");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "#### W\n# rapp\n# ing\n# test\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "Small test", 6, "### ", "#### ");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "### Sm\n#### a\n#### l\n#### l\n#### t\n#### e\n#### s\n#### t\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "First null", 6, NULL, "> ");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "First\n> null\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "Second null", 6, "> ", NULL);
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "> Seco\nnd\nnull\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+ wrap_string(sl, "Both null", 6, NULL, NULL);
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp, "Both\nnull\n");
tor_free(cp);
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_free(sl);
+
+ /* Can't test prefixes that have the same length as the line width, because
+ the function has an assert */
}
/* Test hex_str */
{
- char binary_data[64];
+ char binary_data[68];
size_t i;
for (i = 0; i < sizeof(binary_data); ++i)
binary_data[i] = i;
@@ -431,7 +966,36 @@ test_util_strmisc(void)
test_streq(hex_str(binary_data, 32),
"000102030405060708090A0B0C0D0E0F"
"101112131415161718191A1B1C1D1E1F");
+ test_streq(hex_str(binary_data, 34),
+ "000102030405060708090A0B0C0D0E0F"
+ "101112131415161718191A1B1C1D1E1F");
+ /* Repeat these tests for shorter strings after longer strings
+ have been tried, to make sure we're correctly terminating strings */
+ test_streq(hex_str(binary_data, 1), "00");
+ test_streq(hex_str(binary_data, 0), "");
}
+
+ /* Test strcmp_opt */
+ tt_int_op(strcmp_opt("", "foo"), <, 0);
+ tt_int_op(strcmp_opt("", ""), ==, 0);
+ tt_int_op(strcmp_opt("foo", ""), >, 0);
+
+ tt_int_op(strcmp_opt(NULL, ""), <, 0);
+ tt_int_op(strcmp_opt(NULL, NULL), ==, 0);
+ tt_int_op(strcmp_opt("", NULL), >, 0);
+
+ tt_int_op(strcmp_opt(NULL, "foo"), <, 0);
+ tt_int_op(strcmp_opt("foo", NULL), >, 0);
+
+ /* Test strcmp_len */
+ tt_int_op(strcmp_len("foo", "bar", 3), >, 0);
+ tt_int_op(strcmp_len("foo", "bar", 2), <, 0); /* First len, then lexical */
+ tt_int_op(strcmp_len("foo2", "foo1", 4), >, 0);
+ tt_int_op(strcmp_len("foo2", "foo1", 3), <, 0); /* Really stop at len */
+ tt_int_op(strcmp_len("foo2", "foo", 3), ==, 0); /* Really stop at len */
+ tt_int_op(strcmp_len("blah", "", 4), >, 0);
+ tt_int_op(strcmp_len("blah", "", 0), ==, 0);
+
done:
;
}
@@ -619,13 +1183,14 @@ test_util_gzip(void)
test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
GZIP_METHOD));
test_assert(buf2);
- test_assert(!memcmp(buf2, "\037\213", 2)); /* Gzip magic. */
+ test_assert(len1 < strlen(buf1));
test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
GZIP_METHOD, 1, LOG_INFO));
test_assert(buf3);
- test_streq(buf1,buf3);
+ test_eq(strlen(buf1) + 1, len2);
+ test_streq(buf1, buf3);
tor_free(buf2);
tor_free(buf3);
@@ -634,13 +1199,13 @@ test_util_gzip(void)
test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
ZLIB_METHOD));
test_assert(buf2);
- test_assert(!memcmp(buf2, "\x78\xDA", 2)); /* deflate magic. */
test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
ZLIB_METHOD, 1, LOG_INFO));
test_assert(buf3);
- test_streq(buf1,buf3);
+ test_eq(strlen(buf1) + 1, len2);
+ test_streq(buf1, buf3);
/* Check whether we can uncompress concatenated, compressed strings. */
tor_free(buf3);
@@ -648,7 +1213,7 @@ test_util_gzip(void)
memcpy(buf2+len1, buf2, len1);
test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
ZLIB_METHOD, 1, LOG_INFO));
- test_eq(len2, (strlen(buf1)+1)*2);
+ test_eq((strlen(buf1)+1)*2, len2);
test_memeq(buf3,
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
@@ -667,8 +1232,8 @@ test_util_gzip(void)
/* when we allow an incomplete string, we should succeed.*/
tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
ZLIB_METHOD, 0, LOG_INFO));
- buf3[len2]='\0';
tt_assert(len2 > 5);
+ buf3[len2]='\0';
tt_assert(!strcmpstart(buf1, buf3));
/* when we demand a complete string, this must fail. */
@@ -689,19 +1254,20 @@ test_util_gzip(void)
len2 = 21;
test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
== TOR_ZLIB_OK);
- test_eq(len2, 0); /* Make sure we compressed it all. */
+ test_eq(0, len2); /* Make sure we compressed it all. */
test_assert(cp1 > buf1);
len2 = 0;
cp2 = cp1;
test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
== TOR_ZLIB_DONE);
- test_eq(len2, 0);
+ test_eq(0, len2);
test_assert(cp1 > cp2); /* Make sure we really added something. */
tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
ZLIB_METHOD, 1, LOG_WARN));
test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
+ test_eq(21, len2);
done:
if (state)
@@ -728,8 +1294,6 @@ test_util_mmap(void)
test_assert(! mapping);
write_str_to_file(fname1, "Short file.", 1);
- write_bytes_to_file(fname2, buf, buflen, 1);
- write_bytes_to_file(fname3, buf, 16384, 1);
mapping = tor_mmap_file(fname1);
test_assert(mapping);
@@ -756,9 +1320,10 @@ test_util_mmap(void)
/* Make sure that we fail to map a no-longer-existent file. */
mapping = tor_mmap_file(fname1);
- test_assert(mapping == NULL);
+ test_assert(! mapping);
/* Now try a big file that stretches across a few pages and isn't aligned */
+ write_bytes_to_file(fname2, buf, buflen, 1);
mapping = tor_mmap_file(fname2);
test_assert(mapping);
test_eq(mapping->size, buflen);
@@ -767,6 +1332,7 @@ test_util_mmap(void)
mapping = NULL;
/* Now try a big aligned file. */
+ write_bytes_to_file(fname3, buf, 16384, 1);
mapping = tor_mmap_file(fname3);
test_assert(mapping);
test_eq(mapping->size, 16384);
@@ -794,12 +1360,12 @@ test_util_control_formats(void)
{
char *out = NULL;
const char *inp =
- "..This is a test\r\nof the emergency \nbroadcast\r\n..system.\r\nZ.\r\n";
+ "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
size_t sz;
sz = read_escaped_data(inp, strlen(inp), &out);
test_streq(out,
- ".This is a test\nof the emergency \nbroadcast\n.system.\nZ.\n");
+ ".This is a test\nof the emergency \n.system.\n\rZ.\n");
test_eq(sz, strlen(out));
done:
@@ -810,97 +1376,167 @@ static void
test_util_sscanf(void)
{
unsigned u1, u2, u3;
- char s1[10], s2[10], s3[10], ch;
+ char s1[20], s2[10], s3[10], ch;
int r;
- r = tor_sscanf("hello world", "hello world"); /* String match: success */
- test_eq(r, 0);
- r = tor_sscanf("hello world 3", "hello worlb %u", &u1); /* String fail */
- test_eq(r, 0);
- r = tor_sscanf("12345", "%u", &u1); /* Simple number */
- test_eq(r, 1);
- test_eq(u1, 12345u);
- r = tor_sscanf("", "%u", &u1); /* absent number */
- test_eq(r, 0);
- r = tor_sscanf("A", "%u", &u1); /* bogus number */
- test_eq(r, 0);
- r = tor_sscanf("4294967295", "%u", &u1); /* UINT32_MAX should work. */
- test_eq(r, 1);
- test_eq(u1, 4294967295u);
- r = tor_sscanf("4294967296", "%u", &u1); /* Always say -1 at 32 bits. */
- test_eq(r, 0);
- r = tor_sscanf("123456", "%2u%u", &u1, &u2); /* Width */
- test_eq(r, 2);
- test_eq(u1, 12u);
- test_eq(u2, 3456u);
- r = tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3); /* separators */
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 456u);
- r = tor_sscanf("12:3:045", "%2u:%2u:%3u", &u1, &u2, &u3); /* 0s */
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 45u);
+ /* Simple tests (malformed patterns, literal matching, ...) */
+ test_eq(-1, tor_sscanf("123", "%i", &r)); /* %i is not supported */
+ test_eq(-1, tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
+ test_eq(-1, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
+ test_eq(-1, tor_sscanf("prettylongstring", "%999999s", s1));
+ test_eq(-1, tor_sscanf("We're the 99 monkeys", "We're the 99%%"));
+#if 0
+ /* GCC thinks these two are illegal. */
+ test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
+ test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
+#endif
+ /* No '%'-strings: always "success" */
+ test_eq(0, tor_sscanf("hello world", "hello world"));
+ test_eq(0, tor_sscanf("hello world", "good bye"));
+ /* Excess data */
+ test_eq(0, tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
+ test_eq(0, tor_sscanf(" 3 hello", "%u", &u1));
+ test_eq(0, tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
+ test_eq(1, tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
+
+ /* Numbers (ie. %u) */
+ test_eq(0, tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
+ test_eq(1, tor_sscanf("12345", "%u", &u1));
+ test_eq(12345u, u1);
+ test_eq(1, tor_sscanf("12346 ", "%u", &u1));
+ test_eq(12346u, u1);
+ test_eq(0, tor_sscanf(" 12347", "%u", &u1));
+ test_eq(1, tor_sscanf(" 12348", " %u", &u1));
+ test_eq(12348u, u1);
+ test_eq(1, tor_sscanf("0", "%u", &u1));
+ test_eq(0u, u1);
+ test_eq(1, tor_sscanf("0000", "%u", &u2));
+ test_eq(0u, u2);
+ test_eq(0, tor_sscanf("", "%u", &u1)); /* absent number */
+ test_eq(0, tor_sscanf("A", "%u", &u1)); /* bogus number */
+ test_eq(0, tor_sscanf("-1", "%u", &u1)); /* negative number */
+ test_eq(1, tor_sscanf("4294967295", "%u", &u1)); /* UINT32_MAX should work */
+ test_eq(4294967295u, u1);
+ test_eq(0, tor_sscanf("4294967296", "%u", &u1)); /* But not at 32 bits */
+ test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); /* but parsing only 9... */
+ test_eq(429496729u, u1);
+
+ /* Numbers with size (eg. %2u) */
+ test_eq(0, tor_sscanf("-1", "%2u", &u1));
+ test_eq(2, tor_sscanf("123456", "%2u%u", &u1, &u2));
+ test_eq(12u, u1);
+ test_eq(3456u, u2);
+ test_eq(1, tor_sscanf("123456", "%8u", &u1));
+ test_eq(123456u, u1);
+ test_eq(1, tor_sscanf("123457 ", "%8u", &u1));
+ test_eq(123457u, u1);
+ test_eq(0, tor_sscanf(" 123456", "%8u", &u1));
+ test_eq(3, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
+ test_eq(12u, u1);
+ test_eq(3u, u2);
+ test_eq(456u, u3);
+ test_eq(3, tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
+ test_eq(67u, u1);
+ test_eq(8u, u2);
+ test_eq(99u, u3);
/* %u does not match space.*/
- r = tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3);
- test_eq(r, 2);
+ test_eq(2, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
+ test_eq(12u, u1);
+ test_eq(3u, u2);
/* %u does not match negative numbers. */
- r = tor_sscanf("12:3:-4", "%2u:%2u:%3u", &u1, &u2, &u3);
- test_eq(r, 2);
+ test_eq(2, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
+ test_eq(67u, u1);
+ test_eq(8u, u2);
/* Arbitrary amounts of 0-padding are okay */
- r = tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1, &u2, &u3);
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 99u);
-
- /* %x should work. */
- r = tor_sscanf("1234 02aBcdEf", "%x %x", &u1, &u2);
- test_eq(r, 2);
- test_eq(u1, 0x1234);
- test_eq(u2, 0x2ABCDEF);
+ test_eq(3, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
+ &u1, &u2, &u3));
+ test_eq(12u, u1);
+ test_eq(3u, u2);
+ test_eq(99u, u3);
+
+ /* Hex (ie. %x) */
+ test_eq(3, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
+ test_eq(0x1234, u1);
+ test_eq(0x2ABCDEF, u2);
+ test_eq(0xFF, u3);
/* Width works on %x */
- r = tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3);
- test_eq(r, 3);
- test_eq(u1, 0xf00d);
- test_eq(u2, 0xcafe);
- test_eq(u3, 444);
-
- r = tor_sscanf("99% fresh", "%3u%% fresh", &u1); /* percents are scannable.*/
- test_eq(r, 1);
- test_eq(u1, 99);
-
- r = tor_sscanf("hello", "%s", s1); /* %s needs a number. */
- test_eq(r, -1);
-
- r = tor_sscanf("hello", "%3s%7s", s1, s2); /* %s matches characters. */
- test_eq(r, 2);
+ test_eq(3, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
+ test_eq(0xf00d, u1);
+ test_eq(0xcafe, u2);
+ test_eq(444, u3);
+
+ /* Literal '%' (ie. '%%') */
+ test_eq(1, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
+ test_eq(99, u1);
+ test_eq(1, tor_sscanf("% boo", "%% %3s", s1));
+ test_streq("boo", s1);
+
+ /* Strings (ie. %s) */
+ test_eq(2, tor_sscanf("hello", "%3s%7s", s1, s2));
test_streq(s1, "hel");
test_streq(s2, "lo");
- r = tor_sscanf("WD40", "%2s%u", s3, &u1); /* %s%u */
- test_eq(r, 2);
+ test_eq(2, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
test_streq(s3, "WD");
- test_eq(u1, 40);
- r = tor_sscanf("76trombones", "%6u%9s", &u1, s1); /* %u%s */
- test_eq(r, 2);
- test_eq(u1, 76);
+ test_eq(40, u1);
+ test_eq(2, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
+ test_streq(s3, "WD4");
+ test_eq(0, u1);
+ test_eq(2, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
+ test_eq(76, u1);
test_streq(s1, "trombones");
- r = tor_sscanf("hello world", "%9s %9s", s1, s2); /* %s doesn't eat space. */
- test_eq(r, 2);
+ test_eq(1, tor_sscanf("prettylongstring", "%999s", s1));
+ test_streq(s1, "prettylongstring");
+ /* %s doesn't eat spaces */
+ test_eq(2, tor_sscanf("hello world", "%9s %9s", s1, s2));
test_streq(s1, "hello");
test_streq(s2, "world");
- r = tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3); /* %s can be empty. */
- test_eq(r, 3);
+ test_eq(2, tor_sscanf("bye world?", "%9s %9s", s1, s2));
+ test_streq(s1, "bye");
+ test_streq(s2, "");
+ test_eq(3, tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
test_streq(s1, "hi");
test_streq(s2, "");
test_streq(s3, "");
- r = tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
- test_eq(r, 3);
- r = tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
- test_eq(r, 4);
+ test_eq(3, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
+ test_eq(4, tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
+ test_eq(' ', ch);
+
+ done:
+ ;
+}
+
+static void
+test_util_path_is_relative(void)
+{
+ /* OS-independent tests */
+ test_eq(1, path_is_relative(""));
+ test_eq(1, path_is_relative("dir"));
+ test_eq(1, path_is_relative("dir/"));
+ test_eq(1, path_is_relative("./dir"));
+ test_eq(1, path_is_relative("../dir"));
+
+ test_eq(0, path_is_relative("/"));
+ test_eq(0, path_is_relative("/dir"));
+ test_eq(0, path_is_relative("/dir/"));
+
+ /* Windows */
+#ifdef MS_WINDOWS
+ /* I don't have Windows so I can't test this, hence the "#ifdef
+ 0". These are tests that look useful, so please try to get them
+ running and uncomment if it all works as it should */
+#ifdef 0
+ test_eq(1, path_is_relative("dir"));
+ test_eq(1, path_is_relative("dir\\"));
+ test_eq(1, path_is_relative("dir\\a:"));
+ test_eq(1, path_is_relative("dir\\a:\\"));
+
+ test_eq(0, path_is_relative("\\dir"));
+ test_eq(0, path_is_relative("a:\\dir"));
+ test_eq(0, path_is_relative("z:\\dir"));
+ test_eq(0, path_is_relative("http:\\dir"));
+#endif
+#endif
done:
;
@@ -1121,8 +1757,28 @@ test_util_strtok(void)
test_streq("perfect", S2());
test_streq("descent", S1());
test_streq("monument", S2());
- test_assert(NULL == S1());
- test_assert(NULL == S2());
+ test_eq_ptr(NULL, S1());
+ test_eq_ptr(NULL, S2());
+
+#if 0
+ buf[0] = 0;
+ test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
+ test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1));
+
+ strlcpy(buf, "Howdy!", sizeof(buf));
+ test_streq("Howdy", tor_strtok_r_impl(buf, "!", &cp1));
+ test_eq_ptr(NULL, tor_strtok_r_impl(NULL, "!", &cp1));
+
+ strlcpy(buf, " ", sizeof(buf));
+ test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
+ strlcpy(buf, " ", sizeof(buf));
+ test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
+#endif
+
+ strlcpy(buf, "something ", sizeof(buf));
+ test_streq("something", tor_strtok_r_impl(buf, " ", &cp1));
+ test_streq(" ", tor_strtok_r_impl(NULL, ";", &cp1));
+ test_eq_ptr(NULL, tor_strtok_r_impl(NULL, " ", &cp1));
done:
;
}
@@ -1131,24 +1787,64 @@ static void
test_util_find_str_at_start_of_line(void *ptr)
{
const char *long_string =
- "hello world. hello world. hello hello. howdy.\n"
- "hello hello world\n";
+ "howdy world. how are you? i hope it's fine.\n"
+ "hello kitty\n"
+ "third line";
+ char *line2 = strchr(long_string,'\n')+1;
+ char *line3 = strchr(line2,'\n')+1;
+ const char *short_string = "hello kitty\n"
+ "second line\n";
+ char *short_line2 = strchr(short_string,'\n')+1;
(void)ptr;
- /* not-found case. */
- tt_assert(! find_str_at_start_of_line(long_string, "fred"));
+ test_eq_ptr(long_string, find_str_at_start_of_line(long_string, ""));
+ test_eq_ptr(NULL, find_str_at_start_of_line(short_string, "nonsense"));
+ test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "nonsense"));
+ test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "\n"));
+ test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "how "));
+ test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "kitty"));
+ test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "h"));
+ test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "how"));
+ test_eq_ptr(line2, find_str_at_start_of_line(long_string, "he"));
+ test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hell"));
+ test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello k"));
+ test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\n"));
+ test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\nt"));
+ test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third"));
+ test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third line"));
+ test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "third line\n"));
+ test_eq_ptr(short_line2, find_str_at_start_of_line(short_string,
+ "second line\n"));
+ done:
+ ;
+}
- /* not-found case where haystack doesn't end with \n */
- tt_assert(! find_str_at_start_of_line("foobar\nbaz", "fred"));
+static void
+test_util_string_is_C_identifier(void *ptr)
+{
+ (void)ptr;
- /* start-of-string case */
- tt_assert(long_string ==
- find_str_at_start_of_line(long_string, "hello world."));
+ test_eq(1, string_is_C_identifier("string_is_C_identifier"));
+ test_eq(1, string_is_C_identifier("_string_is_C_identifier"));
+ test_eq(1, string_is_C_identifier("_"));
+ test_eq(1, string_is_C_identifier("i"));
+ test_eq(1, string_is_C_identifier("_____"));
+ test_eq(1, string_is_C_identifier("__00__"));
+ test_eq(1, string_is_C_identifier("__init__"));
+ test_eq(1, string_is_C_identifier("_0"));
+ test_eq(1, string_is_C_identifier("_0string_is_C_identifier"));
+ test_eq(1, string_is_C_identifier("_0"));
+
+ test_eq(0, string_is_C_identifier("0_string_is_C_identifier"));
+ test_eq(0, string_is_C_identifier("0"));
+ test_eq(0, string_is_C_identifier(""));
+ test_eq(0, string_is_C_identifier(";"));
+ test_eq(0, string_is_C_identifier("i;"));
+ test_eq(0, string_is_C_identifier("_;"));
+ test_eq(0, string_is_C_identifier("í"));
+ test_eq(0, string_is_C_identifier("ñ"));
- /* start-of-line case */
- tt_assert(strchr(long_string,'\n')+1 ==
- find_str_at_start_of_line(long_string, "hello hello"));
done:
;
}
@@ -1162,36 +1858,47 @@ test_util_asprintf(void *ptr)
int r;
(void)ptr;
- /* empty string. */
+ /* simple string */
+ r = tor_asprintf(&cp, "simple string 100%% safe");
+ test_assert(cp);
+ test_streq("simple string 100% safe", cp);
+ test_eq(strlen(cp), r);
+
+ /* empty string */
r = tor_asprintf(&cp, "%s", "");
- tt_assert(cp);
- tt_int_op(r, ==, strlen(cp));
- tt_str_op(cp, ==, "");
+ test_assert(cp);
+ test_streq("", cp);
+ test_eq(strlen(cp), r);
+
+ /* numbers (%i) */
+ r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
+ test_assert(cp);
+ test_streq("I like numbers--1, 2, etc.", cp);
+ test_eq(strlen(cp), r);
- /* Short string with some printing in it. */
+ /* numbers (%d) */
r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
- tt_assert(cp2);
- tt_int_op(r, ==, strlen(cp2));
- tt_str_op(cp2, ==, "First=101, Second=202");
- tt_assert(cp != cp2);
+ test_assert(cp2);
+ test_eq(strlen(cp2), r);
+ test_streq("First=101, Second=202", cp2);
+ test_assert(cp != cp2);
tor_free(cp);
tor_free(cp2);
/* Glass-box test: a string exactly 128 characters long. */
r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
- tt_assert(cp);
- tt_int_op(r, ==, 128);
- tt_assert(cp[128] == '\0');
- tt_str_op(cp, ==,
- "Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM);
+ test_assert(cp);
+ test_eq(128, r);
+ test_assert(cp[128] == '\0');
+ test_streq("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM, cp);
tor_free(cp);
/* String longer than 128 characters */
r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
- tt_assert(cp);
- tt_int_op(r, ==, strlen(cp));
- tt_str_op(cp, ==, "1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM);
+ test_assert(cp);
+ test_eq(strlen(cp), r);
+ test_streq("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM, cp);
done:
tor_free(cp);
@@ -1202,24 +1909,40 @@ static void
test_util_listdir(void *ptr)
{
smartlist_t *dir_contents = NULL;
- char *fname1=NULL, *fname2=NULL, *dirname=NULL;
+ char *fname1=NULL, *fname2=NULL, *fname3=NULL, *dir1=NULL, *dirname=NULL;
+ int r;
(void)ptr;
fname1 = tor_strdup(get_fname("hopscotch"));
fname2 = tor_strdup(get_fname("mumblety-peg"));
+ fname3 = tor_strdup(get_fname(".hidden-file"));
+ dir1 = tor_strdup(get_fname("some-directory"));
dirname = tor_strdup(get_fname(NULL));
- tt_int_op(write_str_to_file(fname1, "X\n", 0), ==, 0);
- tt_int_op(write_str_to_file(fname2, "Y\n", 0), ==, 0);
+ test_eq(0, write_str_to_file(fname1, "X\n", 0));
+ test_eq(0, write_str_to_file(fname2, "Y\n", 0));
+ test_eq(0, write_str_to_file(fname3, "Z\n", 0));
+#ifdef MS_WINDOWS
+ r = mkdir(dir1);
+#else
+ r = mkdir(dir1, 0700);
+#endif
+ if (r) {
+ fprintf(stderr, "Can't create directory %s:", dir1);
+ perror("");
+ exit(1);
+ }
dir_contents = tor_listdir(dirname);
- tt_assert(dir_contents);
+ test_assert(dir_contents);
/* make sure that each filename is listed. */
- tt_assert(smartlist_string_isin_case(dir_contents, "hopscotch"));
- tt_assert(smartlist_string_isin_case(dir_contents, "mumblety-peg"));
+ test_assert(smartlist_string_isin_case(dir_contents, "hopscotch"));
+ test_assert(smartlist_string_isin_case(dir_contents, "mumblety-peg"));
+ test_assert(smartlist_string_isin_case(dir_contents, ".hidden-file"));
+ test_assert(smartlist_string_isin_case(dir_contents, "some-directory"));
- tt_assert(!smartlist_string_isin(dir_contents, "."));
- tt_assert(!smartlist_string_isin(dir_contents, ".."));
+ test_assert(!smartlist_string_isin(dir_contents, "."));
+ test_assert(!smartlist_string_isin(dir_contents, ".."));
done:
tor_free(fname1);
@@ -1237,24 +1960,46 @@ test_util_parent_dir(void *ptr)
char *cp;
(void)ptr;
-#define T(input,expect_ok,output) \
+#define T(output,expect_ok,input) \
do { \
int ok; \
cp = tor_strdup(input); \
ok = get_parent_directory(cp); \
- tt_int_op(ok, ==, expect_ok); \
+ tt_int_op(expect_ok, ==, ok); \
if (ok==0) \
- tt_str_op(cp, ==, output); \
+ tt_str_op(output, ==, cp); \
tor_free(cp); \
} while (0);
- T("/home/wombat/knish", 0, "/home/wombat");
- T("/home/wombat/knish/", 0, "/home/wombat");
- T("./home/wombat/knish/", 0, "./home/wombat");
- T("./wombat", 0, ".");
+ T("/home/wombat", 0, "/home/wombat/knish");
+ T("/home/wombat", 0, "/home/wombat/knish/");
+ T("/home/wombat", 0, "/home/wombat/knish///");
+ T("./home/wombat", 0, "./home/wombat/knish/");
+#if 0
+ T("/", 0, "/home");
+ T("/", 0, "/home//");
+#endif
+ T(".", 0, "./wombat");
+ T(".", 0, "./wombat/");
+ T(".", 0, "./wombat//");
+ T("wombat", 0, "wombat/foo");
+ T("wombat/..", 0, "wombat/../foo");
+ T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
+ T("wombat/.", 0, "wombat/./foo");
+ T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
+ T("wombat", 0, "wombat/..//");
+ T("wombat", 0, "wombat/foo/");
+ T("wombat", 0, "wombat/.foo");
+ T("wombat", 0, "wombat/.foo/");
+
T("", -1, "");
- T("/", -1, "");
- T("////", -1, "");
+ T("", -1, ".");
+ T("", -1, "..");
+ T("", -1, "../");
+ T("", -1, "/");
+ T("", -1, "////");
+ T("", -1, "wombat");
+ T("", -1, "wombat/");
done:
tor_free(cp);
@@ -1290,23 +2035,23 @@ test_util_exit_status(void *ptr)
clear_hex_errno(hex_errno);
format_helper_exit_status(0, 0, hex_errno);
- tt_str_op(hex_errno, ==, " 0/0\n");
+ test_streq(" 0/0\n", hex_errno);
clear_hex_errno(hex_errno);
format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
- tt_str_op(hex_errno, ==, " 0/7FFFFFFF\n");
+ test_streq(" 0/7FFFFFFF\n", hex_errno);
clear_hex_errno(hex_errno);
format_helper_exit_status(0xFF, -0x80000000, hex_errno);
- tt_str_op(hex_errno, ==, "FF/-80000000\n");
+ test_streq("FF/-80000000\n", hex_errno);
clear_hex_errno(hex_errno);
format_helper_exit_status(0x7F, 0, hex_errno);
- tt_str_op(hex_errno, ==, " 7F/0\n");
+ test_streq(" 7F/0\n", hex_errno);
clear_hex_errno(hex_errno);
format_helper_exit_status(0x08, -0x242, hex_errno);
- tt_str_op(hex_errno, ==, " 8/-242\n");
+ test_streq(" 8/-242\n", hex_errno);
done:
;
@@ -1418,37 +2163,37 @@ run_util_spawn_background(const char *argv[], const char *expected_out,
status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
#endif
- tt_int_op(status, ==, expected_status);
+ test_eq(expected_status, status);
if (status == PROCESS_STATUS_ERROR)
return;
- tt_assert(process_handle != NULL);
- tt_int_op(process_handle->status, ==, expected_status);
+ test_assert(process_handle != NULL);
+ test_eq(expected_status, process_handle->status);
- tt_int_op(process_handle->stdout_pipe, >, 0);
- tt_int_op(process_handle->stderr_pipe, >, 0);
+ test_assert(process_handle->stdout_pipe > 0);
+ test_assert(process_handle->stderr_pipe > 0);
/* Check stdout */
pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
sizeof(stdout_buf) - 1);
tt_assert(pos >= 0);
stdout_buf[pos] = '\0';
- tt_str_op(stdout_buf, ==, expected_out);
- tt_int_op(pos, ==, strlen(expected_out));
+ test_eq(strlen(expected_out), pos);
+ test_streq(expected_out, stdout_buf);
/* Check it terminated correctly */
retval = tor_get_exit_code(process_handle, 1, &exit_code);
- tt_int_op(retval, ==, PROCESS_EXIT_EXITED);
- tt_int_op(exit_code, ==, expected_exit);
+ test_eq(PROCESS_EXIT_EXITED, retval);
+ test_eq(expected_exit, exit_code);
// TODO: Make test-child exit with something other than 0
/* Check stderr */
pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
sizeof(stderr_buf) - 1);
- tt_assert(pos >= 0);
+ test_assert(pos >= 0);
stderr_buf[pos] = '\0';
- tt_str_op(stderr_buf, ==, expected_err);
- tt_int_op(pos, ==, strlen(expected_err));
+ test_streq(expected_err, stderr_buf);
+ test_eq(strlen(expected_err), pos);
done:
if (process_handle)
@@ -1538,9 +2283,9 @@ test_util_spawn_background_partial_read(void *ptr)
#else
status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
#endif
- tt_int_op(status, ==, expected_status);
- tt_assert(process_handle);
- tt_int_op(process_handle->status, ==, expected_status);
+ test_eq(expected_status, status);
+ test_assert(process_handle);
+ test_eq(expected_status, process_handle->status);
/* Check stdout */
for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
@@ -1549,7 +2294,7 @@ test_util_spawn_background_partial_read(void *ptr)
sizeof(stdout_buf) - 1, NULL);
#else
/* Check that we didn't read the end of file last time */
- tt_assert(!eof);
+ test_assert(!eof);
pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
sizeof(stdout_buf) - 1, NULL, &eof);
#endif
@@ -1559,10 +2304,10 @@ test_util_spawn_background_partial_read(void *ptr)
if (0 == pos)
continue;
- tt_int_op(pos, >, 0);
+ test_assert(pos > 0);
stdout_buf[pos] = '\0';
- tt_str_op(stdout_buf, ==, expected_out[expected_out_ctr]);
- tt_int_op(pos, ==, strlen(expected_out[expected_out_ctr]));
+ test_streq(expected_out[expected_out_ctr], stdout_buf);
+ test_eq(strlen(expected_out[expected_out_ctr]), pos);
expected_out_ctr++;
}
@@ -1571,33 +2316,33 @@ test_util_spawn_background_partial_read(void *ptr)
pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
sizeof(stdout_buf) - 1,
process_handle);
- tt_int_op(pos, ==, 0);
+ test_eq(0, pos);
#else
if (!eof) {
/* We should have got all the data, but maybe not the EOF flag */
pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
sizeof(stdout_buf) - 1,
process_handle, &eof);
- tt_int_op(pos, ==, 0);
- tt_assert(eof);
+ test_eq(0, pos);
+ test_assert(eof);
}
/* Otherwise, we got the EOF on the last read */
#endif
/* Check it terminated correctly */
retval = tor_get_exit_code(process_handle, 1, &exit_code);
- tt_int_op(retval, ==, PROCESS_EXIT_EXITED);
- tt_int_op(exit_code, ==, expected_exit);
+ test_eq(PROCESS_EXIT_EXITED, retval);
+ test_eq(expected_exit, exit_code);
// TODO: Make test-child exit with something other than 0
/* Check stderr */
pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
sizeof(stderr_buf) - 1);
- tt_assert(pos >= 0);
+ test_assert(pos >= 0);
stderr_buf[pos] = '\0';
- tt_str_op(stderr_buf, ==, expected_err);
- tt_int_op(pos, ==, strlen(expected_err));
+ test_streq(expected_err, stderr_buf);
+ test_eq(strlen(expected_err), pos);
done:
tor_process_handle_destroy(process_handle, 1);
@@ -1646,7 +2391,7 @@ test_util_join_win_cmdline(void *ptr)
for (i=0; cmdlines[i]!=NULL; i++) {
log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
joined_argv = tor_join_win_cmdline(argvs[i]);
- tt_str_op(joined_argv, ==, cmdlines[i]);
+ test_streq(cmdlines[i], joined_argv);
tor_free(joined_argv);
}
@@ -1654,7 +2399,7 @@ test_util_join_win_cmdline(void *ptr)
;
}
-#define MAX_SPLIT_LINE_COUNT 3
+#define MAX_SPLIT_LINE_COUNT 4
struct split_lines_test_t {
const char *orig_line; // Line to be split (may contain \0's)
int orig_length; // Length of orig_line
@@ -1675,6 +2420,12 @@ test_util_split_lines(void *ptr)
{"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL}},
{"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL}},
{"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL}},
+ {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL}},
+ {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL}},
+ {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL}},
+ {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL}},
+ {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL}},
+ {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL}},
{NULL, 0, { NULL }}
};
@@ -1696,17 +2447,17 @@ test_util_split_lines(void *ptr)
SMARTLIST_FOREACH(sl, const char *, line,
{
/* Check we have not got too many lines */
- tt_int_op(j, <, MAX_SPLIT_LINE_COUNT);
+ test_assert(j < MAX_SPLIT_LINE_COUNT);
/* Check that there actually should be a line here */
- tt_assert(tests[i].split_line[j] != NULL);
+ test_assert(tests[i].split_line[j] != NULL);
log_info(LD_GENERAL, "Line %d of test %d, should be <%s>",
j, i, tests[i].split_line[j]);
/* Check that the line is as expected */
- tt_str_op(tests[i].split_line[j], ==, line);
+ test_streq(line, tests[i].split_line[j]);
j++;
});
/* Check that we didn't miss some lines */
- tt_assert(tests[i].split_line[j] == NULL);
+ test_eq_ptr(NULL, tests[i].split_line[j]);
tor_free(orig_line);
smartlist_free(sl);
sl = NULL;
@@ -1777,10 +2528,12 @@ static void
test_util_n_bits_set(void *ptr)
{
(void)ptr;
- test_eq(n_bits_set_u8(0), 0);
- test_eq(n_bits_set_u8(1), 1);
- test_eq(n_bits_set_u8(129), 2);
- test_eq(n_bits_set_u8(255), 8);
+ test_eq(0, n_bits_set_u8(0));
+ test_eq(1, n_bits_set_u8(1));
+ test_eq(3, n_bits_set_u8(7));
+ test_eq(1, n_bits_set_u8(8));
+ test_eq(2, n_bits_set_u8(129));
+ test_eq(8, n_bits_set_u8(255));
done:
;
}
@@ -1801,61 +2554,323 @@ test_util_eat_whitespace(void *ptr)
strcpy(str, "fuubaar");
for (i = 0; i < sizeof(ws); ++i) {
str[0] = ws[i];
- test_streq(eat_whitespace(str), str + 1);
- test_streq(eat_whitespace_eos(str, str + strlen(str)), str + 1);
- test_streq(eat_whitespace_eos_no_nl(str, str + strlen(str)), str + 1);
- test_streq(eat_whitespace_no_nl(str), str + 1);
+ test_eq_ptr(str + 1, eat_whitespace(str));
+ test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
+ test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
}
str[0] = '\n';
- test_streq(eat_whitespace(str), str + 1);
- test_streq(eat_whitespace_eos(str, str + strlen(str)), str + 1);
+ test_eq_ptr(str + 1, eat_whitespace(str));
+ test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str, eat_whitespace_no_nl(str));
+ test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Empty string */
strcpy(str, "");
- test_eq_ptr(eat_whitespace(str), str);
- test_eq_ptr(eat_whitespace_eos(str, str), str);
- test_eq_ptr(eat_whitespace_eos_no_nl(str, str), str);
- test_eq_ptr(eat_whitespace_no_nl(str), str);
+ test_eq_ptr(str, eat_whitespace(str));
+ test_eq_ptr(str, eat_whitespace_eos(str, str));
+ test_eq_ptr(str, eat_whitespace_no_nl(str));
+ test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str));
/* Only ws */
strcpy(str, " \t\r\n");
- test_eq_ptr(eat_whitespace(str), str + strlen(str));
- test_eq_ptr(eat_whitespace_eos(str, str + strlen(str)), str + strlen(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + strlen(str) - 1,
+ eat_whitespace_no_nl(str));
+ test_eq_ptr(str + strlen(str) - 1,
+ eat_whitespace_eos_no_nl(str, str + strlen(str)));
strcpy(str, " \t\r ");
- test_eq_ptr(eat_whitespace_no_nl(str), str + strlen(str));
- test_eq_ptr(eat_whitespace_eos_no_nl(str, str + strlen(str)),
- str + strlen(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace(str));
+ test_eq_ptr(str + strlen(str),
+ eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + strlen(str), eat_whitespace_no_nl(str));
+ test_eq_ptr(str + strlen(str),
+ eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Multiple ws */
strcpy(str, "fuubaar");
for (i = 0; i < sizeof(ws); ++i)
str[i] = ws[i];
- test_streq(eat_whitespace(str), str + sizeof(ws));
- test_streq(eat_whitespace_eos(str, str + strlen(str)), str + sizeof(ws));
- test_streq(eat_whitespace_no_nl(str), str + sizeof(ws));
- test_streq(eat_whitespace_eos_no_nl(str, str + strlen(str)),
- str + sizeof(ws));
+ test_eq_ptr(str + sizeof(ws), eat_whitespace(str));
+ test_eq_ptr(str + sizeof(ws), eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + sizeof(ws), eat_whitespace_no_nl(str));
+ test_eq_ptr(str + sizeof(ws),
+ eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat comment */
strcpy(str, "# Comment \n No Comment");
- test_streq(eat_whitespace(str), "No Comment");
- test_streq(eat_whitespace_eos(str, str + strlen(str)), "No Comment");
+ test_streq("No Comment", eat_whitespace(str));
+ test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str, eat_whitespace_no_nl(str));
+ test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat comment & ws mix */
strcpy(str, " # \t Comment \n\t\nNo Comment");
- test_streq(eat_whitespace(str), "No Comment");
- test_streq(eat_whitespace_eos(str, str + strlen(str)), "No Comment");
+ test_streq("No Comment", eat_whitespace(str));
+ test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
+ test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat entire comment */
strcpy(str, "#Comment");
- test_eq_ptr(eat_whitespace(str), str + strlen(str));
- test_eq_ptr(eat_whitespace_eos(str, str + strlen(str)), str + strlen(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str, eat_whitespace_no_nl(str));
+ test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+
+ /* Blank line, then comment */
+ strcpy(str, " \t\n # Comment");
+ test_eq_ptr(str + strlen(str), eat_whitespace(str));
+ test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
+ test_eq_ptr(str + 2, eat_whitespace_no_nl(str));
+ test_eq_ptr(str + 2, eat_whitespace_eos_no_nl(str, str + strlen(str)));
done:
;
}
+/** Return a newly allocated smartlist containing the lines of text in
+ * <b>lines</b>. The returned strings are heap-allocated, and must be
+ * freed by the caller.
+ *
+ * XXXX? Move to container.[hc] ? */
+static smartlist_t *
+smartlist_new_from_text_lines(const char *lines)
+{
+ smartlist_t *sl = smartlist_new();
+ char *last_line;
+
+ smartlist_split_string(sl, lines, "\n", 0, 0);
+
+ last_line = smartlist_pop_last(sl);
+ if (last_line != NULL && *last_line != '\0') {
+ smartlist_add(sl, last_line);
+ }
+
+ return sl;
+}
+
+/** Test smartlist_new_from_text_lines */
+static void
+test_util_sl_new_from_text_lines(void *ptr)
+{
+ (void)ptr;
+
+ { /* Normal usage */
+ smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz\n");
+ int sl_len = smartlist_len(sl);
+
+ tt_want_int_op(sl_len, ==, 3);
+
+ if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
+ if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), ==, "bar");
+ if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), ==, "baz");
+
+ SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
+ smartlist_free(sl);
+ }
+
+ { /* No final newline */
+ smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz");
+ int sl_len = smartlist_len(sl);
+
+ tt_want_int_op(sl_len, ==, 3);
+
+ if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
+ if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), ==, "bar");
+ if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), ==, "baz");
+
+ SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
+ smartlist_free(sl);
+ }
+
+ { /* No newlines */
+ smartlist_t *sl = smartlist_new_from_text_lines("foo");
+ int sl_len = smartlist_len(sl);
+
+ tt_want_int_op(sl_len, ==, 1);
+
+ if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
+
+ SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
+ smartlist_free(sl);
+ }
+
+ { /* No text at all */
+ smartlist_t *sl = smartlist_new_from_text_lines("");
+ int sl_len = smartlist_len(sl);
+
+ tt_want_int_op(sl_len, ==, 0);
+
+ SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
+ smartlist_free(sl);
+ }
+}
+
+/** Test process_environment_make */
+static void
+test_util_make_environment(void *ptr)
+{
+ const char *env_vars_string =
+ "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
+ "HOME=/home/foozer\n";
+ const char expected_windows_env_block[] =
+ "HOME=/home/foozer\000"
+ "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
+ "\000";
+ size_t expected_windows_env_block_len =
+ sizeof(expected_windows_env_block) - 1;
+
+ smartlist_t *env_vars = smartlist_new_from_text_lines(env_vars_string);
+ smartlist_t *env_vars_sorted = smartlist_new();
+ smartlist_t *env_vars_in_unixoid_env_block_sorted = smartlist_new();
+
+ process_environment_t *env;
+
+ (void)ptr;
+
+ env = process_environment_make(env_vars);
+
+ /* Check that the Windows environment block is correct. */
+ tt_want(tor_memeq(expected_windows_env_block, env->windows_environment_block,
+ expected_windows_env_block_len));
+
+ /* Now for the Unixoid environment block. We don't care which order
+ * these environment variables are in, so we sort both lists first. */
+
+ smartlist_add_all(env_vars_sorted, env_vars);
+
+ {
+ char **v;
+ for (v = env->unixoid_environment_block; *v; ++v) {
+ smartlist_add(env_vars_in_unixoid_env_block_sorted, *v);
+ }
+ }
+
+ smartlist_sort_strings(env_vars_sorted);
+ smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted);
+
+ tt_want_int_op(smartlist_len(env_vars_sorted), ==,
+ smartlist_len(env_vars_in_unixoid_env_block_sorted));
+ {
+ int len = smartlist_len(env_vars_sorted);
+ int i;
+
+ if (smartlist_len(env_vars_in_unixoid_env_block_sorted) < len) {
+ len = smartlist_len(env_vars_in_unixoid_env_block_sorted);
+ }
+
+ for (i = 0; i < len; ++i) {
+ tt_want_str_op(smartlist_get(env_vars_sorted, i), ==,
+ smartlist_get(env_vars_in_unixoid_env_block_sorted, i));
+ }
+ }
+
+ /* Clean up. */
+ smartlist_free(env_vars_in_unixoid_env_block_sorted);
+ smartlist_free(env_vars_sorted);
+
+ SMARTLIST_FOREACH(env_vars, char *, x, tor_free(x));
+ smartlist_free(env_vars);
+
+ process_environment_free(env);
+}
+
+/** Test set_environment_variable_in_smartlist */
+static void
+test_util_set_env_var_in_sl(void *ptr)
+{
+ /* The environment variables in these strings are in arbitrary
+ * order; we sort the resulting lists before comparing them.
+ *
+ * (They *will not* end up in the order shown in
+ * expected_resulting_env_vars_string.) */
+
+ const char *base_env_vars_string =
+ "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
+ "HOME=/home/foozer\n"
+ "TERM=xterm\n"
+ "SHELL=/bin/ksh\n"
+ "USER=foozer\n"
+ "LOGNAME=foozer\n"
+ "USERNAME=foozer\n"
+ "LANG=en_US.utf8\n"
+ ;
+
+ const char *new_env_vars_string =
+ "TERM=putty\n"
+ "DISPLAY=:18.0\n"
+ ;
+
+ const char *expected_resulting_env_vars_string =
+ "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
+ "HOME=/home/foozer\n"
+ "TERM=putty\n"
+ "SHELL=/bin/ksh\n"
+ "USER=foozer\n"
+ "LOGNAME=foozer\n"
+ "USERNAME=foozer\n"
+ "LANG=en_US.utf8\n"
+ "DISPLAY=:18.0\n"
+ ;
+
+ smartlist_t *merged_env_vars =
+ smartlist_new_from_text_lines(base_env_vars_string);
+ smartlist_t *new_env_vars =
+ smartlist_new_from_text_lines(new_env_vars_string);
+ smartlist_t *expected_resulting_env_vars =
+ smartlist_new_from_text_lines(expected_resulting_env_vars_string);
+
+ /* Elements of merged_env_vars are heap-allocated, and must be
+ * freed. Some of them are (or should) be freed by
+ * set_environment_variable_in_smartlist.
+ *
+ * Elements of new_env_vars are heap-allocated, but are copied into
+ * merged_env_vars, so they are not freed separately at the end of
+ * the function.
+ *
+ * Elements of expected_resulting_env_vars are heap-allocated, and
+ * must be freed. */
+
+ (void)ptr;
+
+ SMARTLIST_FOREACH(new_env_vars, char *, env_var,
+ set_environment_variable_in_smartlist(merged_env_vars,
+ env_var,
+ _tor_free,
+ 1));
+
+ smartlist_sort_strings(merged_env_vars);
+ smartlist_sort_strings(expected_resulting_env_vars);
+
+ tt_want_int_op(smartlist_len(merged_env_vars), ==,
+ smartlist_len(expected_resulting_env_vars));
+ {
+ int len = smartlist_len(merged_env_vars);
+ int i;
+
+ if (smartlist_len(expected_resulting_env_vars) < len) {
+ len = smartlist_len(expected_resulting_env_vars);
+ }
+
+ for (i = 0; i < len; ++i) {
+ tt_want_str_op(smartlist_get(merged_env_vars, i), ==,
+ smartlist_get(expected_resulting_env_vars, i));
+ }
+ }
+
+ /* Clean up. */
+ SMARTLIST_FOREACH(merged_env_vars, char *, x, tor_free(x));
+ smartlist_free(merged_env_vars);
+
+ smartlist_free(new_env_vars);
+
+ SMARTLIST_FOREACH(expected_resulting_env_vars, char *, x, tor_free(x));
+ smartlist_free(expected_resulting_env_vars);
+}
+
#define UTIL_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
@@ -1865,6 +2880,10 @@ test_util_eat_whitespace(void *ptr)
struct testcase_t util_tests[] = {
UTIL_LEGACY(time),
UTIL_LEGACY(config_line),
+ UTIL_LEGACY(config_line_quotes),
+ UTIL_LEGACY(config_line_comment_character),
+ UTIL_LEGACY(config_line_escaped_content),
+ UTIL_LEGACY(expand_filename),
UTIL_LEGACY(strmisc),
UTIL_LEGACY(pow2),
UTIL_LEGACY(gzip),
@@ -1875,9 +2894,11 @@ struct testcase_t util_tests[] = {
UTIL_LEGACY(mmap),
UTIL_LEGACY(threads),
UTIL_LEGACY(sscanf),
+ UTIL_LEGACY(path_is_relative),
UTIL_LEGACY(strtok),
UTIL_LEGACY(di_ops),
UTIL_TEST(find_str_at_start_of_line, 0),
+ UTIL_TEST(string_is_C_identifier, 0),
UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0),
UTIL_TEST(parent_dir, 0),
@@ -1895,6 +2916,9 @@ struct testcase_t util_tests[] = {
UTIL_TEST(split_lines, 0),
UTIL_TEST(n_bits_set, 0),
UTIL_TEST(eat_whitespace, 0),
+ UTIL_TEST(sl_new_from_text_lines, 0),
+ UTIL_TEST(make_environment, 0),
+ UTIL_TEST(set_env_var_in_sl, 0),
END_OF_TESTCASES
};
diff --git a/src/test/tinytest.c b/src/test/tinytest.c
index 8caa4f5453..4d9afacce4 100644
--- a/src/test/tinytest.c
+++ b/src/test/tinytest.c
@@ -1,4 +1,4 @@
-/* tinytest.c -- Copyright 2009-2010 Nick Mathewson
+/* tinytest.c -- Copyright 2009-2012 Nick Mathewson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,16 +22,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifdef TINYTEST_LOCAL
+#include "tinytest_local.h"
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-#ifdef TINYTEST_LOCAL
-#include "tinytest_local.h"
-#endif
-
#ifdef _WIN32
#include <windows.h>
#else
@@ -66,15 +65,15 @@ const char *cur_test_prefix = NULL; /**< prefix of the current test group */
const char *cur_test_name = NULL;
#ifdef _WIN32
-/** Pointer to argv[0] for win32. */
-static const char *commandname = NULL;
+/* Copy of argv[0] for win32. */
+static char commandname[MAX_PATH+1];
#endif
static void usage(struct testgroup_t *groups, int list_groups)
__attribute__((noreturn));
static enum outcome
-_testcase_run_bare(const struct testcase_t *testcase)
+testcase_run_bare_(const struct testcase_t *testcase)
{
void *env = NULL;
int outcome;
@@ -101,7 +100,7 @@ _testcase_run_bare(const struct testcase_t *testcase)
#define MAGIC_EXITCODE 42
static enum outcome
-_testcase_run_forked(const struct testgroup_t *group,
+testcase_run_forked_(const struct testgroup_t *group,
const struct testcase_t *testcase)
{
#ifdef _WIN32
@@ -120,7 +119,7 @@ _testcase_run_forked(const struct testgroup_t *group,
DWORD exitcode;
if (!in_tinytest_main) {
- printf("\nERROR. On Windows, _testcase_run_forked must be"
+ printf("\nERROR. On Windows, testcase_run_forked_ must be"
" called from within tinytest_main.\n");
abort();
}
@@ -166,7 +165,7 @@ _testcase_run_forked(const struct testgroup_t *group,
int test_r, write_r;
char b[1];
close(outcome_pipe[0]);
- test_r = _testcase_run_bare(testcase);
+ test_r = testcase_run_bare_(testcase);
assert(0<=(int)test_r && (int)test_r<=2);
b[0] = "NYS"[test_r];
write_r = (int)write(outcome_pipe[1], b, 1);
@@ -220,9 +219,9 @@ testcase_run_one(const struct testgroup_t *group,
}
if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) {
- outcome = _testcase_run_forked(group, testcase);
+ outcome = testcase_run_forked_(group, testcase);
} else {
- outcome = _testcase_run_bare(testcase);
+ outcome = testcase_run_bare_(testcase);
}
if (outcome == OK) {
@@ -248,7 +247,7 @@ testcase_run_one(const struct testgroup_t *group,
}
int
-_tinytest_set_flag(struct testgroup_t *groups, const char *arg, unsigned long flag)
+tinytest_set_flag_(struct testgroup_t *groups, const char *arg, unsigned long flag)
{
int i, j;
size_t length = LONGEST_TEST_NAME;
@@ -280,7 +279,7 @@ usage(struct testgroup_t *groups, int list_groups)
puts(" Use --list-tests for a list of tests.");
if (list_groups) {
puts("Known tests are:");
- _tinytest_set_flag(groups, "..", 0);
+ tinytest_set_flag_(groups, "..", 0);
}
exit(0);
}
@@ -291,7 +290,12 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
int i, j, n=0;
#ifdef _WIN32
- commandname = v[0];
+ const char *sp = strrchr(v[0], '.');
+ const char *extension = "";
+ if (!sp || stricmp(sp, ".exe"))
+ extension = ".exe"; /* Add an exe so CreateProcess will work */
+ snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension);
+ commandname[MAX_PATH]='\0';
#endif
for (i=1; i<c; ++i) {
if (v[i][0] == '-') {
@@ -318,28 +322,28 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
}
} else {
const char *test = v[i];
- int flag = _TT_ENABLED;
+ int flag = TT_ENABLED_;
if (test[0] == ':') {
++test;
flag = TT_SKIP;
} else {
++n;
}
- if (!_tinytest_set_flag(groups, test, flag)) {
+ if (!tinytest_set_flag_(groups, test, flag)) {
printf("No such test as %s!\n", v[i]);
return -1;
}
}
}
if (!n)
- _tinytest_set_flag(groups, "..", _TT_ENABLED);
+ tinytest_set_flag_(groups, "..", TT_ENABLED_);
setvbuf(stdout, NULL, _IONBF, 0);
++in_tinytest_main;
for (i=0; groups[i].prefix; ++i)
for (j=0; groups[i].cases[j].name; ++j)
- if (groups[i].cases[j].flags & _TT_ENABLED)
+ if (groups[i].cases[j].flags & TT_ENABLED_)
testcase_run_one(&groups[i],
&groups[i].cases[j]);
@@ -358,13 +362,13 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
}
int
-_tinytest_get_verbosity(void)
+tinytest_get_verbosity_(void)
{
return opt_verbosity;
}
void
-_tinytest_set_test_failed(void)
+tinytest_set_test_failed_(void)
{
if (opt_verbosity <= 0 && cur_test_name) {
if (opt_verbosity==0) puts("");
@@ -375,7 +379,7 @@ _tinytest_set_test_failed(void)
}
void
-_tinytest_set_test_skipped(void)
+tinytest_set_test_skipped_(void)
{
if (cur_test_outcome==OK)
cur_test_outcome = SKIP;
diff --git a/src/test/tinytest.h b/src/test/tinytest.h
index cbe28b7f51..bcac9f079c 100644
--- a/src/test/tinytest.h
+++ b/src/test/tinytest.h
@@ -1,4 +1,4 @@
-/* tinytest.h -- Copyright 2009-2010 Nick Mathewson
+/* tinytest.h -- Copyright 2009-2012 Nick Mathewson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,15 +23,15 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _TINYTEST_H
-#define _TINYTEST_H
+#ifndef TINYTEST_H_INCLUDED_
+#define TINYTEST_H_INCLUDED_
/** Flag for a test that needs to run in a subprocess. */
#define TT_FORK (1<<0)
/** Runtime flag for a test we've decided to skip. */
#define TT_SKIP (1<<1)
/** Internal runtime flag for a test we've decided to run. */
-#define _TT_ENABLED (1<<2)
+#define TT_ENABLED_ (1<<2)
/** If you add your own flags, make them start at this point. */
#define TT_FIRST_USER_FLAG (1<<3)
@@ -65,18 +65,18 @@ struct testgroup_t {
#define END_OF_GROUPS { NULL, NULL}
/** Implementation: called from a test to indicate failure, before logging. */
-void _tinytest_set_test_failed(void);
+void tinytest_set_test_failed_(void);
/** Implementation: called from a test to indicate that we're skipping. */
-void _tinytest_set_test_skipped(void);
+void tinytest_set_test_skipped_(void);
/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */
-int _tinytest_get_verbosity(void);
+int tinytest_get_verbosity_(void);
/** Implementation: Set a flag on tests matching a name; returns number
* of tests that matched. */
-int _tinytest_set_flag(struct testgroup_t *, const char *, unsigned long);
+int tinytest_set_flag_(struct testgroup_t *, const char *, unsigned long);
/** Set all tests in 'groups' matching the name 'named' to be skipped. */
#define tinytest_skip(groups, named) \
- _tinytest_set_flag(groups, named, TT_SKIP)
+ tinytest_set_flag_(groups, named, TT_SKIP)
/** Run a single testcase in a single group. */
int testcase_run_one(const struct testgroup_t *,const struct testcase_t *);
diff --git a/src/test/tinytest_demo.c b/src/test/tinytest_demo.c
index 98cb773d1a..be95ce4c1d 100644
--- a/src/test/tinytest_demo.c
+++ b/src/test/tinytest_demo.c
@@ -1,4 +1,4 @@
-/* tinytest_demo.c -- Copyright 2009-2010 Nick Mathewson
+/* tinytest_demo.c -- Copyright 2009-2012 Nick Mathewson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/test/tinytest_macros.h b/src/test/tinytest_macros.h
index 032393ccf7..9ff69b1d50 100644
--- a/src/test/tinytest_macros.h
+++ b/src/test/tinytest_macros.h
@@ -1,4 +1,4 @@
-/* tinytest_macros.h -- Copyright 2009-2010 Nick Mathewson
+/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _TINYTEST_MACROS_H
-#define _TINYTEST_MACROS_H
+#ifndef TINYTEST_MACROS_H_INCLUDED_
+#define TINYTEST_MACROS_H_INCLUDED_
/* Helpers for defining statement-like macros */
#define TT_STMT_BEGIN do {
@@ -51,19 +51,19 @@
/* Announce a non-failure if we're verbose. */
#define TT_BLATHER(args) \
TT_STMT_BEGIN \
- if (_tinytest_get_verbosity()>1) TT_DECLARE(" OK", args); \
+ if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \
TT_STMT_END
#define TT_DIE(args) \
TT_STMT_BEGIN \
- _tinytest_set_test_failed(); \
+ tinytest_set_test_failed_(); \
TT_GRIPE(args); \
TT_EXIT_TEST_FUNCTION; \
TT_STMT_END
#define TT_FAIL(args) \
TT_STMT_BEGIN \
- _tinytest_set_test_failed(); \
+ tinytest_set_test_failed_(); \
TT_GRIPE(args); \
TT_STMT_END
@@ -74,7 +74,7 @@
#define tt_abort() TT_DIE(("%s", "(Failed.)"))
/* Fail but do not abort the current test for the reason in msg. */
-#define tt_fail_printf(msg) TT_FAIL(msg)
+#define tt_failprint_f(msg) TT_FAIL(msg)
#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno))
#define tt_fail_msg(msg) TT_FAIL(("%s", msg))
#define tt_fail() TT_FAIL(("%s", "(Failed.)"))
@@ -82,14 +82,14 @@
/* End the current test, and indicate we are skipping it. */
#define tt_skip() \
TT_STMT_BEGIN \
- _tinytest_set_test_skipped(); \
+ tinytest_set_test_skipped_(); \
TT_EXIT_TEST_FUNCTION; \
TT_STMT_END
-#define _tt_want(b, msg, fail) \
+#define tt_want_(b, msg, fail) \
TT_STMT_BEGIN \
if (!(b)) { \
- _tinytest_set_test_failed(); \
+ tinytest_set_test_failed_(); \
TT_GRIPE(("%s",msg)); \
fail; \
} else { \
@@ -99,11 +99,11 @@
/* Assert b, but do not stop the test if b fails. Log msg on failure. */
#define tt_want_msg(b, msg) \
- _tt_want(b, msg, );
+ tt_want_(b, msg, );
/* Assert b and stop the test if b fails. Log msg on failure. */
#define tt_assert_msg(b, msg) \
- _tt_want(b, msg, TT_EXIT_TEST_FUNCTION);
+ tt_want_(b, msg, TT_EXIT_TEST_FUNCTION);
/* Assert b, but do not stop the test if b fails. */
#define tt_want(b) tt_want_msg( (b), "want("#b")")
@@ -113,28 +113,28 @@
#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \
setup_block,cleanup_block,die_on_fail) \
TT_STMT_BEGIN \
- type _val1 = (type)(a); \
- type _val2 = (type)(b); \
- int _tt_status = (test); \
- if (!_tt_status || _tinytest_get_verbosity()>1) { \
- printf_type _print; \
- printf_type _print1; \
- printf_type _print2; \
- type _value = _val1; \
+ type val1_ = (type)(a); \
+ type val2_ = (type)(b); \
+ int tt_status_ = (test); \
+ if (!tt_status_ || tinytest_get_verbosity_()>1) { \
+ printf_type print_; \
+ printf_type print1_; \
+ printf_type print2_; \
+ type value_ = val1_; \
setup_block; \
- _print1 = _print; \
- _value = _val2; \
+ print1_ = print_; \
+ value_ = val2_; \
setup_block; \
- _print2 = _print; \
- TT_DECLARE(_tt_status?" OK":"FAIL", \
+ print2_ = print_; \
+ TT_DECLARE(tt_status_?" OK":"FAIL", \
("assert(%s): "printf_fmt" vs "printf_fmt, \
- str_test, _print1, _print2)); \
- _print = _print1; \
+ str_test, print1_, print2_)); \
+ print_ = print1_; \
cleanup_block; \
- _print = _print2; \
+ print_ = print2_; \
cleanup_block; \
- if (!_tt_status) { \
- _tinytest_set_test_failed(); \
+ if (!tt_status_) { \
+ tinytest_set_test_failed_(); \
die_on_fail ; \
} \
} \
@@ -142,43 +142,43 @@
#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \
tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \
- {_print=_value;},{},die_on_fail)
+ {print_=value_;},{},die_on_fail)
/* Helper: assert that a op b, when cast to type. Format the values with
* printf format fmt on failure. */
#define tt_assert_op_type(a,op,b,type,fmt) \
- tt_assert_test_type(a,b,#a" "#op" "#b,type,(_val1 op _val2),fmt, \
+ tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \
TT_EXIT_TEST_FUNCTION)
#define tt_int_op(a,op,b) \
- tt_assert_test_type(a,b,#a" "#op" "#b,long,(_val1 op _val2), \
+ tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \
"%ld",TT_EXIT_TEST_FUNCTION)
#define tt_uint_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
- (_val1 op _val2),"%lu",TT_EXIT_TEST_FUNCTION)
+ (val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION)
#define tt_ptr_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,void*, \
- (_val1 op _val2),"%p",TT_EXIT_TEST_FUNCTION)
+ (val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION)
#define tt_str_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \
- (strcmp(_val1,_val2) op 0),"<%s>",TT_EXIT_TEST_FUNCTION)
+ (strcmp(val1_,val2_) op 0),"<%s>",TT_EXIT_TEST_FUNCTION)
#define tt_want_int_op(a,op,b) \
- tt_assert_test_type(a,b,#a" "#op" "#b,long,(_val1 op _val2),"%ld",(void)0)
+ tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0)
#define tt_want_uint_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
- (_val1 op _val2),"%lu",(void)0)
+ (val1_ op val2_),"%lu",(void)0)
#define tt_want_ptr_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,void*, \
- (_val1 op _val2),"%p",(void)0)
+ (val1_ op val2_),"%p",(void)0)
#define tt_want_str_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \
- (strcmp(_val1,_val2) op 0),"<%s>",(void)0)
+ (strcmp(val1_,val2_) op 0),"<%s>",(void)0)
#endif