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:
parent
85617ef888
commit
7455ead93e
|
@ -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'))
|
||||
|
|
@ -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())
|
|
@ -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
|
|
@ -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')
|
||||
|
||||
|
|
Loading…
Reference in New Issue