]>
Commit | Line | Data |
---|---|---|
f158ba15 SG |
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> | |
401d1c4f | 10 | #include <asm/global_data.h> |
f158ba15 SG |
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 | ||
4448fe8e SG |
19 | enum { |
20 | BUF_SIZE = 1024, | |
21 | }; | |
22 | ||
f158ba15 SG |
23 | #define CONSOLE_STR "console=/dev/ttyS0" |
24 | ||
4448fe8e SG |
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) | |
f158ba15 | 71 | { |
4448fe8e SG |
72 | char buf[BUF_SIZE]; |
73 | ||
f158ba15 SG |
74 | /* 'silent_linux' not set should do nothing */ |
75 | env_set("silent_linux", NULL); | |
4448fe8e SG |
76 | strcpy(buf, CONSOLE_STR); |
77 | ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); | |
78 | ut_asserteq_str(CONSOLE_STR, buf); | |
f158ba15 SG |
79 | |
80 | ut_assertok(env_set("silent_linux", "no")); | |
4448fe8e SG |
81 | ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); |
82 | ut_asserteq_str(CONSOLE_STR, buf); | |
f158ba15 SG |
83 | |
84 | ut_assertok(env_set("silent_linux", "yes")); | |
4448fe8e SG |
85 | ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); |
86 | ut_asserteq_str("console=", buf); | |
f158ba15 SG |
87 | |
88 | /* Empty buffer should still add the string */ | |
4448fe8e SG |
89 | *buf = '\0'; |
90 | ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); | |
91 | ut_asserteq_str("console=", 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, 8, BOOTM_CL_SILENT)); | |
101 | ||
102 | /* Just enough space */ | |
103 | *buf = '\0'; | |
104 | ut_assertok(bootm_process_cmdline(buf, 9, 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=", 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= something", buf); | |
115 | ||
116 | return 0; | |
117 | } | |
118 | BOOTM_TEST(bootm_test_silent, 0); | |
119 | ||
51bb3384 SG |
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 | ||
4448fe8e SG |
193 | /* Test silent processing in the bootargs variable */ |
194 | static int bootm_test_silent_var(struct unit_test_state *uts) | |
195 | { | |
f158ba15 | 196 | env_set("bootargs", NULL); |
51bb3384 | 197 | ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST)); |
4448fe8e SG |
198 | ut_assertnull(env_get("bootargs")); |
199 | ||
51bb3384 SG |
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 | env_set("bootargs", NULL); | |
b3c01678 | 212 | ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); |
f158ba15 SG |
213 | ut_asserteq_str("console=", env_get("bootargs")); |
214 | ||
51bb3384 SG |
215 | ut_assertok(env_set("var", "abc")); |
216 | ut_assertok(env_set("bootargs", "some${var}thing")); | |
217 | ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); | |
218 | ut_asserteq_str("some${var}thing console=", env_get("bootargs")); | |
219 | ||
f158ba15 SG |
220 | return 0; |
221 | } | |
51bb3384 SG |
222 | BOOTM_TEST(bootm_test_subst_var, 0); |
223 | ||
224 | /* Test substitution and silent console processing in the bootargs variable */ | |
225 | static int bootm_test_subst_both(struct unit_test_state *uts) | |
226 | { | |
227 | ut_assertok(env_set("silent_linux", "yes")); | |
228 | env_set("bootargs", NULL); | |
229 | ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL)); | |
230 | ut_asserteq_str("console=", env_get("bootargs")); | |
231 | ||
232 | ut_assertok(env_set("bootargs", "some${var}thing " CONSOLE_STR)); | |
233 | ut_assertok(env_set("var", "1234567890")); | |
234 | ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL)); | |
235 | ut_asserteq_str("some1234567890thing console=", env_get("bootargs")); | |
236 | ||
237 | return 0; | |
238 | } | |
239 | BOOTM_TEST(bootm_test_subst_both, 0); | |
f158ba15 SG |
240 | |
241 | int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) | |
242 | { | |
243 | struct unit_test *tests = ll_entry_start(struct unit_test, bootm_test); | |
244 | const int n_ents = ll_entry_count(struct unit_test, bootm_test); | |
245 | ||
246 | return cmd_ut_category("bootm", "bootm_test_", tests, n_ents, | |
247 | argc, argv); | |
248 | } |