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) diff --git a/src/test/Makefile b/src/test/Makefile index 0cfdff1d793..961172eac35 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -62,6 +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/.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_set_function/Makefile b/src/test/obj_log_set_function/Makefile new file mode 100644 index 00000000000..f3a26da93da --- /dev/null +++ b/src/test/obj_log_set_function/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation + +TARGET = obj_log_set_function +OBJS = obj_log_set_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_set_function.c) diff --git a/src/test/obj_log_set_function/TESTS.py b/src/test/obj_log_set_function/TESTS.py new file mode 100755 index 00000000000..7d59355dd63 --- /dev/null +++ b/src/test/obj_log_set_function/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_set_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' 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 new file mode 100644 index 00000000000..bf95b03f690 --- /dev/null +++ b/src/test/obj_log_set_function/obj_log_set_function.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2024, Intel Corporation */ + +/* + * obj_log_set_function.c -- unit test for pmemobj_log_set_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) + +#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 = 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); + } 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); +} + +static struct test_case test_cases[] = { + TEST_CASE(test_log_set_function), + TEST_CASE(test_log_set_function_EAGAIN), +}; + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_log_set_function"); + TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); + DONE(NULL); +} 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); +}