From: Phil Carmody Date: Wed, 2 Jul 2014 15:21:24 +0000 (+0300) Subject: lib: test-lib - add unit tests for str_to_*() helpers X-Git-Tag: 2.2.14.rc1~319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42826d96c8d0bba9eddc85b01bf70d7db571ae7f;p=thirdparty%2Fdovecot%2Fcore.git lib: test-lib - add unit tests for str_to_*() helpers This doesn't test all the helpers, but ensures both signed and unsigned are tested, as are 32-bit and 64-bit cases. All the other helpers fall back onto using one of those cases. Unless uintmax_t is larger than 64 bits, in which case this needs a revisit. NOTE: This causes the following make check errors: test-strnum.c:35: Assert(#7) failed: ret == u64tests[i].ret test-strnum.c:35: Assert(#10) failed: ret == u64tests[i].ret test-strnum.c:37: Assert(#10) failed: val == u64tests[i].val str_to_uint64 ........................................................ : FAILED Corresponding to test cases: [7] = INVALID(18446744073709551616), This does not wrap-past-0 (become smaller) on multiply, but wraps-past-0 on addition. [10]= INVALID(20496382304121724020), This wraps-past-n (becomes larger) on multiply. Signed-off-by: Phil Carmody --- diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b00b475131..81c4fc7163 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -304,6 +304,7 @@ test_lib_SOURCES = \ test-str.c \ test-strescape.c \ test-strfuncs.c \ + test-strnum.c \ test-str-find.c \ test-str-sanitize.c \ test-time-util.c \ diff --git a/src/lib/test-lib.c b/src/lib/test-lib.c index f8a4941c2d..5f98912fc4 100644 --- a/src/lib/test-lib.c +++ b/src/lib/test-lib.c @@ -37,6 +37,7 @@ int main(void) test_str, test_strescape, test_strfuncs, + test_strnum, test_str_find, test_str_sanitize, test_time_util, diff --git a/src/lib/test-lib.h b/src/lib/test-lib.h index 1f8e5b012a..f87bb6c8de 100644 --- a/src/lib/test-lib.h +++ b/src/lib/test-lib.h @@ -36,6 +36,7 @@ void test_seq_range_array(void); void test_str(void); void test_strescape(void); void test_strfuncs(void); +void test_strnum(void); void test_str_find(void); void test_str_sanitize(void); void test_time_util(void); diff --git a/src/lib/test-strnum.c b/src/lib/test-strnum.c new file mode 100644 index 0000000000..4c80bd39de --- /dev/null +++ b/src/lib/test-strnum.c @@ -0,0 +1,141 @@ +/* Copyright (c) 2014-2014 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" + +#include + +#define INVALID(n) { #n, -1, 0 } +#define VALID(n) { #n, 0, n } + +/* Assumes uintmax_t is 64 bit */ +static void test_str_to_u64(void) +{ + unsigned int i; + const struct { + const char *input; + int ret; + uintmax_t val; + } u64tests[] = { + INVALID(-1), + INVALID(foo), + VALID(0), + { "0 ", -1, 0 }, /* invalid as doesn't end with a '\0' */ + VALID(000000000000000000000000000000000000000000000000000000000000000), + { "000000000000000000000000000000000000000000000000000001000000001", 0, 1000000001 }, + { "18446744073709551615", 0, 18446744073709551615ULL }, + INVALID(18446744073709551616), + INVALID(20496382304121724010), /* 2^64*10/9 doesn't wrap */ + INVALID(20496382304121724017), /* 2^64*10/9 wraps only after addition */ + INVALID(20496382304121724020), /* 2^64*10/9 wraps on multiply*/ + }; + test_begin("str_to_uint64"); + for (i = 0; i < N_ELEMENTS(u64tests); ++i) { + uintmax_t val = 0xBADBEEF15BADF00D; + int ret = str_to_uint64(u64tests[i].input, &val); + test_assert_idx(ret == u64tests[i].ret, i); + if (ret == 0) + test_assert_idx(val == u64tests[i].val, i); + else + test_assert_idx(val == 0xBADBEEF15BADF00D, i); + } + test_end(); +} + +static void test_str_to_u32(void) +{ + unsigned int i; + const struct { + const char *input; + int ret; + uint32_t val; + } u32tests[] = { + VALID(0), + INVALID(-0), + VALID(4294967295), + INVALID(4294967296), + INVALID(4772185880), + INVALID(4772185884), + INVALID(4772185890), + }; + test_begin("str_to_uint32"); + for (i = 0; i < N_ELEMENTS(u32tests); ++i) { + uint32_t val = 0xDEADF00D; + int ret = str_to_uint32(u32tests[i].input, &val); + test_assert_idx(ret == u32tests[i].ret, i); + if (ret == 0) + test_assert_idx(val == u32tests[i].val, i); + else + test_assert_idx(val == 0xDEADF00D, i); + } + test_end(); +} + +/* Assumes long long is 64 bit, 2's complement */ +static void test_str_to_llong(void) +{ + unsigned int i; + const struct { + const char *input; + int ret; + long long val; + } i64tests[] = { + VALID(0), + VALID(-0), + INVALID(--0), + VALID(2147483648), + VALID(-2147483649), + VALID(9223372036854775807), + { "-9223372036854775808", 0, -9223372036854775807-1 }, + INVALID(9223372036854775808), + INVALID(-9223372036854775809), + }; + test_begin("str_to_llong"); + for (i = 0; i < N_ELEMENTS(i64tests); ++i) { + long long val = 123456789; + int ret = str_to_llong(i64tests[i].input, &val); + test_assert_idx(ret == i64tests[i].ret, i); + if (ret == 0) + test_assert_idx(val == i64tests[i].val, i); + else + test_assert_idx(val == 123456789, i); + } + test_end(); +} + +/* Assumes int is 32 bit, 2's complement */ +static void test_str_to_i32(void) +{ + unsigned int i; + const struct { + const char *input; + int ret; + int val; + } i32tests[] = { + VALID(0), + VALID(-0), + INVALID(--0), + VALID(2147483647), + VALID(-2147483648), + INVALID(2147483648), + INVALID(-2147483649), + }; + test_begin("str_to_int"); + for (i = 0; i < N_ELEMENTS(i32tests); ++i) { + int val = 123456789; + int ret = str_to_int(i32tests[i].input, &val); + test_assert_idx(ret == i32tests[i].ret, i); + if (ret == 0) + test_assert_idx(val == i32tests[i].val, i); + else + test_assert_idx(val == 123456789, i); + } + test_end(); +} + +void test_strnum(void) +{ + test_str_to_u64(); + test_str_to_u32(); + test_str_to_llong(); + test_str_to_i32(); +}