Commit ef11ed82 authored by Simon Glass's avatar Simon Glass Committed by Tom Rini

log: Add a test command

Add a command which exercises the logging system.
Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
parent d5f61f27
......@@ -316,6 +316,7 @@ S: Maintained
T: git git://git.denx.de/u-boot.git
F: common/log.c
F: cmd/log.c
F: test/log/log_test.c
MICROBLAZE
M: Michal Simek <monstr@monstr.eu>
......
......@@ -1507,7 +1507,8 @@ config CMD_LOG
help
This provides access to logging features. It allows the output of
log data to be controlled to a limited extent (setting up the default
maximum log level for emitting of records).
maximum log level for emitting of records). It also provides access
to a command used for testing the log system.
config CMD_TRACE
bool "trace - Support tracing of function calls and timing"
......
......@@ -23,6 +23,9 @@ static int do_log_level(cmd_tbl_t *cmdtp, int flag, int argc,
static cmd_tbl_t log_sub[] = {
U_BOOT_CMD_MKENT(level, CONFIG_SYS_MAXARGS, 1, do_log_level, "", ""),
#ifdef CONFIG_LOG_TEST
U_BOOT_CMD_MKENT(test, 2, 1, do_log_test, "", ""),
#endif
};
static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
......@@ -46,6 +49,9 @@ static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_LONGHELP
static char log_help_text[] =
"level - get/set log level\n"
#ifdef CONFIG_LOG_TEST
"log test - run log tests\n"
#endif
;
#endif
......
......@@ -494,6 +494,16 @@ config LOG_SPL_CONSOLE
log message is shown - other details like level, category, file and
line number are omitted.
config LOG_TEST
bool "Provide a test for logging"
depends on LOG
default y if SANDBOX
help
This enables a 'log test' command to test logging. It is normally
executed from a pytest and simply outputs logging information
in various different ways to test that the logging system works
correctly with varoius settings.
endmenu
config DEFAULT_FDT_FILE
......
......@@ -256,6 +256,9 @@ struct log_filter {
#define LOG_DRIVER(_name) \
ll_entry_declare(struct log_driver, _name, log_driver)
/* Handle the 'log test' command */
int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
/**
* log_add_filter() - Add a new filter to a log device
*
......
......@@ -10,3 +10,4 @@ obj-$(CONFIG_SANDBOX) += command_ut.o
obj-$(CONFIG_SANDBOX) += compression.o
obj-$(CONFIG_SANDBOX) += print_ut.o
obj-$(CONFIG_UT_TIME) += time_ut.o
obj-$(CONFIG_$(SPL_)LOG) += log/
#
# Copyright (c) 2017 Google, Inc
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_LOG_TEST) += log_test.o
/*
* Logging support test program
*
* Copyright (c) 2017 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
/* emit some sample log records in different ways, for testing */
static int log_run(enum uclass_id cat, const char *file)
{
int i;
debug("debug\n");
for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
log(cat, i, "log %d\n", i);
_log(log_uc_cat(cat), i, file, 100 + i, "func", "_log %d\n",
i);
}
return 0;
}
static int log_test(int testnum)
{
int ret;
printf("test %d\n", testnum);
switch (testnum) {
case 0: {
/* Check a category filter using the first category */
enum log_category_t cat_list[] = {
log_uc_cat(UCLASS_MMC), log_uc_cat(UCLASS_SPI),
LOGC_NONE, LOGC_END
};
ret = log_add_filter("console", cat_list, LOGL_MAX, NULL);
if (ret < 0)
return ret;
log_run(UCLASS_MMC, "file");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 1: {
/* Check a category filter using the second category */
enum log_category_t cat_list[] = {
log_uc_cat(UCLASS_MMC), log_uc_cat(UCLASS_SPI), LOGC_END
};
ret = log_add_filter("console", cat_list, LOGL_MAX, NULL);
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 2: {
/* Check a category filter that should block log entries */
enum log_category_t cat_list[] = {
log_uc_cat(UCLASS_MMC), LOGC_NONE, LOGC_END
};
ret = log_add_filter("console", cat_list, LOGL_MAX, NULL);
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 3: {
/* Check a passing file filter */
ret = log_add_filter("console", NULL, LOGL_MAX, "file");
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 4: {
/* Check a failing file filter */
ret = log_add_filter("console", NULL, LOGL_MAX, "file");
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file2");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 5: {
/* Check a passing file filter (second in list) */
ret = log_add_filter("console", NULL, LOGL_MAX, "file,file2");
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file2");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 6: {
/* Check a passing file filter */
ret = log_add_filter("console", NULL, LOGL_MAX,
"file,file2,log/log_test.c");
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file2");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 7: {
/* Check a log level filter */
ret = log_add_filter("console", NULL, LOGL_WARNING, NULL);
if (ret < 0)
return ret;
log_run(UCLASS_SPI, "file");
ret = log_remove_filter("console", ret);
if (ret < 0)
return ret;
break;
}
case 8: {
/* Check two filters, one of which passes everything */
int filt1, filt2;
ret = log_add_filter("console", NULL, LOGL_WARNING, NULL);
if (ret < 0)
return ret;
filt1 = ret;
ret = log_add_filter("console", NULL, LOGL_MAX, NULL);
if (ret < 0)
return ret;
filt2 = ret;
log_run(UCLASS_SPI, "file");
ret = log_remove_filter("console", filt1);
if (ret < 0)
return ret;
ret = log_remove_filter("console", filt2);
if (ret < 0)
return ret;
break;
}
case 9: {
/* Check three filters, which together pass everything */
int filt1, filt2, filt3;
ret = log_add_filter("console", NULL, LOGL_MAX, "file)");
if (ret < 0)
return ret;
filt1 = ret;
ret = log_add_filter("console", NULL, LOGL_MAX, "file2");
if (ret < 0)
return ret;
filt2 = ret;
ret = log_add_filter("console", NULL, LOGL_MAX,
"log/log_test.c");
if (ret < 0)
return ret;
filt3 = ret;
log_run(UCLASS_SPI, "file2");
ret = log_remove_filter("console", filt1);
if (ret < 0)
return ret;
ret = log_remove_filter("console", filt2);
if (ret < 0)
return ret;
ret = log_remove_filter("console", filt3);
if (ret < 0)
return ret;
break;
}
}
return 0;
}
#ifdef CONFIG_LOG_TEST
int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int testnum = 0;
int ret;
if (argc > 1)
testnum = simple_strtoul(argv[1], NULL, 10);
ret = log_test(testnum);
if (ret)
printf("Test failure (err=%d)\n", ret);
return ret ? CMD_RET_FAILURE : 0;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment