blob: 6585f0574c01d305394496ec3a28c45bcbae1c08 [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
Love Kumarb2835c52024-06-05 15:19:35 +05304"""
5Note: This test relies on boardenv_* containing configuration values to define
6which the network environment available for testing. Without this, this test
7will be automatically skipped.
8
9For example:
10
Tom Rini562f2652025-05-07 16:08:19 -060011.. code-block:: python
Love Kumarb2835c52024-06-05 15:19:35 +053012
Tom Rini562f2652025-05-07 16:08:19 -060013 # Details regarding a boot image file that may be read from a TFTP server. This
14 # variable may be omitted or set to None if TFTP boot testing is not possible
15 # or desired.
16 env__net_tftp_bootable_file = {
17 'fn': 'image.ub',
18 'addr': 0x10000000,
19 'size': 5058624,
20 'crc32': 'c2244b26',
21 'pattern': 'Linux',
22 'config': 'config@2',
23 'timeout': 50000,
24 'check_type': 'boot_error',
25 'check_pattern': 'ERROR',
26 }
Love Kumarb2835c52024-06-05 15:19:35 +053027
Tom Rini562f2652025-05-07 16:08:19 -060028 # False or omitted if a TFTP boot test should be tested.
29 # If TFTP boot testing is not possible or desired, set this variable to True.
30 # For example: If FIT image is not proper to boot
31 env__tftp_boot_test_skip = False
Love Kumarb2835c52024-06-05 15:19:35 +053032
Love Kumarb2835c52024-06-05 15:19:35 +053033
Tom Rini562f2652025-05-07 16:08:19 -060034Here is the example of FIT image configurations:
Love Kumarb2835c52024-06-05 15:19:35 +053035
Tom Rini562f2652025-05-07 16:08:19 -060036.. code-block:: devicetree
37
38 configurations {
39 default = "config@1";
40 config@1 {
41 description = "Boot Linux kernel with config@1";
42 kernel = "kernel@0";
43 fdt = "fdt@0";
44 ramdisk = "ramdisk@0";
45 hash@1 {
46 algo = "sha1";
47 };
48 };
49 config@2 {
50 description = "Boot Linux kernel with config@2";
51 kernel = "kernel@1";
52 fdt = "fdt@1";
53 ramdisk = "ramdisk@1";
54 hash@1 {
55 algo = "sha1";
56 };
57 };
58 };
59
60.. code-block:: python
61
62 # Details regarding a file that may be read from a TFTP server. This variable
63 # may be omitted or set to None if PXE testing is not possible or desired.
64 env__net_pxe_bootable_file = {
65 'fn': 'default',
66 'addr': 0x10000000,
67 'size': 74,
68 'timeout': 50000,
69 'pattern': 'Linux',
70 'valid_label': '1',
71 'invalid_label': '2',
72 'exp_str_invalid': 'Skipping install for failure retrieving',
73 'local_label': '3',
74 'exp_str_local': 'missing environment variable: localcmd',
75 'empty_label': '4',
76 'exp_str_empty': 'No kernel given, skipping boot',
77 'check_type': 'boot_error',
78 'check_pattern': 'ERROR',
79 }
80
81 # False if a PXE boot test should be tested.
82 # If PXE boot testing is not possible or desired, set this variable to True.
83 # For example: If pxe configuration file is not proper to boot
84 env__pxe_boot_test_skip = False
85
86Here is the example of pxe configuration file ordered based on the execution
87flow:
88
Love Kumarb2835c52024-06-05 15:19:35 +0530891) /tftpboot/pxelinux.cfg/default-arm-zynqmp
90
Tom Rini562f2652025-05-07 16:08:19 -060091.. code-block::
92
Love Kumarb2835c52024-06-05 15:19:35 +053093 menu include pxelinux.cfg/default-arm
94 timeout 50
95
96 default Linux
97
982) /tftpboot/pxelinux.cfg/default-arm
99
Tom Rini562f2652025-05-07 16:08:19 -0600100.. code-block::
101
Love Kumarb2835c52024-06-05 15:19:35 +0530102 menu title Linux boot selections
103 menu include pxelinux.cfg/default
104
105 label install
106 menu label Invalid boot
107 kernel kernels/install.bin
108 append console=ttyAMA0,38400 debug earlyprintk
109 initrd initrds/uzInitrdDebInstall
110
111 label local
112 menu label Local boot
113 append root=/dev/sdb1
114 localboot 1
115
116 label boot
117 menu label Empty boot
118
1193) /tftpboot/pxelinux.cfg/default
120
Tom Rini562f2652025-05-07 16:08:19 -0600121.. code-block::
122
Love Kumarb2835c52024-06-05 15:19:35 +0530123 label Linux
124 menu label Boot kernel
125 kernel Image
126 fdt system.dtb
127 initrd rootfs.cpio.gz.u-boot
128"""
129
Tom Rini562f2652025-05-07 16:08:19 -0600130import pytest
131import utils
132import test_net
133import re
134
Simon Glassddba5202025-02-09 09:07:14 -0700135def setup_networking(ubman):
136 test_net.test_net_dhcp(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530137 if not test_net.net_set_up:
Simon Glassddba5202025-02-09 09:07:14 -0700138 test_net.test_net_setup_static(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530139
Simon Glassddba5202025-02-09 09:07:14 -0700140def setup_tftpboot_boot(ubman):
141 f = ubman.config.env.get('env__net_tftp_bootable_file', None)
Love Kumarb2835c52024-06-05 15:19:35 +0530142 if not f:
143 pytest.skip('No TFTP bootable file to read')
144
Simon Glassddba5202025-02-09 09:07:14 -0700145 setup_networking(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530146 addr = f.get('addr', None)
147 if not addr:
Simon Glassfb916372025-02-09 09:07:15 -0700148 addr = utils.find_ram_base(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530149
150 fn = f['fn']
151 timeout = f.get('timeout', 50000)
152
Simon Glassddba5202025-02-09 09:07:14 -0700153 with ubman.temporary_timeout(timeout):
154 output = ubman.run_command('tftpboot %x %s' % (addr, fn))
Love Kumarb2835c52024-06-05 15:19:35 +0530155
156 expected_text = 'Bytes transferred = '
157 sz = f.get('size', None)
158 if sz:
159 expected_text += '%d' % sz
160 assert expected_text in output
161
162 expected_crc = f.get('crc32', None)
Simon Glassddba5202025-02-09 09:07:14 -0700163 output = ubman.run_command('crc32 %x $filesize' % addr)
Love Kumarb2835c52024-06-05 15:19:35 +0530164 if expected_crc:
165 assert expected_crc in output
166
167 pattern = f.get('pattern')
168 chk_type = f.get('check_type', 'boot_error')
169 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
170 config = f.get('config', None)
171
172 return addr, timeout, pattern, chk_type, chk_pattern, config
173
Tom Rini5568cc32024-06-18 14:23:43 -0600174@pytest.mark.buildconfigspec('cmd_tftpboot')
Simon Glassddba5202025-02-09 09:07:14 -0700175def test_net_tftpboot_boot(ubman):
Love Kumarb2835c52024-06-05 15:19:35 +0530176 """Boot the loaded image
177
178 A boot file (fit image) is downloaded from the TFTP server and booted using
179 bootm command with the default fit configuration, its boot log pattern are
180 validated.
181
182 The details of the file to download are provided by the boardenv_* file;
183 see the comment at the beginning of this file.
184 """
Simon Glassddba5202025-02-09 09:07:14 -0700185 if ubman.config.env.get('env__tftp_boot_test_skip', True):
Love Kumarb2835c52024-06-05 15:19:35 +0530186 pytest.skip('TFTP boot test is not enabled!')
187
188 addr, timeout, pattern, chk_type, chk_pattern, imcfg = setup_tftpboot_boot(
Simon Glassddba5202025-02-09 09:07:14 -0700189 ubman
Love Kumarb2835c52024-06-05 15:19:35 +0530190 )
191
192 if imcfg:
193 bootcmd = 'bootm %x#%s' % (addr, imcfg)
194 else:
195 bootcmd = 'bootm %x' % addr
196
Simon Glassddba5202025-02-09 09:07:14 -0700197 with ubman.enable_check(
Love Kumarb2835c52024-06-05 15:19:35 +0530198 chk_type, chk_pattern
Simon Glassddba5202025-02-09 09:07:14 -0700199 ), ubman.temporary_timeout(timeout):
Love Kumarb2835c52024-06-05 15:19:35 +0530200 try:
201 # wait_for_prompt=False makes the core code not wait for the U-Boot
202 # prompt code to be seen, since it won't be on a successful kernel
203 # boot
Simon Glassddba5202025-02-09 09:07:14 -0700204 ubman.run_command(bootcmd, wait_for_prompt=False)
Love Kumarb2835c52024-06-05 15:19:35 +0530205
206 # Wait for boot log pattern
Simon Glassddba5202025-02-09 09:07:14 -0700207 ubman.wait_for(pattern)
Love Kumarb2835c52024-06-05 15:19:35 +0530208 finally:
209 # This forces the console object to be shutdown, so any subsequent
210 # test will reset the board back into U-Boot. We want to force this
211 # no matter whether the kernel boot passed or failed.
Simon Glassddba5202025-02-09 09:07:14 -0700212 ubman.drain_console()
213 ubman.cleanup_spawn()
Love Kumarb2835c52024-06-05 15:19:35 +0530214
Simon Glassddba5202025-02-09 09:07:14 -0700215def setup_pxe_boot(ubman):
216 f = ubman.config.env.get('env__net_pxe_bootable_file', None)
Love Kumarb2835c52024-06-05 15:19:35 +0530217 if not f:
218 pytest.skip('No PXE bootable file to read')
219
Simon Glassddba5202025-02-09 09:07:14 -0700220 setup_networking(ubman)
221 bootfile = ubman.run_command('echo $bootfile')
Love Kumarb2835c52024-06-05 15:19:35 +0530222 if not bootfile:
223 bootfile = '<NULL>'
224
225 return f, bootfile
226
Love Kumarb2835c52024-06-05 15:19:35 +0530227@pytest.mark.buildconfigspec('cmd_pxe')
Simon Glassddba5202025-02-09 09:07:14 -0700228def test_net_pxe_boot(ubman):
Love Kumarb2835c52024-06-05 15:19:35 +0530229 """Test the pxe boot command.
230
231 A pxe configuration file is downloaded from the TFTP server and interpreted
232 to boot the images mentioned in pxe configuration file.
233
234 The details of the file to download are provided by the boardenv_* file;
235 see the comment at the beginning of this file.
236 """
Simon Glassddba5202025-02-09 09:07:14 -0700237 if ubman.config.env.get('env__pxe_boot_test_skip', True):
Love Kumarb2835c52024-06-05 15:19:35 +0530238 pytest.skip('PXE boot test is not enabled!')
239
Simon Glassddba5202025-02-09 09:07:14 -0700240 f, bootfile = setup_pxe_boot(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530241 addr = f.get('addr', None)
Simon Glassddba5202025-02-09 09:07:14 -0700242 timeout = f.get('timeout', ubman.p.timeout)
Love Kumarb2835c52024-06-05 15:19:35 +0530243 fn = f['fn']
244
245 if addr:
Simon Glassddba5202025-02-09 09:07:14 -0700246 ubman.run_command('setenv pxefile_addr_r %x' % addr)
Love Kumarb2835c52024-06-05 15:19:35 +0530247
Simon Glassddba5202025-02-09 09:07:14 -0700248 with ubman.temporary_timeout(timeout):
249 output = ubman.run_command('pxe get')
Love Kumarb2835c52024-06-05 15:19:35 +0530250
251 expected_text = 'Bytes transferred = '
252 sz = f.get('size', None)
253 if sz:
254 expected_text += '%d' % sz
255 assert 'TIMEOUT' not in output
256 assert expected_text in output
257 assert f"Config file '{bootfile}' found" in output
258
259 pattern = f.get('pattern')
260 chk_type = f.get('check_type', 'boot_error')
261 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
262
263 if not addr:
264 pxe_boot_cmd = 'pxe boot'
265 else:
266 pxe_boot_cmd = 'pxe boot %x' % addr
267
Simon Glassddba5202025-02-09 09:07:14 -0700268 with ubman.enable_check(
Love Kumarb2835c52024-06-05 15:19:35 +0530269 chk_type, chk_pattern
Simon Glassddba5202025-02-09 09:07:14 -0700270 ), ubman.temporary_timeout(timeout):
Love Kumarb2835c52024-06-05 15:19:35 +0530271 try:
Simon Glassddba5202025-02-09 09:07:14 -0700272 ubman.run_command(pxe_boot_cmd, wait_for_prompt=False)
273 ubman.wait_for(pattern)
Love Kumarb2835c52024-06-05 15:19:35 +0530274 finally:
Simon Glassddba5202025-02-09 09:07:14 -0700275 ubman.drain_console()
276 ubman.cleanup_spawn()
Love Kumarb2835c52024-06-05 15:19:35 +0530277
Love Kumarb2835c52024-06-05 15:19:35 +0530278@pytest.mark.buildconfigspec('cmd_pxe')
Simon Glassddba5202025-02-09 09:07:14 -0700279def test_net_pxe_boot_config(ubman):
Love Kumarb2835c52024-06-05 15:19:35 +0530280 """Test the pxe boot command by selecting different combination of labels
281
282 A pxe configuration file is downloaded from the TFTP server and interpreted
283 to boot the images mentioned in pxe configuration file.
284
285 The details of the file to download are provided by the boardenv_* file;
286 see the comment at the beginning of this file.
287 """
Simon Glassddba5202025-02-09 09:07:14 -0700288 if ubman.config.env.get('env__pxe_boot_test_skip', True):
Love Kumarb2835c52024-06-05 15:19:35 +0530289 pytest.skip('PXE boot test is not enabled!')
290
Simon Glassddba5202025-02-09 09:07:14 -0700291 f, bootfile = setup_pxe_boot(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530292 addr = f.get('addr', None)
Simon Glassddba5202025-02-09 09:07:14 -0700293 timeout = f.get('timeout', ubman.p.timeout)
Love Kumarb2835c52024-06-05 15:19:35 +0530294 fn = f['fn']
295 local_label = f['local_label']
296 empty_label = f['empty_label']
297 exp_str_local = f['exp_str_local']
298 exp_str_empty = f['exp_str_empty']
299
300 if addr:
Simon Glassddba5202025-02-09 09:07:14 -0700301 ubman.run_command('setenv pxefile_addr_r %x' % addr)
Love Kumarb2835c52024-06-05 15:19:35 +0530302
Simon Glassddba5202025-02-09 09:07:14 -0700303 with ubman.temporary_timeout(timeout):
304 output = ubman.run_command('pxe get')
Love Kumarb2835c52024-06-05 15:19:35 +0530305
306 expected_text = 'Bytes transferred = '
307 sz = f.get('size', None)
308 if sz:
309 expected_text += '%d' % sz
310 assert 'TIMEOUT' not in output
311 assert expected_text in output
312 assert f"Config file '{bootfile}' found" in output
313
314 pattern = f.get('pattern')
315 chk_type = f.get('check_type', 'boot_error')
316 chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
317
318 if not addr:
319 pxe_boot_cmd = 'pxe boot'
320 else:
321 pxe_boot_cmd = 'pxe boot %x' % addr
322
Simon Glassddba5202025-02-09 09:07:14 -0700323 with ubman.enable_check(
Love Kumarb2835c52024-06-05 15:19:35 +0530324 chk_type, chk_pattern
Simon Glassddba5202025-02-09 09:07:14 -0700325 ), ubman.temporary_timeout(timeout):
Love Kumarb2835c52024-06-05 15:19:35 +0530326 try:
Simon Glassddba5202025-02-09 09:07:14 -0700327 ubman.run_command(pxe_boot_cmd, wait_for_prompt=False)
Love Kumarb2835c52024-06-05 15:19:35 +0530328
329 # pxe config is loaded where multiple labels are there and need to
330 # select particular label to boot and check for expected string
331 # In this case, local label is selected and it should look for
332 # localcmd env variable and if that variable is not defined it
333 # should not boot it and come out to u-boot prompt
Simon Glassddba5202025-02-09 09:07:14 -0700334 ubman.wait_for('Enter choice:')
335 ubman.run_command(local_label, wait_for_prompt=False)
336 expected_str = ubman.p.expect([exp_str_local])
Love Kumarb2835c52024-06-05 15:19:35 +0530337 assert (
338 expected_str == 0
339 ), f'Expected string: {exp_str_local} did not match!'
340
341 # In this case, empty label is selected and it should look for
342 # kernel image path and if it is not set it should fail it and load
343 # default label to boot
Simon Glassddba5202025-02-09 09:07:14 -0700344 ubman.run_command(pxe_boot_cmd, wait_for_prompt=False)
345 ubman.wait_for('Enter choice:')
346 ubman.run_command(empty_label, wait_for_prompt=False)
347 expected_str = ubman.p.expect([exp_str_empty])
Love Kumarb2835c52024-06-05 15:19:35 +0530348 assert (
349 expected_str == 0
350 ), f'Expected string: {exp_str_empty} did not match!'
351
Simon Glassddba5202025-02-09 09:07:14 -0700352 ubman.wait_for(pattern)
Love Kumarb2835c52024-06-05 15:19:35 +0530353 finally:
Simon Glassddba5202025-02-09 09:07:14 -0700354 ubman.drain_console()
355 ubman.cleanup_spawn()
Love Kumarb2835c52024-06-05 15:19:35 +0530356
Love Kumarb2835c52024-06-05 15:19:35 +0530357@pytest.mark.buildconfigspec('cmd_pxe')
Simon Glassddba5202025-02-09 09:07:14 -0700358def test_net_pxe_boot_config_invalid(ubman):
Love Kumarb2835c52024-06-05 15:19:35 +0530359 """Test the pxe boot command by selecting invalid label
360
361 A pxe configuration file is downloaded from the TFTP server and interpreted
362 to boot the images mentioned in pxe configuration file.
363
364 The details of the file to download are provided by the boardenv_* file;
365 see the comment at the beginning of this file.
366 """
Simon Glassddba5202025-02-09 09:07:14 -0700367 if ubman.config.env.get('env__pxe_boot_test_skip', True):
Love Kumarb2835c52024-06-05 15:19:35 +0530368 pytest.skip('PXE boot test is not enabled!')
369
Simon Glassddba5202025-02-09 09:07:14 -0700370 f, bootfile = setup_pxe_boot(ubman)
Love Kumarb2835c52024-06-05 15:19:35 +0530371 addr = f.get('addr', None)
Simon Glassddba5202025-02-09 09:07:14 -0700372 timeout = f.get('timeout', ubman.p.timeout)
Love Kumarb2835c52024-06-05 15:19:35 +0530373 fn = f['fn']
374 invalid_label = f['invalid_label']
375 exp_str_invalid = f['exp_str_invalid']
376
377 if addr:
Simon Glassddba5202025-02-09 09:07:14 -0700378 ubman.run_command('setenv pxefile_addr_r %x' % addr)
Love Kumarb2835c52024-06-05 15:19:35 +0530379
Simon Glassddba5202025-02-09 09:07:14 -0700380 with ubman.temporary_timeout(timeout):
381 output = ubman.run_command('pxe get')
Love Kumarb2835c52024-06-05 15:19:35 +0530382
383 expected_text = 'Bytes transferred = '
384 sz = f.get('size', None)
385 if sz:
386 expected_text += '%d' % sz
387 assert 'TIMEOUT' not in output
388 assert expected_text in output
389 assert f"Config file '{bootfile}' found" in output
390
391 pattern = f.get('pattern')
392 if not addr:
393 pxe_boot_cmd = 'pxe boot'
394 else:
395 pxe_boot_cmd = 'pxe boot %x' % addr
396
Simon Glassddba5202025-02-09 09:07:14 -0700397 with ubman.temporary_timeout(timeout):
Love Kumarb2835c52024-06-05 15:19:35 +0530398 try:
Simon Glassddba5202025-02-09 09:07:14 -0700399 ubman.run_command(pxe_boot_cmd, wait_for_prompt=False)
Love Kumarb2835c52024-06-05 15:19:35 +0530400
401 # pxe config is loaded where multiple labels are there and need to
402 # select particular label to boot and check for expected string
403 # In this case invalid label is selected, it should load invalid
404 # label and if it fails it should load the default label to boot
Simon Glassddba5202025-02-09 09:07:14 -0700405 ubman.wait_for('Enter choice:')
406 ubman.run_command(invalid_label, wait_for_prompt=False)
407 expected_str = ubman.p.expect([exp_str_invalid])
Love Kumarb2835c52024-06-05 15:19:35 +0530408 assert (
409 expected_str == 0
410 ), f'Expected string: {exp_str_invalid} did not match!'
411
Simon Glassddba5202025-02-09 09:07:14 -0700412 ubman.wait_for(pattern)
Love Kumarb2835c52024-06-05 15:19:35 +0530413 finally:
Simon Glassddba5202025-02-09 09:07:14 -0700414 ubman.drain_console()
415 ubman.cleanup_spawn()