blob: 9455f44884cbf1f1e32143a89745ad3329423feb [file] [log] [blame]
Simon Glass07a88862020-11-05 10:33:38 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Tests for bootm routines
4 *
5 * Copyright 2020 Google LLC
6 */
7
Simon Glass07a88862020-11-05 10:33:38 -07008#include <bootm.h>
Simon Glass3ba929a2020-10-30 21:38:53 -06009#include <asm/global_data.h>
Simon Glass07a88862020-11-05 10:33:38 -070010#include <test/suites.h>
11#include <test/test.h>
12#include <test/ut.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
16#define BOOTM_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootm_test)
17
Simon Glassb4e1b6d2020-11-05 10:33:45 -070018enum {
19 BUF_SIZE = 1024,
20};
21
Simon Glass07a88862020-11-05 10:33:38 -070022#define CONSOLE_STR "console=/dev/ttyS0"
23
Simon Glassb4e1b6d2020-11-05 10:33:45 -070024/* Test cmdline processing where nothing happens */
25static int bootm_test_nop(struct unit_test_state *uts)
Simon Glass07a88862020-11-05 10:33:38 -070026{
Simon Glassb4e1b6d2020-11-05 10:33:45 -070027 char buf[BUF_SIZE];
28
Andrew Goodbodyb4af83a2024-11-01 13:02:54 +000029 /* This tests relies on GD_FLG_SILENT not being set */
30 gd->flags &= ~GD_FLG_SILENT;
Andrew Goodbodyf6711b42024-11-06 13:50:17 +000031 env_set("silent_linux", NULL);
Andrew Goodbodyb4af83a2024-11-01 13:02:54 +000032
Simon Glassb4e1b6d2020-11-05 10:33:45 -070033 *buf = '\0';
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000034 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070035 ut_asserteq_str("", buf);
36
37 strcpy(buf, "test");
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000038 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070039 ut_asserteq_str("test", buf);
40
41 return 0;
42}
43BOOTM_TEST(bootm_test_nop, 0);
44
45/* Test cmdline processing when out of space */
46static int bootm_test_nospace(struct unit_test_state *uts)
47{
48 char buf[BUF_SIZE];
49
Andrew Goodbodyb4af83a2024-11-01 13:02:54 +000050 /* This tests relies on GD_FLG_SILENT not being set */
51 gd->flags &= ~GD_FLG_SILENT;
52
Simon Glassb4e1b6d2020-11-05 10:33:45 -070053 /* Zero buffer size */
54 *buf = '\0';
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000055 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070056
57 /* Buffer string not terminated */
58 memset(buf, 'a', BUF_SIZE);
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000059 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070060
61 /* Not enough space to copy string */
62 memset(buf, '\0', BUF_SIZE);
63 memset(buf, 'a', BUF_SIZE / 2);
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000064 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070065
66 /* Just enough space */
67 memset(buf, '\0', BUF_SIZE);
68 memset(buf, 'a', BUF_SIZE / 2 - 1);
Andrew Goodbodycbe01ae2024-11-01 13:02:53 +000069 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_ALL));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070070
71 return 0;
72}
73BOOTM_TEST(bootm_test_nospace, 0);
74
75/* Test silent processing */
76static int bootm_test_silent(struct unit_test_state *uts)
77{
78 char buf[BUF_SIZE];
79
Andrew Goodbodyb4af83a2024-11-01 13:02:54 +000080 /* This tests relies on GD_FLG_SILENT not being set */
81 gd->flags &= ~GD_FLG_SILENT;
82
Simon Glass07a88862020-11-05 10:33:38 -070083 /* 'silent_linux' not set should do nothing */
84 env_set("silent_linux", NULL);
Simon Glassb4e1b6d2020-11-05 10:33:45 -070085 strcpy(buf, CONSOLE_STR);
86 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
87 ut_asserteq_str(CONSOLE_STR, buf);
Simon Glass07a88862020-11-05 10:33:38 -070088
89 ut_assertok(env_set("silent_linux", "no"));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070090 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
91 ut_asserteq_str(CONSOLE_STR, buf);
Simon Glass07a88862020-11-05 10:33:38 -070092
93 ut_assertok(env_set("silent_linux", "yes"));
Simon Glassb4e1b6d2020-11-05 10:33:45 -070094 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -040095 ut_asserteq_str("console=ttynull", buf);
Simon Glass07a88862020-11-05 10:33:38 -070096
97 /* Empty buffer should still add the string */
Simon Glassb4e1b6d2020-11-05 10:33:45 -070098 *buf = '\0';
99 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400100 ut_asserteq_str("console=ttynull", buf);
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700101
102 /* Check nothing happens when do_silent is false */
103 *buf = '\0';
104 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, 0));
105 ut_asserteq_str("", buf);
106
107 /* Not enough space */
108 *buf = '\0';
Sean Anderson15bdcd42022-05-19 18:26:05 -0400109 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 15, BOOTM_CL_SILENT));
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700110
111 /* Just enough space */
112 *buf = '\0';
Sean Anderson15bdcd42022-05-19 18:26:05 -0400113 ut_assertok(bootm_process_cmdline(buf, 16, BOOTM_CL_SILENT));
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700114
115 /* add at end */
116 strcpy(buf, "something");
117 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400118 ut_asserteq_str("something console=ttynull", buf);
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700119
120 /* change at start */
121 strcpy(buf, CONSOLE_STR " something");
122 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400123 ut_asserteq_str("console=ttynull something", buf);
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700124
125 return 0;
126}
127BOOTM_TEST(bootm_test_silent, 0);
128
Simon Glass529e2082020-11-05 10:33:48 -0700129/* Test substitution processing */
130static int bootm_test_subst(struct unit_test_state *uts)
131{
132 char buf[BUF_SIZE];
133
134 /* try with an unset variable */
135 ut_assertok(env_set("var", NULL));
136 strcpy(buf, "some${var}thing");
137 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
138 ut_asserteq_str("something", buf);
139
140 /* Replace with shorter string */
141 ut_assertok(env_set("var", "bb"));
142 strcpy(buf, "some${var}thing");
143 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
144 ut_asserteq_str("somebbthing", buf);
145
146 /* Replace with same-length string */
147 ut_assertok(env_set("var", "abc"));
148 strcpy(buf, "some${var}thing");
149 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
150 ut_asserteq_str("someabcthing", buf);
151
152 /* Replace with longer string */
153 ut_assertok(env_set("var", "abcde"));
154 strcpy(buf, "some${var}thing");
155 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
156 ut_asserteq_str("someabcdething", buf);
157
158 /* Check it is case sensitive */
159 ut_assertok(env_set("VAR", NULL));
160 strcpy(buf, "some${VAR}thing");
161 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
162 ut_asserteq_str("something", buf);
163
164 /* Check too long - need 12 bytes for each string */
165 strcpy(buf, "some${var}thing");
166 ut_asserteq(-ENOSPC,
167 bootm_process_cmdline(buf, 12 * 2 - 1, BOOTM_CL_SUBST));
168
169 /* Check just enough space */
170 strcpy(buf, "some${var}thing");
171 ut_assertok(bootm_process_cmdline(buf, 16 * 2, BOOTM_CL_SUBST));
172 ut_asserteq_str("someabcdething", buf);
173
174 /*
175 * Check the substition string being too long. This results in a string
176 * of 12 (13 bytes). We need enough space for that plus the original
177 * "a${var}c" string of 9 bytes. So 12 + 9 = 21 bytes.
178 */
179 ut_assertok(env_set("var", "1234567890"));
180 strcpy(buf, "a${var}c");
181 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 21, BOOTM_CL_SUBST));
182
183 strcpy(buf, "a${var}c");
184 ut_asserteq(0, bootm_process_cmdline(buf, 22, BOOTM_CL_SUBST));
185
186 /* Check multiple substitutions */
Andrew Goodbodyf6711b42024-11-06 13:50:17 +0000187 ut_assertok(env_set("bvar", NULL));
Simon Glass529e2082020-11-05 10:33:48 -0700188 ut_assertok(env_set("var", "abc"));
189 strcpy(buf, "some${var}thing${bvar}else");
190 ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
191 ut_asserteq_str("someabcthingelse", buf);
192
193 /* Check multiple substitutions */
194 ut_assertok(env_set("bvar", "123"));
195 strcpy(buf, "some${var}thing${bvar}else");
196 ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
197 ut_asserteq_str("someabcthing123else", buf);
198
199 return 0;
200}
201BOOTM_TEST(bootm_test_subst, 0);
202
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700203/* Test silent processing in the bootargs variable */
204static int bootm_test_silent_var(struct unit_test_state *uts)
205{
Andrew Goodbodyf6711b42024-11-06 13:50:17 +0000206 ut_assertok(env_set("var", NULL));
Simon Glass07a88862020-11-05 10:33:38 -0700207 env_set("bootargs", NULL);
Simon Glass529e2082020-11-05 10:33:48 -0700208 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
Simon Glassb4e1b6d2020-11-05 10:33:45 -0700209 ut_assertnull(env_get("bootargs"));
210
Simon Glass529e2082020-11-05 10:33:48 -0700211 ut_assertok(env_set("bootargs", "some${var}thing"));
212 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
213 ut_asserteq_str("something", env_get("bootargs"));
214
215 return 0;
216}
217BOOTM_TEST(bootm_test_silent_var, 0);
218
219/* Test substitution processing in the bootargs variable */
220static int bootm_test_subst_var(struct unit_test_state *uts)
221{
Simon Glass5e666ed2022-08-06 17:51:46 -0600222 ut_assertok(env_set("silent_linux", "yes"));
223 ut_assertok(env_set("bootargs", NULL));
Simon Glass63660dc2020-11-05 10:33:44 -0700224 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400225 ut_asserteq_str("console=ttynull", env_get("bootargs"));
Simon Glass07a88862020-11-05 10:33:38 -0700226
Simon Glass529e2082020-11-05 10:33:48 -0700227 ut_assertok(env_set("var", "abc"));
228 ut_assertok(env_set("bootargs", "some${var}thing"));
229 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400230 ut_asserteq_str("some${var}thing console=ttynull", env_get("bootargs"));
Simon Glass529e2082020-11-05 10:33:48 -0700231
Simon Glass07a88862020-11-05 10:33:38 -0700232 return 0;
233}
Simon Glass529e2082020-11-05 10:33:48 -0700234BOOTM_TEST(bootm_test_subst_var, 0);
235
236/* Test substitution and silent console processing in the bootargs variable */
237static int bootm_test_subst_both(struct unit_test_state *uts)
238{
239 ut_assertok(env_set("silent_linux", "yes"));
240 env_set("bootargs", NULL);
241 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400242 ut_asserteq_str("console=ttynull", env_get("bootargs"));
Simon Glass529e2082020-11-05 10:33:48 -0700243
244 ut_assertok(env_set("bootargs", "some${var}thing " CONSOLE_STR));
245 ut_assertok(env_set("var", "1234567890"));
246 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
Sean Anderson15bdcd42022-05-19 18:26:05 -0400247 ut_asserteq_str("some1234567890thing console=ttynull", env_get("bootargs"));
Simon Glass529e2082020-11-05 10:33:48 -0700248
249 return 0;
250}
251BOOTM_TEST(bootm_test_subst_both, 0);
Simon Glass07a88862020-11-05 10:33:38 -0700252
253int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
254{
Simon Glassb50211f2021-03-07 17:35:10 -0700255 struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test);
256 const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test);
Simon Glass07a88862020-11-05 10:33:38 -0700257
258 return cmd_ut_category("bootm", "bootm_test_", tests, n_ents,
259 argc, argv);
260}