Merge tag 'doc-2023-10-rc5-3' of https://source.denx.de/u-boot/custodians/u-boot-efi
[platform/kernel/u-boot.git] / test / bootm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Tests for bootm routines
4  *
5  * Copyright 2020 Google LLC
6  */
7
8 #include <common.h>
9 #include <bootm.h>
10 #include <asm/global_data.h>
11 #include <test/suites.h>
12 #include <test/test.h>
13 #include <test/ut.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
17 #define BOOTM_TEST(_name, _flags)       UNIT_TEST(_name, _flags, bootm_test)
18
19 enum {
20         BUF_SIZE        = 1024,
21 };
22
23 #define CONSOLE_STR     "console=/dev/ttyS0"
24
25 /* Test cmdline processing where nothing happens */
26 static int bootm_test_nop(struct unit_test_state *uts)
27 {
28         char buf[BUF_SIZE];
29
30         *buf = '\0';
31         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
32         ut_asserteq_str("", buf);
33
34         strcpy(buf, "test");
35         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
36         ut_asserteq_str("test", buf);
37
38         return 0;
39 }
40 BOOTM_TEST(bootm_test_nop, 0);
41
42 /* Test cmdline processing when out of space */
43 static int bootm_test_nospace(struct unit_test_state *uts)
44 {
45         char buf[BUF_SIZE];
46
47         /* Zero buffer size */
48         *buf = '\0';
49         ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, true));
50
51         /* Buffer string not terminated */
52         memset(buf, 'a', BUF_SIZE);
53         ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
54
55         /* Not enough space to copy string */
56         memset(buf, '\0', BUF_SIZE);
57         memset(buf, 'a', BUF_SIZE / 2);
58         ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
59
60         /* Just enough space */
61         memset(buf, '\0', BUF_SIZE);
62         memset(buf, 'a', BUF_SIZE / 2 - 1);
63         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
64
65         return 0;
66 }
67 BOOTM_TEST(bootm_test_nospace, 0);
68
69 /* Test silent processing */
70 static int bootm_test_silent(struct unit_test_state *uts)
71 {
72         char buf[BUF_SIZE];
73
74         /* 'silent_linux' not set should do nothing */
75         env_set("silent_linux", NULL);
76         strcpy(buf, CONSOLE_STR);
77         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
78         ut_asserteq_str(CONSOLE_STR, buf);
79
80         ut_assertok(env_set("silent_linux", "no"));
81         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
82         ut_asserteq_str(CONSOLE_STR, buf);
83
84         ut_assertok(env_set("silent_linux", "yes"));
85         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
86         ut_asserteq_str("console=ttynull", buf);
87
88         /* Empty buffer should still add the string */
89         *buf = '\0';
90         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
91         ut_asserteq_str("console=ttynull", buf);
92
93         /* Check nothing happens when do_silent is false */
94         *buf = '\0';
95         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, 0));
96         ut_asserteq_str("", buf);
97
98         /* Not enough space */
99         *buf = '\0';
100         ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 15, BOOTM_CL_SILENT));
101
102         /* Just enough space */
103         *buf = '\0';
104         ut_assertok(bootm_process_cmdline(buf, 16, BOOTM_CL_SILENT));
105
106         /* add at end */
107         strcpy(buf, "something");
108         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
109         ut_asserteq_str("something console=ttynull", buf);
110
111         /* change at start */
112         strcpy(buf, CONSOLE_STR " something");
113         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
114         ut_asserteq_str("console=ttynull something", buf);
115
116         return 0;
117 }
118 BOOTM_TEST(bootm_test_silent, 0);
119
120 /* Test substitution processing */
121 static int bootm_test_subst(struct unit_test_state *uts)
122 {
123         char buf[BUF_SIZE];
124
125         /* try with an unset variable */
126         ut_assertok(env_set("var", NULL));
127         strcpy(buf, "some${var}thing");
128         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
129         ut_asserteq_str("something", buf);
130
131         /* Replace with shorter string */
132         ut_assertok(env_set("var", "bb"));
133         strcpy(buf, "some${var}thing");
134         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
135         ut_asserteq_str("somebbthing", buf);
136
137         /* Replace with same-length string */
138         ut_assertok(env_set("var", "abc"));
139         strcpy(buf, "some${var}thing");
140         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
141         ut_asserteq_str("someabcthing", buf);
142
143         /* Replace with longer string */
144         ut_assertok(env_set("var", "abcde"));
145         strcpy(buf, "some${var}thing");
146         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
147         ut_asserteq_str("someabcdething", buf);
148
149         /* Check it is case sensitive */
150         ut_assertok(env_set("VAR", NULL));
151         strcpy(buf, "some${VAR}thing");
152         ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
153         ut_asserteq_str("something", buf);
154
155         /* Check too long - need 12 bytes for each string */
156         strcpy(buf, "some${var}thing");
157         ut_asserteq(-ENOSPC,
158                     bootm_process_cmdline(buf, 12 * 2 - 1, BOOTM_CL_SUBST));
159
160         /* Check just enough space */
161         strcpy(buf, "some${var}thing");
162         ut_assertok(bootm_process_cmdline(buf, 16 * 2, BOOTM_CL_SUBST));
163         ut_asserteq_str("someabcdething", buf);
164
165         /*
166          * Check the substition string being too long. This results in a string
167          * of 12 (13 bytes). We need enough space for that plus the original
168          * "a${var}c" string of 9 bytes. So 12 + 9 = 21 bytes.
169          */
170         ut_assertok(env_set("var", "1234567890"));
171         strcpy(buf, "a${var}c");
172         ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 21, BOOTM_CL_SUBST));
173
174         strcpy(buf, "a${var}c");
175         ut_asserteq(0, bootm_process_cmdline(buf, 22, BOOTM_CL_SUBST));
176
177         /* Check multiple substitutions */
178         ut_assertok(env_set("var", "abc"));
179         strcpy(buf, "some${var}thing${bvar}else");
180         ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
181         ut_asserteq_str("someabcthingelse", buf);
182
183         /* Check multiple substitutions */
184         ut_assertok(env_set("bvar", "123"));
185         strcpy(buf, "some${var}thing${bvar}else");
186         ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
187         ut_asserteq_str("someabcthing123else", buf);
188
189         return 0;
190 }
191 BOOTM_TEST(bootm_test_subst, 0);
192
193 /* Test silent processing in the bootargs variable */
194 static int bootm_test_silent_var(struct unit_test_state *uts)
195 {
196         env_set("bootargs", NULL);
197         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
198         ut_assertnull(env_get("bootargs"));
199
200         ut_assertok(env_set("bootargs", "some${var}thing"));
201         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
202         ut_asserteq_str("something", env_get("bootargs"));
203
204         return 0;
205 }
206 BOOTM_TEST(bootm_test_silent_var, 0);
207
208 /* Test substitution processing in the bootargs variable */
209 static int bootm_test_subst_var(struct unit_test_state *uts)
210 {
211         ut_assertok(env_set("silent_linux", "yes"));
212         ut_assertok(env_set("bootargs", NULL));
213         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
214         ut_asserteq_str("console=ttynull", env_get("bootargs"));
215
216         ut_assertok(env_set("var", "abc"));
217         ut_assertok(env_set("bootargs", "some${var}thing"));
218         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
219         ut_asserteq_str("some${var}thing console=ttynull", env_get("bootargs"));
220
221         return 0;
222 }
223 BOOTM_TEST(bootm_test_subst_var, 0);
224
225 /* Test substitution and silent console processing in the bootargs variable */
226 static int bootm_test_subst_both(struct unit_test_state *uts)
227 {
228         ut_assertok(env_set("silent_linux", "yes"));
229         env_set("bootargs", NULL);
230         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
231         ut_asserteq_str("console=ttynull", env_get("bootargs"));
232
233         ut_assertok(env_set("bootargs", "some${var}thing " CONSOLE_STR));
234         ut_assertok(env_set("var", "1234567890"));
235         ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
236         ut_asserteq_str("some1234567890thing console=ttynull", env_get("bootargs"));
237
238         return 0;
239 }
240 BOOTM_TEST(bootm_test_subst_both, 0);
241
242 int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
243 {
244         struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test);
245         const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test);
246
247         return cmd_ut_category("bootm", "bootm_test_", tests, n_ents,
248                                argc, argv);
249 }