1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Test for bootdev functions. All start with 'bootmeth'
4 *
5 * Copyright 2021 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9 #include <bootmeth.h>
10 #include <bootstd.h>
11 #include <dm.h>
12 #include <env.h>
13 #include <test/ut.h>
14 #include "bootstd_common.h"
15
16 /* Check 'bootmeth list' command */
bootmeth_cmd_list(struct unit_test_state * uts)17 static int bootmeth_cmd_list(struct unit_test_state *uts)
18 {
19 ut_assertok(run_command("bootmeth list", 0));
20 ut_assert_nextline("Order Seq Name Description");
21 ut_assert_nextlinen("---");
22 ut_assert_nextline(" 0 0 extlinux Extlinux boot from a block device");
23 ut_assert_nextline(" 1 1 efi EFI boot from an .efi file");
24 if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
25 ut_assert_nextline(" glob 2 firmware0 VBE simple");
26 ut_assert_nextlinen("---");
27 ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
28 "(3 bootmeths)" : "(2 bootmeths)");
29 ut_assert_console_end();
30
31 return 0;
32 }
33 BOOTSTD_TEST(bootmeth_cmd_list, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
34
35 /* Check 'bootmeth order' command */
bootmeth_cmd_order(struct unit_test_state * uts)36 static int bootmeth_cmd_order(struct unit_test_state *uts)
37 {
38 /* Select just one bootmethod */
39 ut_assertok(run_command("bootmeth order extlinux", 0));
40 ut_assert_console_end();
41 ut_assertnonnull(env_get("bootmeths"));
42 ut_asserteq_str("extlinux", env_get("bootmeths"));
43
44 /* Only that one should be listed */
45 ut_assertok(run_command("bootmeth list", 0));
46 ut_assert_nextline("Order Seq Name Description");
47 ut_assert_nextlinen("---");
48 ut_assert_nextline(" 0 0 extlinux Extlinux boot from a block device");
49 ut_assert_nextlinen("---");
50 ut_assert_nextline("(1 bootmeth)");
51 ut_assert_console_end();
52
53 /* Check the -a flag, efi should show as not in the order ("-") */
54 ut_assertok(run_command("bootmeth list -a", 0));
55 ut_assert_nextline("Order Seq Name Description");
56 ut_assert_nextlinen("---");
57 ut_assert_nextline(" 0 0 extlinux Extlinux boot from a block device");
58 ut_assert_nextline(" - 1 efi EFI boot from an .efi file");
59 if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
60 ut_assert_nextline(" glob 2 firmware0 VBE simple");
61 ut_assert_nextlinen("---");
62 ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
63 "(3 bootmeths)" : "(2 bootmeths)");
64 ut_assert_console_end();
65
66 /* Check the -a flag with the reverse order */
67 ut_assertok(run_command("bootmeth order \"efi extlinux\"", 0));
68 ut_assert_console_end();
69 ut_assertok(run_command("bootmeth list -a", 0));
70 ut_assert_nextline("Order Seq Name Description");
71 ut_assert_nextlinen("---");
72 ut_assert_nextline(" 1 0 extlinux Extlinux boot from a block device");
73 ut_assert_nextline(" 0 1 efi EFI boot from an .efi file");
74 if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
75 ut_assert_nextline(" glob 2 firmware0 VBE simple");
76 ut_assert_nextlinen("---");
77 ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
78 "(3 bootmeths)" : "(2 bootmeths)");
79 ut_assert_console_end();
80
81 /* Now reset the order to empty, which should show all of them again */
82 ut_assertok(run_command("bootmeth order", 0));
83 ut_assert_console_end();
84 ut_assertnull(env_get("bootmeths"));
85 ut_assertok(run_command("bootmeth list", 0));
86 ut_assert_skip_to_line(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
87 "(3 bootmeths)" : "(2 bootmeths)");
88
89 /* Try reverse order */
90 ut_assertok(run_command("bootmeth order \"efi extlinux\"", 0));
91 ut_assert_console_end();
92 ut_assertok(run_command("bootmeth list", 0));
93 ut_assert_nextline("Order Seq Name Description");
94 ut_assert_nextlinen("---");
95 ut_assert_nextline(" 0 1 efi EFI boot from an .efi file");
96 ut_assert_nextline(" 1 0 extlinux Extlinux boot from a block device");
97 ut_assert_nextlinen("---");
98 ut_assert_nextline("(2 bootmeths)");
99 ut_assertnonnull(env_get("bootmeths"));
100 ut_asserteq_str("efi extlinux", env_get("bootmeths"));
101 ut_assert_console_end();
102
103 return 0;
104 }
105 BOOTSTD_TEST(bootmeth_cmd_order, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
106
107 /* Check 'bootmeth order' command with global bootmeths */
bootmeth_cmd_order_glob(struct unit_test_state * uts)108 static int bootmeth_cmd_order_glob(struct unit_test_state *uts)
109 {
110 if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
111 return -EAGAIN;
112
113 ut_assertok(run_command("bootmeth order \"efi firmware0\"", 0));
114 ut_assert_console_end();
115 ut_assertok(run_command("bootmeth list", 0));
116 ut_assert_nextline("Order Seq Name Description");
117 ut_assert_nextlinen("---");
118 ut_assert_nextline(" 0 1 efi EFI boot from an .efi file");
119 ut_assert_nextline(" glob 2 firmware0 VBE simple");
120 ut_assert_nextlinen("---");
121 ut_assert_nextline("(2 bootmeths)");
122 ut_assertnonnull(env_get("bootmeths"));
123 ut_asserteq_str("efi firmware0", env_get("bootmeths"));
124 ut_assert_console_end();
125
126 return 0;
127 }
128 BOOTSTD_TEST(bootmeth_cmd_order_glob, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
129
130 /* Check 'bootmeth set' command */
bootmeth_cmd_set(struct unit_test_state * uts)131 static int bootmeth_cmd_set(struct unit_test_state *uts)
132 {
133 /* Check we can enable extlinux fallback */
134 console_record_reset_enable();
135 ut_assertok(run_command("bootmeth set extlinux fallback 1", 0));
136 ut_assert_console_end();
137
138 /* Check we can disable extlinux fallback */
139 console_record_reset_enable();
140 ut_assertok(run_command("bootmeth set extlinux fallback 0", 0));
141 ut_assert_console_end();
142
143 /* Check extlinux fallback unexpected value */
144 console_record_reset_enable();
145 ut_asserteq(1, run_command("bootmeth set extlinux fallback fred", 0));
146 ut_assert_nextline("Unexpected value 'fred'");
147 ut_assert_nextline("Failed (err=-22)");
148 ut_assert_console_end();
149
150 /* Check that we need to provide right number of parameters */
151 ut_asserteq(1, run_command("bootmeth set extlinux fallback", 0));
152 ut_assert_nextline("Required parameters not provided");
153 ut_assert_console_end();
154
155 /* Check that we need to provide a valid bootmethod */
156 ut_asserteq(1, run_command("bootmeth set fred fallback 0", 0));
157 ut_assert_nextline("Unknown bootmeth 'fred'");
158 ut_assert_nextline("Failed (err=-19)");
159 ut_assert_console_end();
160
161 /* Check that we need to provide a valid property */
162 ut_asserteq(1, run_command("bootmeth set extlinux fred 0", 0));
163 ut_assert_nextline("Invalid option");
164 ut_assert_nextline("Failed (err=-22)");
165 ut_assert_console_end();
166
167 /* Check that we need to provide a bootmeth that supports properties */
168 ut_asserteq(1, run_command("bootmeth set efi fallback 0", 0));
169 ut_assert_nextline("set_property not found");
170 ut_assert_nextline("Failed (err=-19)");
171 ut_assert_console_end();
172
173 return 0;
174 }
175 BOOTSTD_TEST(bootmeth_cmd_set, UTF_DM | UTF_SCAN_FDT);
176
177 /* Check 'bootmeths' env var */
bootmeth_env(struct unit_test_state * uts)178 static int bootmeth_env(struct unit_test_state *uts)
179 {
180 struct bootstd_priv *std;
181
182 ut_assertok(bootstd_get_priv(&std));
183
184 /* Select just one bootmethod */
185 ut_assertok(env_set("bootmeths", "extlinux"));
186 ut_asserteq(1, std->bootmeth_count);
187
188 /* Select an invalid bootmethod */
189 ut_asserteq(1, run_command("setenv bootmeths fred", 0));
190 ut_assert_nextline("Unknown bootmeth 'fred'");
191 ut_assert_nextlinen("## Error inserting");
192 ut_assert_console_end();
193
194 ut_assertok(env_set("bootmeths", "efi extlinux"));
195 ut_asserteq(2, std->bootmeth_count);
196 ut_assert_console_end();
197
198 return 0;
199 }
200 BOOTSTD_TEST(bootmeth_env, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
201
202 /* Check the get_state_desc() method */
bootmeth_state(struct unit_test_state * uts)203 static int bootmeth_state(struct unit_test_state *uts)
204 {
205 struct udevice *dev;
206 char buf[50];
207
208 ut_assertok(uclass_first_device_err(UCLASS_BOOTMETH, &dev));
209 ut_assertnonnull(dev);
210
211 ut_assertok(bootmeth_get_state_desc(dev, buf, sizeof(buf)));
212 ut_asserteq_str("OK", buf);
213
214 return 0;
215 }
216 BOOTSTD_TEST(bootmeth_state, UTF_DM | UTF_SCAN_FDT);
217