From ef817684b71b9e52a58bfb06614c4ec7d0cbc44e Mon Sep 17 00:00:00 2001 From: Oksana Salyk Date: Wed, 20 Mar 2024 09:03:42 +0100 Subject: [PATCH] pmem: add pmem_log_set_function function + UT --- src/include/libpmem.h | 22 +++++ src/libpmem/libpmem.c | 11 +++ src/test/Makefile | 1 + src/test/pmem_log_set_function/.gitignore | 1 + src/test/pmem_log_set_function/Makefile | 15 +++ src/test/pmem_log_set_function/TESTS.py | 27 ++++++ .../pmem_log_set_function.c | 91 +++++++++++++++++++ 7 files changed, 168 insertions(+) create mode 100644 src/test/pmem_log_set_function/.gitignore create mode 100644 src/test/pmem_log_set_function/Makefile create mode 100755 src/test/pmem_log_set_function/TESTS.py create mode 100644 src/test/pmem_log_set_function/pmem_log_set_function.c diff --git a/src/include/libpmem.h b/src/include/libpmem.h index ad1a11c6e7f..5786cffd0af 100644 --- a/src/include/libpmem.h +++ b/src/include/libpmem.h @@ -142,6 +142,28 @@ int pmem_log_set_threshold(enum pmem_log_threshold threshold, int pmem_log_get_threshold(enum pmem_log_threshold threshold, enum pmem_log_level *value); +/* + * the type used for defining logging functions + */ +typedef void pmem_log_function( + /* the log level of the message */ + enum pmem_log_level level, + /* name of the source file where the message coming from */ + const char *file_name, + /* the source file line where the message coming from */ + const int line_no, + /* the function name where the message coming from */ + const char *function_name, + /* message */ + const char *message); + +#define PMEM_LOG_USE_DEFAULT_FUNCTION (NULL) + +/* + * pmem_log_set_function - set the logging function + */ +int pmem_log_set_function(pmem_log_function *log_function); + #ifdef __cplusplus } #endif diff --git a/src/libpmem/libpmem.c b/src/libpmem/libpmem.c index 514ee05d022..865deedf28f 100644 --- a/src/libpmem/libpmem.c +++ b/src/libpmem/libpmem.c @@ -120,3 +120,14 @@ pmem_log_get_threshold(enum pmem_log_threshold threshold, (enum core_log_level *)value); return core_log_error_translate(ret); } + +/* + * pmem_log_set_function -- set the log function pointer either to + * a user-provided function pointer or to the default logging function. + */ +int +pmem_log_set_function(pmem_log_function *log_function) +{ + int ret = core_log_set_function((core_log_function *)log_function); + return core_log_error_translate(ret); +} diff --git a/src/test/Makefile b/src/test/Makefile index a3558c3f6eb..0e9d87aa5c7 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -162,6 +162,7 @@ PMEM_TESTS = \ pmem_is_pmem\ pmem_is_pmem_posix\ pmem_log_get_treshold\ + pmem_log_set_function\ pmem_log_set_treshold\ pmem_map_file\ pmem_has_auto_flush\ diff --git a/src/test/pmem_log_set_function/.gitignore b/src/test/pmem_log_set_function/.gitignore new file mode 100644 index 00000000000..ee9f2a39097 --- /dev/null +++ b/src/test/pmem_log_set_function/.gitignore @@ -0,0 +1 @@ +pmem_log_set_function diff --git a/src/test/pmem_log_set_function/Makefile b/src/test/pmem_log_set_function/Makefile new file mode 100644 index 00000000000..ac703e1e285 --- /dev/null +++ b/src/test/pmem_log_set_function/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024, Intel Corporation + +TARGET = pmem_log_set_function +OBJS = pmem_log_set_function.o + +BUILD_STATIC_DEBUG=n +BUILD_STATIC_NONDEBUG=n + +# required for proper mock integration +LIBPMEMCOMMON=internal-debug +LIBPMEM=internal-debug + +include ../Makefile.inc +LDFLAGS += $(call extract_funcs, pmem_log_set_function.c) diff --git a/src/test/pmem_log_set_function/TESTS.py b/src/test/pmem_log_set_function/TESTS.py new file mode 100755 index 00000000000..0058a101a1a --- /dev/null +++ b/src/test/pmem_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 PMEM_LOG(t.BaseTest): + test_type = t.Short + + def run(self, ctx): + ctx.exec('pmem_log_set_function', self.test_case) + + +class TEST0(PMEM_LOG): + test_case = 'test_log_set_function' + + +class TEST1(PMEM_LOG): + test_case = 'test_log_set_function_EAGAIN' diff --git a/src/test/pmem_log_set_function/pmem_log_set_function.c b/src/test/pmem_log_set_function/pmem_log_set_function.c new file mode 100644 index 00000000000..9f92d9cbd15 --- /dev/null +++ b/src/test/pmem_log_set_function/pmem_log_set_function.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2024, Intel Corporation */ + +/* + * pmem_log_set_function.c -- unit test for pmem_log_set_function + */ + +#include "unittest.h" +#include "log_internal.h" +#include "libpmem.h" + +#define NO_ARGS_CONSUMED 0 + +#define VALIDATED_CALL 127 +#define CALLED (VALIDATED_CALL + 1) + +#define PMEM_LOG_CUSTOM_FUNCTION_MOCK ((pmem_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 *)PMEM_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 = pmem_log_set_function(PMEM_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 pmem_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 pmem_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, "pmem_log_set_function"); + TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases)); + DONE(NULL); +}