summaryrefslogtreecommitdiffstats
path: root/src/test/test-macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test-macro.c')
-rw-r--r--src/test/test-macro.c374
1 files changed, 260 insertions, 114 deletions
diff --git a/src/test/test-macro.c b/src/test/test-macro.c
index b91a1f9..9e2875d 100644
--- a/src/test/test-macro.c
+++ b/src/test/test-macro.c
@@ -1,7 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stddef.h>
+#include <sys/stat.h>
+#include "errno-util.h"
#include "log.h"
#include "macro.h"
#include "tests.h"
@@ -159,6 +161,153 @@ TEST(container_of) {
#pragma GCC diagnostic pop
+#define TEST_OVERFLOW_MATH_BY_TYPE(type, min, max, lit) \
+ ({ \
+ type x; \
+ \
+ assert_se(ADD_SAFE(&x, lit(5), lit(10))); \
+ assert_se(x == lit(15)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(ADD_SAFE(&x, lit(5), lit(-10))); \
+ assert_se(x == lit(-5)); \
+ } \
+ assert_se(ADD_SAFE(&x, min, lit(0))); \
+ assert_se(x == min); \
+ assert_se(ADD_SAFE(&x, max, lit(0))); \
+ assert_se(x == max); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) \
+ assert_se(!ADD_SAFE(&x, min, lit(-1))); \
+ assert_se(!ADD_SAFE(&x, max, lit(1))); \
+ \
+ x = lit(5); \
+ assert_se(INC_SAFE(&x, lit(10))); \
+ assert_se(x == lit(15)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(INC_SAFE(&x, lit(-20))); \
+ assert_se(x == lit(-5)); \
+ } \
+ x = min; \
+ assert_se(INC_SAFE(&x, lit(0))); \
+ assert_se(x == min); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) \
+ assert_se(!INC_SAFE(&x, lit(-1))); \
+ x = max; \
+ assert_se(INC_SAFE(&x, lit(0))); \
+ assert_se(x == max); \
+ assert_se(!INC_SAFE(&x, lit(1))); \
+ \
+ assert_se(SUB_SAFE(&x, lit(10), lit(5))); \
+ assert_se(x == lit(5)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(SUB_SAFE(&x, lit(5), lit(10))); \
+ assert_se(x == lit(-5)); \
+ \
+ assert_se(SUB_SAFE(&x, lit(5), lit(-10))); \
+ assert_se(x == lit(15)); \
+ } else \
+ assert_se(!SUB_SAFE(&x, lit(5), lit(10))); \
+ assert_se(SUB_SAFE(&x, min, lit(0))); \
+ assert_se(x == min); \
+ assert_se(SUB_SAFE(&x, max, lit(0))); \
+ assert_se(x == max); \
+ assert_se(!SUB_SAFE(&x, min, lit(1))); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) \
+ assert_se(!SUB_SAFE(&x, max, lit(-1))); \
+ \
+ x = lit(10); \
+ assert_se(DEC_SAFE(&x, lit(5))); \
+ assert_se(x == lit(5)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(DEC_SAFE(&x, lit(10))); \
+ assert_se(x == lit(-5)); \
+ \
+ x = lit(5); \
+ assert_se(DEC_SAFE(&x, lit(-10))); \
+ assert_se(x == lit(15)); \
+ } else \
+ assert_se(!DEC_SAFE(&x, lit(10))); \
+ x = min; \
+ assert_se(DEC_SAFE(&x, lit(0))); \
+ assert_se(x == min); \
+ assert_se(!DEC_SAFE(&x, lit(1))); \
+ x = max; \
+ assert_se(DEC_SAFE(&x, lit(0))); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) \
+ assert_se(!DEC_SAFE(&x, lit(-1))); \
+ \
+ assert_se(MUL_SAFE(&x, lit(2), lit(4))); \
+ assert_se(x == lit(8)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(MUL_SAFE(&x, lit(2), lit(-4))); \
+ assert_se(x == lit(-8)); \
+ } \
+ assert_se(MUL_SAFE(&x, lit(5), lit(0))); \
+ assert_se(x == lit(0)); \
+ assert_se(MUL_SAFE(&x, min, lit(1))); \
+ assert_se(x == min); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) \
+ assert_se(!MUL_SAFE(&x, min, lit(2))); \
+ assert_se(MUL_SAFE(&x, max, lit(1))); \
+ assert_se(x == max); \
+ assert_se(!MUL_SAFE(&x, max, lit(2))); \
+ \
+ x = lit(2); \
+ assert_se(MUL_ASSIGN_SAFE(&x, lit(4))); \
+ assert_se(x == lit(8)); \
+ if (IS_SIGNED_INTEGER_TYPE(type)) { \
+ assert_se(MUL_ASSIGN_SAFE(&x, lit(-1))); \
+ assert_se(x == lit(-8)); \
+ } \
+ assert_se(MUL_ASSIGN_SAFE(&x, lit(0))); \
+ assert_se(x == lit(0)); \
+ x = min; \
+ assert_se(MUL_ASSIGN_SAFE(&x, lit(1))); \
+ assert_se(x == min); \
+ if IS_SIGNED_INTEGER_TYPE(type) \
+ assert_se(!MUL_ASSIGN_SAFE(&x, lit(2))); \
+ x = max; \
+ assert_se(MUL_ASSIGN_SAFE(&x, lit(1))); \
+ assert_se(x == max); \
+ assert_se(!MUL_ASSIGN_SAFE(&x, lit(2))); \
+ })
+
+TEST(overflow_safe_math) {
+ int64_t i;
+ uint64_t u, *p;
+
+ /* basic tests */
+ TEST_OVERFLOW_MATH_BY_TYPE(int8_t, INT8_MIN, INT8_MAX, INT8_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(int16_t, INT16_MIN, INT16_MAX, INT16_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(int32_t, INT32_MIN, INT32_MAX, INT32_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(int64_t, INT64_MIN, INT64_MAX, INT64_C);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits" /* Otherwise the compiler complains about comparisons to negative numbers always being false */
+ TEST_OVERFLOW_MATH_BY_TYPE(uint8_t, UINT8_C(0), UINT8_MAX, UINT8_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(uint16_t, UINT16_C(0), UINT16_MAX, UINT16_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(uint32_t, UINT32_C(0), UINT32_MAX, UINT32_C);
+ TEST_OVERFLOW_MATH_BY_TYPE(uint64_t, UINT64_C(0), UINT64_MAX, UINT64_C);
+#pragma GCC diagnostic pop
+
+ /* make sure we handle pointers correctly */
+ p = &u;
+ assert_se(ADD_SAFE(p, 35, 15) && (u == 50));
+ assert_se(SUB_SAFE(p, 35, 15) && (u == 20));
+ assert_se(MUL_SAFE(p, 5, 10) && (u == 50));
+ assert_se(INC_SAFE(p, 10) && (u == 60));
+ assert_se(DEC_SAFE(p, 10) && (u == 50));
+ assert_se(MUL_ASSIGN_SAFE(p, 3) && (u == 150));
+ assert_se(!ADD_SAFE(p, UINT64_MAX, 1));
+ assert_se(!SUB_SAFE(p, 0, 1));
+
+ /* cross-type sanity checks */
+ assert_se(ADD_SAFE(&i, INT32_MAX, 1));
+ assert_se(SUB_SAFE(&i, INT32_MIN, 1));
+ assert_se(!ADD_SAFE(&i, UINT64_MAX, 0));
+ assert_se(ADD_SAFE(&u, INT32_MAX, 1));
+ assert_se(MUL_SAFE(&u, INT32_MAX, 2));
+}
+
TEST(DIV_ROUND_UP) {
int div;
@@ -221,92 +370,13 @@ TEST(IN_SET) {
assert_se(!IN_SET(t.x, 2, 3, 4));
}
-TEST(FOREACH_POINTER) {
- int a, b, c, *i;
- size_t k = 0;
-
- FOREACH_POINTER(i, &a, &b, &c) {
- switch (k) {
-
- case 0:
- assert_se(i == &a);
- break;
-
- case 1:
- assert_se(i == &b);
- break;
-
- case 2:
- assert_se(i == &c);
- break;
-
- default:
- assert_not_reached();
- break;
- }
-
- k++;
- }
-
- assert_se(k == 3);
-
- FOREACH_POINTER(i, &b) {
- assert_se(k == 3);
- assert_se(i == &b);
- k = 4;
- }
-
- assert_se(k == 4);
-
- FOREACH_POINTER(i, NULL, &c, NULL, &b, NULL, &a, NULL) {
- switch (k) {
-
- case 4:
- assert_se(i == NULL);
- break;
-
- case 5:
- assert_se(i == &c);
- break;
-
- case 6:
- assert_se(i == NULL);
- break;
-
- case 7:
- assert_se(i == &b);
- break;
-
- case 8:
- assert_se(i == NULL);
- break;
-
- case 9:
- assert_se(i == &a);
- break;
-
- case 10:
- assert_se(i == NULL);
- break;
-
- default:
- assert_not_reached();
- break;
- }
-
- k++;
- }
-
- assert_se(k == 11);
-}
-
-TEST(FOREACH_VA_ARGS) {
+TEST(FOREACH_ARGUMENT) {
size_t i;
i = 0;
uint8_t u8, u8_1 = 1, u8_2 = 2, u8_3 = 3;
- VA_ARGS_FOREACH(u8, u8_2, 8, 0xff, u8_1, u8_3, 0, 1) {
- switch(i++) {
+ FOREACH_ARGUMENT(u8, u8_2, 8, 0xff, u8_1, u8_3, 0, 1) {
+ switch (i++) {
case 0: assert_se(u8 == u8_2); break;
case 1: assert_se(u8 == 8); break;
case 2: assert_se(u8 == 0xff); break;
@@ -319,24 +389,24 @@ TEST(FOREACH_VA_ARGS) {
}
assert_se(i == 7);
i = 0;
- VA_ARGS_FOREACH(u8, 0) {
+ FOREACH_ARGUMENT(u8, 0) {
assert_se(u8 == 0);
assert_se(i++ == 0);
}
assert_se(i == 1);
i = 0;
- VA_ARGS_FOREACH(u8, 0xff) {
+ FOREACH_ARGUMENT(u8, 0xff) {
assert_se(u8 == 0xff);
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(u8)
+ FOREACH_ARGUMENT(u8)
assert_se(false);
i = 0;
uint32_t u32, u32_1 = 0xffff0000, u32_2 = 10, u32_3 = 0xffff;
- VA_ARGS_FOREACH(u32, 1, 100, u32_2, 1000, u32_3, u32_1, 1, 0) {
- switch(i++) {
+ FOREACH_ARGUMENT(u32, 1, 100, u32_2, 1000, u32_3, u32_1, 1, 0) {
+ switch (i++) {
case 0: assert_se(u32 == 1); break;
case 1: assert_se(u32 == 100); break;
case 2: assert_se(u32 == u32_2); break;
@@ -350,24 +420,24 @@ TEST(FOREACH_VA_ARGS) {
}
assert_se(i == 8);
i = 0;
- VA_ARGS_FOREACH(u32, 0) {
+ FOREACH_ARGUMENT(u32, 0) {
assert_se(u32 == 0);
assert_se(i++ == 0);
}
assert_se(i == 1);
i = 0;
- VA_ARGS_FOREACH(u32, 1000) {
+ FOREACH_ARGUMENT(u32, 1000) {
assert_se(u32 == 1000);
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(u32)
+ FOREACH_ARGUMENT(u32)
assert_se(false);
i = 0;
uint64_t u64, u64_1 = 0xffffffffffffffff, u64_2 = 50, u64_3 = 0xffff;
- VA_ARGS_FOREACH(u64, 44, 0, u64_3, 100, u64_2, u64_1, 50000) {
- switch(i++) {
+ FOREACH_ARGUMENT(u64, 44, 0, u64_3, 100, u64_2, u64_1, 50000) {
+ switch (i++) {
case 0: assert_se(u64 == 44); break;
case 1: assert_se(u64 == 0); break;
case 2: assert_se(u64 == u64_3); break;
@@ -380,18 +450,18 @@ TEST(FOREACH_VA_ARGS) {
}
assert_se(i == 7);
i = 0;
- VA_ARGS_FOREACH(u64, 0) {
+ FOREACH_ARGUMENT(u64, 0) {
assert_se(u64 == 0);
assert_se(i++ == 0);
}
assert_se(i == 1);
i = 0;
- VA_ARGS_FOREACH(u64, 0xff00ff00000000) {
+ FOREACH_ARGUMENT(u64, 0xff00ff00000000) {
assert_se(u64 == 0xff00ff00000000);
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(u64)
+ FOREACH_ARGUMENT(u64)
assert_se(false);
struct test {
@@ -405,8 +475,8 @@ TEST(FOREACH_VA_ARGS) {
s_2 = { .a = 100000, .b = 'z', },
s_3 = { .a = 0xff, .b = 'q', },
s_4 = { .a = 1, .b = 'x', };
- VA_ARGS_FOREACH(s, s_1, (struct test){ .a = 10, .b = 'd', }, s_2, (struct test){}, s_3, s_4) {
- switch(i++) {
+ FOREACH_ARGUMENT(s, s_1, (struct test){ .a = 10, .b = 'd', }, s_2, (struct test){}, s_3, s_4) {
+ switch (i++) {
case 0: assert_se(s.a == 0 ); assert_se(s.b == 'c'); break;
case 1: assert_se(s.a == 10 ); assert_se(s.b == 'd'); break;
case 2: assert_se(s.a == 100000); assert_se(s.b == 'z'); break;
@@ -418,69 +488,69 @@ TEST(FOREACH_VA_ARGS) {
}
assert_se(i == 6);
i = 0;
- VA_ARGS_FOREACH(s, (struct test){ .a = 1, .b = 'A', }) {
+ FOREACH_ARGUMENT(s, (struct test){ .a = 1, .b = 'A', }) {
assert_se(s.a == 1);
assert_se(s.b == 'A');
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(s)
+ FOREACH_ARGUMENT(s)
assert_se(false);
i = 0;
struct test *p, *p_1 = &s_1, *p_2 = &s_2, *p_3 = &s_3, *p_4 = &s_4;
- VA_ARGS_FOREACH(p, p_1, NULL, p_2, p_3, NULL, p_4, NULL) {
- switch(i++) {
+ FOREACH_ARGUMENT(p, p_1, NULL, p_2, p_3, NULL, p_4, NULL) {
+ switch (i++) {
case 0: assert_se(p == p_1); break;
- case 1: assert_se(p == NULL); break;
+ case 1: ASSERT_NULL(p); break;
case 2: assert_se(p == p_2); break;
case 3: assert_se(p == p_3); break;
- case 4: assert_se(p == NULL); break;
+ case 4: ASSERT_NULL(p); break;
case 5: assert_se(p == p_4); break;
- case 6: assert_se(p == NULL); break;
+ case 6: ASSERT_NULL(p); break;
default: assert_se(false);
}
}
assert_se(i == 7);
i = 0;
- VA_ARGS_FOREACH(p, p_3) {
+ FOREACH_ARGUMENT(p, p_3) {
assert_se(p == p_3);
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(p)
+ FOREACH_ARGUMENT(p)
assert_se(false);
i = 0;
void *v, *v_1 = p_1, *v_2 = p_2, *v_3 = p_3;
uint32_t *u32p = &u32;
- VA_ARGS_FOREACH(v, v_1, NULL, u32p, v_3, p_2, p_4, v_2, NULL) {
- switch(i++) {
+ FOREACH_ARGUMENT(v, v_1, NULL, u32p, v_3, p_2, p_4, v_2, NULL) {
+ switch (i++) {
case 0: assert_se(v == v_1); break;
- case 1: assert_se(v == NULL); break;
+ case 1: ASSERT_NULL(v); break;
case 2: assert_se(v == u32p); break;
case 3: assert_se(v == v_3); break;
case 4: assert_se(v == p_2); break;
case 5: assert_se(v == p_4); break;
case 6: assert_se(v == v_2); break;
- case 7: assert_se(v == NULL); break;
+ case 7: ASSERT_NULL(v); break;
default: assert_se(false);
}
}
assert_se(i == 8);
i = 0;
- VA_ARGS_FOREACH(v, NULL) {
- assert_se(v == NULL);
+ FOREACH_ARGUMENT(v, NULL) {
+ ASSERT_NULL(v);
assert_se(i++ == 0);
}
assert_se(i == 1);
i = 0;
- VA_ARGS_FOREACH(v, v_1) {
+ FOREACH_ARGUMENT(v, v_1) {
assert_se(v == v_1);
assert_se(i++ == 0);
}
assert_se(i == 1);
- VA_ARGS_FOREACH(v)
+ FOREACH_ARGUMENT(v)
assert_se(false);
}
@@ -1037,4 +1107,80 @@ TEST(u64_multiply_safe) {
assert_se(u64_multiply_safe(UINT64_MAX, UINT64_MAX) == 0);
}
+TEST(ASSERT) {
+ char *null = NULL;
+
+ ASSERT_OK(0);
+ ASSERT_OK(255);
+ ASSERT_OK(printf("Hello world\n"));
+ ASSERT_SIGNAL(ASSERT_OK(-1), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK(-ENOANO), SIGABRT);
+
+ ASSERT_OK_ERRNO(0 >= 0);
+ ASSERT_OK_ERRNO(255 >= 0);
+ ASSERT_OK_ERRNO(printf("Hello world\n"));
+ ASSERT_SIGNAL(ASSERT_OK_ERRNO(-1), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_ERRNO(-ENOANO), SIGABRT);
+
+ ASSERT_ERROR(-ENOENT, ENOENT);
+ ASSERT_ERROR(RET_NERRNO(mkdir("/i/will/fail/with/enoent", 666)), ENOENT);
+ ASSERT_SIGNAL(ASSERT_ERROR(0, ENOENT), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_ERROR(RET_NERRNO(mkdir("/i/will/fail/with/enoent", 666)), ENOANO), SIGABRT);
+
+ errno = ENOENT;
+ ASSERT_ERROR_ERRNO(-1, ENOENT);
+ errno = 0;
+ ASSERT_ERROR_ERRNO(mkdir("/i/will/fail/with/enoent", 666), ENOENT);
+ ASSERT_SIGNAL(ASSERT_ERROR_ERRNO(0, ENOENT), SIGABRT);
+ errno = 0;
+ ASSERT_SIGNAL(ASSERT_ERROR_ERRNO(mkdir("/i/will/fail/with/enoent", 666), ENOANO), SIGABRT);
+
+ ASSERT_TRUE(true);
+ ASSERT_TRUE(255);
+ ASSERT_TRUE(getpid());
+ ASSERT_SIGNAL(ASSERT_TRUE(1 == 0), SIGABRT);
+
+ ASSERT_FALSE(false);
+ ASSERT_FALSE(1 == 0);
+ ASSERT_SIGNAL(ASSERT_FALSE(1 > 0), SIGABRT);
+
+ ASSERT_NULL(NULL);
+ ASSERT_SIGNAL(ASSERT_NULL(signal_to_string(SIGINT)), SIGABRT);
+
+ ASSERT_NOT_NULL(signal_to_string(SIGTERM));
+ ASSERT_SIGNAL(ASSERT_NOT_NULL(NULL), SIGABRT);
+
+ ASSERT_STREQ(NULL, null);
+ ASSERT_STREQ("foo", "foo");
+ ASSERT_SIGNAL(ASSERT_STREQ(null, "bar"), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_STREQ("foo", "bar"), SIGABRT);
+
+ ASSERT_EQ(0, 0);
+ ASSERT_EQ(-1, -1);
+ ASSERT_SIGNAL(ASSERT_EQ(255, -1), SIGABRT);
+
+ ASSERT_GE(0, 0);
+ ASSERT_GE(1, -1);
+ ASSERT_SIGNAL(ASSERT_GE(-1, 1), SIGABRT);
+
+ ASSERT_LE(0, 0);
+ ASSERT_LE(-1, 1);
+ ASSERT_SIGNAL(ASSERT_LE(1, -1), SIGABRT);
+
+ ASSERT_NE(0, (int64_t) UINT_MAX);
+ ASSERT_NE(-1, 1);
+ ASSERT_SIGNAL(ASSERT_NE(0, 0), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_NE(-1, -1), SIGABRT);
+
+ ASSERT_GT(1, 0);
+ ASSERT_GT(1, -1);
+ ASSERT_SIGNAL(ASSERT_GT(0, 0), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_GT(-1, 1), SIGABRT);
+
+ ASSERT_LT(0, 1);
+ ASSERT_LT(-1, 1);
+ ASSERT_SIGNAL(ASSERT_LT(0, 0), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_LT(1, -1), SIGABRT);
+}
+
DEFINE_TEST_MAIN(LOG_INFO);