-
Notifications
You must be signed in to change notification settings - Fork 510
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: pmemobj_log_function UT implementation
Signed-off-by: Tomasz Gromadzki <tomasz.gromadzki@intel.com>
- Loading branch information
Showing
5 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
obj_log_function |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# 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 | ||
|
||
# 'internal' is required for proper mock integration | ||
# 'debug' is required for debug version of core/log.o that provides | ||
# implementation of 'out_log()' that is used by 'ut_log_function()' | ||
LIBPMEMOBJ=internal-debug | ||
|
||
include ../Makefile.inc | ||
LDFLAGS += $(call extract_funcs, obj_log_function.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 CORE_LOG(t.BaseTest): | ||
test_type = t.Short | ||
|
||
def run(self, ctx): | ||
ctx.exec('obj_log_function', self.test_case) | ||
|
||
|
||
class TEST0(CORE_LOG): | ||
test_case = 'test_log_set_function' | ||
|
||
|
||
class TEST1(CORE_LOG): | ||
test_case = 'test_log_set_function_EAGAIN' | ||
|
||
|
||
class TEST2(CORE_LOG): | ||
test_case = 'test_log_set_treshold' | ||
|
||
|
||
class TEST3(CORE_LOG): | ||
test_case = 'test_log_set_treshold_EAGAIN' | ||
|
||
|
||
class TEST4(CORE_LOG): | ||
test_case = 'test_log_set_treshold_EINVAL' | ||
|
||
|
||
class TEST5(CORE_LOG): | ||
test_case = 'test_log_get_treshold' | ||
|
||
|
||
class TEST6(CORE_LOG): | ||
test_case = 'test_log_get_treshold_EAGAIN' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
/* Copyright 2024, Intel Corporation */ | ||
|
||
/* | ||
* core_log_default_function.c -- unit test for core_log_default_function | ||
*/ | ||
|
||
#undef _GNU_SOURCE | ||
#include <string.h> | ||
#include <syslog.h> | ||
#include <stdbool.h> | ||
|
||
#include "unittest.h" | ||
#include "log_internal.h" | ||
#include "log_default.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_ASSERT((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); | ||
} 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 tresholds[PMEMOBJ_LOG_THRESHOLD_MAX] = { | ||
CORE_LOG_THRESHOLD, CORE_LOG_THRESHOLD_AUX}; | ||
|
||
static enum core_log_level levels[PMEMOBJ_LOG_LEVEL_MAX] = { | ||
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 threshold; | ||
enum core_log_level 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.threshold); | ||
UT_ASSERTeq(level, Core_log_set_treshold.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_MAX; treshold++) { | ||
Core_log_set_treshold.threshold = tresholds[treshold]; | ||
for (enum pmemobj_log_level level = PMEMOBJ_LOG_LEVEL_HARK; | ||
level < PMEMOBJ_LOG_LEVEL_MAX; level++) { | ||
Core_log_set_treshold.level = 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); | ||
} | ||
|
||
/* | ||
* *** pmemobj_log_get_treshold() tests *** | ||
*/ | ||
/* Mock */ | ||
static struct { | ||
enum core_log_threshold 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.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_MAX; treshold++) { | ||
Core_log_get_treshold.threshold = tresholds[treshold]; | ||
for (enum pmemobj_log_level exp_level = PMEMOBJ_LOG_LEVEL_HARK; | ||
exp_level < PMEMOBJ_LOG_LEVEL_MAX; exp_level++) { | ||
enum pmemobj_log_level level; | ||
Core_log_get_treshold.level = 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_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); | ||
} |