Add linux boot test in travis (#657)

This patch added test script for Linux boot test in travis for QEMU.

It fixed #656.

Signed-off-by: Maurice Ma <maurice.ma@intel.com>
This commit is contained in:
Maurice Ma 2020-04-12 22:27:12 -07:00 committed by GitHub
parent 85617ef888
commit 7455ead93e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 219 additions and 78 deletions

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
## @ qemu_fwu.py
## @ firmware_update.py
#
# QEMU firmware update test script
# Test firmware update on QEMU
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -14,7 +14,8 @@ import struct
import signal
import subprocess
from threading import Timer
from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
from test_base import *
class FlashMapDesc(Structure):
@ -75,16 +76,17 @@ def get_check_lines (bp = 0, mode = 0):
])
return lines
def check_result (lines):
def check_fwu_result (output):
ret = 0
index = 0
cycle = 1
count = len(lines)
count = len(output)
for bp, mode in [(0, 0x12), (1, 0x12), (0, 0)]:
for line in get_check_lines (bp, mode):
found = False
while not found and index < count:
if line in lines[index]:
if line in output[index]:
found = True
break
else:
@ -93,7 +95,7 @@ def check_result (lines):
index += 1
continue
else:
print ("Failed locatting '%s' in cycke %d !" % (line, cycle))
print ("Failed locating '%s' in cycle %d !" % (line, cycle))
ret = -1
break
if ret < 0:
@ -227,46 +229,6 @@ def handle_ts(bios_image, set_ts_val=0):
return fwu_flg
def run_process (cmd, timeout = 0):
def timerout (p):
timer.cancel()
os.kill(p.pid, signal.SIGTERM)
lines = []
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)
if timeout:
timer = Timer(timeout, timerout, args=[p])
timer.start()
for line in iter(p.stdout.readline, ''):
line = line.rstrip()
print (line)
lines.append (line)
p.stdout.close()
retcode = p.wait()
if timeout:
timer.cancel()
return lines
def run_qemu(bios_img, fwu_path, fwu_mode=False, timeout=0):
if os.name == 'nt':
path = r"C:\Program Files\qemu\qemu-system-x86_64"
else:
path = r"qemu-system-x86_64"
cmd_list = [
path, "-nographic", "-machine", "q35,accel=tcg",
"-serial", "mon:stdio",
"-m", "256M", "-drive",
"id=mydrive,if=none,format=raw,file=fat:rw:%s" % fwu_path, "-device",
"ide-hd,drive=mydrive", "-boot", "order=d%s" % ('an' if fwu_mode else ''),
"-no-reboot", "-drive", "file=%s,if=pflash,format=raw" % bios_img
]
lines = run_process (cmd_list, timeout)
return lines
def usage():
print("usage:\n python %s bios_image fwu_cap_dir\n" % sys.argv[0])
print(" bios_image : QEMU Slim Bootloader firmware image.")
@ -290,6 +252,22 @@ def main():
print("Firmware update for Slim BootLoader")
# create FWU capsule
create_dirs ([fwu_dir])
cmd = [ sys.executable,
'BootloaderCorePkg/Tools/GenCapsuleFirmware.py',
'-p', 'BIOS', bios_img,
'-k', 'BootloaderCorePkg/Tools/Keys/TestSigningPrivateKey.pem',
'-o', '%s/FwuImage.bin' % fwu_dir
]
try:
output = subprocess.run (cmd)
output.check_returncode()
except subprocess.CalledProcessError:
print ('Failed to generate QEMU SlimBootloader capsule image !')
return -3
# run FWU
output = []
fwu_mode = 2
lines = run_qemu(bios_img, fwu_dir, True if fwu_mode != 0 else False)
@ -309,7 +287,7 @@ def main():
output.extend(lines)
# check test result
ret = check_result (output)
ret = check_fwu_result (output)
print ('\nQEMU FWU test %s !\n' % ('PASSED' if ret == 0 else 'FAILED'))

View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
## @ linux_boot.py
#
# Test boot linux on QEMU
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
import os
import sys
import struct
from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
from test_base import *
def get_check_lines ():
lines = [
"===== Intel Slim Bootloader STAGE1A =====",
"===== Intel Slim Bootloader STAGE1B =====",
"===== Intel Slim Bootloader STAGE2 ======",
"Jump to payload",
"Starting Kernel ...",
"Linux version",
"Freeing unused kernel image",
'Welcome to "Minimal Linux"',
]
return lines
def usage():
print("usage:\n python %s bios_image os_image_dir\n" % sys.argv[0])
print(" bios_image : QEMU Slim Bootloader firmware image.")
print(" This image can be generated through the normal Slim Bootloader build process.")
print(" os_image_dir: Directory containing bootable OS image.")
print(" This image can be generated using GenContainer.py tool.")
print("")
def main():
if sys.version_info.major < 3:
print ("This script needs Python3 !")
return -1
if len(sys.argv) != 3:
usage()
return -2
bios_img = sys.argv[1]
os_dir = sys.argv[2]
print("Linux boot test for Slim BootLoader")
# download and unzip OS image
tmp_dir = os.path.dirname(os_dir) + '/temp'
create_dirs ([tmp_dir, os_dir])
local_file = tmp_dir + '/QemuLinux.zip'
download_url (
'https://github.com/slimbootloader/slimbootloader/files/4463548/QemuLinux.zip',
local_file
)
unzip_file (local_file, os_dir)
# run QEMU boot with timeout
output = []
lines = run_qemu(bios_img, os_dir, timeout = 8)
output.extend(lines)
# check test result
ret = check_result (output, get_check_lines())
print ('\nLinux Boot test %s !\n' % ('PASSED' if ret == 0 else 'FAILED'))
return ret
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,95 @@
#!/usr/bin/env python
## @ test_base.py
#
# Provide common functions for test script
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
import os
import sys
import struct
import signal
import subprocess
import zipfile
import urllib.request
from threading import Timer
def unzip_file (zip_file, tgt_dir):
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall (tgt_dir)
def download_url (url, save_path):
urllib.request.urlretrieve (url, save_path)
def create_dirs (dirs):
# create dirs
for dir_name in dirs:
if not os.path.exists(dir_name):
os.mkdir (dir_name)
def run_qemu (bios_img, fwu_path, fwu_mode=False, timeout=0):
if os.name == 'nt':
path = r"C:\Program Files\qemu\qemu-system-x86_64"
else:
path = r"qemu-system-x86_64"
cmd_list = [
path, "-nographic", "-machine", "q35,accel=tcg",
"-cpu", "max", "-serial", "mon:stdio",
"-m", "256M", "-drive",
"id=mydrive,if=none,format=raw,file=fat:rw:%s" % fwu_path, "-device",
"ide-hd,drive=mydrive", "-boot", "order=d%s" % ('an' if fwu_mode else ''),
"-no-reboot", "-drive", "file=%s,if=pflash,format=raw" % bios_img
]
lines = run_process (cmd_list, timeout)
return lines
def run_process (cmd, timeout = 0):
def timerout (p):
timer.cancel()
os.kill(p.pid, signal.SIGTERM)
lines = []
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)
if timeout:
timer = Timer(timeout, timerout, args=[p])
timer.start()
for line in iter(p.stdout.readline, ''):
line = line.rstrip()
print (line)
lines.append (line)
p.stdout.close()
retcode = p.wait()
if timeout:
timer.cancel()
return lines
def check_result (output, check_lines):
ret = 0
index = 0
count = len (output)
for line in check_lines:
found = False
while not found and index < count:
if line in output[index]:
found = True
break
else:
index += 1
if found:
index += 1
continue
else:
print ("Failed locating '%s' !" % (line))
ret = -1
break
return ret

View File

@ -12,48 +12,40 @@ import sys
import shutil
import subprocess
def main():
sbl_img = 'Outputs/qemu/SlimBootloader.bin'
tst_img = 'Outputs/qemu/SblFwuTest.bin'
fwu_dir = 'Outputs/qemu/temp'
tmp_dir = 'Outputs/qemu/temp'
fwu_dir = 'Outputs/qemu/fwu'
img_dir = 'Outputs/qemu/image'
# check QEMU SlimBootloader.bin
if not os.path.exists(sbl_img):
print ('Could not find QEMU SlimBootloader.bin image !')
return -1
# copy a test image so that the original image will not change
shutil.copyfile (sbl_img, tst_img)
# run test cases
test_cases = [
('firmware_update.py', [tst_img, fwu_dir]),
('linux_boot.py' , [tst_img, img_dir])
]
# generate QEMU FWU capsule
if not os.path.exists(fwu_dir):
os.mkdir (fwu_dir)
cmd = [ sys.executable,
'BootloaderCorePkg/Tools/GenCapsuleFirmware.py',
'-p', 'BIOS', tst_img,
'-k', 'BootloaderCorePkg/Tools/Keys/TestSigningPrivateKey.pem',
'-o', '%s/FwuImage.bin' % fwu_dir
]
try:
output = subprocess.run (cmd)
output.check_returncode()
except subprocess.CalledProcessError:
print ('Failed to generate QEMU SlimBootloader capsule image !')
return -2
for test_file, test_args in test_cases:
print ('######### Running run test %s' % test_file)
# copy a test image so that the original image will not change
shutil.copyfile (sbl_img, tst_img)
# run QEMU FWU test
cmd = [ sys.executable,
'Platform/QemuBoardPkg/Script/qemu_fwu.py',
tst_img,
fwu_dir
]
try:
output = subprocess.run (cmd)
output.check_returncode()
except subprocess.CalledProcessError:
print ('Failed to run QEMU firmware update test !')
return -3
# run QEMU test cases
cmd = [ sys.executable, 'Platform/QemuBoardPkg/Script/TestCases/%s' % test_file] + test_args
try:
output = subprocess.run (cmd)
output.check_returncode()
except subprocess.CalledProcessError:
print ('Failed to run test %s !' % test_file)
return -3
print ('######### Completed test %s\n\n' % test_file)
print ('\nAll tests passed !\n')