]> git.proxmox.com Git - pve-edk2-firmware.git/blob - debian/tests/shell.py
debian: update build and packaging from Debian upstream
[pve-edk2-firmware.git] / debian / tests / shell.py
1 #!/usr/bin/env python3
2 #
3 # Copyright 2019-2021 Canonical Ltd.
4 # Authors:
5 # - dann frazier <dann.frazier@canonical.com>
6 #
7 # This program is free software: you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License version 3, as published
9 # by the Free Software Foundation.
10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
13 # SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # this program. If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 import enum
21 import pexpect
22 import subprocess
23 import sys
24 import unittest
25
26 from UEFI.Filesystems import GrubShellBootableIsoImage
27 from UEFI.Qemu import QemuEfiMachine, QemuEfiVariant, QemuEfiFlashSize
28 from UEFI import Qemu
29
30 DPKG_ARCH = subprocess.check_output(
31 ['dpkg', '--print-architecture']
32 ).decode().rstrip()
33
34
35 class BootToShellTest(unittest.TestCase):
36 debug = True
37
38 def run_cmd_check_shell(self, cmd):
39 child = pexpect.spawn(' '.join(cmd))
40
41 if self.debug:
42 child.logfile = sys.stdout.buffer
43 try:
44 while True:
45 i = child.expect(
46 [
47 'Press .* or any other key to continue',
48 'Shell> '
49 ],
50 timeout=60,
51 )
52 if i == 0:
53 child.sendline('\x1b')
54 continue
55 if i == 1:
56 child.sendline('reset -s\r')
57 continue
58 except pexpect.EOF:
59 return
60 except pexpect.TIMEOUT as err:
61 self.fail("%s\n" % (err))
62
63 def run_cmd_check_secure_boot(self, cmd, efiarch, should_verify):
64 class State(enum.Enum):
65 PRE_EXEC = 1
66 POST_EXEC = 2
67
68 child = pexpect.spawn(' '.join(cmd))
69
70 if self.debug:
71 child.logfile = sys.stdout.buffer
72 try:
73 state = State.PRE_EXEC
74 while True:
75 i = child.expect(
76 [
77 'Press .* or any other key to continue',
78 'Shell> ',
79 "FS0:\\\\> ",
80 'grub> ',
81 'Command Error Status: Access Denied',
82 ],
83 timeout=60,
84 )
85 if i == 0:
86 child.sendline('\x1b')
87 continue
88 if i == 1:
89 child.sendline('fs0:\r')
90 continue
91 if i == 2:
92 if state == State.PRE_EXEC:
93 child.sendline(f'\\efi\\boot\\boot{efiarch}.efi\r')
94 state = State.POST_EXEC
95 elif state == State.POST_EXEC:
96 child.sendline('reset -s\r')
97 continue
98 if i == 3:
99 child.sendline('halt\r')
100 verified = True
101 continue
102 if i == 4:
103 verified = False
104 continue
105 except pexpect.TIMEOUT as err:
106 self.fail("%s\n" % (err))
107 except pexpect.EOF:
108 pass
109 self.assertEqual(should_verify, verified)
110
111 def test_aavmf(self):
112 q = Qemu.QemuCommand(QemuEfiMachine.AAVMF)
113 self.run_cmd_check_shell(q.command)
114
115 @unittest.skipUnless(DPKG_ARCH == 'arm64', "Requires grub-efi-arm64")
116 def test_aavmf_ms_secure_boot_signed(self):
117 q = Qemu.QemuCommand(
118 QemuEfiMachine.AAVMF,
119 variant=QemuEfiVariant.MS,
120 )
121 iso = GrubShellBootableIsoImage('AA64', use_signed=True)
122 q.add_disk(iso.path)
123 self.run_cmd_check_secure_boot(q.command, 'aa64', True)
124
125 @unittest.skipUnless(DPKG_ARCH == 'arm64', "Requires grub-efi-arm64")
126 def test_aavmf_ms_secure_boot_unsigned(self):
127 q = Qemu.QemuCommand(
128 QemuEfiMachine.AAVMF,
129 variant=QemuEfiVariant.MS,
130 )
131 iso = GrubShellBootableIsoImage('AA64', use_signed=False)
132 q.add_disk(iso.path)
133 self.run_cmd_check_secure_boot(q.command, 'aa64', False)
134
135 def test_aavmf_snakeoil(self):
136 q = Qemu.QemuCommand(
137 QemuEfiMachine.AAVMF,
138 variant=QemuEfiVariant.SNAKEOIL,
139 )
140 self.run_cmd_check_shell(q.command)
141
142 def test_aavmf32(self):
143 q = Qemu.QemuCommand(QemuEfiMachine.AAVMF32)
144 self.run_cmd_check_shell(q.command)
145
146 def test_ovmf_pc(self):
147 q = Qemu.QemuCommand(
148 QemuEfiMachine.OVMF_PC, flash_size=QemuEfiFlashSize.SIZE_2MB,
149 )
150 self.run_cmd_check_shell(q.command)
151
152 def test_ovmf_q35(self):
153 q = Qemu.QemuCommand(
154 QemuEfiMachine.OVMF_Q35, flash_size=QemuEfiFlashSize.SIZE_2MB,
155 )
156 self.run_cmd_check_shell(q.command)
157
158 def test_ovmf_secboot(self):
159 q = Qemu.QemuCommand(
160 QemuEfiMachine.OVMF_Q35,
161 variant=QemuEfiVariant.SECBOOT,
162 flash_size=QemuEfiFlashSize.SIZE_2MB,
163 )
164 self.run_cmd_check_shell(q.command)
165
166 def test_ovmf_ms(self):
167 q = Qemu.QemuCommand(
168 QemuEfiMachine.OVMF_Q35,
169 variant=QemuEfiVariant.MS,
170 flash_size=QemuEfiFlashSize.SIZE_2MB,
171 )
172 self.run_cmd_check_shell(q.command)
173
174 @unittest.skipUnless(DPKG_ARCH == 'amd64', "amd64-only")
175 def test_ovmf_ms_secure_boot_signed(self):
176 q = Qemu.QemuCommand(
177 QemuEfiMachine.OVMF_Q35,
178 variant=QemuEfiVariant.MS,
179 flash_size=QemuEfiFlashSize.SIZE_2MB,
180 )
181 iso = GrubShellBootableIsoImage('X64', use_signed=True)
182 q.add_disk(iso.path)
183 self.run_cmd_check_secure_boot(q.command, 'x64', True)
184
185 @unittest.skipUnless(DPKG_ARCH == 'amd64', "amd64-only")
186 def test_ovmf_ms_secure_boot_unsigned(self):
187 q = Qemu.QemuCommand(
188 QemuEfiMachine.OVMF_Q35,
189 variant=QemuEfiVariant.MS,
190 flash_size=QemuEfiFlashSize.SIZE_2MB,
191 )
192 iso = GrubShellBootableIsoImage('X64', use_signed=False)
193 q.add_disk(iso.path)
194 self.run_cmd_check_secure_boot(q.command, 'x64', False)
195
196 def test_ovmf_4m(self):
197 q = Qemu.QemuCommand(
198 QemuEfiMachine.OVMF_Q35,
199 flash_size=QemuEfiFlashSize.SIZE_4MB,
200 )
201 self.run_cmd_check_shell(q.command)
202
203 def test_ovmf_4m_secboot(self):
204 q = Qemu.QemuCommand(
205 QemuEfiMachine.OVMF_Q35,
206 variant=QemuEfiVariant.SECBOOT,
207 flash_size=QemuEfiFlashSize.SIZE_4MB,
208 )
209 self.run_cmd_check_shell(q.command)
210
211 def test_ovmf_4m_ms(self):
212 q = Qemu.QemuCommand(
213 QemuEfiMachine.OVMF_Q35,
214 variant=QemuEfiVariant.MS,
215 flash_size=QemuEfiFlashSize.SIZE_4MB,
216 )
217 self.run_cmd_check_shell(q.command)
218
219 def test_ovmf_snakeoil(self):
220 q = Qemu.QemuCommand(
221 QemuEfiMachine.OVMF_Q35,
222 variant=QemuEfiVariant.SNAKEOIL,
223 )
224 self.run_cmd_check_shell(q.command)
225
226 @unittest.skipUnless(DPKG_ARCH == 'amd64', "amd64-only")
227 def test_ovmf_4m_ms_secure_boot_signed(self):
228 q = Qemu.QemuCommand(
229 QemuEfiMachine.OVMF_Q35,
230 variant=QemuEfiVariant.MS,
231 flash_size=QemuEfiFlashSize.SIZE_4MB,
232 )
233 iso = GrubShellBootableIsoImage('X64', use_signed=True)
234 q.add_disk(iso.path)
235 self.run_cmd_check_secure_boot(q.command, 'x64', True)
236
237 @unittest.skipUnless(DPKG_ARCH == 'amd64', "amd64-only")
238 def test_ovmf_4m_ms_secure_boot_unsigned(self):
239 q = Qemu.QemuCommand(
240 QemuEfiMachine.OVMF_Q35,
241 variant=QemuEfiVariant.MS,
242 flash_size=QemuEfiFlashSize.SIZE_4MB,
243 )
244 iso = GrubShellBootableIsoImage('X64', use_signed=False)
245 q.add_disk(iso.path)
246 self.run_cmd_check_secure_boot(q.command, 'x64', False)
247
248 def test_ovmf32_4m_secboot(self):
249 q = Qemu.QemuCommand(
250 QemuEfiMachine.OVMF32,
251 variant=QemuEfiVariant.SECBOOT,
252 flash_size=QemuEfiFlashSize.SIZE_4MB,
253 )
254 self.run_cmd_check_shell(q.command)
255
256
257 if __name__ == '__main__':
258 unittest.main(verbosity=2)