* [PATCH v2 2/2] testsuite: Fix code style
2024-07-19 6:29 [PATCH v2 0/2] Python code style for the testsuite Anton Mikanovich
2024-07-19 6:29 ` [PATCH v2 1/2] testsuite: Provide code style documentation Anton Mikanovich
@ 2024-07-19 6:29 ` Anton Mikanovich
2024-07-31 6:44 ` [PATCH v2 0/2] Python code style for the testsuite Uladzimir Bely
2 siblings, 0 replies; 4+ messages in thread
From: Anton Mikanovich @ 2024-07-19 6:29 UTC (permalink / raw)
To: isar-users; +Cc: Anton Mikanovich, Ilia Skochilov
Bring the Python code into compliance with PEP8 requirements.
Also change string quotes style for consistency throughout the code.
Rebuild line wrapping and function/classes declaration spacing to be
compliant with the current rules described in testsuite/README.md.
Used black v23.1.0 and flake8 v5.0.4.
Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
Signed-off-by: Ilia Skochilov <iskochilov@ilbers.de>
---
testsuite/cibase.py | 237 ++++++----
testsuite/cibuilder.py | 425 +++++++++++-------
testsuite/citest.py | 245 ++++++----
testsuite/repro-build-test.py | 39 +-
testsuite/start_vm.py | 152 +++++--
testsuite/unittests/bitbake.py | 22 +-
testsuite/unittests/rootfs.py | 9 +-
.../unittests/test_image_account_extension.py | 162 ++++---
8 files changed, 816 insertions(+), 475 deletions(-)
diff --git a/testsuite/cibase.py b/testsuite/cibase.py
index b2a804b7..cccac86c 100755
--- a/testsuite/cibase.py
+++ b/testsuite/cibase.py
@@ -5,18 +5,18 @@ import os
import re
import shutil
import tempfile
-import time
from cibuilder import CIBuilder, isar_root
from utils import CIUtils
from avocado.utils import process
+
class CIBaseTest(CIBuilder):
def perform_build_test(self, targets, **kwargs):
self.configure(**kwargs)
- self.log.info('Starting build...')
+ self.log.info("Starting build...")
self.bitbake(targets, **kwargs)
@@ -24,31 +24,43 @@ class CIBaseTest(CIBuilder):
self.configure(wic_deploy_parts=wic_deploy_parts, **kwargs)
self.bitbake(targets, **kwargs)
- partition_files = set(glob.glob(f'{self.build_dir}/tmp/deploy/images/*/*.wic.p1'))
+ wic_path = f"{self.build_dir}/tmp/deploy/images/*/*.wic.p1"
+ partition_files = set(glob.glob(wic_path))
if wic_deploy_parts and len(partition_files) == 0:
- self.fail('Found raw wic partitions in DEPLOY_DIR')
+ self.fail("Found raw wic partitions in DEPLOY_DIR")
if not wic_deploy_parts and len(partition_files) != 0:
- self.fail('Did not find raw wic partitions in DEPLOY_DIR')
+ self.fail("Did not find raw wic partitions in DEPLOY_DIR")
def perform_repro_test(self, targets, signed=False, **kwargs):
- gpg_pub_key = os.path.dirname(__file__) + '/keys/base-apt/test_pub.key'
- gpg_priv_key = os.path.dirname(__file__) + '/keys/base-apt/test_priv.key'
+ keys_dir = os.path.dirname(__file__) + '/keys/base-apt'
+ gpg_pub_key = os.path.join(keys_dir, 'test_pub.key')
+ gpg_priv_key = os.path.join(keys_dir, 'test_priv.key')
- self.configure(gpg_pub_key=gpg_pub_key if signed else None, sstate_dir="", **kwargs)
+ self.configure(
+ gpg_pub_key=gpg_pub_key if signed else None,
+ sstate_dir='',
+ **kwargs,
+ )
os.chdir(self.build_dir)
os.environ['GNUPGHOME'] = gnupg_home = tempfile.mkdtemp()
- result = process.run('gpg --import %s %s' % (gpg_pub_key, gpg_priv_key))
+ result = process.run(f"gpg --import {gpg_pub_key} {gpg_priv_key}")
if result.exit_status:
- self.fail('GPG import failed')
+ self.fail("GPG import failed")
try:
self.bitbake(targets, **kwargs)
- self.move_in_build_dir('tmp', 'tmp_middle_repro_%s' % ('signed' if signed else 'unsigned'))
- self.configure(gpg_pub_key=gpg_pub_key if signed else None, offline=True, sstate_dir="", **kwargs)
+ repro_type = 'signed' if signed else 'unsigned'
+ self.move_in_build_dir('tmp', f"tmp_middle_repro_{repro_type}")
+ self.configure(
+ gpg_pub_key=gpg_pub_key if signed else None,
+ offline=True,
+ sstate_dir='',
+ **kwargs,
+ )
self.bitbake(targets, **kwargs)
@@ -71,13 +83,13 @@ class CIBaseTest(CIBuilder):
count = 0
for filename in glob.iglob(dir + '/**/stats', recursive=True):
if os.path.isfile(filename):
- with open(filename,'r') as file:
+ with open(filename, 'r') as file:
content = file.readlines()
- if (field < len(content)):
+ if field < len(content):
count += int(content[field])
return count
- self.configure(ccache=True, sstate_dir="", **kwargs)
+ self.configure(ccache=True, sstate_dir='', **kwargs)
# Field that stores direct ccache hits
direct_cache_hit = 22
@@ -86,21 +98,21 @@ class CIBaseTest(CIBuilder):
self.delete_from_build_dir('sstate-cache')
self.delete_from_build_dir('ccache')
- self.log.info('Starting build and filling ccache dir...')
+ self.log.info("Starting build and filling ccache dir...")
self.bitbake(targets, **kwargs)
hit1 = ccache_stats(self.build_dir + '/ccache', direct_cache_hit)
- self.log.info('Ccache hits 1: ' + str(hit1))
+ self.log.info(f"Ccache hits 1: {str(hit1)}")
self.move_in_build_dir('tmp', 'tmp_middle_ccache')
self.delete_from_build_dir('sstate-cache')
- self.log.info('Starting build and using ccache dir...')
+ self.log.info("Starting build and using ccache dir...")
self.bitbake(targets, **kwargs)
hit2 = ccache_stats(self.build_dir + '/ccache', direct_cache_hit)
- self.log.info('Ccache hits 2: ' + str(hit2))
+ self.log.info(f"Ccache hits 2: {str(hit2)}")
if hit2 <= hit1:
- self.fail('Ccache was not used on second build')
+ self.fail("Ccache was not used on second build")
# Cleanup
self.move_in_build_dir('tmp', 'tmp_after_ccache')
@@ -112,10 +124,10 @@ class CIBaseTest(CIBuilder):
# Use a different isar root for populating sstate cache
isar_sstate = f"{isar_root}/isar-sstate"
os.makedirs(isar_sstate)
- process.run(f'git --work-tree={isar_sstate} checkout HEAD -- .')
+ process.run(f"git --work-tree={isar_sstate} checkout HEAD -- .")
self.init('../build-sstate', isar_dir=isar_sstate)
- self.configure(sstate=True, sstate_dir="", **kwargs)
+ self.configure(sstate=True, sstate_dir='', **kwargs)
# Cleanup sstate and tmp before test
self.delete_from_build_dir('sstate-cache')
@@ -127,17 +139,30 @@ class CIBaseTest(CIBuilder):
# Remove isar configuration so the the following test creates a new one
self.delete_from_build_dir('conf')
- def perform_signature_lint(self, targets, verbose=False, sources_dir=isar_root,
- excluded_tasks=None, **kwargs):
- """Generate signature data for target(s) and check for cachability issues."""
+ def perform_signature_lint(
+ self,
+ targets,
+ verbose=False,
+ sources_dir=isar_root,
+ excluded_tasks=None,
+ **kwargs,
+ ):
+ """
+ Generate signature data for target(s) and check for cachability issues
+ """
self.configure(**kwargs)
- self.move_in_build_dir("tmp", "tmp_before_sstate")
- self.bitbake(targets, sig_handler="none")
-
- verbose_arg = "--verbose" if verbose else ""
- excluded_arg = f"--excluded-tasks {','.join(excluded_tasks)}" if excluded_tasks else ""
- cmd = f"{isar_root}/scripts/isar-sstate lint --lint-stamps {self.build_dir}/tmp/stamps " \
- f"--build-dir {self.build_dir} --sources-dir {sources_dir} {verbose_arg} {excluded_arg}"
+ self.move_in_build_dir('tmp', 'tmp_before_sstate')
+ self.bitbake(targets, sig_handler='none')
+
+ verbose_arg = '--verbose' if verbose else ''
+ excluded_arg = ''
+ if excluded_tasks:
+ excluded_arg = f"--excluded-tasks {','.join(excluded_tasks)}"
+ cmd = (
+ f"{isar_root}/scripts/isar-sstate lint --lint-stamps "
+ f"{self.build_dir}/tmp/stamps --build-dir {self.build_dir} "
+ f"--sources-dir {sources_dir} {verbose_arg} {excluded_arg}"
+ )
self.log.info(f"Running: {cmd}")
exit_status, output = process.getstatusoutput(cmd, ignore_status=True)
if exit_status > 0:
@@ -148,10 +173,11 @@ class CIBaseTest(CIBuilder):
def perform_sstate_test(self, image_target, package_target, **kwargs):
def check_executed_tasks(target, expected):
- taskorder_file = glob.glob(f'{self.build_dir}/tmp/work/*/{target}/*/temp/log.task_order')
+ recipe_workdir = f"{self.build_dir}/tmp/work/*/{target}/*"
+ taskorder_file = glob.glob(f"{recipe_workdir}/temp/log.task_order")
try:
with open(taskorder_file[0], 'r') as f:
- tasks = [l.split()[1] for l in f.readlines()]
+ tasks = [line.split()[1] for line in f.readlines()]
except (FileNotFoundError, IndexError):
tasks = []
if expected is None:
@@ -163,75 +189,116 @@ class CIBaseTest(CIBuilder):
should_run = False
e = e[1:]
if should_run != (e in tasks):
- self.log.error(f"{target}: executed tasks {str(tasks)} did not match expected {str(expected)}")
+ self.log.error(
+ f"{target}: executed tasks {str(tasks)} did not match "
+ f"expected {str(expected)}"
+ )
return False
return True
- self.configure(sstate=True, sstate_dir="", **kwargs)
+ self.configure(sstate=True, sstate_dir='', **kwargs)
+
+ deploy_dir = f"{self.build_dir}/tmp/deploy"
- # Check signature files for cachability issues like absolute paths in signatures
- result = process.run(f'{isar_root}/scripts/isar-sstate lint {self.build_dir}/sstate-cache '
- f'--build-dir {self.build_dir} --sources-dir {isar_root}')
+ # Check signature files for cachability issues like absolute paths in
+ # signatures
+ result = process.run(
+ f"{isar_root}/scripts/isar-sstate lint "
+ f"{self.build_dir}/sstate-cache --build-dir {self.build_dir} "
+ f"--sources-dir {isar_root}"
+ )
if result.exit_status > 0:
self.fail("Detected cachability issues")
# Save contents of image deploy dir
- expected_files = set(glob.glob(f'{self.build_dir}/tmp/deploy/images/*/*'))
+ expected_files = set(glob.glob(f"{deploy_dir}/images/*/*"))
# Rebuild image
self.move_in_build_dir('tmp', 'tmp_before_sstate')
self.bitbake(image_target, **kwargs)
- if not all([
- check_executed_tasks('isar-bootstrap-target',
- ['do_bootstrap_setscene', '!do_bootstrap']),
- check_executed_tasks('sbuild-chroot-target',
- ['do_rootfs_install_setscene', '!do_rootfs_install']),
- check_executed_tasks('isar-image-base-*',
- ['do_rootfs_install_setscene', '!do_rootfs_install'])
- ]):
+ if not all(
+ [
+ check_executed_tasks(
+ 'isar-bootstrap-target',
+ ['do_bootstrap_setscene', '!do_bootstrap'],
+ ),
+ check_executed_tasks(
+ 'sbuild-chroot-target',
+ ['do_rootfs_install_setscene', '!do_rootfs_install'],
+ ),
+ check_executed_tasks(
+ 'isar-image-base-*',
+ ['do_rootfs_install_setscene', '!do_rootfs_install'],
+ ),
+ ]
+ ):
self.fail("Failed rebuild image")
# Verify content of image deploy dir
- deployed_files = set(glob.glob(f'{self.build_dir}/tmp/deploy/images/*/*'))
+ deployed_files = set(glob.glob(f"{deploy_dir}/images/*/*"))
if not deployed_files == expected_files:
if len(expected_files - deployed_files) > 0:
- self.log.error(f"{target}: files missing from deploy dir after rebuild with sstate cache:"
- f"{expected_files - deployed_files}")
+ self.log.error(
+ f"{image_target}: files missing from deploy dir after "
+ f"rebuild with sstate cache:"
+ f"{expected_files - deployed_files}"
+ )
if len(deployed_files - expected_files) > 0:
- self.log.error(f"{target}: additional files in deploy dir after rebuild with sstate cache:"
- f"{deployed_files - expected_files}")
+ self.log.error(
+ f"{image_target}: additional files in deploy dir after "
+ f"rebuild with sstate cache:"
+ f"{deployed_files - expected_files}"
+ )
self.fail("Failed rebuild image")
# Rebuild single package
self.move_in_build_dir('tmp', 'tmp_middle_sstate')
self.bitbake(package_target, **kwargs)
- if not all([
- check_executed_tasks('isar-bootstrap-target',
- ['do_bootstrap_setscene']),
- check_executed_tasks('sbuild-chroot-target',
- ['!do_sbuildchroot_deploy']),
- check_executed_tasks('hello',
- ['do_dpkg_build_setscene', 'do_deploy_deb', '!do_dpkg_build'])
- ]):
+ if not all(
+ [
+ check_executed_tasks(
+ 'isar-bootstrap-target', ['do_bootstrap_setscene']
+ ),
+ check_executed_tasks(
+ 'sbuild-chroot-target', ['!do_sbuildchroot_deploy']
+ ),
+ check_executed_tasks(
+ 'hello',
+ [
+ 'do_dpkg_build_setscene',
+ 'do_deploy_deb',
+ '!do_dpkg_build',
+ ],
+ ),
+ ]
+ ):
self.fail("Failed rebuild single package")
# Rebuild package and image
self.move_in_build_dir('tmp', 'tmp_middle2_sstate')
- process.run(f'find {self.build_dir}/sstate-cache/ -name sstate:hello:* -delete')
+ sstate_cache_dir = f"{self.build_dir}/sstate-cache/"
+ process.run(f"find {sstate_cache_dir} -name sstate:hello:* -delete")
self.bitbake(image_target, **kwargs)
- if not all([
- check_executed_tasks('isar-bootstrap-target',
- ['do_bootstrap_setscene', '!do_bootstrap']),
- check_executed_tasks('sbuild-chroot-target',
- ['do_rootfs_install_setscene', '!do_rootfs_install']),
- check_executed_tasks('hello',
- ['do_fetch', 'do_dpkg_build']),
- # TODO: if we actually make a change to hello, then we could test
- # that do_rootfs is executed. currently, hello is rebuilt,
- # but its sstate sig/hash does not change.
- check_executed_tasks('isar-image-base-*',
- ['do_rootfs_install_setscene', '!do_rootfs_install'])
- ]):
+ if not all(
+ [
+ check_executed_tasks(
+ 'isar-bootstrap-target',
+ ['do_bootstrap_setscene', '!do_bootstrap'],
+ ),
+ check_executed_tasks(
+ 'sbuild-chroot-target',
+ ['do_rootfs_install_setscene', '!do_rootfs_install'],
+ ),
+ check_executed_tasks('hello', ['do_fetch', 'do_dpkg_build']),
+ # TODO: if we actually make a change to hello, then we could
+ # test that do_rootfs is executed. currently, hello is
+ # rebuilt, but its sstate sig/hash does not change.
+ check_executed_tasks(
+ 'isar-image-base-*',
+ ['do_rootfs_install_setscene', '!do_rootfs_install'],
+ ),
+ ]
+ ):
self.fail("Failed rebuild package and image")
def perform_source_test(self, targets, **kwargs):
@@ -242,9 +309,9 @@ class CIBaseTest(CIBuilder):
package = target.rsplit(':', 1)[-1]
isar_apt = CIUtils.getVars('REPO_ISAR_DB_DIR', target=target)
fpath = f"{package}/{package}*.tar.*"
- targz = set(glob.glob(f'{isar_apt}/../apt/*/pool/*/*/{fpath}'))
+ targz = set(glob.glob(f"{isar_apt}/../apt/*/pool/*/*/{fpath}"))
if len(targz) < 1:
- self.fail('No source packages found')
+ self.fail("No source packages found")
for fname in targz:
sfiles[target][fname] = CIUtils.get_tar_content(fname)
return sfiles
@@ -260,14 +327,16 @@ class CIBaseTest(CIBuilder):
for filename in sfiles_before[tdir]:
for file in sfiles_before[tdir][filename]:
if os.path.basename(file).startswith('.git'):
- self.fail('Found .git files')
+ self.fail("Found .git files")
package = targets[0].rsplit(':', 1)[-1]
- tmp_layer_nested_dirs = os.path.join(tmp_layer_dir,
- 'recipes-app', package)
+ tmp_layer_nested_dirs = os.path.join(
+ tmp_layer_dir, 'recipes-app', package
+ )
os.makedirs(tmp_layer_nested_dirs, exist_ok=True)
- bbappend_file = os.path.join(tmp_layer_nested_dirs,
- package + '.bbappend')
+ bbappend_file = os.path.join(
+ tmp_layer_nested_dirs, package + '.bbappend'
+ )
with open(bbappend_file, 'w') as file:
file.write('DPKG_SOURCE_EXTRA_ARGS = ""')
@@ -278,12 +347,12 @@ class CIBaseTest(CIBuilder):
for tdir in sfiles_after:
for filename in sfiles_after[tdir]:
if not sfiles_before[tdir][filename]:
- self.fail('Source filenames are different')
+ self.fail("Source filenames are different")
diff = []
for file in sfiles_after[tdir][filename]:
if file not in sfiles_before[tdir][filename]:
diff.append(file)
if len(diff) < 1:
- self.fail('Source packages are equal')
+ self.fail("Source packages are equal")
finally:
self.cleanup_tmp_layer(tmp_layer_dir)
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index a20e88f9..35af3d9c 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -19,7 +19,7 @@ from avocado import Test
from avocado.utils import path
from avocado.utils import process
-sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/../bitbake/lib')
+sys.path.append(os.path.join(os.path.dirname(__file__), '../bitbake/lib'))
import bb
@@ -28,19 +28,23 @@ DEF_VM_TO_SEC = 600
isar_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
backup_prefix = '.ci-backup'
-app_log = logging.getLogger("avocado.app")
+app_log = logging.getLogger('avocado.app')
+
class CanBeFinished(Exception):
pass
+
class CIBuilder(Test):
def setUp(self):
super(CIBuilder, self).setUp()
job_log = os.path.join(os.path.dirname(self.logdir), '..', 'job.log')
self._file_handler = logging.FileHandler(filename=job_log)
self._file_handler.setLevel(logging.ERROR)
- fmt = ('%(asctime)s %(module)-16.16s L%(lineno)-.4d %('
- 'levelname)-5.5s| %(message)s')
+ fmt = (
+ '%(asctime)s %(module)-16.16s L%(lineno)-.4d '
+ '%(levelname)-5.5s| %(message)s'
+ )
formatter = logging.Formatter(fmt=fmt)
self._file_handler.setFormatter(formatter)
app_log.addHandler(self._file_handler)
@@ -49,22 +53,31 @@ class CIBuilder(Test):
# initialize build_dir and setup environment
# needs to run once (per test case)
if hasattr(self, 'build_dir'):
- self.error("Broken test implementation: init() called multiple times.")
+ self.error(
+ "Broken test implementation: init() called multiple times."
+ )
self.build_dir = os.path.join(isar_dir, build_dir)
os.chdir(isar_dir)
- os.environ["TEMPLATECONF"] = "meta-test/conf"
+ os.environ['TEMPLATECONF'] = 'meta-test/conf'
path.usable_rw_dir(self.build_dir)
- output = process.getoutput('/bin/bash -c "source isar-init-build-env \
- %s 2>&1 >/dev/null; env"' % self.build_dir)
- env = dict(((x.split('=', 1) + [''])[:2] \
- for x in output.splitlines() if x != ''))
+ output = process.getoutput(
+ f"/bin/bash -c 'source isar-init-build-env {self.build_dir} 2>&1 "
+ f">/dev/null; env'"
+ )
+ env = dict(
+ (
+ (x.split('=', 1) + [''])[:2]
+ for x in output.splitlines()
+ if x != ''
+ )
+ )
os.environ.update(env)
self.vm_dict = {}
self.vm_dict_file = '%s/vm_dict_file' % self.build_dir
if os.path.isfile(self.vm_dict_file):
- with open(self.vm_dict_file, "rb") as f:
+ with open(self.vm_dict_file, 'rb') as f:
data = f.read()
if data:
self.vm_dict = pickle.loads(data)
@@ -73,12 +86,25 @@ class CIBuilder(Test):
if not hasattr(self, 'build_dir'):
self.error("Broken test implementation: need to call init().")
- def configure(self, compat_arch=True, cross=True, debsrc_cache=False,
- container=False, ccache=False, sstate=False, offline=False,
- gpg_pub_key=None, wic_deploy_parts=False, dl_dir=None,
- sstate_dir=None, ccache_dir=None,
- source_date_epoch=None, use_apt_snapshot=False,
- image_install=None, **kwargs):
+ def configure(
+ self,
+ compat_arch=True,
+ cross=True,
+ debsrc_cache=False,
+ container=False,
+ ccache=False,
+ sstate=False,
+ offline=False,
+ gpg_pub_key=None,
+ wic_deploy_parts=False,
+ dl_dir=None,
+ sstate_dir=None,
+ ccache_dir=None,
+ source_date_epoch=None,
+ use_apt_snapshot=False,
+ image_install=None,
+ **kwargs,
+ ):
# write configuration file and set bitbake_args
# can run multiple times per test case
self.check_init()
@@ -104,24 +130,26 @@ class CIBuilder(Test):
# get parameters from environment
distro_apt_premir = os.getenv('DISTRO_APT_PREMIRRORS')
- self.log.info(f'===================================================\n'
- f'Configuring build_dir {self.build_dir}\n'
- f' compat_arch = {compat_arch}\n'
- f' cross = {cross}\n'
- f' debsrc_cache = {debsrc_cache}\n'
- f' offline = {offline}\n'
- f' container = {container}\n'
- f' ccache = {ccache}\n'
- f' sstate = {sstate}\n'
- f' gpg_pub_key = {gpg_pub_key}\n'
- f' wic_deploy_parts = {wic_deploy_parts}\n'
- f' source_date_epoch = {source_date_epoch} \n'
- f' use_apt_snapshot = {use_apt_snapshot} \n'
- f' dl_dir = {dl_dir}\n'
- f' sstate_dir = {sstate_dir}\n'
- f' ccache_dir = {ccache_dir}\n'
- f' image_install = {image_install}\n'
- f'===================================================')
+ self.log.info(
+ f"===================================================\n"
+ f"Configuring build_dir {self.build_dir}\n"
+ f" compat_arch = {compat_arch}\n"
+ f" cross = {cross}\n"
+ f" debsrc_cache = {debsrc_cache}\n"
+ f" offline = {offline}\n"
+ f" container = {container}\n"
+ f" ccache = {ccache}\n"
+ f" sstate = {sstate}\n"
+ f" gpg_pub_key = {gpg_pub_key}\n"
+ f" wic_deploy_parts = {wic_deploy_parts}\n"
+ f" source_date_epoch = {source_date_epoch} \n"
+ f" use_apt_snapshot = {use_apt_snapshot} \n"
+ f" dl_dir = {dl_dir}\n"
+ f" sstate_dir = {sstate_dir}\n"
+ f" ccache_dir = {ccache_dir}\n"
+ f" image_install = {image_install}\n"
+ f"==================================================="
+ )
# determine bitbake_args
self.bitbake_args = []
@@ -142,7 +170,10 @@ class CIBuilder(Test):
f.write('IMAGE_INSTALL += "kselftest"\n')
if cross:
f.write('ISAR_CROSS_COMPILE = "1"\n')
- f.write('IMAGE_INSTALL:append:hikey = " linux-headers-${KERNEL_NAME}"\n')
+ f.write(
+ 'IMAGE_INSTALL:append:hikey = '
+ '" linux-headers-${KERNEL_NAME}"\n'
+ )
if debsrc_cache:
f.write('BASE_REPO_FEATURES = "cache-deb-src"\n')
if offline:
@@ -150,7 +181,10 @@ class CIBuilder(Test):
f.write('BB_NO_NETWORK = "1"\n')
if container:
f.write('SDK_FORMATS = "docker-archive"\n')
- f.write('IMAGE_INSTALL:remove = "example-module-${KERNEL_NAME} enable-fsck"\n')
+ f.write(
+ 'IMAGE_INSTALL:remove = '
+ '"example-module-${KERNEL_NAME} enable-fsck"\n'
+ )
if gpg_pub_key:
f.write('BASE_REPO_KEY="file://' + gpg_pub_key + '"\n')
if wic_deploy_parts:
@@ -161,7 +195,9 @@ class CIBuilder(Test):
f.write('USE_CCACHE = "1"\n')
f.write('CCACHE_TOP_DIR = "%s"\n' % ccache_dir)
if source_date_epoch:
- f.write('SOURCE_DATE_EPOCH_FALLBACK = "%s"\n' % source_date_epoch)
+ f.write(
+ 'SOURCE_DATE_EPOCH_FALLBACK = "%s"\n' % source_date_epoch
+ )
if use_apt_snapshot:
f.write('ISAR_USE_APT_SNAPSHOT = "1"\n')
if dl_dir:
@@ -194,9 +230,9 @@ class CIBuilder(Test):
def bitbake(self, target, bitbake_cmd=None, sig_handler=None, **kwargs):
self.check_init()
- self.log.info('===================================================')
- self.log.info('Building ' + str(target))
- self.log.info('===================================================')
+ self.log.info("===================================================")
+ self.log.info(f"Building {str(target)}")
+ self.log.info("===================================================")
os.chdir(self.build_dir)
cmdline = ['bitbake']
if self.bitbake_args:
@@ -212,9 +248,13 @@ class CIBuilder(Test):
else:
cmdline.append(target)
- with subprocess.Popen(" ".join(cmdline), stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, universal_newlines=True,
- shell=True) as p1:
+ with subprocess.Popen(
+ ' '.join(cmdline),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ shell=True,
+ ) as p1:
poller = select.poll()
poller.register(p1.stdout, select.POLLIN)
poller.register(p1.stderr, select.POLLIN)
@@ -229,28 +269,28 @@ class CIBuilder(Test):
app_log.error(p1.stderr.readline().rstrip())
p1.wait()
if p1.returncode:
- self.fail('Bitbake failed')
+ self.fail("Bitbake failed")
def backupfile(self, path):
self.check_init()
try:
shutil.copy2(path, path + backup_prefix)
except FileNotFoundError:
- self.log.warn(path + ' not exist')
+ self.log.warn(f"{path} not exist")
def backupmove(self, path):
self.check_init()
try:
shutil.move(path, path + backup_prefix)
except FileNotFoundError:
- self.log.warn(path + ' not exist')
+ self.log.warn(f"{path} not exist")
def restorefile(self, path):
self.check_init()
try:
shutil.move(path + backup_prefix, path)
except FileNotFoundError:
- self.log.warn(path + backup_prefix + ' not exist')
+ self.log.warn(f"{path}{backup_prefix} not exist")
def create_tmp_layer(self):
tmp_layer_dir = os.path.join(isar_root, 'meta-tmp')
@@ -259,82 +299,102 @@ class CIBuilder(Test):
os.makedirs(conf_dir, exist_ok=True)
layer_conf_file = os.path.join(conf_dir, 'layer.conf')
with open(layer_conf_file, 'w') as file:
- file.write('\
-BBPATH .= ":${LAYERDIR}"\
-\nBBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\
-\nBBFILE_COLLECTIONS += "tmp"\
-\nBBFILE_PATTERN_tmp = "^${LAYERDIR}/"\
-\nBBFILE_PRIORITY_tmp = "5"\
-\nLAYERVERSION_tmp = "1"\
-\nLAYERSERIES_COMPAT_tmp = "v0.6"\
-')
-
- bblayersconf_file = os.path.join(self.build_dir, 'conf',
- 'bblayers.conf')
+ file.write(
+ 'BBPATH .= ":${LAYERDIR}"\n'
+ 'BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n'
+ 'BBFILE_COLLECTIONS += "tmp"\n'
+ 'BBFILE_PATTERN_tmp = "^${LAYERDIR}/"\n'
+ 'BBFILE_PRIORITY_tmp = "5"\n'
+ 'LAYERVERSION_tmp = "1"\n'
+ 'LAYERSERIES_COMPAT_tmp = "v0.6"\n'
+ )
+
+ bblayersconf_file = os.path.join(
+ self.build_dir, 'conf', 'bblayers.conf'
+ )
bb.utils.edit_bblayers_conf(bblayersconf_file, tmp_layer_dir, None)
return tmp_layer_dir
def cleanup_tmp_layer(self, tmp_layer_dir):
- bblayersconf_file = os.path.join(self.build_dir, 'conf',
- 'bblayers.conf')
+ bblayersconf_file = os.path.join(
+ self.build_dir, 'conf', 'bblayers.conf'
+ )
bb.utils.edit_bblayers_conf(bblayersconf_file, None, tmp_layer_dir)
bb.utils.prunedir(tmp_layer_dir)
def get_ssh_cmd_prefix(self, user, host, port, priv_key):
- cmd_prefix = 'ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no '\
- '-p %s -o IdentityFile=%s %s@%s ' \
- % (port, priv_key, user, host)
+ cmd_prefix = (
+ f"ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no -p {port} "
+ f"-o IdentityFile={priv_key} {user}@{host}"
+ )
return cmd_prefix
-
def exec_cmd(self, cmd, cmd_prefix):
- proc = subprocess.run('exec ' + str(cmd_prefix) + ' "' + str(cmd) + '"', shell=True,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc = subprocess.run(
+ f"exec {str(cmd_prefix)} '{str(cmd)}'",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
return proc.returncode, proc.stdout, proc.stderr
-
def remote_send_file(self, src, dest, mode):
priv_key = self.prepare_priv_key()
- cmd_prefix = self.get_ssh_cmd_prefix(self.ssh_user, self.ssh_host, self.ssh_port, priv_key)
-
- proc = subprocess.run('cat %s | %s install -m %s /dev/stdin %s' %
- (src, cmd_prefix, mode, dest), shell=True,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ cmd_prefix = self.get_ssh_cmd_prefix(
+ self.ssh_user, self.ssh_host, self.ssh_port, priv_key
+ )
+
+ proc = subprocess.run(
+ f"cat {src} | {cmd_prefix} install -m {mode} /dev/stdin {dest}",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
return proc.returncode, proc.stdout, proc.stderr
def run_script(self, script, cmd_prefix):
- script_dir = self.params.get('test_script_dir',
- default=os.path.abspath(os.path.dirname(__file__))) + '/scripts/'
+ file_dirname = os.path.abspath(os.path.dirname(__file__))
+ script_dir = self.params.get('test_script_dir', default=file_dirname)
+ script_dir = script_dir + '/scripts/'
script_path = script_dir + script.split()[0]
script_args = ' '.join(script.split()[1:])
if not os.path.exists(script_path):
- self.log.error('Script not found: ' + script_path)
- return (2, '', 'Script not found: ' + script_path)
+ self.log.error(f"Script not found: {script_path}")
+ return (2, '', f"Script not found: {script_path}")
- rc, stdout, stderr = self.remote_send_file(script_path, "./ci.sh", "755")
+ rc, stdout, stderr = self.remote_send_file(
+ script_path, './ci.sh', '755'
+ )
if rc != 0:
- self.log.error('Failed to deploy the script on target')
+ self.log.error("Failed to deploy the script on target")
return (rc, stdout, stderr)
time.sleep(1)
- proc = subprocess.run('%s ./ci.sh %s' % (cmd_prefix, script_args), shell=True,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc = subprocess.run(
+ f"{cmd_prefix} ./ci.sh {script_args}",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
return (proc.returncode, proc.stdout, proc.stderr)
def wait_connection(self, cmd_prefix, timeout):
- self.log.info('Waiting for SSH server ready...')
+ self.log.info("Waiting for SSH server ready...")
rc = None
- stdout = ""
- stderr = ""
+ stdout = ''
+ stderr = ''
goodcnt = 0
# Use 3 good SSH ping attempts to consider SSH connection is stable
@@ -348,33 +408,34 @@ BBPATH .= ":${LAYERDIR}"\
goodcnt = 0
time_left = timeout - time.time()
- self.log.info('SSH ping result: %d, left: %.fs' % (rc, time_left))
+ self.log.info("SSH ping result: %d, left: %.fs" % (rc, time_left))
return rc, stdout, stderr
-
def prepare_priv_key(self):
- # copy private key to build directory (that is writable)
+ # Copy private key to build directory (that is writable)
priv_key = '%s/ci_priv_key' % self.build_dir
if not os.path.exists(priv_key):
- shutil.copy(os.path.dirname(__file__) + '/keys/ssh/id_rsa', priv_key)
+ key = os.path.join(os.path.dirname(__file__), 'keys/ssh/id_rsa')
+ shutil.copy(key, priv_key)
os.chmod(priv_key, 0o400)
return priv_key
-
def remote_run(self, cmd=None, script=None, timeout=0):
if cmd:
- self.log.info('Remote command is `%s`' % (cmd))
+ self.log.info(f"Remote command is `{cmd}`")
if script:
- self.log.info('Remote script is `%s`' % (script))
+ self.log.info(f"Remote script is `{script}`")
priv_key = self.prepare_priv_key()
- cmd_prefix = self.get_ssh_cmd_prefix(self.ssh_user, self.ssh_host, self.ssh_port, priv_key)
+ cmd_prefix = self.get_ssh_cmd_prefix(
+ self.ssh_user, self.ssh_host, self.ssh_port, priv_key
+ )
rc = None
- stdout = ""
- stderr = ""
+ stdout = ''
+ stderr = ''
if timeout != 0:
rc, stdout, stderr = self.wait_connection(cmd_prefix, timeout)
@@ -382,20 +443,20 @@ BBPATH .= ":${LAYERDIR}"\
if rc == 0 or timeout == 0:
if cmd is not None:
rc, stdout, stderr = self.exec_cmd(cmd, cmd_prefix)
- self.log.info('`' + cmd + '` returned ' + str(rc))
+ self.log.info(f"`{cmd}` returned {str(rc)}")
elif script is not None:
rc, stdout, stderr = self.run_script(script, cmd_prefix)
- self.log.info('`' + script + '` returned ' + str(rc))
+ self.log.info(f"`{script}` returned {str(rc)}")
return rc, stdout, stderr
-
- def ssh_start(self, user='ci', host='localhost', port=22,
- cmd=None, script=None):
- self.log.info('===================================================')
- self.log.info('Running Isar SSH test for `%s@%s:%s`' % (user, host, port))
- self.log.info('Isar build folder is: ' + self.build_dir)
- self.log.info('===================================================')
+ def ssh_start(
+ self, user='ci', host='localhost', port=22, cmd=None, script=None
+ ):
+ self.log.info("===================================================")
+ self.log.info(f"Running Isar SSH test for `{user}@{host}:{port}`")
+ self.log.info(f"Isar build folder is: {self.build_dir}")
+ self.log.info("===================================================")
self.check_init()
@@ -404,52 +465,63 @@ BBPATH .= ":${LAYERDIR}"\
self.ssh_port = port
priv_key = self.prepare_priv_key()
- cmd_prefix = self.get_ssh_cmd_prefix(self.ssh_user, self.ssh_host, self.ssh_port, priv_key)
- self.log.info('Connect command:\n' + cmd_prefix)
+ cmd_prefix = self.get_ssh_cmd_prefix(
+ self.ssh_user, self.ssh_host, self.ssh_port, priv_key
+ )
+ self.log.info(f"Connect command:\n{cmd_prefix}")
if cmd is not None or script is not None:
rc, stdout, stderr = self.remote_run(cmd, script)
if rc != 0:
- self.fail('Failed with rc=%s' % rc)
+ self.fail(f"Failed with rc={rc}")
return stdout, stderr
- self.fail('No command to run specified')
+ self.fail("No command to run specified")
-
- def vm_turn_on(self, arch='amd64', distro='buster', image='isar-image-base',
- enforce_pcbios=False):
+ def vm_turn_on(
+ self,
+ arch='amd64',
+ distro='buster',
+ image='isar-image-base',
+ enforce_pcbios=False,
+ ):
logdir = '%s/vm_start' % self.build_dir
if not os.path.exists(logdir):
os.mkdir(logdir)
- prefix = '%s-vm_start_%s_%s_' % (time.strftime('%Y%m%d-%H%M%S'),
- distro, arch)
- fd, boot_log = tempfile.mkstemp(suffix='_log.txt', prefix=prefix,
- dir=logdir, text=True)
+ prefix = f"{time.strftime('%Y%m%d-%H%M%S')}-vm_start_{distro}_{arch}_"
+ fd, boot_log = tempfile.mkstemp(
+ suffix='_log.txt', prefix=prefix, dir=logdir, text=True
+ )
os.chmod(boot_log, 0o644)
latest_link = '%s/vm_start_%s_%s_latest.txt' % (logdir, distro, arch)
if os.path.exists(latest_link):
os.unlink(latest_link)
os.symlink(os.path.basename(boot_log), latest_link)
- cmdline = start_vm.format_qemu_cmdline(arch, self.build_dir, distro, image,
- boot_log, None, enforce_pcbios)
+ cmdline = start_vm.format_qemu_cmdline(
+ arch, self.build_dir, distro, image, boot_log, None, enforce_pcbios
+ )
cmdline.insert(1, '-nographic')
need_sb_cleanup = start_vm.sb_copy_vars(cmdline)
- self.log.info('QEMU boot line:\n' + ' '.join(cmdline))
- self.log.info('QEMU boot log:\n' + boot_log)
-
- p1 = subprocess.Popen('exec ' + ' '.join(cmdline), shell=True,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- universal_newlines=True)
+ self.log.info(f"QEMU boot line:\n{' '.join(cmdline)}")
+ self.log.info(f"QEMU boot log:\ni{boot_log}")
+
+ p1 = subprocess.Popen(
+ f"exec {' '.join(cmdline)}",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ )
self.log.info("Started VM with pid %s" % (p1.pid))
return p1, cmdline, boot_log, need_sb_cleanup
-
def vm_wait_boot(self, p1, timeout):
login_prompt = b' login:'
@@ -471,7 +543,7 @@ BBPATH .= ":${LAYERDIR}"\
shift = max(0, len(data) + len(databuf) - databuf_size)
databuf = databuf[shift:] + bytearray(data)
if login_prompt in databuf:
- self.log.info('Got login prompt')
+ self.log.info("Got login prompt")
return 0
if fd == p1.stderr.fileno():
app_log.error(p1.stderr.readline().rstrip())
@@ -479,35 +551,31 @@ BBPATH .= ":${LAYERDIR}"\
self.log.error("Didn't get login prompt")
return 1
-
def vm_parse_output(self, boot_log, multiconfig, skip_modulecheck):
# the printk of recipes-kernel/example-module
module_output = b'Just an example'
resize_output = None
- image_fstypes, \
- wks_file, \
- bbdistro = CIUtils.getVars('IMAGE_FSTYPES',
- 'WKS_FILE',
- 'DISTRO',
- target=multiconfig)
+ image_fstypes, wks_file, bbdistro = CIUtils.getVars(
+ 'IMAGE_FSTYPES', 'WKS_FILE', 'DISTRO', target=multiconfig
+ )
# only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':
if wks_file:
# ubuntu is less verbose so we do not see the message
# /etc/sysctl.d/10-console-messages.conf
- if bbdistro and "ubuntu" not in bbdistro:
- if "sdimage-efi-sd" in wks_file:
+ if bbdistro and 'ubuntu' not in bbdistro:
+ if 'sdimage-efi-sd' in wks_file:
# output we see when expand-on-first-boot runs on ext4
resize_output = b'resized filesystem to'
- if "sdimage-efi-btrfs" in wks_file:
+ if 'sdimage-efi-btrfs' in wks_file:
resize_output = b': resize device '
rc = 0
if os.path.exists(boot_log) and os.path.getsize(boot_log) > 0:
- with open(boot_log, "rb") as f1:
+ with open(boot_log, 'rb') as f1:
data = f1.read()
- if (module_output in data or skip_modulecheck):
- if resize_output and not resize_output in data:
+ if module_output in data or skip_modulecheck:
+ if resize_output and resize_output not in data:
rc = 1
self.log.error("No resize output while expected")
else:
@@ -515,13 +583,11 @@ BBPATH .= ":${LAYERDIR}"\
self.log.error("No example module output while expected")
return rc
-
def vm_dump_dict(self, vm):
- f = open(self.vm_dict_file, "wb")
+ f = open(self.vm_dict_file, 'wb')
pickle.dump(self.vm_dict, f)
f.close()
-
def vm_turn_off(self, vm):
pid = self.vm_dict[vm][0]
os.kill(pid, signal.SIGKILL)
@@ -529,24 +595,30 @@ BBPATH .= ":${LAYERDIR}"\
if self.vm_dict[vm][3]:
start_vm.sb_cleanup()
- del(self.vm_dict[vm])
+ del self.vm_dict[vm]
self.vm_dump_dict(vm)
self.log.info("Stopped VM with pid %s" % (pid))
-
- def vm_start(self, arch='amd64', distro='buster',
- enforce_pcbios=False, skip_modulecheck=False,
- image='isar-image-base', cmd=None, script=None,
- keep=False):
+ def vm_start(
+ self,
+ arch='amd64',
+ distro='buster',
+ enforce_pcbios=False,
+ skip_modulecheck=False,
+ image='isar-image-base',
+ cmd=None,
+ script=None,
+ keep=False,
+ ):
time_to_wait = self.params.get('time_to_wait', default=DEF_VM_TO_SEC)
- self.log.info('===================================================')
- self.log.info('Running Isar VM boot test for (' + distro + '-' + arch + ')')
- self.log.info('Remote command is ' + str(cmd))
- self.log.info('Remote script is ' + str(script))
- self.log.info('Isar build folder is: ' + self.build_dir)
- self.log.info('===================================================')
+ self.log.info("===================================================")
+ self.log.info(f"Running Isar VM boot test for ({distro}-{arch})")
+ self.log.info(f"Remote command is {str(cmd)}")
+ self.log.info(f"Remote script is {str(script)}")
+ self.log.info(f"Isar build folder is: {self.build_dir}")
+ self.log.info("===================================================")
self.check_init()
@@ -556,41 +628,50 @@ BBPATH .= ":${LAYERDIR}"\
p1 = None
pid = None
- cmdline = ""
- boot_log = ""
+ cmdline = ''
+ boot_log = ''
run_qemu = True
- stdout = ""
- stderr = ""
+ stdout = ''
+ stderr = ''
if vm in self.vm_dict:
pid, cmdline, boot_log, need_sb_cleanup = self.vm_dict[vm]
# Check that corresponding process exists
- proc = subprocess.run("ps -o cmd= %d" % (pid), shell=True, text=True,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc = subprocess.run(
+ f"ps -o cmd= {pid}",
+ shell=True,
+ text=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
if cmdline[0] in proc.stdout:
- self.log.info("Found '%s' process with pid '%d', use it" % (cmdline[0], pid))
+ self.log.info(
+ f"Found '{cmdline[0]}' process with pid '{pid}', use it"
+ )
run_qemu = False
if run_qemu:
- self.log.info("No qemu-system process for `%s` found, run new VM" % (vm))
+ self.log.info(
+ f"No qemu-system process for `{vm}` found, run new VM"
+ )
- p1, cmdline, boot_log, \
- need_sb_cleanup = self.vm_turn_on(arch, distro, image,
- enforce_pcbios)
+ p1, cmdline, boot_log, need_sb_cleanup = self.vm_turn_on(
+ arch, distro, image, enforce_pcbios
+ )
self.vm_dict[vm] = p1.pid, cmdline, boot_log, need_sb_cleanup
self.vm_dump_dict(vm)
rc = self.vm_wait_boot(p1, timeout)
if rc != 0:
self.vm_turn_off(vm)
- self.fail('Failed to boot qemu machine')
+ self.fail("Failed to boot qemu machine")
if cmd is not None or script is not None:
- self.ssh_user='ci'
- self.ssh_host='localhost'
+ self.ssh_user = 'ci'
+ self.ssh_host = 'localhost'
self.ssh_port = 22
for arg in cmdline:
match = re.match(r".*hostfwd=tcp::(\d*).*", arg)
@@ -599,21 +680,23 @@ BBPATH .= ":${LAYERDIR}"\
break
priv_key = self.prepare_priv_key()
- cmd_prefix = self.get_ssh_cmd_prefix(self.ssh_user, self.ssh_host, self.ssh_port, priv_key)
- self.log.info('Connect command:\n' + cmd_prefix)
+ cmd_prefix = self.get_ssh_cmd_prefix(
+ self.ssh_user, self.ssh_host, self.ssh_port, priv_key
+ )
+ self.log.info(f"Connect command:\n{cmd_prefix}")
rc, stdout, stderr = self.remote_run(cmd, script, timeout)
if rc != 0:
if not keep:
self.vm_turn_off(vm)
- self.fail('Failed to run test over ssh')
+ self.fail("Failed to run test over ssh")
else:
multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
rc = self.vm_parse_output(boot_log, multiconfig, skip_modulecheck)
if rc != 0:
if not keep:
self.vm_turn_off(vm)
- self.fail('Failed to parse output')
+ self.fail("Failed to parse output")
if not keep:
self.vm_turn_off(vm)
diff --git a/testsuite/citest.py b/testsuite/citest.py
index 8dd907d0..4e1634b7 100755
--- a/testsuite/citest.py
+++ b/testsuite/citest.py
@@ -1,8 +1,7 @@
#!/usr/bin/env python3
-import os
-
from avocado import skipUnless
+from avocado.core import exceptions
from avocado.utils import path
from cibase import CIBaseTest
from utils import CIUtils
@@ -26,22 +25,23 @@ class DevTest(CIBaseTest):
:avocado: tags=dev,fast,full
"""
+
def test_dev(self):
targets = [
'mc:qemuamd64-bullseye:isar-image-ci',
'mc:qemuarm-bullseye:isar-image-base',
'mc:qemuarm-bullseye:isar-image-base:do_populate_sdk',
'mc:qemuarm64-bullseye:isar-image-base',
- ]
+ ]
self.init()
- self.perform_build_test(targets, image_install="example-raw")
+ self.perform_build_test(targets, image_install='example-raw')
def test_dev_apps(self):
targets = [
'mc:qemuamd64-bullseye:isar-image-ci',
'mc:qemuarm64-bullseye:isar-image-base',
- ]
+ ]
self.init()
self.perform_build_test(targets)
@@ -73,6 +73,7 @@ class DevTest(CIBaseTest):
self.init()
self.vm_start('arm', 'bullseye', skip_modulecheck=True)
+
class ReproTest(CIBaseTest):
"""
@@ -80,12 +81,13 @@ class ReproTest(CIBaseTest):
:avocado: tags=repro,full
"""
+
def test_repro_signed(self):
targets = [
'mc:rpi-arm-v7-bullseye:isar-image-base',
'mc:rpi-arm64-v8-bullseye:isar-image-base',
'mc:qemuarm64-bullseye:isar-image-base',
- ]
+ ]
self.init()
try:
@@ -97,7 +99,7 @@ class ReproTest(CIBaseTest):
targets = [
'mc:qemuamd64-bullseye:isar-image-base',
'mc:qemuarm-bullseye:isar-image-base',
- ]
+ ]
self.init()
try:
@@ -105,6 +107,7 @@ class ReproTest(CIBaseTest):
finally:
self.move_in_build_dir('tmp', 'tmp_repro_unsigned')
+
class CcacheTest(CIBaseTest):
"""
@@ -112,11 +115,13 @@ class CcacheTest(CIBaseTest):
:avocado: tags=ccache,full
"""
+
def test_ccache_rebuild(self):
targets = ['mc:qemuamd64-bullseye:hello-isar']
self.init()
self.perform_ccache_test(targets)
+
class CrossTest(CIBaseTest):
"""
@@ -124,6 +129,7 @@ class CrossTest(CIBaseTest):
:avocado: tags=cross,fast,full
"""
+
def test_cross(self):
targets = [
'mc:qemuarm-buster:isar-image-ci',
@@ -135,7 +141,7 @@ class CrossTest(CIBaseTest):
'mc:qemuarm64-focal:isar-image-base',
'mc:nanopi-neo-efi-bookworm:isar-image-base',
'mc:phyboard-mira-bookworm:isar-image-base',
- ]
+ ]
self.init()
self.perform_build_test(targets, debsrc_cache=True)
@@ -143,14 +149,15 @@ class CrossTest(CIBaseTest):
def test_cross_rpi(self):
targets = [
'mc:rpi-arm-v7-bullseye:isar-image-base',
- ]
+ ]
self.init()
try:
self.perform_build_test(targets, debsrc_cache=True)
- except:
+ except exceptions.TestFail:
self.cancel('KFAIL')
+
class WicTest(CIBaseTest):
"""
@@ -158,21 +165,31 @@ class WicTest(CIBaseTest):
:avocado: tags=wic,full
"""
+
def test_wic_nodeploy_partitions(self):
targets = ['mc:qemuarm64-bookworm:isar-image-ci']
self.init()
self.move_in_build_dir('tmp', 'tmp_before_wic')
- self.perform_wic_partition_test(targets,
- wic_deploy_parts=False, debsrc_cache=True, compat_arch=False)
+ self.perform_wic_partition_test(
+ targets,
+ wic_deploy_parts=False,
+ debsrc_cache=True,
+ compat_arch=False,
+ )
def test_wic_deploy_partitions(self):
targets = ['mc:qemuarm64-bookworm:isar-image-ci']
self.init()
# reuse artifacts
- self.perform_wic_partition_test(targets,
- wic_deploy_parts=True, debsrc_cache=True, compat_arch=False)
+ self.perform_wic_partition_test(
+ targets,
+ wic_deploy_parts=True,
+ debsrc_cache=True,
+ compat_arch=False,
+ )
+
class NoCrossTest(CIBaseTest):
@@ -181,6 +198,7 @@ class NoCrossTest(CIBaseTest):
:avocado: tags=nocross,full
"""
+
def test_nocross(self):
targets = [
'mc:qemuarm-buster:isar-image-ci',
@@ -209,7 +227,7 @@ class NoCrossTest(CIBaseTest):
'mc:hikey-bookworm:isar-image-base',
'mc:de0-nano-soc-bookworm:isar-image-base',
'mc:beagleplay-bookworm:isar-image-base',
- ]
+ ]
self.init()
# Cleanup after cross build
@@ -226,12 +244,12 @@ class NoCrossTest(CIBaseTest):
'mc:rpi-arm-v7-bookworm:isar-image-base',
'mc:rpi-arm-v7l-bookworm:isar-image-base',
'mc:rpi-arm64-v8-bookworm:isar-image-base',
- ]
+ ]
self.init()
try:
self.perform_build_test(targets, cross=False, debsrc_cache=True)
- except:
+ except exceptions.TestFail:
self.cancel('KFAIL')
def test_nocross_trixie(self):
@@ -239,12 +257,12 @@ class NoCrossTest(CIBaseTest):
'mc:qemuamd64-trixie:isar-image-base',
'mc:qemuarm64-trixie:isar-image-base',
'mc:qemuarm-trixie:isar-image-base',
- ]
+ ]
self.init()
try:
self.perform_build_test(targets, cross=False)
- except:
+ except exceptions.TestFail:
self.cancel('KFAIL')
def test_nocross_sid(self):
@@ -252,14 +270,15 @@ class NoCrossTest(CIBaseTest):
'mc:qemuriscv64-sid:isar-image-base',
'mc:sifive-fu540-sid:isar-image-base',
'mc:starfive-visionfive2-sid:isar-image-base',
- ]
+ ]
self.init()
try:
self.perform_build_test(targets, cross=False)
- except:
+ except exceptions.TestFail:
self.cancel('KFAIL')
+
class ContainerImageTest(CIBaseTest):
"""
@@ -267,17 +286,19 @@ class ContainerImageTest(CIBaseTest):
:avocado: tags=containerbuild,fast,full,container
"""
+
@skipUnless(UMOCI_AVAILABLE and SKOPEO_AVAILABLE, 'umoci/skopeo not found')
def test_container_image(self):
targets = [
'mc:container-amd64-buster:isar-image-base',
'mc:container-amd64-bullseye:isar-image-base',
'mc:container-amd64-bookworm:isar-image-base',
- ]
+ ]
self.init()
self.perform_build_test(targets, container=True)
+
class ContainerSdkTest(CIBaseTest):
"""
@@ -285,35 +306,44 @@ class ContainerSdkTest(CIBaseTest):
:avocado: tags=containersdk,fast,full,container
"""
+
@skipUnless(UMOCI_AVAILABLE and SKOPEO_AVAILABLE, 'umoci/skopeo not found')
def test_container_sdk(self):
targets = ['mc:container-amd64-bullseye:isar-image-base']
self.init()
- self.perform_build_test(targets, bitbake_cmd='do_populate_sdk', container=True)
+ self.perform_build_test(
+ targets, bitbake_cmd='do_populate_sdk', container=True
+ )
+
class SignatureTest(CIBaseTest):
+
"""
Test for signature cachability issues which prevent shared state reuse.
- SstateTest also checks for these, but this test is faster and will check more cases.
+ SstateTest also checks for these, but this test is faster and will check
+ more cases.
:avocado: tags=signatures,sstate
"""
+
def test_signature_lint(self):
- verbose = bool(int(self.params.get("verbose", default=0)))
+ verbose = bool(int(self.params.get('verbose', default=0)))
targets = [
'mc:qemuamd64-bullseye:isar-image-ci',
'mc:qemuarm-bullseye:isar-image-base',
'mc:qemuarm-bullseye:isar-image-base:do_populate_sdk',
'mc:qemuarm64-bullseye:isar-image-base',
- 'mc:qemuamd64-focal:isar-image-base'
- ]
+ 'mc:qemuamd64-focal:isar-image-base',
+ ]
self.init()
self.perform_signature_lint(targets, verbose=verbose)
+
class SstateTest(CIBaseTest):
+
"""
Test builds with artifacts taken from sstate cache
@@ -332,6 +362,7 @@ class SstateTest(CIBaseTest):
self.init('build-sstate')
self.perform_sstate_test(image_target, package_target)
+
class SingleTest(CIBaseTest):
"""
@@ -339,6 +370,7 @@ class SingleTest(CIBaseTest):
:avocado: tags=single
"""
+
def test_single_build(self):
self.init()
machine = self.params.get('machine', default='qemuamd64')
@@ -354,6 +386,7 @@ class SingleTest(CIBaseTest):
self.vm_start(machine.removeprefix('qemu'), distro)
+
class SourceTest(CIBaseTest):
"""
@@ -361,15 +394,17 @@ class SourceTest(CIBaseTest):
:avocado: tags=source
"""
+
def test_source(self):
targets = [
'mc:qemuamd64-bookworm:libhello',
'mc:qemuarm64-bookworm:libhello',
- ]
+ ]
self.init()
self.perform_source_test(targets)
+
class VmBootTestFast(CIBaseTest):
"""
@@ -380,47 +415,72 @@ class VmBootTestFast(CIBaseTest):
def test_arm_bullseye(self):
self.init()
- self.vm_start('arm','bullseye', image='isar-image-ci', keep=True)
+ self.vm_start('arm', 'bullseye', image='isar-image-ci', keep=True)
def test_arm_bullseye_example_module(self):
self.init()
- self.vm_start('arm','bullseye', image='isar-image-ci',
- cmd='lsmod | grep example_module', keep=True)
+ self.vm_start(
+ 'arm',
+ 'bullseye',
+ image='isar-image-ci',
+ cmd='lsmod | grep example_module',
+ keep=True,
+ )
def test_arm_bullseye_getty_target(self):
self.init()
- self.vm_start('arm','bullseye', image='isar-image-ci',
- script='test_systemd_unit.sh getty.target 10')
-
+ self.vm_start(
+ 'arm',
+ 'bullseye',
+ image='isar-image-ci',
+ script='test_systemd_unit.sh getty.target 10',
+ )
def test_arm_buster(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci', keep=True)
+ self.vm_start('arm', 'buster', image='isar-image-ci', keep=True)
def test_arm_buster_getty_target(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci',
- cmd='systemctl is-active getty.target', keep=True)
+ self.vm_start(
+ 'arm',
+ 'buster',
+ image='isar-image-ci',
+ cmd='systemctl is-active getty.target',
+ keep=True,
+ )
def test_arm_buster_example_module(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci',
- script='test_kernel_module.sh example_module')
-
+ self.vm_start(
+ 'arm',
+ 'buster',
+ image='isar-image-ci',
+ script='test_kernel_module.sh example_module',
+ )
def test_arm_bookworm(self):
self.init()
- self.vm_start('arm','bookworm', image='isar-image-ci', keep=True)
+ self.vm_start('arm', 'bookworm', image='isar-image-ci', keep=True)
def test_arm_bookworm_example_module(self):
self.init()
- self.vm_start('arm','bookworm', image='isar-image-ci',
- cmd='lsmod | grep example_module', keep=True)
+ self.vm_start(
+ 'arm',
+ 'bookworm',
+ image='isar-image-ci',
+ cmd='lsmod | grep example_module',
+ keep=True,
+ )
def test_arm_bookworm_getty_target(self):
self.init()
- self.vm_start('arm','bookworm', image='isar-image-ci',
- script='test_systemd_unit.sh getty.target 10')
+ self.vm_start(
+ 'arm',
+ 'bookworm',
+ image='isar-image-ci',
+ script='test_systemd_unit.sh getty.target 10',
+ )
class VmBootTestFull(CIBaseTest):
@@ -433,92 +493,119 @@ class VmBootTestFull(CIBaseTest):
def test_arm_bullseye(self):
self.init()
- self.vm_start('arm','bullseye')
-
+ self.vm_start('arm', 'bullseye')
def test_arm_buster(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci', keep=True)
+ self.vm_start('arm', 'buster', image='isar-image-ci', keep=True)
def test_arm_buster_example_module(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci',
- cmd='lsmod | grep example_module', keep=True)
+ self.vm_start(
+ 'arm',
+ 'buster',
+ image='isar-image-ci',
+ cmd='lsmod | grep example_module',
+ keep=True,
+ )
def test_arm_buster_getty_target(self):
self.init()
- self.vm_start('arm','buster', image='isar-image-ci',
- script='test_systemd_unit.sh getty.target 10')
-
+ self.vm_start(
+ 'arm',
+ 'buster',
+ image='isar-image-ci',
+ script='test_systemd_unit.sh getty.target 10',
+ )
def test_arm64_bullseye(self):
self.init()
- self.vm_start('arm64','bullseye', image='isar-image-ci', keep=True)
+ self.vm_start('arm64', 'bullseye', image='isar-image-ci', keep=True)
def test_arm64_bullseye_getty_target(self):
self.init()
- self.vm_start('arm64','bullseye', image='isar-image-ci',
- cmd='systemctl is-active getty.target', keep=True)
+ self.vm_start(
+ 'arm64',
+ 'bullseye',
+ image='isar-image-ci',
+ cmd='systemctl is-active getty.target',
+ keep=True,
+ )
def test_arm64_bullseye_example_module(self):
self.init()
- self.vm_start('arm64','bullseye', image='isar-image-ci',
- script='test_kernel_module.sh example_module')
-
+ self.vm_start(
+ 'arm64',
+ 'bullseye',
+ image='isar-image-ci',
+ script='test_kernel_module.sh example_module',
+ )
def test_i386_buster(self):
self.init()
- self.vm_start('i386','buster')
-
+ self.vm_start('i386', 'buster')
def test_amd64_buster(self):
self.init()
# test efi boot
- self.vm_start('amd64','buster', image='isar-image-ci')
+ self.vm_start('amd64', 'buster', image='isar-image-ci')
# test pcbios boot
self.vm_start('amd64', 'buster', True, image='isar-image-ci')
-
def test_amd64_focal(self):
self.init()
- self.vm_start('amd64','focal', image='isar-image-ci', keep=True)
+ self.vm_start('amd64', 'focal', image='isar-image-ci', keep=True)
def test_amd64_focal_example_module(self):
self.init()
- self.vm_start('amd64','focal', image='isar-image-ci',
- cmd='lsmod | grep example_module', keep=True)
+ self.vm_start(
+ 'amd64',
+ 'focal',
+ image='isar-image-ci',
+ cmd='lsmod | grep example_module',
+ keep=True,
+ )
def test_amd64_focal_getty_target(self):
self.init()
- self.vm_start('amd64','focal', image='isar-image-ci',
- script='test_systemd_unit.sh getty.target 10')
-
+ self.vm_start(
+ 'amd64',
+ 'focal',
+ image='isar-image-ci',
+ script='test_systemd_unit.sh getty.target 10',
+ )
def test_amd64_bookworm(self):
self.init()
self.vm_start('amd64', 'bookworm', image='isar-image-ci')
-
def test_arm_bookworm(self):
self.init()
- self.vm_start('arm','bookworm', image='isar-image-ci')
-
+ self.vm_start('arm', 'bookworm', image='isar-image-ci')
def test_i386_bookworm(self):
self.init()
- self.vm_start('i386','bookworm')
-
+ self.vm_start('i386', 'bookworm')
def test_mipsel_bookworm(self):
self.init()
- self.vm_start('mipsel','bookworm', image='isar-image-ci', keep=True)
+ self.vm_start('mipsel', 'bookworm', image='isar-image-ci', keep=True)
def test_mipsel_bookworm_getty_target(self):
self.init()
- self.vm_start('mipsel','bookworm', image='isar-image-ci',
- cmd='systemctl is-active getty.target', keep=True)
+ self.vm_start(
+ 'mipsel',
+ 'bookworm',
+ image='isar-image-ci',
+ cmd='systemctl is-active getty.target',
+ keep=True,
+ )
def test_mipsel_bookworm_example_module(self):
self.init()
- self.vm_start('mipsel','bookworm', image='isar-image-ci',
- script='test_kernel_module.sh example_module')
+ self.vm_start(
+ 'mipsel',
+ 'bookworm',
+ image='isar-image-ci',
+ script='test_kernel_module.sh example_module',
+ )
diff --git a/testsuite/repro-build-test.py b/testsuite/repro-build-test.py
index 04e4ddc7..d24e8f84 100755
--- a/testsuite/repro-build-test.py
+++ b/testsuite/repro-build-test.py
@@ -15,32 +15,33 @@ class ReproBuild(CIBuilder):
def test_repro_build(self):
target = self.params.get(
- "build_target", default="mc:qemuamd64-bullseye:isar-image-base"
+ 'build_target', default='mc:qemuamd64-bullseye:isar-image-base'
)
source_date_epoch = self.params.get(
- "source_date_epoch", default=self.git_last_commit_timestamp()
+ 'source_date_epoch', default=self.git_last_commit_timestamp()
)
self.init()
- self.build_repro_image(target, source_date_epoch, "image1.tar.gz")
- self.build_repro_image(target, source_date_epoch, "image2.tar.gz")
- self.compare_repro_image("image1.tar.gz", "image2.tar.gz")
+ self.build_repro_image(target, source_date_epoch, 'image1.tar.gz')
+ self.build_repro_image(target, source_date_epoch, 'image2.tar.gz')
+ self.compare_repro_image('image1.tar.gz', 'image2.tar.gz')
def git_last_commit_timestamp(self):
- return process.run("git log -1 --pretty=%ct").stdout.decode().strip()
+ return process.run('git log -1 --pretty=%ct').stdout.decode().strip()
def get_image_path(self, target_name):
- image_dir = "tmp/deploy/images"
- machine, image_name = CIUtils.getVars('MACHINE', 'IMAGE_FULLNAME',
- target=target_name)
+ image_dir = 'tmp/deploy/images'
+ machine, image_name = CIUtils.getVars(
+ 'MACHINE', 'IMAGE_FULLNAME', target=target_name
+ )
return f"{image_dir}/{machine}/{image_name}.tar.gz"
def build_repro_image(
- self, target, source_date_epoch=None, image_name="image.tar.gz"
+ self, target, source_date_epoch=None, image_name='image.tar.gz'
):
-
if not source_date_epoch:
self.error(
- "Reproducible build should configure with source_date_epoch time"
+ "Reproducible build should configure with "
+ "source_date_epoch time"
)
# clean artifacts before build
@@ -48,7 +49,9 @@ class ReproBuild(CIBuilder):
# Build
self.log.info("Started Build " + image_name)
- self.configure(source_date_epoch=source_date_epoch, use_apt_snapshot=True)
+ self.configure(
+ source_date_epoch=source_date_epoch, use_apt_snapshot=True
+ )
self.bitbake(target)
# copy the artifacts image name with given name
@@ -57,18 +60,16 @@ class ReproBuild(CIBuilder):
self.move_in_build_dir(image_path, image_name)
def clean(self):
- self.delete_from_build_dir("tmp")
- self.delete_from_build_dir("sstate-cache")
+ self.delete_from_build_dir('tmp')
+ self.delete_from_build_dir('sstate-cache')
def compare_repro_image(self, image1, image2):
self.log.info(
"Compare artifacts image1: " + image1 + ", image2: " + image2
)
result = process.run(
- "diffoscope "
- "--text " + self.build_dir + "/diffoscope-output.txt"
- " " + self.build_dir + "/" + image1 +
- " " + self.build_dir + "/" + image2,
+ f"diffoscope --text {self.build_dir}/diffoscope-output.txt"
+ f" {self.build_dir}/{image1} {self.build_dir}/{image2}",
ignore_status=True,
)
if result.exit_status > 0:
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index d6e04049..2c986344 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -9,43 +9,48 @@ import socket
import subprocess
import sys
import shutil
-import time
from utils import CIUtils
OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'
-def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
- multiconfig = f'mc:qemu{arch}-{distro}:{image}'
-
- image_fstypes, \
- deploy_dir_image, \
- kernel_image, \
- initrd_image, \
- serial, \
- root_dev, \
- qemu_arch, \
- qemu_machine, \
- qemu_cpu, \
- qemu_disk_args = CIUtils.getVars('IMAGE_FSTYPES',
- 'DEPLOY_DIR_IMAGE',
- 'KERNEL_IMAGE',
- 'INITRD_DEPLOY_FILE',
- 'MACHINE_SERIAL',
- 'QEMU_ROOTFS_DEV',
- 'QEMU_ARCH',
- 'QEMU_MACHINE',
- 'QEMU_CPU',
- 'QEMU_DISK_ARGS',
- target=multiconfig)
+
+def format_qemu_cmdline(
+ arch, build, distro, image, out, pid, enforce_pcbios=False
+):
+ multiconfig = f"mc:qemu{arch}-{distro}:{image}"
+
+ (
+ image_fstypes,
+ deploy_dir_image,
+ kernel_image,
+ initrd_image,
+ serial,
+ root_dev,
+ qemu_arch,
+ qemu_machine,
+ qemu_cpu,
+ qemu_disk_args,
+ ) = CIUtils.getVars(
+ 'IMAGE_FSTYPES',
+ 'DEPLOY_DIR_IMAGE',
+ 'KERNEL_IMAGE',
+ 'INITRD_DEPLOY_FILE',
+ 'MACHINE_SERIAL',
+ 'QEMU_ROOTFS_DEV',
+ 'QEMU_ARCH',
+ 'QEMU_MACHINE',
+ 'QEMU_CPU',
+ 'QEMU_DISK_ARGS',
+ target=multiconfig,
+ )
extra_args = ''
- cpu = ['']
image_type = image_fstypes.split()[0]
base = 'ubuntu' if distro in ['jammy', 'focal'] else 'debian'
- rootfs_image = image + '-' + base + '-' + distro + '-qemu' + arch + '.' + image_type
+ rootfs_image = f"{image}-{base}-{distro}-qemu{arch}.{image_type}"
if image_type == 'ext4':
kernel_image = deploy_dir_image + '/' + kernel_image
@@ -55,33 +60,37 @@ def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal
else:
initrd_image = deploy_dir_image + '/' + initrd_image
- kargs = ['-append', '"console=' + serial + ' root=/dev/' + root_dev + ' rw"']
+ kargs = ['-append', f'"console={serial} root=/dev/{root_dev} rw"']
extra_args = ['-kernel', kernel_image, '-initrd', initrd_image]
extra_args.extend(kargs)
elif image_type == 'wic':
extra_args = ['-snapshot']
else:
- raise ValueError('Invalid image type: ' + str(image_type))
+ raise ValueError(f"Invalid image type: {str(image_type)}")
if out:
- extra_args.extend(['-chardev','stdio,id=ch0,logfile=' + out])
- extra_args.extend(['-serial','chardev:ch0'])
- extra_args.extend(['-monitor','none'])
+ extra_args.extend(['-chardev', 'stdio,id=ch0,logfile=' + out])
+ extra_args.extend(['-serial', 'chardev:ch0'])
+ extra_args.extend(['-monitor', 'none'])
if pid:
extra_args.extend(['-pidfile', pid])
- qemu_disk_args = qemu_disk_args.replace('##ROOTFS_IMAGE##', deploy_dir_image + '/' + rootfs_image).split()
+ rootfs_path = os.path.join(deploy_dir_image, rootfs_image)
+ qemu_disk_args = qemu_disk_args.replace('##ROOTFS_IMAGE##', rootfs_path)
+ qemu_disk_args = qemu_disk_args.split()
if enforce_pcbios and '-bios' in qemu_disk_args:
bios_idx = qemu_disk_args.index('-bios')
- del qemu_disk_args[bios_idx : bios_idx+2]
+ del qemu_disk_args[bios_idx : bios_idx + 2]
# Support SSH access from host
ssh_sock = socket.socket()
ssh_sock.bind(('', 0))
- ssh_port=ssh_sock.getsockname()[1]
+ ssh_port = ssh_sock.getsockname()[1]
extra_args.extend(['-device', 'e1000,netdev=net0'])
- extra_args.extend(['-netdev', 'user,id=net0,hostfwd=tcp::' + str(ssh_port) + '-:22'])
+ extra_args.extend(
+ ['-netdev', 'user,id=net0,hostfwd=tcp::' + str(ssh_port) + '-:22']
+ )
cmd = ['qemu-system-' + qemu_arch, '-m', '1024M']
@@ -105,8 +114,10 @@ def sb_copy_vars(cmdline):
if os.path.exists(ovmf_vars_filename):
break
if not os.path.exists(OVMF_VARS_PATH):
- print(f'{OVMF_VARS_PATH} required but not found!',
- file=sys.stderr)
+ print(
+ f"{OVMF_VARS_PATH} required but not found!",
+ file=sys.stderr,
+ )
break
shutil.copy(OVMF_VARS_PATH, ovmf_vars_filename)
return True
@@ -119,7 +130,9 @@ def sb_cleanup():
def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
- cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios)
+ cmdline = format_qemu_cmdline(
+ arch, build, distro, image, out, pid, enforce_pcbios
+ )
cmdline.insert(1, '-nographic')
need_cleanup = sb_copy_vars(cmdline)
@@ -136,17 +149,60 @@ def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
def parse_args():
parser = argparse.ArgumentParser()
arch_names = ['arm', 'arm64', 'amd64', 'amd64-sb', 'i386', 'mipsel']
- parser.add_argument('-a', '--arch', choices=arch_names,
- help='set isar machine architecture.', default='arm')
- parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())
- parser.add_argument('-d', '--distro', choices=['buster', 'bullseye', 'bookworm', 'trixie', 'focal', 'jammy'], help='set isar Debian distribution.', default='bookworm')
- parser.add_argument('-i', '--image', help='set image name.', default='isar-image-base')
- parser.add_argument('-o', '--out', help='Route QEMU console output to specified file.')
- parser.add_argument('-p', '--pid', help='Store QEMU pid to specified file.')
- parser.add_argument('--pcbios', action="store_true", help='remove any bios options to enforce use of pc bios')
+ distro_names = [
+ 'buster',
+ 'bullseye',
+ 'bookworm',
+ 'trixie',
+ 'focal',
+ 'jammy',
+ ]
+ parser.add_argument(
+ '-a',
+ '--arch',
+ choices=arch_names,
+ help='set isar machine architecture.',
+ default='arm',
+ )
+ parser.add_argument(
+ '-b',
+ '--build',
+ help='set path to build directory.',
+ default=os.getcwd(),
+ )
+ parser.add_argument(
+ '-d',
+ '--distro',
+ choices=distro_names,
+ help='set isar Debian distribution.',
+ default='bookworm',
+ )
+ parser.add_argument(
+ '-i', '--image', help='set image name.', default='isar-image-base'
+ )
+ parser.add_argument(
+ '-o', '--out', help='Route QEMU console output to specified file.'
+ )
+ parser.add_argument(
+ '-p', '--pid', help='Store QEMU pid to specified file.'
+ )
+ parser.add_argument(
+ '--pcbios',
+ action='store_true',
+ help='remove any ' 'bios options to enforce use of pc bios',
+ )
return parser.parse_args()
-if __name__ == "__main__":
+
+if __name__ == '__main__':
args = parse_args()
- start_qemu(args.arch, args.build, args.distro, args.image, args.out, args.pid, args.pcbios)
+ start_qemu(
+ args.arch,
+ args.build,
+ args.distro,
+ args.image,
+ args.out,
+ args.pid,
+ args.pcbios,
+ )
diff --git a/testsuite/unittests/bitbake.py b/testsuite/unittests/bitbake.py
index 1e2f685a..66cd0b2c 100644
--- a/testsuite/unittests/bitbake.py
+++ b/testsuite/unittests/bitbake.py
@@ -3,35 +3,35 @@
#
# SPDX-License-Identifier: MIT
+import os
import sys
-import pathlib
from typing import Callable
-location = pathlib.Path(__file__).parent.resolve()
-sys.path.insert(0, "{}/../../bitbake/lib".format(location))
+location = os.path.dirname(__file__)
+sys.path.append(os.path.join(location, "../../bitbake/lib"))
from bb.parse import handle
from bb.data import init
-# Modules added for reimport from testfiles
-from bb.data_smart import DataSmart
-
def load_function(file_name: str, function_name: str) -> Callable:
"""Load a python function defined in a bitbake file.
Args:
- file_name (str): The path to the file e.g. `meta/classes/my_special.bbclass`.
- function_name (str): The name of the python function without braces e.g. `my_special_function`
+ file_name (str): The path to the file
+ e.g. `meta/classes/my_special.bbclass`.
+ function_name (str): The name of the python function without braces
+ e.g. `my_special_function`
Returns:
Callable: The loaded function.
"""
d = init()
- parse = handle("{}/../../{}".format(location, file_name), d)
+ parse = handle(f"{location}/../../{file_name}", d)
if function_name not in parse:
- raise KeyError("Function {} does not exist in {}".format(
- function_name, file_name))
+ raise KeyError(
+ f"Function {function_name} does not exist in {file_name}"
+ )
namespace = {}
exec(parse[function_name], namespace)
return namespace[function_name]
diff --git a/testsuite/unittests/rootfs.py b/testsuite/unittests/rootfs.py
index 6c511493..da97d0d3 100644
--- a/testsuite/unittests/rootfs.py
+++ b/testsuite/unittests/rootfs.py
@@ -12,7 +12,7 @@ temp_dirs = []
class TemporaryRootfs:
- """ A temporary rootfs folder that will be removed after the testrun. """
+ """A temporary rootfs folder that will be removed after the testrun."""
def __init__(self):
self._rootfs_path = tempfile.mkdtemp()
@@ -22,7 +22,7 @@ class TemporaryRootfs:
return self._rootfs_path
def create_file(self, path: str, content: str) -> None:
- """ Create a file with the given content.
+ """Create a file with the given content.
Args:
path (str): The path to the file e.g. `/etc/hostname`.
@@ -31,8 +31,9 @@ class TemporaryRootfs:
Returns:
None
"""
- pathlib.Path(self._rootfs_path +
- path).parent.mkdir(parents=True, exist_ok=True)
+ pathlib.Path(self._rootfs_path + path).parent.mkdir(
+ parents=True, exist_ok=True
+ )
with open(self._rootfs_path + path, 'w') as file:
file.write(content)
diff --git a/testsuite/unittests/test_image_account_extension.py b/testsuite/unittests/test_image_account_extension.py
index 08021a4a..636c2a8b 100644
--- a/testsuite/unittests/test_image_account_extension.py
+++ b/testsuite/unittests/test_image_account_extension.py
@@ -3,158 +3,202 @@
#
# SPDX-License-Identifier: MIT
-from bitbake import load_function, DataSmart
+from bitbake import load_function
from rootfs import TemporaryRootfs
+import os
+import sys
import unittest
from unittest.mock import patch
from typing import Tuple
+sys.path.append(os.path.join(os.path.dirname(__file__), '../../bitbake/lib'))
-file_name = "meta/classes/image-account-extension.bbclass"
-image_create_users = load_function(file_name, "image_create_users")
-image_create_groups = load_function(file_name, "image_create_groups")
+from bb import process
+from bb.data_smart import DataSmart
+file_name = 'meta/classes/image-account-extension.bbclass'
+image_create_users = load_function(file_name, 'image_create_users')
+image_create_groups = load_function(file_name, 'image_create_groups')
-class TestImageAccountExtensionCommon(unittest.TestCase):
+class TestImageAccountExtensionCommon(unittest.TestCase):
def setup(self) -> Tuple[DataSmart, TemporaryRootfs]:
rootfs = TemporaryRootfs()
d = DataSmart()
- d.setVar("ROOTFSDIR", rootfs.path())
+ d.setVar('ROOTFSDIR', rootfs.path())
return (d, rootfs)
-class TestImageAccountExtensionImageCreateUsers(TestImageAccountExtensionCommon):
-
+class TestImageAccountExtensionImageCreateUsers(
+ TestImageAccountExtensionCommon
+):
def setup(self, user_name: str) -> Tuple[DataSmart, TemporaryRootfs]:
d, rootfs = super().setup()
rootfs.create_file(
- "/etc/passwd", "test:x:1000:1000::/home/test:/bin/sh")
- d.setVar("USERS", user_name)
+ '/etc/passwd', 'test:x:1000:1000::/home/test:/bin/sh'
+ )
+ d.setVar('USERS', user_name)
return (d, rootfs)
def test_new_user(self):
- test_user = "new"
+ test_user = 'new'
d, rootfs = self.setup(test_user)
- # make the list a bit clumsy to simulate appends and removals to that var
- d.setVarFlag('USER_{}'.format(test_user), 'groups', 'dialout render foo ')
+ # Make the list a bit clumsy to simulate appends and removals to that
+ # var
+ d.setVarFlag(f"USER_{test_user}", 'groups', 'dialout render foo ')
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_users(d)
run_mock.assert_called_once_with(
- ["sudo", "-E", "chroot", rootfs.path(), "/usr/sbin/useradd",
- '--groups', 'dialout,render,foo', test_user])
+ [
+ 'sudo',
+ '-E',
+ 'chroot',
+ rootfs.path(),
+ '/usr/sbin/useradd',
+ '--groups',
+ 'dialout,render,foo',
+ test_user,
+ ]
+ )
def test_existing_user_no_change(self):
- test_user = "test"
+ test_user = 'test'
d, _ = self.setup(test_user)
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_users(d)
run_mock.assert_not_called()
def test_existing_user_home_change(self):
- test_user = "test"
+ test_user = 'test'
d, _ = self.setup(test_user)
- d.setVarFlag("USER_{}".format(test_user), "home", "/home/new_home")
+ d.setVarFlag(f"USER_{test_user}", 'home', '/home/new_home')
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_users(d)
assert run_mock.call_count == 1
- assert run_mock.call_args[0][0][-5:] == ["/usr/sbin/usermod",
- '--home', '/home/new_home', '--move-home', 'test']
+ assert run_mock.call_args[0][0][-5:] == [
+ '/usr/sbin/usermod',
+ '--home',
+ '/home/new_home',
+ '--move-home',
+ 'test',
+ ]
def test_deterministic_password(self):
- test_user = "new"
- cleartext_password = "test"
+ test_user = 'new'
+ cleartext_password = 'test'
d, _ = self.setup(test_user)
- d.setVarFlag("USER_{}".format(test_user),
- "flags", "clear-text-password")
- d.setVarFlag("USER_{}".format(test_user),
- "password", cleartext_password)
+ d.setVarFlag(f"USER_{test_user}", 'flags', 'clear-text-password')
+ d.setVarFlag(f"USER_{test_user}", 'password', cleartext_password)
- source_date_epoch = "1672427776"
- d.setVar("SOURCE_DATE_EPOCH", source_date_epoch)
+ source_date_epoch = '1672427776'
+ d.setVar('SOURCE_DATE_EPOCH', source_date_epoch)
- # openssl passwd -6 -salt $(echo "1672427776" | sha256sum -z | cut -c 1-15) test
- encrypted_password = "$6$eb2e2a12cccc88a$IuhgisFe5AKM5.VREKg8wIAcPSkaJDWBM1cMUsEjNZh2Wa6BT2f5OFhqGTGpL4lFzHGN8oiwvAh0jFO1GhO3S."
+ # openssl passwd -6 -salt $(echo "1672427776" | sha256sum -z | cut \
+ # -c 1-15) test
+ encrypted_password = (
+ '$6$eb2e2a12cccc88a$IuhgisFe5AKM5.VREKg8wIAcPSkaJDWBM1cMUsEjNZh2W'
+ 'a6BT2f5OFhqGTGpL4lFzHGN8oiwvAh0jFO1GhO3S.'
+ )
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_users(d)
- assert run_mock.call_count == 2
- assert run_mock.call_args[0][1] == "{}:{}".format(
- test_user, encrypted_password).encode()
+ password_data = f"{test_user}:{encrypted_password}".encode()
+ assert run_mock.call_count == 2
+ assert run_mock.call_args[0][1] == password_data
-class TestImageAccountExtensionImageCreateGroups(TestImageAccountExtensionCommon):
+class TestImageAccountExtensionImageCreateGroups(
+ TestImageAccountExtensionCommon
+):
def setup(self, group_name: str) -> Tuple[DataSmart, TemporaryRootfs]:
d, rootfs = super().setup()
- rootfs.create_file("/etc/group", "test:x:1000:test")
- d.setVar("GROUPS", group_name)
+ rootfs.create_file('/etc/group', 'test:x:1000:test')
+ d.setVar('GROUPS', group_name)
return (d, rootfs)
def test_new_group(self):
- test_group = "new"
+ test_group = 'new'
d, rootfs = self.setup(test_group)
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_groups(d)
run_mock.assert_called_once_with(
- ["sudo", "-E", "chroot", rootfs.path(), "/usr/sbin/groupadd", test_group])
+ [
+ 'sudo',
+ '-E',
+ 'chroot',
+ rootfs.path(),
+ '/usr/sbin/groupadd',
+ test_group,
+ ]
+ )
def test_existing_group_no_change(self):
- test_group = "test"
+ test_group = 'test'
d, _ = self.setup(test_group)
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_groups(d)
run_mock.assert_not_called()
def test_existing_group_id_change(self):
- test_group = "test"
+ test_group = 'test'
d, rootfs = self.setup(test_group)
- d.setVarFlag("GROUP_{}".format(test_group), "gid", "1005")
+ d.setVarFlag(f"GROUP_{test_group}", 'gid', '1005')
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_groups(d)
run_mock.assert_called_once_with(
- ["sudo", "-E", "chroot", rootfs.path(), "/usr/sbin/groupmod", "--gid", "1005", test_group])
+ [
+ 'sudo',
+ '-E',
+ 'chroot',
+ rootfs.path(),
+ '/usr/sbin/groupmod',
+ '--gid',
+ '1005',
+ test_group,
+ ]
+ )
def test_new_group_system_flag(self):
- test_group = "new"
+ test_group = 'new'
d, _ = self.setup(test_group)
- d.setVarFlag("GROUP_{}".format(test_group), "flags", "system")
+ d.setVarFlag(f"GROUP_{test_group}", 'flags', 'system')
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_groups(d)
assert run_mock.call_count == 1
- assert "--system" in run_mock.call_args[0][0]
+ assert '--system' in run_mock.call_args[0][0]
def test_existing_group_no_system_flag(self):
- test_group = "test"
+ test_group = 'test'
d, _ = self.setup(test_group)
- d.setVarFlag("GROUP_{}".format(test_group), "flags", "system")
- d.setVarFlag("GROUP_{}".format(test_group), "gid", "1005")
+ d.setVarFlag(f"GROUP_{test_group}", 'flags', 'system')
+ d.setVarFlag(f"GROUP_{test_group}", 'gid', '1005')
- with patch.object(bb.process, "run") as run_mock:
+ with patch.object(process, 'run') as run_mock:
image_create_groups(d)
assert run_mock.call_count == 1
- assert "--system" not in run_mock.call_args[0][0]
+ assert '--system' not in run_mock.call_args[0][0]
-if __name__ == "__main__":
+if __name__ == '__main__':
unittest.main()
--
2.34.1
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/isar-users/20240719062940.2601132-3-amikan%40ilbers.de.
^ permalink raw reply [flat|nested] 4+ messages in thread