From e0bc1f3367549b2f1eba2fa09988e573c737daa0 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Tue, 12 Mar 2024 14:47:35 +0100 Subject: [PATCH 1/4] obj: synchronize pmemobj_log API with core_log API Signed-off-by: Tomasz Gromadzki --- src/include/libpmemobj/log.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/include/libpmemobj/log.h b/src/include/libpmemobj/log.h index caa7abf7d48..657819f018a 100644 --- a/src/include/libpmemobj/log.h +++ b/src/include/libpmemobj/log.h @@ -45,7 +45,6 @@ enum pmemobj_log_threshold { * function */ PMEMOBJ_LOG_THRESHOLD_AUX, - PMEMOBJ_LOG_THRESHOLD_MAX }; /* @@ -72,10 +71,8 @@ typedef void pmemobj_log_function( const int line_no, /* the function name where the message coming from */ const char *function_name, - /* printf(3)-like format string of the message */ - const char *message_format, - /* additional arguments of the message format string */ - ...); + /* message */ + const char *message); #define PMEMOBJ_LOG_USE_DEFAULT_FUNCTION (NULL) From a056f434eb1cd03198de7766c7befe4a16ff0d56 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Tue, 12 Mar 2024 08:27:01 +0100 Subject: [PATCH 2/4] test: pmemobj_log_function UT implementation Signed-off-by: Tomasz Gromadzki --- src/test/Makefile | 1 + src/test/obj_log_function/.gitignore | 1 + src/test/obj_log_function/Makefile | 14 + src/test/obj_log_function/TESTS.py | 47 ++++ src/test/obj_log_function/obj_log_function.c | 273 +++++++++++++++++++ 5 files changed, 336 insertions(+) create mode 100644 src/test/obj_log_function/.gitignore create mode 100644 src/test/obj_log_function/Makefile create mode 100755 src/test/obj_log_function/TESTS.py create mode 100644 src/test/obj_log_function/obj_log_function.c diff --git a/src/test/Makefile b/src/test/Makefile index 0cfdff1d793..87f07d65dda 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -62,6 +62,7 @@ OBJ_TESTS = \ obj_list_valgrind\ obj_list_macro\ obj_locks\ + obj_log_function\ obj_mem\ obj_memblock\ obj_memcheck\ diff --git a/src/test/obj_log_function/.gitignore b/src/test/obj_log_function/.gitignore new file mode 100644 index 00000000000..c72c292afa2 --- /dev/null +++ b/src/test/obj_log_function/.gitignore @@ -0,0 +1 @@ +obj_log_function diff --git a/src/test/obj_log_function/Makefile b/src/test/obj_log_function/Makefile new file mode 100644 index 00000000000..47df9a23129 --- /dev/null +++ b/src/test/obj_log_function/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation + +TARGET = obj_log_function +OBJS = obj_log_function.o + +BUILD_STATIC_DEBUG=n +BUILD_STATIC_NONDEBUG=n + +# required for proper mock integration +LIBPMEMOBJ=internal-debug + +include ../Makefile.inc +LDFLAGS += $(call extract_funcs, obj_log_function.c) diff --git a/src/test/obj_log_function/TESTS.py b/src/test/obj_log_function/TESTS.py new file mode 100755 index 00000000000..c80912fc7b5 --- /dev/null +++ b/src/test/obj_log_function/TESTS.py @@ -0,0 +1,47 @@ +#!../env.py +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation +# + + +import testframework as t +from testframework import granularity as g + + +@g.require_granularity(g.ANY) +# The 'debug' build is chosen arbitrarily to ensure these tests are run only +# once. No dynamic libraries are used nor .static_* builds are available. +@t.require_build('debug') +class OBJ_LOG(t.BaseTest): + test_type = t.Short + + def run(self, ctx): + ctx.exec('obj_log_function', self.test_case) + + +class TEST0(OBJ_LOG): + test_case = 'test_log_set_function' + + +class TEST1(OBJ_LOG): + test_case = 'test_log_set_function_EAGAIN' + + +class TEST2(OBJ_LOG): + test_case = 'test_log_set_treshold' + + +class TEST3(OBJ_LOG): + test_case = 'test_log_set_treshold_EAGAIN' + + +class TEST4(OBJ_LOG): + test_case = 'test_log_set_treshold_EINVAL' + + +class TEST5(OBJ_LOG): + test_case = 'test_log_get_treshold' + + +class TEST6(OBJ_LOG): + test_case = 'test_log_get_treshold_EAGAIN' diff --git a/src/test/obj_log_function/obj_log_function.c b/src/test/obj_log_function/obj_log_function.c new file mode 100644 index 00000000000..cdf86d692bf --- /dev/null +++ b/src/test/obj_log_function/obj_log_function.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2024, Intel Corporation */ + +/* + * obj_log_function.c -- unit test for obj_log_function + */ + +#include "unittest.h" +#include "log_internal.h" +#include "libpmemobj/log.h" + +#define NO_ARGS_CONSUMED 0 + +#define VALIDATED_CALL 127 +#define CALLED (VALIDATED_CALL + 1) + +/* + * *** pmemobj_log_set_function() tests *** + */ +#define PMEMOBJ_LOG_CUSTOM_FUNCTION_MOCK ((pmemobj_log_function *) 0xA1C5D68F) + +/* Mock */ +static struct { + int ret; +} Core_log_set_function; + +FUNC_MOCK(core_log_set_function, int, core_log_function *log_function) + FUNC_MOCK_RUN(VALIDATED_CALL) { + UT_ASSERTeq((void *)log_function, + (void *)PMEMOBJ_LOG_CUSTOM_FUNCTION_MOCK); + return Core_log_set_function.ret; + } +FUNC_MOCK_RUN_DEFAULT { + return _FUNC_REAL(core_log_set_function)(log_function); +} +FUNC_MOCK_END + +/* Helper */ +static int +test_log_set_function_helper(int error) +{ + errno = NO_ERRNO; + Core_log_set_function.ret = error == NO_ERRNO ? 0: error; + FUNC_MOCK_RCOUNTER_SET(core_log_set_function, VALIDATED_CALL); + int ret = pmemobj_log_set_function(PMEMOBJ_LOG_CUSTOM_FUNCTION_MOCK); + if (error == NO_ERRNO) { + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(errno, NO_ERRNO); + } else { + UT_ASSERTeq(ret, 1); + UT_ASSERTeq(errno, error); + } + UT_ASSERTeq(RCOUNTER(core_log_set_function), CALLED); + + return NO_ARGS_CONSUMED; +} + +/* Tests */ +/* + * Check: + * - if core_log_set_function is called with proper argument + * - if pmemobj_log_set_function return 0 (no error) + * - no errno is set + */ +static int +test_log_set_function(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_function_helper(NO_ERRNO); +} + +/* + * core_log_set_function() with EAGAIN error + * Check: + * - if core_log_set_function is called with proper argument + * - if pmemobj_log_set_function return 1 (error via errno) + * - errno is set to EAGAIN + */ +static int +test_log_set_function_EAGAIN(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_function_helper(EAGAIN); +} + +/* + * *** pmemobj_log_set_treshold() tests *** + */ +static enum core_log_threshold core_tresholds[] = { + CORE_LOG_THRESHOLD, + CORE_LOG_THRESHOLD_AUX +}; + +static enum core_log_level core_levels[] = { + CORE_LOG_LEVEL_HARK, + CORE_LOG_LEVEL_FATAL, + CORE_LOG_LEVEL_ERROR, + CORE_LOG_LEVEL_WARNING, + CORE_LOG_LEVEL_NOTICE, + CORE_LOG_LEVEL_INFO, + CORE_LOG_LEVEL_DEBUG +}; + +/* Mock */ +static struct { + enum core_log_threshold exp_threshold; + enum core_log_level exp_level; + int ret; +} Core_log_set_treshold; + +FUNC_MOCK(core_log_set_threshold, int, enum core_log_threshold threshold, + enum core_log_level level) + FUNC_MOCK_RUN(VALIDATED_CALL) { + UT_ASSERTeq(threshold, Core_log_set_treshold.exp_threshold); + UT_ASSERTeq(level, Core_log_set_treshold.exp_level); + return Core_log_set_treshold.ret; + } +FUNC_MOCK_RUN_DEFAULT { + return _FUNC_REAL(core_log_set_threshold)(threshold, level); +} +FUNC_MOCK_END + +/* Helper */ +static int +test_log_set_treshold_helper(int error) +{ + errno = NO_ERRNO; + Core_log_set_treshold.ret = error == NO_ERRNO ? 0: error; + for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; + treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { + Core_log_set_treshold.exp_threshold = core_tresholds[treshold]; + for (enum pmemobj_log_level level = PMEMOBJ_LOG_LEVEL_HARK; + level <= PMEMOBJ_LOG_LEVEL_DEBUG; level++) { + Core_log_set_treshold.exp_level = core_levels[level]; + FUNC_MOCK_RCOUNTER_SET(core_log_set_threshold, + VALIDATED_CALL); + int ret = pmemobj_log_set_threshold(treshold, level); + if (error == NO_ERRNO) { + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(errno, NO_ERRNO); + } else { + UT_ASSERTeq(ret, 1); + UT_ASSERTeq(errno, error); + } + UT_ASSERTeq(RCOUNTER(core_log_set_threshold), CALLED); + /* no need to test the error path for all values */ + if (error != NO_ERRNO) + return NO_ARGS_CONSUMED; + } + } + return NO_ARGS_CONSUMED; +} + +/* Tests */ +/* + * Check: + * - if core_log_set_treshold is called with proper arguments + * - if pmemobj_log_set_treshold return 0 (no error) + * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL + * - no errno is set + */ +static int +test_log_set_treshold(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(NO_ERRNO); +} + +/* Check pmemobj_log_set_threshold EAGAIN error handling. */ +static int +test_log_set_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(EAGAIN); +} + +/* Check pmemobj_log_set_threshold EINVAL error handling. */ +static int +test_log_set_treshold_EINVAL(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(EINVAL); +} + +/* + * *** pmemobj_log_get_treshold() tests *** + */ +/* Mock */ +static struct { + enum core_log_threshold exp_threshold; + enum core_log_level level; + int ret; +} Core_log_get_treshold; + +FUNC_MOCK(core_log_get_threshold, int, enum core_log_threshold threshold, + enum core_log_level *level) + FUNC_MOCK_RUN(VALIDATED_CALL) { + UT_ASSERTeq(threshold, Core_log_get_treshold.exp_threshold); + if (Core_log_get_treshold.ret == 0) + *level = Core_log_get_treshold.level; + return Core_log_get_treshold.ret; + } +FUNC_MOCK_RUN_DEFAULT { + return _FUNC_REAL(core_log_get_threshold)(threshold, level); +} +FUNC_MOCK_END + +/* Helper */ +static int +test_log_get_treshold_helper(int error) +{ + errno = NO_ERRNO; + Core_log_get_treshold.ret = error == NO_ERRNO ? 0: error; + for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; + treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { + Core_log_get_treshold.exp_threshold = core_tresholds[treshold]; + for (enum pmemobj_log_level exp_level = PMEMOBJ_LOG_LEVEL_HARK; + exp_level <= PMEMOBJ_LOG_LEVEL_DEBUG; exp_level++) { + enum pmemobj_log_level level; + Core_log_get_treshold.level = core_levels[exp_level]; + FUNC_MOCK_RCOUNTER_SET(core_log_get_threshold, + VALIDATED_CALL); + int ret = pmemobj_log_get_threshold(treshold, &level); + if (error == NO_ERRNO) { + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(level, exp_level); + UT_ASSERTeq(errno, NO_ERRNO); + } else { + UT_ASSERTeq(ret, 1); + UT_ASSERTeq(errno, error); + } + UT_ASSERTeq(RCOUNTER(core_log_get_threshold), CALLED); + /* no need to test the error path for all values */ + if (error != NO_ERRNO) + return NO_ARGS_CONSUMED; + } + } + return NO_ARGS_CONSUMED; +} + +/* Tests */ +/* + * Check: + * - if core_log_get_treshold is called with proper arguments + * - if pmemobj_log_get_treshold return 0 (no error) + * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL + * - no errno is set + */ +static int +test_log_get_treshold(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_get_treshold_helper(NO_ERRNO); +} + +/* Check pmemobj_log_get_threshold EAGAIN error handling. */ +static int +test_log_get_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_get_treshold_helper(EAGAIN); +} + +static struct test_case test_cases[] = { + TEST_CASE(test_log_set_function), + TEST_CASE(test_log_set_function_EAGAIN), + TEST_CASE(test_log_set_treshold), + TEST_CASE(test_log_set_treshold_EAGAIN), + TEST_CASE(test_log_set_treshold_EINVAL), + TEST_CASE(test_log_get_treshold), + TEST_CASE(test_log_get_treshold_EAGAIN), +}; + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_log_function"); + TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); + DONE(NULL); +} From cd79eb526a9f81cdc5fd0728c50bff90acff2281 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Thu, 14 Mar 2024 08:14:45 +0100 Subject: [PATCH 3/4] test: rename obj_log_function to obj_log_set_function Signed-off-by: Tomasz Gromadzki --- src/test/Makefile | 2 +- src/test/obj_log_function/.gitignore | 1 - src/test/obj_log_set_function/.gitignore | 1 + .../{obj_log_function => obj_log_set_function}/Makefile | 6 +++--- .../{obj_log_function => obj_log_set_function}/TESTS.py | 2 +- .../obj_log_set_function.c} | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 src/test/obj_log_function/.gitignore create mode 100644 src/test/obj_log_set_function/.gitignore rename src/test/{obj_log_function => obj_log_set_function}/Makefile (64%) rename src/test/{obj_log_function => obj_log_set_function}/TESTS.py (94%) rename src/test/{obj_log_function/obj_log_function.c => obj_log_set_function/obj_log_set_function.c} (98%) diff --git a/src/test/Makefile b/src/test/Makefile index 87f07d65dda..e36632d0754 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -62,7 +62,7 @@ OBJ_TESTS = \ obj_list_valgrind\ obj_list_macro\ obj_locks\ - obj_log_function\ + obj_log_set_function\ obj_mem\ obj_memblock\ obj_memcheck\ diff --git a/src/test/obj_log_function/.gitignore b/src/test/obj_log_function/.gitignore deleted file mode 100644 index c72c292afa2..00000000000 --- a/src/test/obj_log_function/.gitignore +++ /dev/null @@ -1 +0,0 @@ -obj_log_function diff --git a/src/test/obj_log_set_function/.gitignore b/src/test/obj_log_set_function/.gitignore new file mode 100644 index 00000000000..4d9074233de --- /dev/null +++ b/src/test/obj_log_set_function/.gitignore @@ -0,0 +1 @@ +obj_log_set_function diff --git a/src/test/obj_log_function/Makefile b/src/test/obj_log_set_function/Makefile similarity index 64% rename from src/test/obj_log_function/Makefile rename to src/test/obj_log_set_function/Makefile index 47df9a23129..f3a26da93da 100644 --- a/src/test/obj_log_function/Makefile +++ b/src/test/obj_log_set_function/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright 2024, Intel Corporation -TARGET = obj_log_function -OBJS = obj_log_function.o +TARGET = obj_log_set_function +OBJS = obj_log_set_function.o BUILD_STATIC_DEBUG=n BUILD_STATIC_NONDEBUG=n @@ -11,4 +11,4 @@ BUILD_STATIC_NONDEBUG=n LIBPMEMOBJ=internal-debug include ../Makefile.inc -LDFLAGS += $(call extract_funcs, obj_log_function.c) +LDFLAGS += $(call extract_funcs, obj_log_set_function.c) diff --git a/src/test/obj_log_function/TESTS.py b/src/test/obj_log_set_function/TESTS.py similarity index 94% rename from src/test/obj_log_function/TESTS.py rename to src/test/obj_log_set_function/TESTS.py index c80912fc7b5..2965e56b1ff 100755 --- a/src/test/obj_log_function/TESTS.py +++ b/src/test/obj_log_set_function/TESTS.py @@ -16,7 +16,7 @@ class OBJ_LOG(t.BaseTest): test_type = t.Short def run(self, ctx): - ctx.exec('obj_log_function', self.test_case) + ctx.exec('obj_log_set_function', self.test_case) class TEST0(OBJ_LOG): diff --git a/src/test/obj_log_function/obj_log_function.c b/src/test/obj_log_set_function/obj_log_set_function.c similarity index 98% rename from src/test/obj_log_function/obj_log_function.c rename to src/test/obj_log_set_function/obj_log_set_function.c index cdf86d692bf..49faadbedbc 100644 --- a/src/test/obj_log_function/obj_log_function.c +++ b/src/test/obj_log_set_function/obj_log_set_function.c @@ -2,7 +2,7 @@ /* Copyright 2024, Intel Corporation */ /* - * obj_log_function.c -- unit test for obj_log_function + * obj_log_set_function.c -- unit test for pmemobj_log_set_function */ #include "unittest.h" @@ -267,7 +267,7 @@ static struct test_case test_cases[] = { int main(int argc, char *argv[]) { - START(argc, argv, "obj_log_function"); + START(argc, argv, "obj_log_set_function"); TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); DONE(NULL); } From 0ad2b2baf39fa7cafbbcdc32cd0b86bc7f68aea0 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Thu, 14 Mar 2024 08:27:30 +0100 Subject: [PATCH 4/4] test: split pmemobj_log* tests to separate folders Signed-off-by: Tomasz Gromadzki --- src/test/Makefile | 2 + src/test/obj_log_get_treshold/.gitignore | 1 + src/test/obj_log_get_treshold/Makefile | 14 ++ src/test/obj_log_get_treshold/TESTS.py | 27 +++ .../obj_log_get_treshold.c | 116 +++++++++++ src/test/obj_log_set_function/TESTS.py | 20 -- .../obj_log_set_function.c | 186 +----------------- src/test/obj_log_set_treshold/.gitignore | 1 + src/test/obj_log_set_treshold/Makefile | 14 ++ src/test/obj_log_set_treshold/TESTS.py | 31 +++ .../obj_log_set_treshold.c | 121 ++++++++++++ 11 files changed, 329 insertions(+), 204 deletions(-) create mode 100644 src/test/obj_log_get_treshold/.gitignore create mode 100644 src/test/obj_log_get_treshold/Makefile create mode 100755 src/test/obj_log_get_treshold/TESTS.py create mode 100644 src/test/obj_log_get_treshold/obj_log_get_treshold.c create mode 100644 src/test/obj_log_set_treshold/.gitignore create mode 100644 src/test/obj_log_set_treshold/Makefile create mode 100755 src/test/obj_log_set_treshold/TESTS.py create mode 100644 src/test/obj_log_set_treshold/obj_log_set_treshold.c diff --git a/src/test/Makefile b/src/test/Makefile index e36632d0754..961172eac35 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -62,7 +62,9 @@ OBJ_TESTS = \ obj_list_valgrind\ obj_list_macro\ obj_locks\ + obj_log_get_treshold\ obj_log_set_function\ + obj_log_set_treshold\ obj_mem\ obj_memblock\ obj_memcheck\ diff --git a/src/test/obj_log_get_treshold/.gitignore b/src/test/obj_log_get_treshold/.gitignore new file mode 100644 index 00000000000..72cb85ece1c --- /dev/null +++ b/src/test/obj_log_get_treshold/.gitignore @@ -0,0 +1 @@ +obj_log_get_treshold diff --git a/src/test/obj_log_get_treshold/Makefile b/src/test/obj_log_get_treshold/Makefile new file mode 100644 index 00000000000..8629483392b --- /dev/null +++ b/src/test/obj_log_get_treshold/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation + +TARGET = obj_log_get_treshold +OBJS = obj_log_get_treshold.o + +BUILD_STATIC_DEBUG=n +BUILD_STATIC_NONDEBUG=n + +# required for proper mock integration +LIBPMEMOBJ=internal-debug + +include ../Makefile.inc +LDFLAGS += $(call extract_funcs, obj_log_get_treshold.c) diff --git a/src/test/obj_log_get_treshold/TESTS.py b/src/test/obj_log_get_treshold/TESTS.py new file mode 100755 index 00000000000..47094061bf6 --- /dev/null +++ b/src/test/obj_log_get_treshold/TESTS.py @@ -0,0 +1,27 @@ +#!../env.py +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation +# + + +import testframework as t +from testframework import granularity as g + + +@g.require_granularity(g.ANY) +# The 'debug' build is chosen arbitrarily to ensure these tests are run only +# once. No dynamic libraries are used nor .static_* builds are available. +@t.require_build('debug') +class OBJ_LOG(t.BaseTest): + test_type = t.Short + + def run(self, ctx): + ctx.exec('obj_log_get_treshold', self.test_case) + + +class TEST0(OBJ_LOG): + test_case = 'test_log_get_treshold' + + +class TEST1(OBJ_LOG): + test_case = 'test_log_get_treshold_EAGAIN' diff --git a/src/test/obj_log_get_treshold/obj_log_get_treshold.c b/src/test/obj_log_get_treshold/obj_log_get_treshold.c new file mode 100644 index 00000000000..3dcf79707f5 --- /dev/null +++ b/src/test/obj_log_get_treshold/obj_log_get_treshold.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2024, Intel Corporation */ + +/* + * obj_log_get_treshold.c -- unit test for pmemobj_log_get_treshold + */ + +#include "unittest.h" +#include "log_internal.h" +#include "libpmemobj/log.h" + +#define NO_ARGS_CONSUMED 0 + +#define VALIDATED_CALL 127 +#define CALLED (VALIDATED_CALL + 1) + +static enum core_log_threshold core_tresholds[] = { + CORE_LOG_THRESHOLD, + CORE_LOG_THRESHOLD_AUX +}; + +static enum core_log_level core_levels[] = { + CORE_LOG_LEVEL_HARK, + CORE_LOG_LEVEL_FATAL, + CORE_LOG_LEVEL_ERROR, + CORE_LOG_LEVEL_WARNING, + CORE_LOG_LEVEL_NOTICE, + CORE_LOG_LEVEL_INFO, + CORE_LOG_LEVEL_DEBUG +}; + +/* Mock */ +static struct { + enum core_log_threshold exp_threshold; + enum core_log_level level; + int ret; +} Core_log_get_treshold; + +FUNC_MOCK(core_log_get_threshold, int, enum core_log_threshold threshold, + enum core_log_level *level) + FUNC_MOCK_RUN(VALIDATED_CALL) { + UT_ASSERTeq(threshold, Core_log_get_treshold.exp_threshold); + if (Core_log_get_treshold.ret == 0) + *level = Core_log_get_treshold.level; + return Core_log_get_treshold.ret; + } +FUNC_MOCK_RUN_DEFAULT { + return _FUNC_REAL(core_log_get_threshold)(threshold, level); +} +FUNC_MOCK_END + +/* Helper */ +static int +test_log_get_treshold_helper(int error) +{ + errno = 0; + Core_log_get_treshold.ret = error == NO_ERRNO ? 0 : error; + for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; + treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { + Core_log_get_treshold.exp_threshold = core_tresholds[treshold]; + for (enum pmemobj_log_level exp_level = PMEMOBJ_LOG_LEVEL_HARK; + exp_level <= PMEMOBJ_LOG_LEVEL_DEBUG; exp_level++) { + enum pmemobj_log_level level; + Core_log_get_treshold.level = core_levels[exp_level]; + FUNC_MOCK_RCOUNTER_SET(core_log_get_threshold, + VALIDATED_CALL); + int ret = pmemobj_log_get_threshold(treshold, &level); + if (error == NO_ERRNO) { + UT_ASSERTeq(ret, 0); + UT_ASSERTeq(level, exp_level); + } else { + UT_ASSERTeq(ret, 1); + UT_ASSERTeq(errno, error); + } + UT_ASSERTeq(RCOUNTER(core_log_get_threshold), CALLED); + /* no need to test the error path for all values */ + if (error != NO_ERRNO) + return NO_ARGS_CONSUMED; + } + } + return NO_ARGS_CONSUMED; +} + +/* Tests */ +/* + * Check: + * - if core_log_get_treshold is called with proper arguments + * - if pmemobj_log_get_treshold return 0 (no error) + * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL + * - no errno is set + */ +static int +test_log_get_treshold(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_get_treshold_helper(NO_ERRNO); +} + +/* Check pmemobj_log_get_threshold EAGAIN error handling. */ +static int +test_log_get_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_get_treshold_helper(EAGAIN); +} + +static struct test_case test_cases[] = { + TEST_CASE(test_log_get_treshold), + TEST_CASE(test_log_get_treshold_EAGAIN), +}; + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_log_get_treshold"); + TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); + DONE(NULL); +} diff --git a/src/test/obj_log_set_function/TESTS.py b/src/test/obj_log_set_function/TESTS.py index 2965e56b1ff..7d59355dd63 100755 --- a/src/test/obj_log_set_function/TESTS.py +++ b/src/test/obj_log_set_function/TESTS.py @@ -25,23 +25,3 @@ class TEST0(OBJ_LOG): class TEST1(OBJ_LOG): test_case = 'test_log_set_function_EAGAIN' - - -class TEST2(OBJ_LOG): - test_case = 'test_log_set_treshold' - - -class TEST3(OBJ_LOG): - test_case = 'test_log_set_treshold_EAGAIN' - - -class TEST4(OBJ_LOG): - test_case = 'test_log_set_treshold_EINVAL' - - -class TEST5(OBJ_LOG): - test_case = 'test_log_get_treshold' - - -class TEST6(OBJ_LOG): - test_case = 'test_log_get_treshold_EAGAIN' diff --git a/src/test/obj_log_set_function/obj_log_set_function.c b/src/test/obj_log_set_function/obj_log_set_function.c index 49faadbedbc..bf95b03f690 100644 --- a/src/test/obj_log_set_function/obj_log_set_function.c +++ b/src/test/obj_log_set_function/obj_log_set_function.c @@ -14,9 +14,6 @@ #define VALIDATED_CALL 127 #define CALLED (VALIDATED_CALL + 1) -/* - * *** pmemobj_log_set_function() tests *** - */ #define PMEMOBJ_LOG_CUSTOM_FUNCTION_MOCK ((pmemobj_log_function *) 0xA1C5D68F) /* Mock */ @@ -39,13 +36,12 @@ FUNC_MOCK_END static int test_log_set_function_helper(int error) { - errno = NO_ERRNO; - Core_log_set_function.ret = error == NO_ERRNO ? 0: error; + errno = 0; + Core_log_set_function.ret = error == NO_ERRNO ? 0 : error; FUNC_MOCK_RCOUNTER_SET(core_log_set_function, VALIDATED_CALL); int ret = pmemobj_log_set_function(PMEMOBJ_LOG_CUSTOM_FUNCTION_MOCK); if (error == NO_ERRNO) { UT_ASSERTeq(ret, 0); - UT_ASSERTeq(errno, NO_ERRNO); } else { UT_ASSERTeq(ret, 1); UT_ASSERTeq(errno, error); @@ -81,187 +77,9 @@ test_log_set_function_EAGAIN(const struct test_case *tc, int argc, char *argv[]) return test_log_set_function_helper(EAGAIN); } -/* - * *** pmemobj_log_set_treshold() tests *** - */ -static enum core_log_threshold core_tresholds[] = { - CORE_LOG_THRESHOLD, - CORE_LOG_THRESHOLD_AUX -}; - -static enum core_log_level core_levels[] = { - CORE_LOG_LEVEL_HARK, - CORE_LOG_LEVEL_FATAL, - CORE_LOG_LEVEL_ERROR, - CORE_LOG_LEVEL_WARNING, - CORE_LOG_LEVEL_NOTICE, - CORE_LOG_LEVEL_INFO, - CORE_LOG_LEVEL_DEBUG -}; - -/* Mock */ -static struct { - enum core_log_threshold exp_threshold; - enum core_log_level exp_level; - int ret; -} Core_log_set_treshold; - -FUNC_MOCK(core_log_set_threshold, int, enum core_log_threshold threshold, - enum core_log_level level) - FUNC_MOCK_RUN(VALIDATED_CALL) { - UT_ASSERTeq(threshold, Core_log_set_treshold.exp_threshold); - UT_ASSERTeq(level, Core_log_set_treshold.exp_level); - return Core_log_set_treshold.ret; - } -FUNC_MOCK_RUN_DEFAULT { - return _FUNC_REAL(core_log_set_threshold)(threshold, level); -} -FUNC_MOCK_END - -/* Helper */ -static int -test_log_set_treshold_helper(int error) -{ - errno = NO_ERRNO; - Core_log_set_treshold.ret = error == NO_ERRNO ? 0: error; - for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; - treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { - Core_log_set_treshold.exp_threshold = core_tresholds[treshold]; - for (enum pmemobj_log_level level = PMEMOBJ_LOG_LEVEL_HARK; - level <= PMEMOBJ_LOG_LEVEL_DEBUG; level++) { - Core_log_set_treshold.exp_level = core_levels[level]; - FUNC_MOCK_RCOUNTER_SET(core_log_set_threshold, - VALIDATED_CALL); - int ret = pmemobj_log_set_threshold(treshold, level); - if (error == NO_ERRNO) { - UT_ASSERTeq(ret, 0); - UT_ASSERTeq(errno, NO_ERRNO); - } else { - UT_ASSERTeq(ret, 1); - UT_ASSERTeq(errno, error); - } - UT_ASSERTeq(RCOUNTER(core_log_set_threshold), CALLED); - /* no need to test the error path for all values */ - if (error != NO_ERRNO) - return NO_ARGS_CONSUMED; - } - } - return NO_ARGS_CONSUMED; -} - -/* Tests */ -/* - * Check: - * - if core_log_set_treshold is called with proper arguments - * - if pmemobj_log_set_treshold return 0 (no error) - * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL - * - no errno is set - */ -static int -test_log_set_treshold(const struct test_case *tc, int argc, char *argv[]) -{ - return test_log_set_treshold_helper(NO_ERRNO); -} - -/* Check pmemobj_log_set_threshold EAGAIN error handling. */ -static int -test_log_set_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) -{ - return test_log_set_treshold_helper(EAGAIN); -} - -/* Check pmemobj_log_set_threshold EINVAL error handling. */ -static int -test_log_set_treshold_EINVAL(const struct test_case *tc, int argc, char *argv[]) -{ - return test_log_set_treshold_helper(EINVAL); -} - -/* - * *** pmemobj_log_get_treshold() tests *** - */ -/* Mock */ -static struct { - enum core_log_threshold exp_threshold; - enum core_log_level level; - int ret; -} Core_log_get_treshold; - -FUNC_MOCK(core_log_get_threshold, int, enum core_log_threshold threshold, - enum core_log_level *level) - FUNC_MOCK_RUN(VALIDATED_CALL) { - UT_ASSERTeq(threshold, Core_log_get_treshold.exp_threshold); - if (Core_log_get_treshold.ret == 0) - *level = Core_log_get_treshold.level; - return Core_log_get_treshold.ret; - } -FUNC_MOCK_RUN_DEFAULT { - return _FUNC_REAL(core_log_get_threshold)(threshold, level); -} -FUNC_MOCK_END - -/* Helper */ -static int -test_log_get_treshold_helper(int error) -{ - errno = NO_ERRNO; - Core_log_get_treshold.ret = error == NO_ERRNO ? 0: error; - for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; - treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { - Core_log_get_treshold.exp_threshold = core_tresholds[treshold]; - for (enum pmemobj_log_level exp_level = PMEMOBJ_LOG_LEVEL_HARK; - exp_level <= PMEMOBJ_LOG_LEVEL_DEBUG; exp_level++) { - enum pmemobj_log_level level; - Core_log_get_treshold.level = core_levels[exp_level]; - FUNC_MOCK_RCOUNTER_SET(core_log_get_threshold, - VALIDATED_CALL); - int ret = pmemobj_log_get_threshold(treshold, &level); - if (error == NO_ERRNO) { - UT_ASSERTeq(ret, 0); - UT_ASSERTeq(level, exp_level); - UT_ASSERTeq(errno, NO_ERRNO); - } else { - UT_ASSERTeq(ret, 1); - UT_ASSERTeq(errno, error); - } - UT_ASSERTeq(RCOUNTER(core_log_get_threshold), CALLED); - /* no need to test the error path for all values */ - if (error != NO_ERRNO) - return NO_ARGS_CONSUMED; - } - } - return NO_ARGS_CONSUMED; -} - -/* Tests */ -/* - * Check: - * - if core_log_get_treshold is called with proper arguments - * - if pmemobj_log_get_treshold return 0 (no error) - * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL - * - no errno is set - */ -static int -test_log_get_treshold(const struct test_case *tc, int argc, char *argv[]) -{ - return test_log_get_treshold_helper(NO_ERRNO); -} - -/* Check pmemobj_log_get_threshold EAGAIN error handling. */ -static int -test_log_get_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) -{ - return test_log_get_treshold_helper(EAGAIN); -} - static struct test_case test_cases[] = { TEST_CASE(test_log_set_function), TEST_CASE(test_log_set_function_EAGAIN), - TEST_CASE(test_log_set_treshold), - TEST_CASE(test_log_set_treshold_EAGAIN), - TEST_CASE(test_log_set_treshold_EINVAL), - TEST_CASE(test_log_get_treshold), - TEST_CASE(test_log_get_treshold_EAGAIN), }; int diff --git a/src/test/obj_log_set_treshold/.gitignore b/src/test/obj_log_set_treshold/.gitignore new file mode 100644 index 00000000000..bc77b806407 --- /dev/null +++ b/src/test/obj_log_set_treshold/.gitignore @@ -0,0 +1 @@ +obj_log_set_treshold diff --git a/src/test/obj_log_set_treshold/Makefile b/src/test/obj_log_set_treshold/Makefile new file mode 100644 index 00000000000..d36f662524a --- /dev/null +++ b/src/test/obj_log_set_treshold/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation + +TARGET = obj_log_set_treshold +OBJS = obj_log_set_treshold.o + +BUILD_STATIC_DEBUG=n +BUILD_STATIC_NONDEBUG=n + +# required for proper mock integration +LIBPMEMOBJ=internal-debug + +include ../Makefile.inc +LDFLAGS += $(call extract_funcs, obj_log_set_treshold.c) diff --git a/src/test/obj_log_set_treshold/TESTS.py b/src/test/obj_log_set_treshold/TESTS.py new file mode 100755 index 00000000000..5d9b2416f83 --- /dev/null +++ b/src/test/obj_log_set_treshold/TESTS.py @@ -0,0 +1,31 @@ +#!../env.py +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation +# + + +import testframework as t +from testframework import granularity as g + + +@g.require_granularity(g.ANY) +# The 'debug' build is chosen arbitrarily to ensure these tests are run only +# once. No dynamic libraries are used nor .static_* builds are available. +@t.require_build('debug') +class OBJ_LOG(t.BaseTest): + test_type = t.Short + + def run(self, ctx): + ctx.exec('obj_log_set_treshold', self.test_case) + + +class TEST0(OBJ_LOG): + test_case = 'test_log_set_treshold' + + +class TEST1(OBJ_LOG): + test_case = 'test_log_set_treshold_EAGAIN' + + +class TEST2(OBJ_LOG): + test_case = 'test_log_set_treshold_EINVAL' diff --git a/src/test/obj_log_set_treshold/obj_log_set_treshold.c b/src/test/obj_log_set_treshold/obj_log_set_treshold.c new file mode 100644 index 00000000000..4f9aeec3ed3 --- /dev/null +++ b/src/test/obj_log_set_treshold/obj_log_set_treshold.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2024, Intel Corporation */ + +/* + * obj_log_set_treshold.c -- unit test for pmemobj_log_set_treshold + */ + +#include "unittest.h" +#include "log_internal.h" +#include "libpmemobj/log.h" + +#define NO_ARGS_CONSUMED 0 + +#define VALIDATED_CALL 127 +#define CALLED (VALIDATED_CALL + 1) + +static enum core_log_threshold core_tresholds[] = { + CORE_LOG_THRESHOLD, + CORE_LOG_THRESHOLD_AUX +}; + +static enum core_log_level core_levels[] = { + CORE_LOG_LEVEL_HARK, + CORE_LOG_LEVEL_FATAL, + CORE_LOG_LEVEL_ERROR, + CORE_LOG_LEVEL_WARNING, + CORE_LOG_LEVEL_NOTICE, + CORE_LOG_LEVEL_INFO, + CORE_LOG_LEVEL_DEBUG +}; + +/* Mock */ +static struct { + enum core_log_threshold exp_threshold; + enum core_log_level exp_level; + int ret; +} Core_log_set_treshold; + +FUNC_MOCK(core_log_set_threshold, int, enum core_log_threshold threshold, + enum core_log_level level) + FUNC_MOCK_RUN(VALIDATED_CALL) { + UT_ASSERTeq(threshold, Core_log_set_treshold.exp_threshold); + UT_ASSERTeq(level, Core_log_set_treshold.exp_level); + return Core_log_set_treshold.ret; + } +FUNC_MOCK_RUN_DEFAULT { + return _FUNC_REAL(core_log_set_threshold)(threshold, level); +} +FUNC_MOCK_END + +/* Helper */ +static int +test_log_set_treshold_helper(int error) +{ + errno = 0; + Core_log_set_treshold.ret = error == NO_ERRNO ? 0 : error; + for (enum pmemobj_log_threshold treshold = PMEMOBJ_LOG_THRESHOLD; + treshold <= PMEMOBJ_LOG_THRESHOLD_AUX; treshold++) { + Core_log_set_treshold.exp_threshold = core_tresholds[treshold]; + for (enum pmemobj_log_level level = PMEMOBJ_LOG_LEVEL_HARK; + level <= PMEMOBJ_LOG_LEVEL_DEBUG; level++) { + Core_log_set_treshold.exp_level = core_levels[level]; + FUNC_MOCK_RCOUNTER_SET(core_log_set_threshold, + VALIDATED_CALL); + int ret = pmemobj_log_set_threshold(treshold, level); + if (error == NO_ERRNO) { + UT_ASSERTeq(ret, 0); + } else { + UT_ASSERTeq(ret, 1); + UT_ASSERTeq(errno, error); + } + UT_ASSERTeq(RCOUNTER(core_log_set_threshold), CALLED); + /* no need to test the error path for all values */ + if (error != NO_ERRNO) + return NO_ARGS_CONSUMED; + } + } + return NO_ARGS_CONSUMED; +} + +/* Tests */ +/* + * Check: + * - if core_log_set_treshold is called with proper arguments + * - if pmemobj_log_set_treshold return 0 (no error) + * - if each PMEMOBJ_LOG_LEVEL corespond to relevant CORE_LOG_LEVEL + * - no errno is set + */ +static int +test_log_set_treshold(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(NO_ERRNO); +} + +/* Check pmemobj_log_set_threshold EAGAIN error handling. */ +static int +test_log_set_treshold_EAGAIN(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(EAGAIN); +} + +/* Check pmemobj_log_set_threshold EINVAL error handling. */ +static int +test_log_set_treshold_EINVAL(const struct test_case *tc, int argc, char *argv[]) +{ + return test_log_set_treshold_helper(EINVAL); +} + +static struct test_case test_cases[] = { + TEST_CASE(test_log_set_treshold), + TEST_CASE(test_log_set_treshold_EAGAIN), + TEST_CASE(test_log_set_treshold_EINVAL), +}; + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_log_set_treshold"); + TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); + DONE(NULL); +}