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