Commit ef11ed8239bf02b347e7fb9fc6d980aec0c7810a
Committed by
Tom Rini
1 parent
d5f61f272d
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
log: Add a test command
Add a command which exercises the logging system. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 8 changed files with 235 additions and 1 deletions Side-by-side Diff
MAINTAINERS
cmd/Kconfig
... | ... | @@ -1507,7 +1507,8 @@ |
1507 | 1507 | help |
1508 | 1508 | This provides access to logging features. It allows the output of |
1509 | 1509 | log data to be controlled to a limited extent (setting up the default |
1510 | - maximum log level for emitting of records). | |
1510 | + maximum log level for emitting of records). It also provides access | |
1511 | + to a command used for testing the log system. | |
1511 | 1512 | |
1512 | 1513 | config CMD_TRACE |
1513 | 1514 | bool "trace - Support tracing of function calls and timing" |
cmd/log.c
... | ... | @@ -23,6 +23,9 @@ |
23 | 23 | |
24 | 24 | static cmd_tbl_t log_sub[] = { |
25 | 25 | U_BOOT_CMD_MKENT(level, CONFIG_SYS_MAXARGS, 1, do_log_level, "", ""), |
26 | +#ifdef CONFIG_LOG_TEST | |
27 | + U_BOOT_CMD_MKENT(test, 2, 1, do_log_test, "", ""), | |
28 | +#endif | |
26 | 29 | }; |
27 | 30 | |
28 | 31 | static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
... | ... | @@ -46,6 +49,9 @@ |
46 | 49 | #ifdef CONFIG_SYS_LONGHELP |
47 | 50 | static char log_help_text[] = |
48 | 51 | "level - get/set log level\n" |
52 | +#ifdef CONFIG_LOG_TEST | |
53 | + "log test - run log tests\n" | |
54 | +#endif | |
49 | 55 | ; |
50 | 56 | #endif |
51 | 57 |
common/Kconfig
... | ... | @@ -494,6 +494,16 @@ |
494 | 494 | log message is shown - other details like level, category, file and |
495 | 495 | line number are omitted. |
496 | 496 | |
497 | +config LOG_TEST | |
498 | + bool "Provide a test for logging" | |
499 | + depends on LOG | |
500 | + default y if SANDBOX | |
501 | + help | |
502 | + This enables a 'log test' command to test logging. It is normally | |
503 | + executed from a pytest and simply outputs logging information | |
504 | + in various different ways to test that the logging system works | |
505 | + correctly with varoius settings. | |
506 | + | |
497 | 507 | endmenu |
498 | 508 | |
499 | 509 | config DEFAULT_FDT_FILE |
include/log.h
... | ... | @@ -256,6 +256,9 @@ |
256 | 256 | #define LOG_DRIVER(_name) \ |
257 | 257 | ll_entry_declare(struct log_driver, _name, log_driver) |
258 | 258 | |
259 | +/* Handle the 'log test' command */ | |
260 | +int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); | |
261 | + | |
259 | 262 | /** |
260 | 263 | * log_add_filter() - Add a new filter to a log device |
261 | 264 | * |
test/Makefile
test/log/Makefile
test/log/log_test.c
1 | +/* | |
2 | + * Logging support test program | |
3 | + * | |
4 | + * Copyright (c) 2017 Google, Inc | |
5 | + * Written by Simon Glass <sjg@chromium.org> | |
6 | + * | |
7 | + * SPDX-License-Identifier: GPL-2.0+ | |
8 | + */ | |
9 | + | |
10 | +#include <common.h> | |
11 | + | |
12 | +/* emit some sample log records in different ways, for testing */ | |
13 | +static int log_run(enum uclass_id cat, const char *file) | |
14 | +{ | |
15 | + int i; | |
16 | + | |
17 | + debug("debug\n"); | |
18 | + for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { | |
19 | + log(cat, i, "log %d\n", i); | |
20 | + _log(log_uc_cat(cat), i, file, 100 + i, "func", "_log %d\n", | |
21 | + i); | |
22 | + } | |
23 | + | |
24 | + return 0; | |
25 | +} | |
26 | + | |
27 | +static int log_test(int testnum) | |
28 | +{ | |
29 | + int ret; | |
30 | + | |
31 | + printf("test %d\n", testnum); | |
32 | + switch (testnum) { | |
33 | + case 0: { | |
34 | + /* Check a category filter using the first category */ | |
35 | + enum log_category_t cat_list[] = { | |
36 | + log_uc_cat(UCLASS_MMC), log_uc_cat(UCLASS_SPI), | |
37 | + LOGC_NONE, LOGC_END | |
38 | + }; | |
39 | + | |
40 | + ret = log_add_filter("console", cat_list, LOGL_MAX, NULL); | |
41 | + if (ret < 0) | |
42 | + return ret; | |
43 | + log_run(UCLASS_MMC, "file"); | |
44 | + ret = log_remove_filter("console", ret); | |
45 | + if (ret < 0) | |
46 | + return ret; | |
47 | + break; | |
48 | + } | |
49 | + case 1: { | |
50 | + /* Check a category filter using the second category */ | |
51 | + enum log_category_t cat_list[] = { | |
52 | + log_uc_cat(UCLASS_MMC), log_uc_cat(UCLASS_SPI), LOGC_END | |
53 | + }; | |
54 | + | |
55 | + ret = log_add_filter("console", cat_list, LOGL_MAX, NULL); | |
56 | + if (ret < 0) | |
57 | + return ret; | |
58 | + log_run(UCLASS_SPI, "file"); | |
59 | + ret = log_remove_filter("console", ret); | |
60 | + if (ret < 0) | |
61 | + return ret; | |
62 | + break; | |
63 | + } | |
64 | + case 2: { | |
65 | + /* Check a category filter that should block log entries */ | |
66 | + enum log_category_t cat_list[] = { | |
67 | + log_uc_cat(UCLASS_MMC), LOGC_NONE, LOGC_END | |
68 | + }; | |
69 | + | |
70 | + ret = log_add_filter("console", cat_list, LOGL_MAX, NULL); | |
71 | + if (ret < 0) | |
72 | + return ret; | |
73 | + log_run(UCLASS_SPI, "file"); | |
74 | + ret = log_remove_filter("console", ret); | |
75 | + if (ret < 0) | |
76 | + return ret; | |
77 | + break; | |
78 | + } | |
79 | + case 3: { | |
80 | + /* Check a passing file filter */ | |
81 | + ret = log_add_filter("console", NULL, LOGL_MAX, "file"); | |
82 | + if (ret < 0) | |
83 | + return ret; | |
84 | + log_run(UCLASS_SPI, "file"); | |
85 | + ret = log_remove_filter("console", ret); | |
86 | + if (ret < 0) | |
87 | + return ret; | |
88 | + break; | |
89 | + } | |
90 | + case 4: { | |
91 | + /* Check a failing file filter */ | |
92 | + ret = log_add_filter("console", NULL, LOGL_MAX, "file"); | |
93 | + if (ret < 0) | |
94 | + return ret; | |
95 | + log_run(UCLASS_SPI, "file2"); | |
96 | + ret = log_remove_filter("console", ret); | |
97 | + if (ret < 0) | |
98 | + return ret; | |
99 | + break; | |
100 | + } | |
101 | + case 5: { | |
102 | + /* Check a passing file filter (second in list) */ | |
103 | + ret = log_add_filter("console", NULL, LOGL_MAX, "file,file2"); | |
104 | + if (ret < 0) | |
105 | + return ret; | |
106 | + log_run(UCLASS_SPI, "file2"); | |
107 | + ret = log_remove_filter("console", ret); | |
108 | + if (ret < 0) | |
109 | + return ret; | |
110 | + break; | |
111 | + } | |
112 | + case 6: { | |
113 | + /* Check a passing file filter */ | |
114 | + ret = log_add_filter("console", NULL, LOGL_MAX, | |
115 | + "file,file2,log/log_test.c"); | |
116 | + if (ret < 0) | |
117 | + return ret; | |
118 | + log_run(UCLASS_SPI, "file2"); | |
119 | + ret = log_remove_filter("console", ret); | |
120 | + if (ret < 0) | |
121 | + return ret; | |
122 | + break; | |
123 | + } | |
124 | + case 7: { | |
125 | + /* Check a log level filter */ | |
126 | + ret = log_add_filter("console", NULL, LOGL_WARNING, NULL); | |
127 | + if (ret < 0) | |
128 | + return ret; | |
129 | + log_run(UCLASS_SPI, "file"); | |
130 | + ret = log_remove_filter("console", ret); | |
131 | + if (ret < 0) | |
132 | + return ret; | |
133 | + break; | |
134 | + } | |
135 | + case 8: { | |
136 | + /* Check two filters, one of which passes everything */ | |
137 | + int filt1, filt2; | |
138 | + | |
139 | + ret = log_add_filter("console", NULL, LOGL_WARNING, NULL); | |
140 | + if (ret < 0) | |
141 | + return ret; | |
142 | + filt1 = ret; | |
143 | + ret = log_add_filter("console", NULL, LOGL_MAX, NULL); | |
144 | + if (ret < 0) | |
145 | + return ret; | |
146 | + filt2 = ret; | |
147 | + log_run(UCLASS_SPI, "file"); | |
148 | + ret = log_remove_filter("console", filt1); | |
149 | + if (ret < 0) | |
150 | + return ret; | |
151 | + ret = log_remove_filter("console", filt2); | |
152 | + if (ret < 0) | |
153 | + return ret; | |
154 | + break; | |
155 | + } | |
156 | + case 9: { | |
157 | + /* Check three filters, which together pass everything */ | |
158 | + int filt1, filt2, filt3; | |
159 | + | |
160 | + ret = log_add_filter("console", NULL, LOGL_MAX, "file)"); | |
161 | + if (ret < 0) | |
162 | + return ret; | |
163 | + filt1 = ret; | |
164 | + ret = log_add_filter("console", NULL, LOGL_MAX, "file2"); | |
165 | + if (ret < 0) | |
166 | + return ret; | |
167 | + filt2 = ret; | |
168 | + ret = log_add_filter("console", NULL, LOGL_MAX, | |
169 | + "log/log_test.c"); | |
170 | + if (ret < 0) | |
171 | + return ret; | |
172 | + filt3 = ret; | |
173 | + log_run(UCLASS_SPI, "file2"); | |
174 | + ret = log_remove_filter("console", filt1); | |
175 | + if (ret < 0) | |
176 | + return ret; | |
177 | + ret = log_remove_filter("console", filt2); | |
178 | + if (ret < 0) | |
179 | + return ret; | |
180 | + ret = log_remove_filter("console", filt3); | |
181 | + if (ret < 0) | |
182 | + return ret; | |
183 | + break; | |
184 | + } | |
185 | + } | |
186 | + | |
187 | + return 0; | |
188 | +} | |
189 | + | |
190 | +#ifdef CONFIG_LOG_TEST | |
191 | +int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) | |
192 | +{ | |
193 | + int testnum = 0; | |
194 | + int ret; | |
195 | + | |
196 | + if (argc > 1) | |
197 | + testnum = simple_strtoul(argv[1], NULL, 10); | |
198 | + | |
199 | + ret = log_test(testnum); | |
200 | + if (ret) | |
201 | + printf("Test failure (err=%d)\n", ret); | |
202 | + | |
203 | + return ret ? CMD_RET_FAILURE : 0; | |
204 | +} | |
205 | +#endif |