]> git.proxmox.com Git - pve-edk2-firmware.git/blame - debian/tests/shell.py
debian: update build and packaging from Debian upstream
[pve-edk2-firmware.git] / debian / tests / shell.py
CommitLineData
a65627a8
TL
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
20import enum
21import pexpect
22import subprocess
23import sys
24import unittest
25
26from UEFI.Filesystems import GrubShellBootableIsoImage
27from UEFI.Qemu import QemuEfiMachine, QemuEfiVariant, QemuEfiFlashSize
28from UEFI import Qemu
29
30DPKG_ARCH = subprocess.check_output(
31 ['dpkg', '--print-architecture']
32).decode().rstrip()
33
34
35class 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
257if __name__ == '__main__':
258 unittest.main(verbosity=2)