1# SPDX-License-Identifier: GPL-2.0
2# Copyright (c) 2017, Heinrich Schuchardt <xypron.glpk@gmx.de>
3
4""" Test UEFI API implementation
5"""
6
7import pytest
8
9@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
10def test_efi_selftest_base(u_boot_console):
11    """Run UEFI unit tests
12
13    u_boot_console -- U-Boot console
14
15    This function executes all selftests that are not marked as on request.
16    """
17    u_boot_console.run_command(cmd='setenv efi_selftest')
18    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
19    if u_boot_console.p.expect(['Summary: 0 failures', 'Press any key']):
20        raise Exception('Failures occurred during the EFI selftest')
21    u_boot_console.restart_uboot()
22
23@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
24@pytest.mark.buildconfigspec('hush_parser')
25@pytest.mark.buildconfigspec('of_control')
26@pytest.mark.notbuildconfigspec('generate_acpi_table')
27def test_efi_selftest_device_tree(u_boot_console):
28    """Test the device tree support in the UEFI sub-system
29
30    u_boot_console -- U-Boot console
31
32    This test executes the UEFI unit test by calling 'bootefi selftest'.
33    """
34    u_boot_console.run_command(cmd='setenv efi_selftest list')
35    output = u_boot_console.run_command('bootefi selftest')
36    assert '\'device tree\'' in output
37    u_boot_console.run_command(cmd='setenv efi_selftest device tree')
38    # Set serial# if it is not already set.
39    u_boot_console.run_command(cmd='setenv efi_test "${serial#}x"')
40    u_boot_console.run_command(cmd='test "${efi_test}" = x && setenv serial# 0')
41    u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
42    if u_boot_console.p.expect(['serial-number:', 'U-Boot']):
43        raise Exception('serial-number missing in device tree')
44    u_boot_console.restart_uboot()
45
46@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
47def test_efi_selftest_watchdog_reboot(u_boot_console):
48    """Test the watchdog timer
49
50    u_boot_console -- U-Boot console
51
52    This function executes the 'watchdog reboot' unit test.
53    """
54    u_boot_console.run_command(cmd='setenv efi_selftest list')
55    output = u_boot_console.run_command('bootefi selftest')
56    assert '\'watchdog reboot\'' in output
57    u_boot_console.run_command(cmd='setenv efi_selftest watchdog reboot')
58    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
59    if u_boot_console.p.expect(['resetting', 'U-Boot']):
60        raise Exception('Reset failed in \'watchdog reboot\' test')
61    u_boot_console.restart_uboot()
62
63@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
64def test_efi_selftest_text_input(u_boot_console):
65    """Test the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
66
67    u_boot_console -- U-Boot console
68
69    This function calls the text input EFI selftest.
70    """
71    u_boot_console.run_command(cmd='setenv efi_selftest text input')
72    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
73    if u_boot_console.p.expect([r'To terminate type \'x\'']):
74        raise Exception('No prompt for \'text input\' test')
75    u_boot_console.drain_console()
76    # EOT
77    u_boot_console.run_command(cmd=chr(4), wait_for_echo=False,
78                               send_nl=False, wait_for_prompt=False)
79    if u_boot_console.p.expect([r'Unicode char 4 \(unknown\), scan code 0 \(Null\)']):
80        raise Exception('EOT failed in \'text input\' test')
81    u_boot_console.drain_console()
82    # BS
83    u_boot_console.run_command(cmd=chr(8), wait_for_echo=False,
84                               send_nl=False, wait_for_prompt=False)
85    if u_boot_console.p.expect([r'Unicode char 8 \(BS\), scan code 0 \(Null\)']):
86        raise Exception('BS failed in \'text input\' test')
87    u_boot_console.drain_console()
88    # TAB
89    u_boot_console.run_command(cmd=chr(9), wait_for_echo=False,
90                               send_nl=False, wait_for_prompt=False)
91    if u_boot_console.p.expect([r'Unicode char 9 \(TAB\), scan code 0 \(Null\)']):
92        raise Exception('BS failed in \'text input\' test')
93    u_boot_console.drain_console()
94    # a
95    u_boot_console.run_command(cmd='a', wait_for_echo=False, send_nl=False,
96                               wait_for_prompt=False)
97    if u_boot_console.p.expect([r'Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']):
98        raise Exception('\'a\' failed in \'text input\' test')
99    u_boot_console.drain_console()
100    # UP escape sequence
101    u_boot_console.run_command(cmd=chr(27) + '[A', wait_for_echo=False,
102                               send_nl=False, wait_for_prompt=False)
103    if u_boot_console.p.expect([r'Unicode char 0 \(Null\), scan code 1 \(Up\)']):
104        raise Exception('UP failed in \'text input\' test')
105    u_boot_console.drain_console()
106    # Euro sign
107    u_boot_console.run_command(cmd=b'\xe2\x82\xac'.decode(), wait_for_echo=False,
108                               send_nl=False, wait_for_prompt=False)
109    if u_boot_console.p.expect([r'Unicode char 8364 \(\'']):
110        raise Exception('Euro sign failed in \'text input\' test')
111    u_boot_console.drain_console()
112    u_boot_console.run_command(cmd='x', wait_for_echo=False, send_nl=False,
113                               wait_for_prompt=False)
114    if u_boot_console.p.expect(['Summary: 0 failures', 'Press any key']):
115        raise Exception('Failures occurred during the EFI selftest')
116    u_boot_console.restart_uboot()
117
118@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
119def test_efi_selftest_text_input_ex(u_boot_console):
120    """Test the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
121
122    u_boot_console -- U-Boot console
123
124    This function calls the extended text input EFI selftest.
125    """
126    u_boot_console.run_command(cmd='setenv efi_selftest extended text input')
127    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
128    if u_boot_console.p.expect([r'To terminate type \'CTRL\+x\'']):
129        raise Exception('No prompt for \'text input\' test')
130    u_boot_console.drain_console()
131    # EOT
132    u_boot_console.run_command(cmd=chr(4), wait_for_echo=False,
133                               send_nl=False, wait_for_prompt=False)
134    if u_boot_console.p.expect([r'Unicode char 100 \(\'d\'\), scan code 0 \(CTRL\+Null\)']):
135        raise Exception('EOT failed in \'text input\' test')
136    u_boot_console.drain_console()
137    # BS
138    u_boot_console.run_command(cmd=chr(8), wait_for_echo=False,
139                               send_nl=False, wait_for_prompt=False)
140    if u_boot_console.p.expect([r'Unicode char 8 \(BS\), scan code 0 \(\+Null\)']):
141        raise Exception('BS failed in \'text input\' test')
142    u_boot_console.drain_console()
143    # TAB
144    u_boot_console.run_command(cmd=chr(9), wait_for_echo=False,
145                               send_nl=False, wait_for_prompt=False)
146    if u_boot_console.p.expect([r'Unicode char 9 \(TAB\), scan code 0 \(\+Null\)']):
147        raise Exception('TAB failed in \'text input\' test')
148    u_boot_console.drain_console()
149    # a
150    u_boot_console.run_command(cmd='a', wait_for_echo=False, send_nl=False,
151                               wait_for_prompt=False)
152    if u_boot_console.p.expect([r'Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']):
153        raise Exception('\'a\' failed in \'text input\' test')
154    u_boot_console.drain_console()
155    # UP escape sequence
156    u_boot_console.run_command(cmd=chr(27) + '[A', wait_for_echo=False,
157                               send_nl=False, wait_for_prompt=False)
158    if u_boot_console.p.expect([r'Unicode char 0 \(Null\), scan code 1 \(\+Up\)']):
159        raise Exception('UP failed in \'text input\' test')
160    u_boot_console.drain_console()
161    # Euro sign
162    u_boot_console.run_command(cmd=b'\xe2\x82\xac'.decode(), wait_for_echo=False,
163                               send_nl=False, wait_for_prompt=False)
164    if u_boot_console.p.expect([r'Unicode char 8364 \(\'']):
165        raise Exception('Euro sign failed in \'text input\' test')
166    u_boot_console.drain_console()
167    # SHIFT+ALT+FN 5
168    u_boot_console.run_command(cmd=b'\x1b\x5b\x31\x35\x3b\x34\x7e'.decode(),
169                               wait_for_echo=False, send_nl=False,
170                               wait_for_prompt=False)
171    if u_boot_console.p.expect([r'Unicode char 0 \(Null\), scan code 15 \(SHIFT\+ALT\+FN 5\)']):
172        raise Exception('SHIFT+ALT+FN 5 failed in \'text input\' test')
173    u_boot_console.drain_console()
174    u_boot_console.run_command(cmd=chr(24), wait_for_echo=False, send_nl=False,
175                               wait_for_prompt=False)
176    if u_boot_console.p.expect(['Summary: 0 failures', 'Press any key']):
177        raise Exception('Failures occurred during the EFI selftest')
178    u_boot_console.restart_uboot()
179
180@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
181@pytest.mark.buildconfigspec('efi_tcg2_protocol')
182def test_efi_selftest_tcg2(u_boot_console):
183    """Test the EFI_TCG2 PROTOCOL
184
185    u_boot_console -- U-Boot console
186
187    This function executes the 'tcg2' unit test.
188    """
189    u_boot_console.restart_uboot()
190    u_boot_console.run_command(cmd='setenv efi_selftest list')
191    output = u_boot_console.run_command('bootefi selftest')
192    assert '\'tcg2\'' in output
193    u_boot_console.run_command(cmd='setenv efi_selftest tcg2')
194    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
195    if u_boot_console.p.expect(['Summary: 0 failures', 'Press any key']):
196        raise Exception('Failures occurred during the EFI selftest')
197    u_boot_console.restart_uboot()
198