test: log: test syslog logging driver
[platform/kernel/u-boot.git] / test / log / syslog_test.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
4  *
5  * Logging function tests for CONFIG_LOG_SYSLOG=y.
6  *
7  * Invoke the test with: ./u-boot -d arch/sandbox/dts/test.dtb
8  */
9
10 /* Override CONFIG_LOG_MAX_LEVEL */
11 #define LOG_DEBUG
12
13 #include <common.h>
14 #include <dm/device.h>
15 #include <hexdump.h>
16 #include <test/log.h>
17 #include <test/test.h>
18 #include <test/suites.h>
19 #include <test/ut.h>
20 #include <asm/eth.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 /**
25  * struct sb_log_env - private data for sandbox ethernet driver
26  *
27  * This structure is used for the private data of the sandbox ethernet
28  * driver.
29  *
30  * @expected:   string expected to be written by the syslog driver
31  * @uts:        unit test state
32  */
33 struct sb_log_env {
34         const char *expected;
35         struct unit_test_state *uts;
36 };
37
38 /**
39  * sb_log_tx_handler() - transmit callback function
40  *
41  * This callback function is invoked when a network package is sent using the
42  * sandbox Ethernet driver. The private data of the driver holds a sb_log_env
43  * structure with the unit test state and the expected UDP payload.
44  *
45  * The following checks are executed:
46  *
47  * * the Ethernet packet indicates a IP broadcast message
48  * * the IP header is for a local UDP broadcast message to port 514
49  * * the UDP payload matches the expected string
50  *
51  * After testing the pointer to the expected string is set to NULL to signal
52  * that the callback function has been called.
53  *
54  * @dev:        sandbox ethernet device
55  * @packet:     Ethernet packet
56  * @len:        length of Ethernet packet
57  * Return:      0 = success
58  */
59 static int sb_log_tx_handler(struct udevice *dev, void *packet,
60                              unsigned int len)
61 {
62         struct eth_sandbox_priv *priv = dev_get_priv(dev);
63         struct sb_log_env *env = priv->priv;
64         /* uts is updated by the ut_assert* macros */
65         struct unit_test_state *uts = env->uts;
66         char *buf = packet;
67         struct ethernet_hdr *eth_hdr = packet;
68         struct ip_udp_hdr *ip_udp_hdr;
69
70         /* Check Ethernet header */
71         ut_asserteq_mem(&eth_hdr->et_dest, net_bcast_ethaddr, ARP_HLEN);
72         ut_asserteq(ntohs(eth_hdr->et_protlen), PROT_IP);
73
74         /* Check IP header */
75         buf += sizeof(struct ethernet_hdr);
76         ip_udp_hdr = (struct ip_udp_hdr *)buf;
77         ut_asserteq(ip_udp_hdr->ip_p, IPPROTO_UDP);
78         ut_asserteq(ip_udp_hdr->ip_dst.s_addr, 0xffffffff);
79         ut_asserteq(ntohs(ip_udp_hdr->udp_dst), 514);
80         ut_asserteq(UDP_HDR_SIZE + strlen(env->expected) + 1,
81                     ntohs(ip_udp_hdr->udp_len));
82
83         /* Check payload */
84         buf += sizeof(struct ip_udp_hdr);
85         ut_asserteq_mem(env->expected, buf,
86                         ntohs(ip_udp_hdr->udp_len) - UDP_HDR_SIZE);
87
88         /* Signal that the callback function has been executed */
89         env->expected = NULL;
90
91         return 0;
92 }
93
94 /**
95  * syslog_test_log_err() - test log_err() function
96  *
97  * @uts:        unit test state
98  * Return:      0 = success
99  */
100 static int syslog_test_log_err(struct unit_test_state *uts)
101 {
102         int old_log_level = gd->default_log_level;
103         struct sb_log_env env;
104
105         gd->log_fmt = LOGF_DEFAULT;
106         gd->default_log_level = LOGL_INFO;
107         env_set("ethact", "eth@10002000");
108         env_set("log_hostname", "sandbox");
109         env.expected = "<3>sandbox uboot: syslog_test_log_err() "
110                        "testing log_err\n";
111         env.uts = uts;
112         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
113         /* Used by ut_assert macros in the tx_handler */
114         sandbox_eth_set_priv(0, &env);
115         log_err("testing %s\n", "log_err");
116         /* Check that the callback function was called */
117         sandbox_eth_set_tx_handler(0, NULL);
118         gd->default_log_level = old_log_level;
119
120         return 0;
121 }
122 LOG_TEST(syslog_test_log_err);
123
124 /**
125  * syslog_test_log_warning() - test log_warning() function
126  *
127  * @uts:        unit test state
128  * Return:      0 = success
129  */
130 static int syslog_test_log_warning(struct unit_test_state *uts)
131 {
132         int old_log_level = gd->default_log_level;
133         struct sb_log_env env;
134
135         gd->log_fmt = LOGF_DEFAULT;
136         gd->default_log_level = LOGL_INFO;
137         env_set("ethact", "eth@10002000");
138         env_set("log_hostname", "sandbox");
139         env.expected = "<4>sandbox uboot: syslog_test_log_warning() "
140                        "testing log_warning\n";
141         env.uts = uts;
142         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
143         /* Used by ut_assert macros in the tx_handler */
144         sandbox_eth_set_priv(0, &env);
145         log_warning("testing %s\n", "log_warning");
146         sandbox_eth_set_tx_handler(0, NULL);
147         /* Check that the callback function was called */
148         ut_assertnull(env.expected);
149         gd->default_log_level = old_log_level;
150
151         return 0;
152 }
153 LOG_TEST(syslog_test_log_warning);
154
155 /**
156  * syslog_test_log_notice() - test log_notice() function
157  *
158  * @uts:        unit test state
159  * Return:      0 = success
160  */
161 static int syslog_test_log_notice(struct unit_test_state *uts)
162 {
163         int old_log_level = gd->default_log_level;
164         struct sb_log_env env;
165
166         gd->log_fmt = LOGF_DEFAULT;
167         gd->default_log_level = LOGL_INFO;
168         env_set("ethact", "eth@10002000");
169         env_set("log_hostname", "sandbox");
170         env.expected = "<5>sandbox uboot: syslog_test_log_notice() "
171                        "testing log_notice\n";
172         env.uts = uts;
173         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
174         /* Used by ut_assert macros in the tx_handler */
175         sandbox_eth_set_priv(0, &env);
176         log_notice("testing %s\n", "log_notice");
177         sandbox_eth_set_tx_handler(0, NULL);
178         /* Check that the callback function was called */
179         ut_assertnull(env.expected);
180         gd->default_log_level = old_log_level;
181
182         return 0;
183 }
184 LOG_TEST(syslog_test_log_notice);
185
186 /**
187  * syslog_test_log_info() - test log_info() function
188  *
189  * @uts:        unit test state
190  * Return:      0 = success
191  */
192 static int syslog_test_log_info(struct unit_test_state *uts)
193 {
194         int old_log_level = gd->default_log_level;
195         struct sb_log_env env;
196
197         gd->log_fmt = LOGF_DEFAULT;
198         gd->default_log_level = LOGL_INFO;
199         env_set("ethact", "eth@10002000");
200         env_set("log_hostname", "sandbox");
201         env.expected = "<6>sandbox uboot: syslog_test_log_info() "
202                        "testing log_info\n";
203         env.uts = uts;
204         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
205         /* Used by ut_assert macros in the tx_handler */
206         sandbox_eth_set_priv(0, &env);
207         log_info("testing %s\n", "log_info");
208         sandbox_eth_set_tx_handler(0, NULL);
209         /* Check that the callback function was called */
210         ut_assertnull(env.expected);
211         gd->default_log_level = old_log_level;
212
213         return 0;
214 }
215 LOG_TEST(syslog_test_log_info);
216
217 /**
218  * syslog_test_log_debug() - test log_debug() function
219  *
220  * @uts:        unit test state
221  * Return:      0 = success
222  */
223 static int syslog_test_log_debug(struct unit_test_state *uts)
224 {
225         int old_log_level = gd->default_log_level;
226         struct sb_log_env env;
227
228         gd->log_fmt = LOGF_DEFAULT;
229         gd->default_log_level = LOGL_DEBUG;
230         env_set("ethact", "eth@10002000");
231         env_set("log_hostname", "sandbox");
232         env.expected = "<7>sandbox uboot: syslog_test_log_debug() "
233                        "testing log_debug\n";
234         env.uts = uts;
235         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
236         /* Used by ut_assert macros in the tx_handler */
237         sandbox_eth_set_priv(0, &env);
238         log_debug("testing %s\n", "log_debug");
239         sandbox_eth_set_tx_handler(0, NULL);
240         /* Check that the callback function was called */
241         ut_assertnull(env.expected);
242         gd->default_log_level = old_log_level;
243
244         return 0;
245 }
246 LOG_TEST(syslog_test_log_debug);
247
248 /**
249  * syslog_test_log_nodebug() - test logging level filter
250  *
251  * Verify that log_debug() does not lead to a log message if the logging level
252  * is set to LOGL_INFO.
253  *
254  * @uts:        unit test state
255  * Return:      0 = success
256  */
257 static int syslog_test_log_nodebug(struct unit_test_state *uts)
258 {
259         int old_log_level = gd->default_log_level;
260         struct sb_log_env env;
261
262         gd->log_fmt = LOGF_DEFAULT;
263         gd->default_log_level = LOGL_INFO;
264         env_set("ethact", "eth@10002000");
265         env_set("log_hostname", "sandbox");
266         env.expected = "<7>sandbox uboot: syslog_test_log_nodebug() "
267                        "testing log_debug\n";
268         env.uts = uts;
269         sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
270         /* Used by ut_assert macros in the tx_handler */
271         sandbox_eth_set_priv(0, &env);
272         log_debug("testing %s\n", "log_debug");
273         sandbox_eth_set_tx_handler(0, NULL);
274         /* Check that the callback function was not called */
275         ut_assertnonnull(env.expected);
276         gd->default_log_level = old_log_level;
277
278         return 0;
279 }
280 LOG_TEST(syslog_test_log_nodebug);