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 <common.h>
10 #include <bootmeth.h>
11 #include <bootstd.h>
12 #include <dm.h>
13 #include <test/suites.h>
14 #include <test/ut.h>
15 #include "bootstd_common.h"
16 
17 /* Check 'bootmeth list' command */
bootmeth_cmd_list(struct unit_test_state * uts)18 static int bootmeth_cmd_list(struct unit_test_state *uts)
19 {
20 	console_record_reset_enable();
21 	ut_assertok(run_command("bootmeth list", 0));
22 	ut_assert_nextline("Order  Seq  Name                Description");
23 	ut_assert_nextlinen("---");
24 	ut_assert_nextline("    0    0  extlinux            Extlinux boot from a block device");
25 	ut_assert_nextline("    1    1  efi                 EFI boot from an .efi file");
26 	if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
27 		ut_assert_nextline(" glob    2  firmware0           VBE simple");
28 	ut_assert_nextlinen("---");
29 	ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
30 		 "(3 bootmeths)" : "(2 bootmeths)");
31 	ut_assert_console_end();
32 
33 	return 0;
34 }
35 BOOTSTD_TEST(bootmeth_cmd_list, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
36 
37 /* Check 'bootmeth order' command */
bootmeth_cmd_order(struct unit_test_state * uts)38 static int bootmeth_cmd_order(struct unit_test_state *uts)
39 {
40 	/* Select just one bootmethod */
41 	console_record_reset_enable();
42 	ut_assertok(run_command("bootmeth order extlinux", 0));
43 	ut_assert_console_end();
44 	ut_assertnonnull(env_get("bootmeths"));
45 	ut_asserteq_str("extlinux", env_get("bootmeths"));
46 
47 	/* Only that one should be listed */
48 	ut_assertok(run_command("bootmeth list", 0));
49 	ut_assert_nextline("Order  Seq  Name                Description");
50 	ut_assert_nextlinen("---");
51 	ut_assert_nextline("    0    0  extlinux            Extlinux boot from a block device");
52 	ut_assert_nextlinen("---");
53 	ut_assert_nextline("(1 bootmeth)");
54 	ut_assert_console_end();
55 
56 	/* Check the -a flag, efi should show as not in the order ("-") */
57 	ut_assertok(run_command("bootmeth list -a", 0));
58 	ut_assert_nextline("Order  Seq  Name                Description");
59 	ut_assert_nextlinen("---");
60 	ut_assert_nextline("    0    0  extlinux            Extlinux boot from a block device");
61 	ut_assert_nextline("    -    1  efi                 EFI boot from an .efi file");
62 	if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
63 		ut_assert_nextline(" glob    2  firmware0           VBE simple");
64 	ut_assert_nextlinen("---");
65 	ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
66 		 "(3 bootmeths)" : "(2 bootmeths)");
67 	ut_assert_console_end();
68 
69 	/* Check the -a flag with the reverse order */
70 	ut_assertok(run_command("bootmeth order \"efi extlinux\"", 0));
71 	ut_assert_console_end();
72 	ut_assertok(run_command("bootmeth list -a", 0));
73 	ut_assert_nextline("Order  Seq  Name                Description");
74 	ut_assert_nextlinen("---");
75 	ut_assert_nextline("    1    0  extlinux            Extlinux boot from a block device");
76 	ut_assert_nextline("    0    1  efi                 EFI boot from an .efi file");
77 	if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
78 		ut_assert_nextline(" glob    2  firmware0           VBE simple");
79 	ut_assert_nextlinen("---");
80 	ut_assert_nextline(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
81 		 "(3 bootmeths)" : "(2 bootmeths)");
82 	ut_assert_console_end();
83 
84 	/* Now reset the order to empty, which should show all of them again */
85 	ut_assertok(run_command("bootmeth order", 0));
86 	ut_assert_console_end();
87 	ut_assertnull(env_get("bootmeths"));
88 	ut_assertok(run_command("bootmeth list", 0));
89 	ut_assert_skip_to_line(IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) ?
90 		 "(3 bootmeths)" : "(2 bootmeths)");
91 
92 	/* Try reverse order */
93 	ut_assertok(run_command("bootmeth order \"efi extlinux\"", 0));
94 	ut_assert_console_end();
95 	ut_assertok(run_command("bootmeth list", 0));
96 	ut_assert_nextline("Order  Seq  Name                Description");
97 	ut_assert_nextlinen("---");
98 	ut_assert_nextline("    0    1  efi                 EFI boot from an .efi file");
99 	ut_assert_nextline("    1    0  extlinux            Extlinux boot from a block device");
100 	ut_assert_nextlinen("---");
101 	ut_assert_nextline("(2 bootmeths)");
102 	ut_assertnonnull(env_get("bootmeths"));
103 	ut_asserteq_str("efi extlinux", env_get("bootmeths"));
104 	ut_assert_console_end();
105 
106 	return 0;
107 }
108 BOOTSTD_TEST(bootmeth_cmd_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
109 
110 /* Check 'bootmeth order' command with global bootmeths */
bootmeth_cmd_order_glob(struct unit_test_state * uts)111 static int bootmeth_cmd_order_glob(struct unit_test_state *uts)
112 {
113 	if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
114 		return -EAGAIN;
115 
116 	console_record_reset_enable();
117 	ut_assertok(run_command("bootmeth order \"efi firmware0\"", 0));
118 	ut_assert_console_end();
119 	ut_assertok(run_command("bootmeth list", 0));
120 	ut_assert_nextline("Order  Seq  Name                Description");
121 	ut_assert_nextlinen("---");
122 	ut_assert_nextline("    0    1  efi                 EFI boot from an .efi file");
123 	ut_assert_nextline(" glob    2  firmware0           VBE simple");
124 	ut_assert_nextlinen("---");
125 	ut_assert_nextline("(2 bootmeths)");
126 	ut_assertnonnull(env_get("bootmeths"));
127 	ut_asserteq_str("efi firmware0", env_get("bootmeths"));
128 	ut_assert_console_end();
129 
130 	return 0;
131 }
132 BOOTSTD_TEST(bootmeth_cmd_order_glob, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
133 
134 /* Check 'bootmeths' env var */
bootmeth_env(struct unit_test_state * uts)135 static int bootmeth_env(struct unit_test_state *uts)
136 {
137 	struct bootstd_priv *std;
138 
139 	ut_assertok(bootstd_get_priv(&std));
140 
141 	/* Select just one bootmethod */
142 	console_record_reset_enable();
143 	ut_assertok(env_set("bootmeths", "extlinux"));
144 	ut_asserteq(1, std->bootmeth_count);
145 
146 	/* Select an invalid bootmethod */
147 	ut_asserteq(1, run_command("setenv bootmeths fred", 0));
148 	ut_assert_nextline("Unknown bootmeth 'fred'");
149 	ut_assert_nextlinen("## Error inserting");
150 	ut_assert_console_end();
151 
152 	ut_assertok(env_set("bootmeths", "efi extlinux"));
153 	ut_asserteq(2, std->bootmeth_count);
154 	ut_assert_console_end();
155 
156 	return 0;
157 }
158 BOOTSTD_TEST(bootmeth_env, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
159 
160 /* Check the get_state_desc() method */
bootmeth_state(struct unit_test_state * uts)161 static int bootmeth_state(struct unit_test_state *uts)
162 {
163 	struct udevice *dev;
164 	char buf[50];
165 
166 	ut_assertok(uclass_first_device_err(UCLASS_BOOTMETH, &dev));
167 	ut_assertnonnull(dev);
168 
169 	ut_assertok(bootmeth_get_state_desc(dev, buf, sizeof(buf)));
170 	ut_asserteq_str("OK", buf);
171 
172 	return 0;
173 }
174 BOOTSTD_TEST(bootmeth_state, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
175