blob: 4729ccf07feb903f4e235d9df51b9d29058f5c43 [file] [log] [blame]
Love Kumarb2835c52024-06-05 15:19:35 +05301# SPDX-License-Identifier: GPL-2.0
2# (C) Copyright 2023, Advanced Micro Devices, Inc.
3
4import pytest
5import u_boot_utils
6import test_net
7import re
8
9"""
10Note: This test relies on boardenv_* containing configuration values to define
11which the network environment available for testing. Without this, this test
12will be automatically skipped.
13
14For example:
15
16# Details regarding a boot image file that may be read from a TFTP server. This
17# variable may be omitted or set to None if TFTP boot testing is not possible
18# or desired.
19env__net_tftp_bootable_file = {
20 'fn': 'image.ub',
21 'addr': 0x10000000,
22 'size': 5058624,
23 'crc32': 'c2244b26',
24 'pattern': 'Linux',
25 'config': 'config@2',
26 'timeout': 50000,
27 'check_type': 'boot_error',
28 'check_pattern': 'ERROR',
29}
30
31# False or omitted if a TFTP boot test should be tested.
32# If TFTP boot testing is not possible or desired, set this variable to True.
33# For example: If FIT image is not proper to boot
34env__tftp_boot_test_skip = False
35
36# Here is the example of FIT image configurations:
37configurations {
38 default = "config@1";
39 config@1 {
40 description = "Boot Linux kernel with config@1";
41 kernel = "kernel@0";
42 fdt = "fdt@0";
43 ramdisk = "ramdisk@0";
44 hash@1 {
45 algo = "sha1";
46 };
47 };
48 config@2 {
49 description = "Boot Linux kernel with config@2";
50 kernel = "kernel@1";
51 fdt = "fdt@1";
52 ramdisk = "ramdisk@1";
53 hash@1 {
54 algo = "sha1";
55 };
56 };
57};
58
59# Details regarding a file that may be read from a TFTP server. This variable
60# may be omitted or set to None if PXE testing is not possible or desired.
61env__net_pxe_bootable_file = {
62 'fn': 'default',
63 'addr': 0x10000000,
64 'size': 74,
65 'timeout': 50000,
66 'pattern': 'Linux',
67 'valid_label': '1',
68 'invalid_label': '2',
69 'exp_str_invalid': 'Skipping install for failure retrieving',
70 'local_label': '3',
71 'exp_str_local': 'missing environment variable: localcmd',
72 'empty_label': '4',
73 'exp_str_empty': 'No kernel given, skipping boot',
74 'check_type': 'boot_error',
75 'check_pattern': 'ERROR',
76}
77
78# False or omitted if a PXE boot test should be tested.
79# If PXE boot testing is not possible or desired, set this variable to True.
80# For example: If pxe configuration file is not proper to boot
81env__pxe_boot_test_skip = False
82
83# Here is the example of pxe configuration file ordered based on the execution
84# flow:
851) /tftpboot/pxelinux.cfg/default-arm-zynqmp
86
87 menu include pxelinux.cfg/default-arm
88 timeout 50
89
90 default Linux
91
922) /tftpboot/pxelinux.cfg/default-arm
93
94 menu title Linux boot selections
95 menu include pxelinux.cfg/default
96
97 label install
98 menu label Invalid boot
99 kernel kernels/install.bin
100 append console=ttyAMA0,38400 debug earlyprintk
101 initrd initrds/uzInitrdDebInstall
102
103 label local
104 menu label Local boot
105 append root=/dev/sdb1
106 localboot 1
107
108 label boot
109 menu label Empty boot
110
1113) /tftpboot/pxelinux.cfg/default
112
113 label Linux
114 menu label Boot kernel
115 kernel Image
116 fdt system.dtb
117 initrd rootfs.cpio.gz.u-boot
118"""
119
120def setup_networking(u_boot_console):
121 test_net.test_net_dhcp(u_boot_console)
122 if not test_net.net_set_up:
123 test_net.test_net_setup_static(u_boot_console)
124
125def setup_tftpboot_boot(u_boot_console):
126 f = u_boot_console.config.env.get('env__net_tftp_bootable_file', None)
127 if not f:
128 pytest.skip('No TFTP bootable file to read')
129
130 setup_networking(u_boot_console)
131 addr = f.get('addr', None)
132 if not addr:
133 addr = u_boot_utils.find_ram_base(u_boot_console)
134
135 fn = f['fn']
136 timeout = f.get('timeout', 50000)
137
138 with u_boot_console.temporary_timeout(timeout):
139 output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
140
141 expected_text = 'Bytes transferred = '
142 sz = f.get('size', None)
143 if sz:
144 expected_text += '%d' % sz
145 assert expected_text in output
146
147 expected_crc = f.get('crc32', None)
148 output = u_boot_console.run_command('crc32 %x $filesize' % addr)
149 if expected_crc:
150 assert expected_crc in output
151
152 pattern = f.get('pattern')
153 chk_type = f.get('check_type', 'boot_error')
154 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
155 config = f.get('config', None)
156
157 return addr, timeout, pattern, chk_type, chk_pattern, config
158
159@pytest.mark.buildconfigspec('cmd_net')
160def test_net_tftpboot_boot(u_boot_console):
161 """Boot the loaded image
162
163 A boot file (fit image) is downloaded from the TFTP server and booted using
164 bootm command with the default fit configuration, its boot log pattern are
165 validated.
166
167 The details of the file to download are provided by the boardenv_* file;
168 see the comment at the beginning of this file.
169 """
170 if u_boot_console.config.env.get('env__tftp_boot_test_skip', True):
171 pytest.skip('TFTP boot test is not enabled!')
172
173 addr, timeout, pattern, chk_type, chk_pattern, imcfg = setup_tftpboot_boot(
174 u_boot_console
175 )
176
177 if imcfg:
178 bootcmd = 'bootm %x#%s' % (addr, imcfg)
179 else:
180 bootcmd = 'bootm %x' % addr
181
182 with u_boot_console.enable_check(
183 chk_type, chk_pattern
184 ), u_boot_console.temporary_timeout(timeout):
185 try:
186 # wait_for_prompt=False makes the core code not wait for the U-Boot
187 # prompt code to be seen, since it won't be on a successful kernel
188 # boot
189 u_boot_console.run_command(bootcmd, wait_for_prompt=False)
190
191 # Wait for boot log pattern
192 u_boot_console.wait_for(pattern)
193 finally:
194 # This forces the console object to be shutdown, so any subsequent
195 # test will reset the board back into U-Boot. We want to force this
196 # no matter whether the kernel boot passed or failed.
197 u_boot_console.drain_console()
198 u_boot_console.cleanup_spawn()
199
200def setup_pxe_boot(u_boot_console):
201 f = u_boot_console.config.env.get('env__net_pxe_bootable_file', None)
202 if not f:
203 pytest.skip('No PXE bootable file to read')
204
205 setup_networking(u_boot_console)
206 bootfile = u_boot_console.run_command('echo $bootfile')
207 if not bootfile:
208 bootfile = '<NULL>'
209
210 return f, bootfile
211
212@pytest.mark.buildconfigspec('cmd_net')
213@pytest.mark.buildconfigspec('cmd_pxe')
214def test_net_pxe_boot(u_boot_console):
215 """Test the pxe boot command.
216
217 A pxe configuration file is downloaded from the TFTP server and interpreted
218 to boot the images mentioned in pxe configuration file.
219
220 The details of the file to download are provided by the boardenv_* file;
221 see the comment at the beginning of this file.
222 """
223 if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
224 pytest.skip('PXE boot test is not enabled!')
225
226 f, bootfile = setup_pxe_boot(u_boot_console)
227 addr = f.get('addr', None)
228 timeout = f.get('timeout', u_boot_console.p.timeout)
229 fn = f['fn']
230
231 if addr:
232 u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
233
234 with u_boot_console.temporary_timeout(timeout):
235 output = u_boot_console.run_command('pxe get')
236
237 expected_text = 'Bytes transferred = '
238 sz = f.get('size', None)
239 if sz:
240 expected_text += '%d' % sz
241 assert 'TIMEOUT' not in output
242 assert expected_text in output
243 assert f"Config file '{bootfile}' found" in output
244
245 pattern = f.get('pattern')
246 chk_type = f.get('check_type', 'boot_error')
247 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
248
249 if not addr:
250 pxe_boot_cmd = 'pxe boot'
251 else:
252 pxe_boot_cmd = 'pxe boot %x' % addr
253
254 with u_boot_console.enable_check(
255 chk_type, chk_pattern
256 ), u_boot_console.temporary_timeout(timeout):
257 try:
258 u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
259 u_boot_console.wait_for(pattern)
260 finally:
261 u_boot_console.drain_console()
262 u_boot_console.cleanup_spawn()
263
264@pytest.mark.buildconfigspec('cmd_net')
265@pytest.mark.buildconfigspec('cmd_pxe')
266def test_net_pxe_boot_config(u_boot_console):
267 """Test the pxe boot command by selecting different combination of labels
268
269 A pxe configuration file is downloaded from the TFTP server and interpreted
270 to boot the images mentioned in pxe configuration file.
271
272 The details of the file to download are provided by the boardenv_* file;
273 see the comment at the beginning of this file.
274 """
275 if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
276 pytest.skip('PXE boot test is not enabled!')
277
278 f, bootfile = setup_pxe_boot(u_boot_console)
279 addr = f.get('addr', None)
280 timeout = f.get('timeout', u_boot_console.p.timeout)
281 fn = f['fn']
282 local_label = f['local_label']
283 empty_label = f['empty_label']
284 exp_str_local = f['exp_str_local']
285 exp_str_empty = f['exp_str_empty']
286
287 if addr:
288 u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
289
290 with u_boot_console.temporary_timeout(timeout):
291 output = u_boot_console.run_command('pxe get')
292
293 expected_text = 'Bytes transferred = '
294 sz = f.get('size', None)
295 if sz:
296 expected_text += '%d' % sz
297 assert 'TIMEOUT' not in output
298 assert expected_text in output
299 assert f"Config file '{bootfile}' found" in output
300
301 pattern = f.get('pattern')
302 chk_type = f.get('check_type', 'boot_error')
303 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
304
305 if not addr:
306 pxe_boot_cmd = 'pxe boot'
307 else:
308 pxe_boot_cmd = 'pxe boot %x' % addr
309
310 with u_boot_console.enable_check(
311 chk_type, chk_pattern
312 ), u_boot_console.temporary_timeout(timeout):
313 try:
314 u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
315
316 # pxe config is loaded where multiple labels are there and need to
317 # select particular label to boot and check for expected string
318 # In this case, local label is selected and it should look for
319 # localcmd env variable and if that variable is not defined it
320 # should not boot it and come out to u-boot prompt
321 u_boot_console.wait_for('Enter choice:')
322 u_boot_console.run_command(local_label, wait_for_prompt=False)
323 expected_str = u_boot_console.p.expect([exp_str_local])
324 assert (
325 expected_str == 0
326 ), f'Expected string: {exp_str_local} did not match!'
327
328 # In this case, empty label is selected and it should look for
329 # kernel image path and if it is not set it should fail it and load
330 # default label to boot
331 u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
332 u_boot_console.wait_for('Enter choice:')
333 u_boot_console.run_command(empty_label, wait_for_prompt=False)
334 expected_str = u_boot_console.p.expect([exp_str_empty])
335 assert (
336 expected_str == 0
337 ), f'Expected string: {exp_str_empty} did not match!'
338
339 u_boot_console.wait_for(pattern)
340 finally:
341 u_boot_console.drain_console()
342 u_boot_console.cleanup_spawn()
343
344@pytest.mark.buildconfigspec('cmd_net')
345@pytest.mark.buildconfigspec('cmd_pxe')
346def test_net_pxe_boot_config_invalid(u_boot_console):
347 """Test the pxe boot command by selecting invalid label
348
349 A pxe configuration file is downloaded from the TFTP server and interpreted
350 to boot the images mentioned in pxe configuration file.
351
352 The details of the file to download are provided by the boardenv_* file;
353 see the comment at the beginning of this file.
354 """
355 if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
356 pytest.skip('PXE boot test is not enabled!')
357
358 f, bootfile = setup_pxe_boot(u_boot_console)
359 addr = f.get('addr', None)
360 timeout = f.get('timeout', u_boot_console.p.timeout)
361 fn = f['fn']
362 invalid_label = f['invalid_label']
363 exp_str_invalid = f['exp_str_invalid']
364
365 if addr:
366 u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
367
368 with u_boot_console.temporary_timeout(timeout):
369 output = u_boot_console.run_command('pxe get')
370
371 expected_text = 'Bytes transferred = '
372 sz = f.get('size', None)
373 if sz:
374 expected_text += '%d' % sz
375 assert 'TIMEOUT' not in output
376 assert expected_text in output
377 assert f"Config file '{bootfile}' found" in output
378
379 pattern = f.get('pattern')
380 if not addr:
381 pxe_boot_cmd = 'pxe boot'
382 else:
383 pxe_boot_cmd = 'pxe boot %x' % addr
384
385 with u_boot_console.temporary_timeout(timeout):
386 try:
387 u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
388
389 # pxe config is loaded where multiple labels are there and need to
390 # select particular label to boot and check for expected string
391 # In this case invalid label is selected, it should load invalid
392 # label and if it fails it should load the default label to boot
393 u_boot_console.wait_for('Enter choice:')
394 u_boot_console.run_command(invalid_label, wait_for_prompt=False)
395 expected_str = u_boot_console.p.expect([exp_str_invalid])
396 assert (
397 expected_str == 0
398 ), f'Expected string: {exp_str_invalid} did not match!'
399
400 u_boot_console.wait_for(pattern)
401 finally:
402 u_boot_console.drain_console()
403 u_boot_console.cleanup_spawn()