Merge branch 'makea' into 'master'
test: Move towards using a fixture for test images See merge request u-boot/u-boot!152
This commit is contained in:
@@ -115,6 +115,7 @@ static int check_abrec_norun(struct unit_test_state *uts, bool use_oem,
|
||||
root = oftree_root(tree);
|
||||
|
||||
ut_asserteq_str("snow", ofnode_read_string(root, "compatible"));
|
||||
bootflow_free(&bflow);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class ConsoleSandbox(ConsoleBase):
|
||||
Returns:
|
||||
A spawn.Spawn object that is attached to U-Boot.
|
||||
"""
|
||||
super().get_spawn()
|
||||
self.prepare_for_spawn()
|
||||
bcfg = self.config.buildconfig
|
||||
config_spl = bcfg.get('config_spl', 'n') == 'y'
|
||||
config_vpl = bcfg.get('config_vpl', 'n') == 'y'
|
||||
|
||||
@@ -7,20 +7,18 @@
|
||||
|
||||
import gzip
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import utils
|
||||
from fs_helper import DiskHelper, FsHelper
|
||||
from dtoc import fdt_util
|
||||
from u_boot_pylib import tools
|
||||
|
||||
|
||||
def dtb_for_compatible(ubman, kernpath, version, model):
|
||||
def dtb_for_compatible(log, kernpath, version, model):
|
||||
"""Create a fake devicetree binary for a given model name
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): U-Boot fixture
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
kernpath (str): Path to place the created DTB
|
||||
version (str): Version string to use with the dtb
|
||||
model (str): Model name
|
||||
@@ -30,15 +28,17 @@ def dtb_for_compatible(ubman, kernpath, version, model):
|
||||
"""
|
||||
dtb_file = os.path.join(kernpath, f'dtb-{version}-{model}')
|
||||
data = f'/dts-v1/; / {{ compatible = "{model}"; version = "{version}"; }};'
|
||||
utils.run_and_log(ubman, f'dtc -o {dtb_file}', stdin=data.encode('utf-8'))
|
||||
utils.run_and_log_no_ubman(log, f'dtc -o {dtb_file}',
|
||||
stdin=data.encode('utf-8'))
|
||||
return dtb_file
|
||||
|
||||
|
||||
def create_extlinux(ubman, kernpath, dirpath, slot, version, has_oem):
|
||||
def create_extlinux(config, log, kernpath, dirpath, slot, version, has_oem):
|
||||
"""Create a fake extlinux image
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): U-Boot fixture
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
kernpath (str): Directory path for the kernel
|
||||
dirpath (str): Directory path to write to (created by this function)
|
||||
slot (str): Slot name (A, B or recovery)
|
||||
@@ -80,33 +80,38 @@ label l0
|
||||
with tempfile.TemporaryDirectory(suffix='vbe') as tmp:
|
||||
kern = os.path.join(tmp, 'kern')
|
||||
tools.write_file(kern, gzip.compress(f'vmlinux-{slot}'.encode('utf-8')))
|
||||
mkimage = ubman.config.build_dir + '/tools/mkimage'
|
||||
mkimage = config.build_dir + '/tools/mkimage'
|
||||
|
||||
initrd = os.path.join(tmp, f'initrd.img-{version}')
|
||||
tools.write_file(initrd, f'initrd {version}', binary=False)
|
||||
|
||||
snow = dtb_for_compatible(ubman, tmp, version, 'snow')
|
||||
kevin = dtb_for_compatible(ubman, tmp, version, 'kevin')
|
||||
snow = dtb_for_compatible(log, tmp, version, 'snow')
|
||||
kevin = dtb_for_compatible(log, tmp, version, 'kevin')
|
||||
|
||||
fit = os.path.join(kernpath, f'ubuntu-{version}.fit')
|
||||
cmd = f'{mkimage} -f auto -T kernel -A sandbox -O linux '
|
||||
dts = f'-b {snow} -b {kevin}' if add_dts else ''
|
||||
utils.run_and_log(ubman, cmd + f'-d {kern} -i {initrd} {dts} {fit}')
|
||||
utils.run_and_log_no_ubman(log,
|
||||
cmd + f'-d {kern} -i {initrd} {dts} {fit}')
|
||||
|
||||
# Create a FIT containing OEM devicetrees
|
||||
if has_oem:
|
||||
oem_snow = dtb_for_compatible(ubman, tmp, 'oem', 'snow')
|
||||
oem_kevin = dtb_for_compatible(ubman, tmp, 'oem', 'kevin')
|
||||
oem_snow = dtb_for_compatible(log, tmp, 'oem', 'snow')
|
||||
oem_kevin = dtb_for_compatible(log, tmp, 'oem', 'kevin')
|
||||
|
||||
fit = os.path.join(dirpath, 'oem.fit')
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
f'{mkimage} -f auto -A sandbox -O linux -T flat_dt --load-only'
|
||||
f' -b {oem_snow} -b {oem_kevin} {fit}')
|
||||
|
||||
def setup_vbe_image(ubman):
|
||||
def setup_vbe_image(config, log):
|
||||
"""Create three partitions (fat, boot and root) for a VBE boot flow
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
|
||||
The intent is to load either one or two FITs.
|
||||
|
||||
Two separate images are created:
|
||||
@@ -115,10 +120,10 @@ def setup_vbe_image(ubman):
|
||||
- vbe1 has an OEM FIT containing the devicetrees; OS FIT does not
|
||||
"""
|
||||
for seq in range(2):
|
||||
with (DiskHelper(ubman.config, seq, 'vbe') as img,
|
||||
FsHelper(ubman.config, 'fat', 1, 'efi') as vfat,
|
||||
FsHelper(ubman.config, 'ext4', 1, f'boot{seq}') as boot,
|
||||
FsHelper(ubman.config, 'ext4', 17, 'root') as root):
|
||||
with (DiskHelper(config, seq, 'vbe') as img,
|
||||
FsHelper(config, 'fat', 1, 'efi') as vfat,
|
||||
FsHelper(config, 'ext4', 1, f'boot{seq}') as boot,
|
||||
FsHelper(config, 'ext4', 17, 'root') as root):
|
||||
with open(os.path.join(vfat.srcdir, 'u-boot.efi'), 'wb') as outf:
|
||||
outf.write(b'fake binary\n')
|
||||
vfat.mk_fs()
|
||||
@@ -128,14 +133,14 @@ def setup_vbe_image(ubman):
|
||||
|
||||
dir_a = os.path.join(boot.srcdir, 'a')
|
||||
vera = '6.14.0-24-generic'
|
||||
create_extlinux(ubman, boot.srcdir, dir_a, 'A', vera, has_oem)
|
||||
create_extlinux(config, log, boot.srcdir, dir_a, 'A', vera, has_oem)
|
||||
|
||||
dir_b = os.path.join(boot.srcdir, 'b')
|
||||
verb = '6.8.0-1028-intel'
|
||||
create_extlinux(ubman, boot.srcdir, dir_b, 'B', verb, has_oem)
|
||||
create_extlinux(config, log, boot.srcdir, dir_b, 'B', verb, has_oem)
|
||||
|
||||
boot_slot = 'b' if seq else 'a'
|
||||
fname = os.path.join(ubman.config.result_dir, 'vbe-state.dts')
|
||||
fname = os.path.join(config.result_dir, 'vbe-state.dts')
|
||||
tools.write_file(fname, b'''// VBE state file
|
||||
|
||||
/dts-v1/;
|
||||
@@ -153,9 +158,9 @@ def setup_vbe_image(ubman):
|
||||
};
|
||||
'''.replace(b'boot_slot', boot_slot.encode('utf-8')))
|
||||
|
||||
dtb = fdt_util.EnsureCompiled(fname, ubman.config.result_dir)
|
||||
print('dtb', dtb)
|
||||
shutil.copy(dtb, f'{boot.srcdir}/vbe-state')
|
||||
utils.run_and_log_no_ubman(
|
||||
log, ['dtc', fname, '-O', 'dtb', '-o',
|
||||
f'{boot.srcdir}/vbe-state'])
|
||||
|
||||
boot.mk_fs()
|
||||
img.add_fs(boot, DiskHelper.EXT4)
|
||||
|
||||
@@ -102,43 +102,43 @@ dtb1_addr = loadaddr + dtb1_offset
|
||||
# DTB #2 start address in RAM
|
||||
dtb2_addr = vloadaddr + dtb2_offset
|
||||
|
||||
class AbootimgTestDiskImage(object):
|
||||
class AbootimgTestDiskImage():
|
||||
"""Disk image used by abootimg tests."""
|
||||
|
||||
def __init__(self, ubman, image_name, hex_img):
|
||||
def __init__(self, config, log, image_name, hex_img):
|
||||
"""Initialize a new AbootimgDiskImage object.
|
||||
|
||||
Args:
|
||||
ubman: A U-Boot console.
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
gz_hex = ubman.config.persistent_data_dir + '/' + image_name + '.gz.hex'
|
||||
gz = ubman.config.persistent_data_dir + '/' + image_name + '.gz'
|
||||
gz_hex = config.persistent_data_dir + '/' + image_name + '.gz.hex'
|
||||
gz = config.persistent_data_dir + '/' + image_name + '.gz'
|
||||
|
||||
filename = image_name
|
||||
persistent = ubman.config.persistent_data_dir + '/' + filename
|
||||
self.path = ubman.config.result_dir + '/' + filename
|
||||
ubman.log.action('persistent is ' + persistent)
|
||||
with utils.persistent_file_helper(ubman.log, persistent):
|
||||
persistent = config.persistent_data_dir + '/' + filename
|
||||
self.path = config.result_dir + '/' + filename
|
||||
log.action('persistent is ' + persistent)
|
||||
with utils.persistent_file_helper(log, persistent):
|
||||
if os.path.exists(persistent):
|
||||
ubman.log.action('Disk image file ' + persistent +
|
||||
log.action('Disk image file ' + persistent +
|
||||
' already exists')
|
||||
else:
|
||||
ubman.log.action('Generating ' + persistent)
|
||||
log.action('Generating ' + persistent)
|
||||
|
||||
f = open(gz_hex, "w")
|
||||
f.write(hex_img)
|
||||
f.close()
|
||||
cmd = ('xxd', '-r', '-p', gz_hex, gz)
|
||||
utils.run_and_log(ubman, cmd)
|
||||
utils.run_and_log_no_ubman(log, cmd)
|
||||
cmd = ('gunzip', '-9', gz)
|
||||
utils.run_and_log(ubman, cmd)
|
||||
utils.run_and_log_no_ubman(log, cmd)
|
||||
|
||||
cmd = ('cp', persistent, self.path)
|
||||
utils.run_and_log(ubman, cmd)
|
||||
utils.run_and_log_no_ubman(log, cmd)
|
||||
|
||||
gtdi1 = None
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -150,7 +150,8 @@ def abootimg_disk_image(ubman):
|
||||
|
||||
global gtdi1
|
||||
if not gtdi1:
|
||||
gtdi1 = AbootimgTestDiskImage(ubman, 'boot.img', img_hex)
|
||||
gtdi1 = AbootimgTestDiskImage(ubman.config, ubman.log, 'boot.img',
|
||||
img_hex)
|
||||
return gtdi1
|
||||
|
||||
gtdi2 = None
|
||||
@@ -163,7 +164,8 @@ def abootimgv4_disk_image_vboot(ubman):
|
||||
|
||||
global gtdi2
|
||||
if not gtdi2:
|
||||
gtdi2 = AbootimgTestDiskImage(ubman, 'vendor_boot.img', vboot_img_hex)
|
||||
gtdi2 = AbootimgTestDiskImage(ubman.config, ubman.log,
|
||||
'vendor_boot.img', vboot_img_hex)
|
||||
return gtdi2
|
||||
|
||||
gtdi3 = None
|
||||
@@ -176,7 +178,8 @@ def abootimgv4_disk_image_boot(ubman):
|
||||
|
||||
global gtdi3
|
||||
if not gtdi3:
|
||||
gtdi3 = AbootimgTestDiskImage(ubman, 'bootv4.img', boot_img_hex)
|
||||
gtdi3 = AbootimgTestDiskImage(ubman.config, ubman.log, 'bootv4.img',
|
||||
boot_img_hex)
|
||||
return gtdi3
|
||||
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
|
||||
@@ -19,6 +19,7 @@ env__sleep_margin = 0.25
|
||||
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_sleep(ubman):
|
||||
"""Test the sleep command, and validate that it sleeps for approximately
|
||||
the correct amount of time."""
|
||||
@@ -43,6 +44,7 @@ def test_sleep(ubman):
|
||||
assert elapsed < (sleep_time + sleep_margin)
|
||||
|
||||
@pytest.mark.buildconfigspec("cmd_time")
|
||||
@pytest.mark.slow
|
||||
def test_time(ubman):
|
||||
"""Test the time command, and validate that it gives approximately the
|
||||
correct amount of command execution time."""
|
||||
|
||||
@@ -39,10 +39,14 @@ def copy_partition(ubman, fsfile, outname):
|
||||
utils.run_and_log(ubman,
|
||||
f'dd if={fsfile} of={outname} bs=1M seek=1 conv=notrunc')
|
||||
|
||||
def setup_bootmenu_image(ubman):
|
||||
def setup_bootmenu_image(config, log):
|
||||
"""Create a 20MB disk image with a single ext4 partition
|
||||
|
||||
This is modelled on Armbian 22.08 Jammy
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
mmc_dev = 4
|
||||
|
||||
@@ -120,7 +124,7 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
|
||||
# Recompile with:
|
||||
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
|
||||
'''
|
||||
fsh = FsHelper(ubman.config, 'ext4', 18, 'mmc')
|
||||
fsh = FsHelper(config, 'ext4', 18, 'mmc')
|
||||
fsh.setup()
|
||||
bootdir = os.path.join(fsh.srcdir, 'boot')
|
||||
mkdir_cond(bootdir)
|
||||
@@ -129,16 +133,16 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
|
||||
with open(cmd_fname, 'w', encoding='ascii') as outf:
|
||||
print(script, file=outf)
|
||||
|
||||
infname = os.path.join(ubman.config.source_dir,
|
||||
infname = os.path.join(config.source_dir,
|
||||
'test/py/tests/bootstd/armbian.bmp.xz')
|
||||
bmp_file = os.path.join(bootdir, 'boot.bmp')
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
['sh', '-c', f'xz -dc {infname} >{bmp_file}'])
|
||||
|
||||
mkimage = ubman.config.build_dir + '/tools/mkimage'
|
||||
utils.run_and_log(
|
||||
ubman, f'{mkimage} -C none -A arm -T script -d {cmd_fname} {scr_fname}')
|
||||
mkimage = config.build_dir + '/tools/mkimage'
|
||||
utils.run_and_log_no_ubman(
|
||||
log, f'{mkimage} -C none -A arm -T script -d {cmd_fname} {scr_fname}')
|
||||
|
||||
kernel = 'vmlinuz-5.15.63-rockchip64'
|
||||
target = os.path.join(bootdir, kernel)
|
||||
@@ -148,22 +152,22 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
|
||||
symlink = os.path.join(bootdir, 'Image')
|
||||
if os.path.exists(symlink):
|
||||
os.remove(symlink)
|
||||
utils.run_and_log(
|
||||
ubman, f'echo here {kernel} {symlink}')
|
||||
utils.run_and_log_no_ubman(log, f'echo here {kernel} {symlink}')
|
||||
os.symlink(kernel, symlink)
|
||||
fsh.mk_fs()
|
||||
img = DiskHelper(ubman.config, mmc_dev, 'mmc', True)
|
||||
img = DiskHelper(config, mmc_dev, 'mmc', True)
|
||||
img.add_fs(fsh, DiskHelper.EXT4)
|
||||
img.create()
|
||||
fsh.cleanup()
|
||||
|
||||
|
||||
def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
def setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
script):
|
||||
"""Create a 20MB disk image with a single FAT partition
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): Console to use
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
devnum (int): Device number to use, e.g. 1
|
||||
basename (str): Base name to use in the filename, e.g. 'mmc'
|
||||
vmlinux (str): Kernel filename
|
||||
@@ -171,7 +175,7 @@ def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
dtbdir (str or None): Devicetree filename
|
||||
script (str): Script to place in the extlinux.conf file
|
||||
"""
|
||||
fsh = FsHelper(ubman.config, 'vfat', 18, prefix=basename)
|
||||
fsh = FsHelper(config, 'vfat', 18, prefix=basename)
|
||||
fsh.setup()
|
||||
|
||||
ext = os.path.join(fsh.srcdir, 'extlinux')
|
||||
@@ -181,12 +185,12 @@ def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
with open(conf, 'w', encoding='ascii') as fd:
|
||||
print(script, file=fd)
|
||||
|
||||
inf = os.path.join(ubman.config.persistent_data_dir, 'inf')
|
||||
inf = os.path.join(config.persistent_data_dir, 'inf')
|
||||
with open(inf, 'wb') as fd:
|
||||
fd.write(gzip.compress(b'vmlinux'))
|
||||
mkimage = ubman.config.build_dir + '/tools/mkimage'
|
||||
utils.run_and_log(
|
||||
ubman, f'{mkimage} -f auto -d {inf} {os.path.join(fsh.srcdir, vmlinux)}')
|
||||
mkimage = config.build_dir + '/tools/mkimage'
|
||||
utils.run_and_log_no_ubman(
|
||||
log, f'{mkimage} -f auto -d {inf} {os.path.join(fsh.srcdir, vmlinux)}')
|
||||
|
||||
with open(os.path.join(fsh.srcdir, initrd), 'w', encoding='ascii') as fd:
|
||||
print('initrd', file=fd)
|
||||
@@ -195,15 +199,15 @@ def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
mkdir_cond(os.path.join(fsh.srcdir, dtbdir))
|
||||
|
||||
dtb_file = os.path.join(fsh.srcdir, f'{dtbdir}/sandbox.dtb')
|
||||
utils.run_and_log(
|
||||
ubman, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
|
||||
utils.run_and_log_no_ubman(
|
||||
log, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
|
||||
|
||||
fsh.mk_fs()
|
||||
|
||||
img = DiskHelper(ubman.config, devnum, basename, True)
|
||||
img = DiskHelper(config, devnum, basename, True)
|
||||
img.add_fs(fsh, DiskHelper.VFAT, bootable=True)
|
||||
|
||||
ext4 = FsHelper(ubman.config, 'ext4', 1, prefix=basename)
|
||||
ext4 = FsHelper(config, 'ext4', 1, prefix=basename)
|
||||
ext4.setup()
|
||||
ext4.mk_fs()
|
||||
|
||||
@@ -211,11 +215,12 @@ def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
img.create()
|
||||
fsh.cleanup()
|
||||
|
||||
def setup_fedora_image(ubman, devnum, basename):
|
||||
def setup_fedora_image(config, log, devnum, basename):
|
||||
"""Create a 20MB Fedora disk image with a single FAT partition
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): Console to use
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
devnum (int): Device number to use, e.g. 1
|
||||
basename (str): Base name to use in the filename, e.g. 'mmc'
|
||||
"""
|
||||
@@ -235,14 +240,15 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
|
||||
append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
|
||||
fdtdir /%s/
|
||||
initrd /%s''' % (vmlinux, dtbdir, initrd)
|
||||
setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
script)
|
||||
setup_extlinux_image(config, log, devnum, basename, vmlinux,
|
||||
initrd, dtbdir, script)
|
||||
|
||||
def setup_ubuntu_image(ubman, devnum, basename):
|
||||
def setup_ubuntu_image(config, log, devnum, basename):
|
||||
"""Create a 20MB Ubuntu disk image with a single FAT partition
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): Console to use
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
devnum (int): Device number to use, e.g. 1
|
||||
basename (str): Base name to use in the filename, e.g. 'mmc'
|
||||
"""
|
||||
@@ -274,20 +280,26 @@ label l0r
|
||||
linux /boot/%s
|
||||
initrd /boot/%s
|
||||
''' % (vmlinux, initrd, vmlinux, initrd)
|
||||
setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir,
|
||||
script)
|
||||
|
||||
def setup_cros_image(ubman):
|
||||
"""Create a 20MB disk image with ChromiumOS partitions"""
|
||||
def setup_cros_image(config, log):
|
||||
"""Create a 20MB disk image with ChromiumOS partitions
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
Partition = collections.namedtuple('part', 'start,size,name')
|
||||
parts = {}
|
||||
disk_data = None
|
||||
|
||||
def pack_kernel(ubman, arch, kern, dummy):
|
||||
def pack_kernel(config, log, arch, kern, dummy):
|
||||
"""Pack a kernel containing some fake data
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): Console to use
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
arch (str): Architecture to use ('x86' or 'arm')
|
||||
kern (str): Filename containing kernel
|
||||
dummy (str): Dummy filename to use for config and bootloader
|
||||
@@ -295,10 +307,9 @@ def setup_cros_image(ubman):
|
||||
Return:
|
||||
bytes: Packed-kernel data
|
||||
"""
|
||||
kern_part = os.path.join(ubman.config.result_dir,
|
||||
f'kern-part-{arch}.bin')
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
kern_part = os.path.join(config.result_dir, f'kern-part-{arch}.bin')
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
f'futility vbutil_kernel --pack {kern_part} '
|
||||
'--keyblock doc/chromium/files/devkeys/kernel.keyblock '
|
||||
'--signprivate doc/chromium/files/devkeys/kernel_data_key.vbprivk '
|
||||
@@ -324,9 +335,9 @@ def setup_cros_image(ubman):
|
||||
disk_data = disk_data[:start] + data + disk_data[start + len(data):]
|
||||
|
||||
mmc_dev = 5
|
||||
fname = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log(ubman, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log(ubman, f'cgpt create {fname}')
|
||||
fname = os.path.join(config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log_no_ubman(log, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt create {fname}')
|
||||
|
||||
uuid_state = 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7'
|
||||
uuid_kern = 'fe3a2a5d-4f32-41a7-b725-accc3285a309'
|
||||
@@ -365,13 +376,13 @@ def setup_cros_image(ubman):
|
||||
size = int(size_str[:-1]) * sect_1mb
|
||||
else:
|
||||
size = int(size_str)
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
f"cgpt add -i {part['num']} -b {ptr} -s {size} -t {part['type']} {fname}")
|
||||
ptr += size
|
||||
|
||||
utils.run_and_log(ubman, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log(ubman, f'cgpt show -q {fname}')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log_no_ubman(log, f'cgpt show -q {fname}')
|
||||
|
||||
# We expect something like this:
|
||||
# 8239 2048 1 Basic data
|
||||
@@ -393,14 +404,14 @@ def setup_cros_image(ubman):
|
||||
parts[int(num)] = Partition(int(start), int(size), name)
|
||||
|
||||
# Set up the kernel command-line
|
||||
dummy = os.path.join(ubman.config.result_dir, 'dummy.txt')
|
||||
dummy = os.path.join(config.result_dir, 'dummy.txt')
|
||||
with open(dummy, 'wb') as outf:
|
||||
outf.write(b'BOOT_IMAGE=/vmlinuz-5.15.0-121-generic root=/dev/nvme0n1p1 ro quiet splash vt.handoff=7')
|
||||
|
||||
# For now we just use dummy kernels. This limits testing to just detecting
|
||||
# a signed kernel. We could add support for the x86 data structures so that
|
||||
# testing could cover getting the cmdline, setup.bin and other pieces.
|
||||
kern = os.path.join(ubman.config.result_dir, 'kern.bin')
|
||||
kern = os.path.join(config.result_dir, 'kern.bin')
|
||||
with open(kern, 'wb') as outf:
|
||||
outf.write(b'kernel\n')
|
||||
|
||||
@@ -408,16 +419,21 @@ def setup_cros_image(ubman):
|
||||
disk_data = inf.read()
|
||||
|
||||
# put x86 kernel in partition 2 and arm one in partition 4
|
||||
set_part_data(2, pack_kernel(ubman, 'x86', kern, dummy))
|
||||
set_part_data(4, pack_kernel(ubman, 'arm', kern, dummy))
|
||||
set_part_data(2, pack_kernel(config, log, 'x86', kern, dummy))
|
||||
set_part_data(4, pack_kernel(config, log, 'arm', kern, dummy))
|
||||
|
||||
with open(fname, 'wb') as outf:
|
||||
outf.write(disk_data)
|
||||
|
||||
return fname
|
||||
|
||||
def setup_android_image(ubman):
|
||||
"""Create a 20MB disk image with Android partitions"""
|
||||
def setup_android_image(config, log):
|
||||
"""Create a 20MB disk image with Android partitions
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
Partition = collections.namedtuple('part', 'start,size,name')
|
||||
parts = {}
|
||||
disk_data = None
|
||||
@@ -437,9 +453,9 @@ def setup_android_image(ubman):
|
||||
disk_data = disk_data[:start] + data + disk_data[start + len(data):]
|
||||
|
||||
mmc_dev = 7
|
||||
fname = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log(ubman, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log(ubman, f'cgpt create {fname}')
|
||||
fname = os.path.join(config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log_no_ubman(log, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt create {fname}')
|
||||
|
||||
ptr = 40
|
||||
|
||||
@@ -461,13 +477,13 @@ def setup_android_image(ubman):
|
||||
size = int(size_str[:-1]) * sect_1mb
|
||||
else:
|
||||
size = int(size_str)
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
f"cgpt add -i {part['num']} -b {ptr} -s {size} -l {part['label']} -t basicdata {fname}")
|
||||
ptr += size
|
||||
|
||||
utils.run_and_log(ubman, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log(ubman, f'cgpt show -q {fname}')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log_no_ubman(log, f'cgpt show -q {fname}')
|
||||
|
||||
# Create a dict (indexed by partition number) containing the above info
|
||||
for line in out.splitlines():
|
||||
@@ -477,13 +493,15 @@ def setup_android_image(ubman):
|
||||
with open(fname, 'rb') as inf:
|
||||
disk_data = inf.read()
|
||||
|
||||
test_abootimg.AbootimgTestDiskImage(ubman, 'bootv4.img', test_abootimg.boot_img_hex)
|
||||
boot_img = os.path.join(ubman.config.result_dir, 'bootv4.img')
|
||||
test_abootimg.AbootimgTestDiskImage(config, log, 'bootv4.img',
|
||||
test_abootimg.boot_img_hex)
|
||||
boot_img = os.path.join(config.result_dir, 'bootv4.img')
|
||||
with open(boot_img, 'rb') as inf:
|
||||
set_part_data(2, inf.read())
|
||||
|
||||
test_abootimg.AbootimgTestDiskImage(ubman, 'vendor_boot.img', test_abootimg.vboot_img_hex)
|
||||
vendor_boot_img = os.path.join(ubman.config.result_dir, 'vendor_boot.img')
|
||||
test_abootimg.AbootimgTestDiskImage(config, log, 'vendor_boot.img',
|
||||
test_abootimg.vboot_img_hex)
|
||||
vendor_boot_img = os.path.join(config.result_dir, 'vendor_boot.img')
|
||||
with open(vendor_boot_img, 'rb') as inf:
|
||||
set_part_data(4, inf.read())
|
||||
|
||||
@@ -493,9 +511,9 @@ def setup_android_image(ubman):
|
||||
print(f'wrote to {fname}')
|
||||
|
||||
mmc_dev = 8
|
||||
fname = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log(ubman, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log(ubman, f'cgpt create {fname}')
|
||||
fname = os.path.join(config.source_dir, f'mmc{mmc_dev}.img')
|
||||
utils.run_and_log_no_ubman(log, f'qemu-img create {fname} 20M')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt create {fname}')
|
||||
|
||||
ptr = 40
|
||||
|
||||
@@ -515,13 +533,13 @@ def setup_android_image(ubman):
|
||||
size = int(size_str[:-1]) * sect_1mb
|
||||
else:
|
||||
size = int(size_str)
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
utils.run_and_log_no_ubman(
|
||||
log,
|
||||
f"cgpt add -i {part['num']} -b {ptr} -s {size} -l {part['label']} -t basicdata {fname}")
|
||||
ptr += size
|
||||
|
||||
utils.run_and_log(ubman, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log(ubman, f'cgpt show -q {fname}')
|
||||
utils.run_and_log_no_ubman(log, f'cgpt boot -p {fname}')
|
||||
out = utils.run_and_log_no_ubman(log, f'cgpt show -q {fname}')
|
||||
|
||||
# Create a dict (indexed by partition number) containing the above info
|
||||
for line in out.splitlines():
|
||||
@@ -531,8 +549,9 @@ def setup_android_image(ubman):
|
||||
with open(fname, 'rb') as inf:
|
||||
disk_data = inf.read()
|
||||
|
||||
test_abootimg.AbootimgTestDiskImage(ubman, 'boot.img', test_abootimg.img_hex)
|
||||
boot_img = os.path.join(ubman.config.result_dir, 'boot.img')
|
||||
test_abootimg.AbootimgTestDiskImage(config, log, 'boot.img',
|
||||
test_abootimg.img_hex)
|
||||
boot_img = os.path.join(config.result_dir, 'boot.img')
|
||||
with open(boot_img, 'rb') as inf:
|
||||
set_part_data(2, inf.read())
|
||||
|
||||
@@ -543,16 +562,21 @@ def setup_android_image(ubman):
|
||||
|
||||
return fname
|
||||
|
||||
def setup_cedit_file(ubman):
|
||||
"""Set up a .dtb file for use with testing expo and configuration editor"""
|
||||
infname = os.path.join(ubman.config.source_dir,
|
||||
def setup_cedit_file(config, log):
|
||||
"""Set up a .dtb file for use with testing expo and configuration editor
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
infname = os.path.join(config.source_dir,
|
||||
'test/boot/files/expo_layout.dts')
|
||||
inhname = os.path.join(ubman.config.source_dir,
|
||||
inhname = os.path.join(config.source_dir,
|
||||
'test/boot/files/expo_ids.h')
|
||||
expo_tool = os.path.join(ubman.config.source_dir, 'tools/expo.py')
|
||||
expo_tool = os.path.join(config.source_dir, 'tools/expo.py')
|
||||
outfname = 'cedit.dtb'
|
||||
utils.run_and_log(
|
||||
ubman, f'{expo_tool} -e {inhname} -l {infname} -o {outfname}')
|
||||
utils.run_and_log_no_ubman(
|
||||
log, f'{expo_tool} -e {inhname} -l {infname} -o {outfname}')
|
||||
|
||||
@pytest.mark.buildconfigspec('ut_dm')
|
||||
def test_ut_dm_init(ubman):
|
||||
@@ -590,16 +614,20 @@ def test_ut_dm_init(ubman):
|
||||
fh.write(data)
|
||||
|
||||
|
||||
def setup_efi_image(ubman):
|
||||
"""Create a 20MB disk image with an EFI app on it"""
|
||||
def setup_efi_image(config):
|
||||
"""Create a 20MB disk image with an EFI app on it
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
"""
|
||||
devnum = 1
|
||||
fsh = FsHelper(ubman.config, 'vfat', 18, 'flash')
|
||||
fsh = FsHelper(config, 'vfat', 18, 'flash')
|
||||
fsh.setup()
|
||||
efi_dir = os.path.join(fsh.srcdir, 'EFI')
|
||||
mkdir_cond(efi_dir)
|
||||
bootdir = os.path.join(efi_dir, 'BOOT')
|
||||
mkdir_cond(bootdir)
|
||||
efi_src = os.path.join(ubman.config.build_dir,
|
||||
efi_src = os.path.join(config.build_dir,
|
||||
'lib/efi_loader/testapp.efi')
|
||||
efi_dst = os.path.join(bootdir, 'BOOTSBOX.EFI')
|
||||
with open(efi_src, 'rb') as inf:
|
||||
@@ -608,14 +636,19 @@ def setup_efi_image(ubman):
|
||||
|
||||
fsh.mk_fs()
|
||||
|
||||
img = DiskHelper(ubman.config, devnum, 'flash', True)
|
||||
img = DiskHelper(config, devnum, 'flash', True)
|
||||
img.add_fs(fsh, DiskHelper.VFAT)
|
||||
img.create()
|
||||
fsh.cleanup()
|
||||
|
||||
|
||||
def setup_localboot_image(cons):
|
||||
"""Create a 20MB disk image with a single FAT partition"""
|
||||
def setup_localboot_image(config, log):
|
||||
"""Create a 20MB disk image with a single FAT partition
|
||||
|
||||
Args:
|
||||
config (ArbitraryAttributeContainer): Configuration
|
||||
log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
mmc_dev = 9
|
||||
|
||||
script = '''DEFAULT local
|
||||
@@ -626,27 +659,28 @@ LABEL local
|
||||
'''
|
||||
vmlinux = 'vmlinuz'
|
||||
initrd = 'initrd.img'
|
||||
setup_extlinux_image(cons, mmc_dev, 'mmc', vmlinux, initrd, None, script)
|
||||
setup_extlinux_image(config, log, mmc_dev, 'mmc', vmlinux, initrd, None,
|
||||
script)
|
||||
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_bootflow')
|
||||
@pytest.mark.buildconfigspec('sandbox')
|
||||
def test_ut_dm_init_bootstd(ubman):
|
||||
"""Initialise data for bootflow tests"""
|
||||
|
||||
setup_fedora_image(ubman, 1, 'mmc')
|
||||
setup_bootmenu_image(ubman)
|
||||
setup_cedit_file(ubman)
|
||||
setup_cros_image(ubman)
|
||||
setup_android_image(ubman)
|
||||
setup_efi_image(ubman)
|
||||
setup_ubuntu_image(ubman, 3, 'flash')
|
||||
setup_localboot_image(ubman)
|
||||
setup_vbe_image(ubman)
|
||||
|
||||
# Restart so that the new mmc1.img is picked up
|
||||
ubman.restart_uboot()
|
||||
def test_ut_dm_init_bootstd(u_boot_config, u_boot_log):
|
||||
"""Initialise data for bootflow tests
|
||||
|
||||
Args:
|
||||
u_boot_config (ArbitraryAttributeContainer): Configuration
|
||||
u_boot_log (multiplexed_log.Logfile): Log to write to
|
||||
"""
|
||||
setup_fedora_image(u_boot_config, u_boot_log, 1, 'mmc')
|
||||
setup_bootmenu_image(u_boot_config, u_boot_log)
|
||||
setup_cedit_file(u_boot_config, u_boot_log)
|
||||
setup_cros_image(u_boot_config, u_boot_log)
|
||||
setup_android_image(u_boot_config, u_boot_log)
|
||||
setup_efi_image(u_boot_config)
|
||||
setup_ubuntu_image(u_boot_config, u_boot_log, 3, 'flash')
|
||||
setup_localboot_image(u_boot_config, u_boot_log)
|
||||
setup_vbe_image(u_boot_config, u_boot_log)
|
||||
|
||||
def test_ut(ubman, ut_subtest):
|
||||
"""Execute a "ut" subtest.
|
||||
|
||||
@@ -65,6 +65,36 @@ def dtc(dts, ubman, dtc_args, datadir, tmpdir, dtb):
|
||||
utils.run_and_log(ubman, 'dtc %s %s%s -O dtb '
|
||||
'-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))
|
||||
|
||||
|
||||
def create_rsa_pair(ubman, name, sha_algo, tmpdir):
|
||||
"""Generate a new RSA key paid and certificate
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): U-Boot console
|
||||
name (str): Name of the key (e.g. 'dev')
|
||||
sha_algo (str): SHA algorithm to use, e.g. 'sha256'
|
||||
tmpdir (str): Temporary directory to use for openssl
|
||||
"""
|
||||
public_exponent = 65537
|
||||
|
||||
if sha_algo == 'sha384':
|
||||
rsa_keygen_bits = 3072
|
||||
else:
|
||||
rsa_keygen_bits = 2048
|
||||
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
f'openssl genpkey -algorithm RSA -out {tmpdir}{name}.key '
|
||||
f'-pkeyopt rsa_keygen_bits:{rsa_keygen_bits} '
|
||||
f'-pkeyopt rsa_keygen_pubexp:{public_exponent}')
|
||||
|
||||
# Create a certificate containing the public key
|
||||
utils.run_and_log(
|
||||
ubman,
|
||||
f'openssl req -batch -new -x509 -key {tmpdir}{name}.key '
|
||||
f'-out {tmpdir}{name}.crt')
|
||||
|
||||
|
||||
def make_fit(its, ubman, mkimage, dtc_args, datadir, fit):
|
||||
"""Make a new FIT from the .its source file.
|
||||
|
||||
@@ -265,28 +295,6 @@ def test_vboot_base(ubman, name, sha_algo, padding, sign_options, required,
|
||||
handle.seek(offset)
|
||||
handle.write(struct.pack(">I", value))
|
||||
|
||||
def create_rsa_pair(name):
|
||||
"""Generate a new RSA key paid and certificate
|
||||
|
||||
Args:
|
||||
name: Name of of the key (e.g. 'dev')
|
||||
"""
|
||||
public_exponent = 65537
|
||||
|
||||
if sha_algo == "sha384":
|
||||
rsa_keygen_bits = 3072
|
||||
else:
|
||||
rsa_keygen_bits = 2048
|
||||
|
||||
utils.run_and_log(ubman, 'openssl genpkey -algorithm RSA -out %s%s.key '
|
||||
'-pkeyopt rsa_keygen_bits:%d '
|
||||
'-pkeyopt rsa_keygen_pubexp:%d' %
|
||||
(tmpdir, name, rsa_keygen_bits, public_exponent))
|
||||
|
||||
# Create a certificate containing the public key
|
||||
utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.key '
|
||||
'-out %s%s.crt' % (tmpdir, name, tmpdir, name))
|
||||
|
||||
def test_with_algo(sha_algo, padding, sign_options):
|
||||
"""Test verified boot with the given hash algorithm.
|
||||
|
||||
@@ -520,8 +528,8 @@ def test_vboot_base(ubman, name, sha_algo, padding, sign_options, required,
|
||||
dtb = '%ssandbox-u-boot.dtb' % tmpdir
|
||||
sig_node = '/configurations/conf-1/signature'
|
||||
|
||||
create_rsa_pair('dev')
|
||||
create_rsa_pair('prod')
|
||||
create_rsa_pair(ubman, 'dev', sha_algo, tmpdir)
|
||||
create_rsa_pair(ubman, 'prod', sha_algo, tmpdir)
|
||||
|
||||
# Create a number kernel image with zeroes
|
||||
with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
|
||||
@@ -632,12 +640,22 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
|
||||
datadir = ubman.config.source_dir + '/test/py/tests/vboot/'
|
||||
fit = '%stest.fit' % tmpdir
|
||||
mkimage = ubman.config.build_dir + '/tools/mkimage'
|
||||
binman = ubman.config.source_dir + '/tools/binman/binman'
|
||||
fit_check_sign = ubman.config.build_dir + '/tools/fit_check_sign'
|
||||
fdt_add_pubkey = ubman.config.build_dir + '/tools/fdt_add_pubkey'
|
||||
dtc_args = '-I dts -O dtb -i %s' % tmpdir
|
||||
dtb = '%ssandbox-u-boot.dtb' % tmpdir
|
||||
|
||||
# keys created in test_vboot test
|
||||
create_rsa_pair(ubman, 'dev', sha_algo, tmpdir)
|
||||
create_rsa_pair(ubman, 'prod', sha_algo, tmpdir)
|
||||
|
||||
# Create a number kernel image with zeroes
|
||||
with open(f'{tmpdir}test-kernel.bin', 'wb') as fd:
|
||||
fd.write(500 * b'\0')
|
||||
|
||||
# Compile our device tree files for kernel and U-Boot. These are
|
||||
# regenerated here since mkimage will modify them (by adding a
|
||||
# public key) below.
|
||||
dtc('sandbox-kernel.dts', ubman, dtc_args, datadir, tmpdir, dtb)
|
||||
dtc('sandbox-u-boot.dts', ubman, dtc_args, datadir, tmpdir, dtb)
|
||||
|
||||
test_add_pubkey(sha_algo, padding, sign_options)
|
||||
|
||||
@@ -157,31 +157,53 @@ def wait_until_file_open_fails(fn, ignore_errors):
|
||||
return
|
||||
raise Exception('File can still be opened')
|
||||
|
||||
def run_and_log(ubman, cmd, ignore_errors=False, stdin=None, env=None):
|
||||
def run_and_log_no_ubman(log, cmd, ignore_errors=False, stdin=None, env=None):
|
||||
"""Run a command and log its output.
|
||||
|
||||
This is useful when you don't want to use a ubman fixture
|
||||
|
||||
Args:
|
||||
ubman: A console connection to U-Boot.
|
||||
cmd: The command to run, as an array of argv[], or a string.
|
||||
log (multiplexed_log.Logfile): log fixture
|
||||
cmd (list of str or str): Command to run, as an array of argv[] or str.
|
||||
If a string, note that it is split up so that quoted spaces
|
||||
will not be preserved. E.g. "fred and" becomes ['"fred', 'and"']
|
||||
ignore_errors: Indicate whether to ignore errors. If True, the function
|
||||
will simply return if the command cannot be executed or exits with
|
||||
an error code, otherwise an exception will be raised if such
|
||||
problems occur.
|
||||
stdin: Input string to pass to the command as stdin (or None)
|
||||
env: Environment to use, or None to use the current one
|
||||
ignore_errors (bool): Indicate whether to ignore errors. If True, the
|
||||
function will simply return if the command cannot be executed or
|
||||
exits with an error code, otherwise an exception will be raised if
|
||||
such problems occur.
|
||||
stdin (str): Input string to pass to the command as stdin (or None)
|
||||
env (dict): Environment to use, or None to use the current one
|
||||
|
||||
Returns:
|
||||
The output as a string.
|
||||
"""
|
||||
if isinstance(cmd, str):
|
||||
cmd = cmd.split()
|
||||
runner = ubman.log.get_runner(cmd[0], sys.stdout)
|
||||
runner = log.get_runner(cmd[0], sys.stdout)
|
||||
output = runner.run(cmd, ignore_errors=ignore_errors, stdin=stdin, env=env)
|
||||
runner.close()
|
||||
return output
|
||||
|
||||
def run_and_log(ubman, cmd, ignore_errors=False, stdin=None, env=None):
|
||||
"""Run a command and log its output.
|
||||
|
||||
Args:
|
||||
ubman (ConsoleBase): A console connection to U-Boot.
|
||||
cmd (list of str or str): Command to run, as an array of argv[] or str.
|
||||
If a string, note that it is split up so that quoted spaces
|
||||
will not be preserved. E.g. "fred and" becomes ['"fred', 'and"']
|
||||
ignore_errors (bool): Indicate whether to ignore errors. If True, the
|
||||
function will simply return if the command cannot be executed or
|
||||
exits with an error code, otherwise an exception will be raised if
|
||||
such problems occur.
|
||||
stdin (str): Input string to pass to the command as stdin (or None)
|
||||
env (dict): Environment to use, or None to use the current one
|
||||
|
||||
Returns:
|
||||
The output as a string.
|
||||
"""
|
||||
return run_and_log_no_ubman(ubman.log, cmd, ignore_errors, stdin, env)
|
||||
|
||||
def run_and_log_expect_exception(ubman, cmd, retcode, msg):
|
||||
"""Run a command that is expected to fail.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user