Skip to content

Commit

Permalink
test: pmemobj_log_function UT implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Tomasz Gromadzki <tomasz.gromadzki@intel.com>
  • Loading branch information
grom72 committed Mar 12, 2024
1 parent c8b37e6 commit 68388c8
Show file tree
Hide file tree
Showing 5 changed files with 334 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ OBJ_TESTS = \
obj_list_valgrind\
obj_list_macro\
obj_locks\
obj_log_function\
obj_mem\
obj_memblock\
obj_memcheck\
Expand Down
1 change: 1 addition & 0 deletions src/test/obj_log_function/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj_log_function
16 changes: 16 additions & 0 deletions src/test/obj_log_function/Makefile
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)
47 changes: 47 additions & 0 deletions src/test/obj_log_function/TESTS.py
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'
269 changes: 269 additions & 0 deletions src/test/obj_log_function/obj_log_function.c
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);
}

0 comments on commit 68388c8

Please sign in to comment.