10
# SPDX-License-Identifier: GPL-2.0-or-later
11
12
import shutil
13
-from subprocess import check_call, DEVNULL
13
+import re
14
+from subprocess import check_call, check_output, DEVNULL
15
16
from qemu_test import QemuSystemTest, Asset
17
from qemu_test import get_qemu_img, skipIfMissingCommands
29
failure_message='FAILED',
30
vm=vm)
31
32
+ def append_firmware_blobs(self):
33
+ """
34
+ Setup QEMU firmware blobs for boot.
35
+ """
36
+ code_path = self.build_file('pc-bios', 'edk2-aarch64-code.fd')
37
+ vars_source = self.build_file('pc-bios', 'edk2-arm-vars.fd')
38
+ vars_path = self.scratch_file('vars.fd')
39
+ shutil.copy(vars_source, vars_path)
40
+
41
+ self.vm.add_args('-drive',
42
+ f'if=pflash,format=raw,readonly=on,file={code_path}')
43
+ self.vm.add_args('-drive', f'if=pflash,format=raw,file={vars_path}')
44
+
45
+
46
ASSET_VBSA_EFI = Asset(
47
'https://github.com/ARM-software/sysarch-acs/raw/refs/heads/main'
48
'/prebuilt_images/VBSA/v25.12_VBSA_0.7.0/Vbsa.efi',
60
61
self.vm.set_console()
62
48
- # virt machine wi
63
+ # virt machine
64
self.set_machine('virt')
65
self.vm.add_args('-M', 'virt,gic-version=max,virtualization=on')
66
self.vm.add_args('-cpu', 'max', '-m', '1024')
67
53
- # We will use the QEMU firmware blobs to boot
54
- code_path = self.build_file('pc-bios', 'edk2-aarch64-code.fd')
55
- vars_source = self.build_file('pc-bios', 'edk2-arm-vars.fd')
56
- vars_path = self.scratch_file('vars.fd')
57
- shutil.copy(vars_source, vars_path)
58
-
59
- self.vm.add_args('-drive',
60
- f'if=pflash,format=raw,readonly=on,file={code_path}')
61
- self.vm.add_args('-drive', f'if=pflash,format=raw,file={vars_path}')
68
+ self.append_firmware_blobs()
69
70
# Build an EFI FAT32 file-system for the UEFI tests
71
vbsa_efi = self.ASSET_VBSA_EFI.fetch()
109
self.wait_for_console_pattern('VBSA tests complete. Reset the system.')
110
111
112
+ ASSET_SYSREADY_IMAGE = Asset(
113
+ 'https://github.com/ARM-software/arm-systemready/'
114
+ 'releases/download/v25.10_SR_3.1.0/systemready_acs_live_image.img.xz.zip',
115
+ 'df2c359de15784b1da6a8e6f3c98a053ee38ac0b3f241ccea62e17db092eb03a')
116
+
117
+ ROOT_PROMPT = '/ # '
118
+
119
+ @skipIfMissingCommands("sfdisk", "jq", "sed")
120
+ def test_aarch64_vbsa_linux_tests(self):
121
+ """
122
+ Launch the Linux based VBSA test from the ACS prebuilt images.
123
+
124
+ We can use the pre-built images and then trigger the Linux
125
+ build and run the tests. We then need to slurp the results
126
+ from the partition.
127
+ """
128
+
129
+ self.vm.set_console()
130
+
131
+ # Plain virt machine
132
+ self.set_machine('virt')
133
+ self.vm.add_args('-M', 'virt,gic-version=max')
134
+ self.vm.add_args('-cpu', 'max', '-m', '1024', '-smp', '4')
135
+
136
+ self.append_firmware_blobs()
137
+
138
+ # First fetch, decompress (twice) and prepare the disk image
139
+ # on an NVME device (the kernel only has drivers for that).
140
+ self.archive_extract(self.ASSET_SYSREADY_IMAGE, format="zip")
141
+ disk_image_xz = self.scratch_file("systemready_acs_live_image.img.xz")
142
+ disk_image = self.uncompress(disk_image_xz)
143
+
144
+ self.vm.add_args('-device',
145
+ 'nvme,drive=hd,serial=QEMU_ROOT_SSD')
146
+ self.vm.add_args('-blockdev',
147
+ f'driver=raw,node-name=hd,file.driver=file,file.filename={disk_image}')
148
+
149
+ # Tweak grub.cfg default to avoid manually navigating grub
150
+ grub_cfg = self.scratch_file("grub.cfg")
151
+ offset = int(check_output(f"sfdisk --json {disk_image} |"
152
+ "jq '.partitiontable.partitions[0].start * 512'",
153
+ shell=True))
154
+ check_call(["mcopy", "-i", f"{disk_image}@@{offset}",
155
+ "::/EFI/BOOT/grub.cfg", grub_cfg])
156
+
157
+ with open(grub_cfg, 'a', encoding="utf8") as f:
158
+ f.write("set default='Linux Execution Enviroment'")
159
+
160
+ check_call(["mcopy", "-D", "o", "-i", f"{disk_image}@@{offset}",
161
+ grub_cfg, "::/EFI/BOOT/grub.cfg"])
162
+
163
+ # Launch QEMU and wait for grub and select the "Linux
164
+ # Execution Environment" so we can launch the test.
165
+
166
+ self.vm.launch()
167
+ self.wait_for_console_pattern(self.ROOT_PROMPT)
168
+ ec_and_wait(self, "/usr/bin/bsa.sh --skip "
169
+ "B_REP_1,B_IEP_1,B_PCIe_11,B_MEM_06",
170
+ self.ROOT_PROMPT)
171
+
172
+ # Now we can shutdown
173
+ ec_and_wait(self, "halt -f", "reboot: System halted")
174
+ self.vm.shutdown()
175
+
176
+ # and extract the test logs
177
+ bsa_app_res = self.scratch_file("BsaResultsApp.log")
178
+ bsa_kern_res = self.scratch_file("BsaResultsKernel.log")
179
+
180
+ check_call(["mcopy", "-i", f"{disk_image}@@{offset}",
181
+ "::acs_results/Linux/BsaResultsApp.log", bsa_app_res])
182
+ check_call(["mcopy", "-i", f"{disk_image}@@{offset}",
183
+ "::acs_results/Linux/BsaResultsKernel.log", bsa_kern_res])
184
+
185
+ # for now just check the kernel log for the result summary
186
+ test_result_re = re.compile(r"\[.*\]\s+(.+): Result:\s+(\w+)")
187
+ summary_re = re.compile(r"Total Tests Run =\s*(\d+), Tests Passed =\s*(\d+), Tests Failed =\s*(\d+)")
188
+
189
+ with open(bsa_kern_res, 'r', encoding="utf8") as f:
190
+ for line in f:
191
+ test_match = test_result_re.search(line)
192
+ if test_match:
193
+ desc = test_match.group(1)
194
+ status = test_match.group(2)
195
+ self.log.info(f"Test: {desc} status: {status}")
196
+
197
+ match = summary_re.search(line)
198
+ if match:
199
+ total, passed, failed = match.groups()
200
+
201
+ if int(failed) > 0:
202
+ self.fail(f"{failed} tests failed ({total})")
203
+
204
+
205
if __name__ == '__main__':
206
QemuSystemTest.main()