]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: test-lib - add unit tests for str_to_*() helpers
authorPhil Carmody <phil@dovecot.fi>
Wed, 2 Jul 2014 15:21:24 +0000 (18:21 +0300)
committerPhil Carmody <phil@dovecot.fi>
Wed, 2 Jul 2014 15:21:24 +0000 (18:21 +0300)
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 <phil@dovecot.fi>
src/lib/Makefile.am
src/lib/test-lib.c
src/lib/test-lib.h
src/lib/test-strnum.c [new file with mode: 0644]

index b00b475131971d50feb942bf8ff9e572337cad6d..81c4fc71633b2164f490e4101d37f2bac0865cc1 100644 (file)
@@ -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 \
index f8a4941c2de61c519fe19f68bbbe477bf7cd3171..5f98912fc44b3b85febe242f7f54c58a2875bf8e 100644 (file)
@@ -37,6 +37,7 @@ int main(void)
                test_str,
                test_strescape,
                test_strfuncs,
+               test_strnum,
                test_str_find,
                test_str_sanitize,
                test_time_util,
index 1f8e5b012ac997a82b60961457eef4132faed693..f87bb6c8defa8613995341e0eb1ddb14cba4ccf3 100644 (file)
@@ -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 (file)
index 0000000..4c80bd3
--- /dev/null
@@ -0,0 +1,141 @@
+/* Copyright (c) 2014-2014 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+
+#include <stdlib.h>
+
+#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();
+}