From 02daa8df46c0be859a6802bd22aae5f7d0398881 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Mon, 21 Sep 2015 07:56:02 -0400 Subject: [PATCH 1/2] test/unit: simplify uc_assert_fail() macro This removes the UC_ASSERT_ERR_ANY constant, which was causing a compilation error on OSX: error: comparison of constant 3735928559 with expression of type 'uc_err' (aka 'enum uc_err') is always true [-Werror,-Wtautological-constant-out-of-range-compare] I could have probably changed 0xDEADBEEF to a constant < 0x80000000 but this seems cleaner anyway. --- test/unit/unicorn_test.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/unit/unicorn_test.h b/test/unit/unicorn_test.h index ccb53d75..9342566d 100644 --- a/test/unit/unicorn_test.h +++ b/test/unit/unicorn_test.h @@ -7,16 +7,13 @@ #include #include -#define UC_ASSERT_ERR_ANY 0xDEADBEEF - /** * Assert that err matches expect */ #define uc_assert_err(expect, err) \ do { \ uc_err __err = err; \ - if ((__err != expect) \ - || (expect == UC_ASSERT_ERR_ANY && __err == UC_ERR_OK)) { \ + if (__err != expect) { \ fail_msg("%s", uc_strerror(__err)); \ } \ } while (0) @@ -33,7 +30,13 @@ do { \ * as this serves to document which errors a function will return * in various scenarios. */ -#define uc_assert_fail(err) uc_assert_err(UC_ASSERT_ERR_ANY, err) +#define uc_assert_fail(err) \ +do { \ + uc_err __err = err; \ + if (__err == UC_ERR_OK) { \ + fail_msg("%s", uc_strerror(__err)); \ + } \ +} while (0) #endif /* UNICORN_TEST_H */ From 163e9020c87d0fb15c188457a3f8e0e7b071336c Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Mon, 21 Sep 2015 08:35:59 -0400 Subject: [PATCH 2/2] test/unit: add test_sanity This test ensures that the custom uc_assert_xxx() macros are working as intended. --- test/unit/.gitignore | 1 + test/unit/Makefile | 5 ++- test/unit/test_sanity.c | 88 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 test/unit/test_sanity.c diff --git a/test/unit/.gitignore b/test/unit/.gitignore index 1a39afbc..39d66b15 100644 --- a/test/unit/.gitignore +++ b/test/unit/.gitignore @@ -1,2 +1,3 @@ test_x86 test_mem_map +test_sanity diff --git a/test/unit/Makefile b/test/unit/Makefile index 707e9cd2..499d1a5f 100644 --- a/test/unit/Makefile +++ b/test/unit/Makefile @@ -4,7 +4,7 @@ CFLAGS += -L ../../ CFLAGS += -lcmocka -lunicorn CFLAGS += -I ../../include -ALL_TESTS = test_x86 test_mem_map +ALL_TESTS = test_sanity test_x86 test_mem_map .PHONY: all all: ${ALL_TESTS} @@ -16,10 +16,11 @@ clean: .PHONY: test test: export LD_LIBRARY_PATH=../../ test: ${ALL_TESTS} + ./test_sanity ./test_x86 ./test_mem_map - +test_sanity: test_sanity.c test_x86: test_x86.c test_mem_map: test_mem_map.c diff --git a/test/unit/test_sanity.c b/test/unit/test_sanity.c new file mode 100644 index 00000000..9788658b --- /dev/null +++ b/test/unit/test_sanity.c @@ -0,0 +1,88 @@ +#include "unicorn_test.h" + +/* Make sure the uc_assert macros work with constants */ +static void test_uc_assert_macros_constants(void **state) +{ + const uc_err nomem = UC_ERR_NOMEM; + + uc_assert_success(UC_ERR_OK); + uc_assert_err(UC_ERR_NOMEM, nomem); + uc_assert_fail(UC_ERR_VERSION); +} + +/******************************************************************************/ + +static uc_err feedback(uc_err err, int *callcount) +{ + assert_int_equal(++(*callcount), 1); + return err; +} + +/** + * Make sure the uc_assert macros work with function calls + * and only evaluate them once! + */ +static void test_uc_assert_macros_func_calls(void **state) +{ + int callcount; + + callcount = 0; + uc_assert_success(feedback(UC_ERR_OK, &callcount)); + + callcount = 0; + uc_assert_err(UC_ERR_NOMEM, feedback(UC_ERR_NOMEM, &callcount)); + + callcount = 0; + uc_assert_fail(feedback(UC_ERR_VERSION, &callcount)); +} + +/******************************************************************************/ + +static void fail_uc_assert_success(void **state) +{ + uc_assert_success(UC_ERR_NOMEM); +} + +static void fail_uc_assert_err(void **state) +{ + const uc_err ok = UC_ERR_OK; + uc_assert_err(UC_ERR_VERSION, ok); +} + +static void fail_uc_assert_fail(void **state) +{ + uc_assert_fail(UC_ERR_OK); +} + +static void test_uc_assert_macros_fail(void **state) +{ + /* A test-inside-a-test */ + + const struct CMUnitTest tests[] = { + /* these should all fail */ + cmocka_unit_test(fail_uc_assert_success), + cmocka_unit_test(fail_uc_assert_err), + cmocka_unit_test(fail_uc_assert_fail), + }; + + print_message("\n\n--------------------------------------------------------------------------------\n"); + print_message("START: Failure of the following tests is expected.\n\n"); + + assert_int_not_equal(0, cmocka_run_group_tests(tests, NULL, NULL)); + + print_message("\n\nEND: Failure of the preceding tests was expected.\n"); + print_message("--------------------------------------------------------------------------------\n\n"); +} + +/******************************************************************************/ + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_uc_assert_macros_constants), + cmocka_unit_test(test_uc_assert_macros_func_calls), + cmocka_unit_test(test_uc_assert_macros_fail), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}