summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r--meta/lib/oeqa/core/runner.py2
-rw-r--r--meta/lib/oeqa/core/target/ssh.py16
-rw-r--r--meta/lib/oeqa/runtime/cases/ssh.py4
-rw-r--r--meta/lib/oeqa/sdk/context.py12
-rw-r--r--meta/lib/oeqa/selftest/cases/devtool.py2
-rw-r--r--meta/lib/oeqa/selftest/cases/meta_ide.py4
-rw-r--r--meta/lib/oeqa/selftest/cases/overlayfs.py41
-rw-r--r--meta/lib/oeqa/selftest/cases/reproducible.py10
-rw-r--r--meta/lib/oeqa/selftest/cases/rust.py13
-rw-r--r--meta/lib/oeqa/selftest/cases/sstatetests.py2
-rw-r--r--meta/lib/oeqa/utils/gitarchive.py4
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py11
12 files changed, 79 insertions, 42 deletions
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index a86a706bd9..b683d9b80a 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -357,7 +357,7 @@ class OETestResultJSONHelper(object):
357 os.makedirs(write_dir, exist_ok=True) 357 os.makedirs(write_dir, exist_ok=True)
358 test_results = self._get_existing_testresults_if_available(write_dir) 358 test_results = self._get_existing_testresults_if_available(write_dir)
359 test_results[result_id] = {'configuration': configuration, 'result': test_result} 359 test_results[result_id] = {'configuration': configuration, 'result': test_result}
360 json_testresults = json.dumps(test_results, sort_keys=True, indent=4) 360 json_testresults = json.dumps(test_results, sort_keys=True, indent=1)
361 self._write_file(write_dir, self.testresult_filename, json_testresults) 361 self._write_file(write_dir, self.testresult_filename, json_testresults)
362 if has_bb: 362 if has_bb:
363 bb.utils.unlockfile(lf) 363 bb.utils.unlockfile(lf)
diff --git a/meta/lib/oeqa/core/target/ssh.py b/meta/lib/oeqa/core/target/ssh.py
index 09cdd14c75..d473469384 100644
--- a/meta/lib/oeqa/core/target/ssh.py
+++ b/meta/lib/oeqa/core/target/ssh.py
@@ -55,14 +55,14 @@ class OESSHTarget(OETarget):
55 def stop(self, **kwargs): 55 def stop(self, **kwargs):
56 pass 56 pass
57 57
58 def _run(self, command, timeout=None, ignore_status=True): 58 def _run(self, command, timeout=None, ignore_status=True, raw=False):
59 """ 59 """
60 Runs command in target using SSHProcess. 60 Runs command in target using SSHProcess.
61 """ 61 """
62 self.logger.debug("[Running]$ %s" % " ".join(command)) 62 self.logger.debug("[Running]$ %s" % " ".join(command))
63 63
64 starttime = time.time() 64 starttime = time.time()
65 status, output = SSHCall(command, self.logger, timeout) 65 status, output = SSHCall(command, self.logger, timeout, raw)
66 self.logger.debug("[Command returned '%d' after %.2f seconds]" 66 self.logger.debug("[Command returned '%d' after %.2f seconds]"
67 "" % (status, time.time() - starttime)) 67 "" % (status, time.time() - starttime))
68 68
@@ -72,7 +72,7 @@ class OESSHTarget(OETarget):
72 72
73 return (status, output) 73 return (status, output)
74 74
75 def run(self, command, timeout=None, ignore_status=True): 75 def run(self, command, timeout=None, ignore_status=True, raw=False):
76 """ 76 """
77 Runs command in target. 77 Runs command in target.
78 78
@@ -91,7 +91,7 @@ class OESSHTarget(OETarget):
91 else: 91 else:
92 processTimeout = self.timeout 92 processTimeout = self.timeout
93 93
94 status, output = self._run(sshCmd, processTimeout, ignore_status) 94 status, output = self._run(sshCmd, processTimeout, ignore_status, raw)
95 self.logger.debug('Command: %s\nStatus: %d Output: %s\n' % (command, status, output)) 95 self.logger.debug('Command: %s\nStatus: %d Output: %s\n' % (command, status, output))
96 96
97 return (status, output) 97 return (status, output)
@@ -206,7 +206,7 @@ class OESSHTarget(OETarget):
206 remoteDir = os.path.join(remotePath, tmpDir.lstrip("/")) 206 remoteDir = os.path.join(remotePath, tmpDir.lstrip("/"))
207 self.deleteDir(remoteDir) 207 self.deleteDir(remoteDir)
208 208
209def SSHCall(command, logger, timeout=None, **opts): 209def SSHCall(command, logger, timeout=None, raw=False, **opts):
210 210
211 def run(): 211 def run():
212 nonlocal output 212 nonlocal output
@@ -265,7 +265,7 @@ def SSHCall(command, logger, timeout=None, **opts):
265 else: 265 else:
266 output_raw = process.communicate()[0] 266 output_raw = process.communicate()[0]
267 267
268 output = output_raw.decode('utf-8', errors='ignore') 268 output = output_raw if raw else output_raw.decode('utf-8', errors='ignore')
269 logger.debug('Data from SSH call:\n%s' % output.rstrip()) 269 logger.debug('Data from SSH call:\n%s' % output.rstrip())
270 270
271 # timout or not, make sure process exits and is not hanging 271 # timout or not, make sure process exits and is not hanging
@@ -292,7 +292,7 @@ def SSHCall(command, logger, timeout=None, **opts):
292 292
293 options = { 293 options = {
294 "stdout": subprocess.PIPE, 294 "stdout": subprocess.PIPE,
295 "stderr": subprocess.STDOUT, 295 "stderr": subprocess.STDOUT if not raw else None,
296 "stdin": None, 296 "stdin": None,
297 "shell": False, 297 "shell": False,
298 "bufsize": -1, 298 "bufsize": -1,
@@ -320,4 +320,4 @@ def SSHCall(command, logger, timeout=None, **opts):
320 logger.debug('Something went wrong, killing SSH process') 320 logger.debug('Something went wrong, killing SSH process')
321 raise 321 raise
322 322
323 return (process.returncode, output.rstrip()) 323 return (process.returncode, output if raw else output.rstrip())
diff --git a/meta/lib/oeqa/runtime/cases/ssh.py b/meta/lib/oeqa/runtime/cases/ssh.py
index b86428002f..89d64430e5 100644
--- a/meta/lib/oeqa/runtime/cases/ssh.py
+++ b/meta/lib/oeqa/runtime/cases/ssh.py
@@ -16,8 +16,8 @@ class SSHTest(OERuntimeTestCase):
16 @OETestDepends(['ping.PingTest.test_ping']) 16 @OETestDepends(['ping.PingTest.test_ping'])
17 @OEHasPackage(['dropbear', 'openssh-sshd']) 17 @OEHasPackage(['dropbear', 'openssh-sshd'])
18 def test_ssh(self): 18 def test_ssh(self):
19 for i in range(20): 19 for i in range(5):
20 status, output = self.target.run("uname -a", timeout=5) 20 status, output = self.target.run("uname -a", timeout=30)
21 if status == 0: 21 if status == 0:
22 break 22 break
23 elif status == 255 or status == -signal.SIGTERM: 23 elif status == 255 or status == -signal.SIGTERM:
diff --git a/meta/lib/oeqa/sdk/context.py b/meta/lib/oeqa/sdk/context.py
index 01c38c24e6..77e6a98f39 100644
--- a/meta/lib/oeqa/sdk/context.py
+++ b/meta/lib/oeqa/sdk/context.py
@@ -41,11 +41,13 @@ class OESDKTestContext(OETestContext):
41 41
42 def hasTargetPackage(self, pkg, multilib=False, regex=False): 42 def hasTargetPackage(self, pkg, multilib=False, regex=False):
43 if multilib: 43 if multilib:
44 # match multilib according to sdk_env 44 stripped_sdk_env = os.path.basename(self.sdk_env)
45 mls = self.td.get('MULTILIB_VARIANTS', '').split() 45 if stripped_sdk_env.startswith('environment-setup-'):
46 for ml in mls: 46 # match multilib according to sdk_env
47 if ('ml'+ml) in self.sdk_env: 47 mls = self.td.get('MULTILIB_VARIANTS', '').split()
48 pkg = ml + '-' + pkg 48 for ml in mls:
49 if ('ml'+ml) in stripped_sdk_env:
50 pkg = ml + '-' + pkg
49 return self._hasPackage(self.target_pkg_manifest, pkg, regex=regex) 51 return self._hasPackage(self.target_pkg_manifest, pkg, regex=regex)
50 52
51class OESDKTestContextExecutor(OETestContextExecutor): 53class OESDKTestContextExecutor(OETestContextExecutor):
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index fc08906117..ee75687f01 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -2493,7 +2493,7 @@ class DevtoolIdeSdkTests(DevtoolBase):
2493 self.track_for_cleanup(tempdir) 2493 self.track_for_cleanup(tempdir)
2494 self.add_command_to_tearDown('bitbake -c clean %s' % recipe_name) 2494 self.add_command_to_tearDown('bitbake -c clean %s' % recipe_name)
2495 2495
2496 result = runCmd('devtool modify %s -x %s' % (recipe_name, tempdir)) 2496 result = runCmd('devtool modify %s -x %s --debug-build' % (recipe_name, tempdir))
2497 self.assertExists(os.path.join(tempdir, build_file), 2497 self.assertExists(os.path.join(tempdir, build_file),
2498 'Extracted source could not be found') 2498 'Extracted source could not be found')
2499 self.assertExists(os.path.join(self.workspacedir, 'conf', 2499 self.assertExists(os.path.join(self.workspacedir, 'conf',
diff --git a/meta/lib/oeqa/selftest/cases/meta_ide.py b/meta/lib/oeqa/selftest/cases/meta_ide.py
index ffe0d2604d..5a17ca52ea 100644
--- a/meta/lib/oeqa/selftest/cases/meta_ide.py
+++ b/meta/lib/oeqa/selftest/cases/meta_ide.py
@@ -20,8 +20,8 @@ class MetaIDE(OESelftestTestCase):
20 bitbake('meta-ide-support') 20 bitbake('meta-ide-support')
21 bitbake('build-sysroots -c build_native_sysroot') 21 bitbake('build-sysroots -c build_native_sysroot')
22 bitbake('build-sysroots -c build_target_sysroot') 22 bitbake('build-sysroots -c build_target_sysroot')
23 bb_vars = get_bb_vars(['MULTIMACH_TARGET_SYS', 'DEPLOY_DIR_IMAGE', 'COREBASE']) 23 bb_vars = get_bb_vars(['MACHINE_ARCH', 'TARGET_VENDOR', 'TARGET_OS', 'DEPLOY_DIR_IMAGE', 'COREBASE'])
24 cls.environment_script = 'environment-setup-%s' % bb_vars['MULTIMACH_TARGET_SYS'] 24 cls.environment_script = 'environment-setup-%s%s-%s' % (bb_vars['MACHINE_ARCH'], bb_vars['TARGET_VENDOR'], bb_vars['TARGET_OS'])
25 cls.deploydir = bb_vars['DEPLOY_DIR_IMAGE'] 25 cls.deploydir = bb_vars['DEPLOY_DIR_IMAGE']
26 cls.environment_script_path = '%s/%s' % (cls.deploydir, cls.environment_script) 26 cls.environment_script_path = '%s/%s' % (cls.deploydir, cls.environment_script)
27 cls.corebasedir = bb_vars['COREBASE'] 27 cls.corebasedir = bb_vars['COREBASE']
diff --git a/meta/lib/oeqa/selftest/cases/overlayfs.py b/meta/lib/oeqa/selftest/cases/overlayfs.py
index e31063567b..580fbdcb9c 100644
--- a/meta/lib/oeqa/selftest/cases/overlayfs.py
+++ b/meta/lib/oeqa/selftest/cases/overlayfs.py
@@ -5,7 +5,7 @@
5# 5#
6 6
7from oeqa.selftest.case import OESelftestTestCase 7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import bitbake, runqemu 8from oeqa.utils.commands import bitbake, runqemu, get_bb_vars
9from oeqa.core.decorator import OETestTag 9from oeqa.core.decorator import OETestTag
10from oeqa.core.decorator.data import skipIfNotMachine 10from oeqa.core.decorator.data import skipIfNotMachine
11 11
@@ -466,6 +466,45 @@ IMAGE_INSTALL:append = " overlayfs-user"
466 line = getline_qemu(output, "Read-only file system") 466 line = getline_qemu(output, "Read-only file system")
467 self.assertTrue(line, msg=output) 467 self.assertTrue(line, msg=output)
468 468
469 @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently")
470 def test_postinst_on_target_for_read_only_rootfs(self):
471 """
472 Summary: The purpose of this test case is to verify that post-installation
473 on target scripts are executed even if using read-only rootfs when
474 read-only-rootfs-delayed-postinsts is set
475 Expected: The test files are created on first boot
476 """
477
478 import oe.path
479
480 vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal")
481 sysconfdir = vars["sysconfdir"]
482 self.assertIsNotNone(sysconfdir)
483 # Need to use oe.path here as sysconfdir starts with /
484 targettestdir = os.path.join(sysconfdir, "postinst-test")
485
486 config = self.get_working_config()
487
488 args = {
489 'OVERLAYFS_INIT_OPTION': "",
490 'OVERLAYFS_ETC_USE_ORIG_INIT_NAME': 1,
491 'OVERLAYFS_ROOTFS_TYPE': "ext4",
492 'OVERLAYFS_ETC_CREATE_MOUNT_DIRS': 1
493 }
494
495 # read-only-rootfs is already set in get_working_config()
496 config += 'EXTRA_IMAGE_FEATURES += "read-only-rootfs-delayed-postinsts"\n'
497 config += 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n'
498
499 self.write_config(config.format(**args))
500
501 res = bitbake('core-image-minimal')
502
503 with runqemu('core-image-minimal', image_fstype='wic') as qemu:
504 for filename in ("rootfs", "delayed-a", "delayed-b"):
505 status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename))
506 self.assertIn("found", output, "%s was not present on boot" % filename)
507
469 def get_working_config(self): 508 def get_working_config(self):
470 return """ 509 return """
471# Use systemd as init manager 510# Use systemd as init manager
diff --git a/meta/lib/oeqa/selftest/cases/reproducible.py b/meta/lib/oeqa/selftest/cases/reproducible.py
index 021e894012..34efa730e5 100644
--- a/meta/lib/oeqa/selftest/cases/reproducible.py
+++ b/meta/lib/oeqa/selftest/cases/reproducible.py
@@ -16,6 +16,8 @@ import os
16import datetime 16import datetime
17 17
18exclude_packages = [ 18exclude_packages = [
19 'rust-rustdoc',
20 'rust-dbg'
19 ] 21 ]
20 22
21def is_excluded(package): 23def is_excluded(package):
@@ -177,12 +179,8 @@ class ReproducibleTests(OESelftestTestCase):
177 self.sstate_targets = bb_vars['OEQA_REPRODUCIBLE_TEST_SSTATE_TARGETS'].split() 179 self.sstate_targets = bb_vars['OEQA_REPRODUCIBLE_TEST_SSTATE_TARGETS'].split()
178 180
179 self.extraresults = {} 181 self.extraresults = {}
180 self.extraresults.setdefault('reproducible.rawlogs', {})['log'] = ''
181 self.extraresults.setdefault('reproducible', {}).setdefault('files', {}) 182 self.extraresults.setdefault('reproducible', {}).setdefault('files', {})
182 183
183 def append_to_log(self, msg):
184 self.extraresults['reproducible.rawlogs']['log'] += msg
185
186 def compare_packages(self, reference_dir, test_dir, diffutils_sysroot): 184 def compare_packages(self, reference_dir, test_dir, diffutils_sysroot):
187 result = PackageCompareResults(self.oeqa_reproducible_excluded_packages) 185 result = PackageCompareResults(self.oeqa_reproducible_excluded_packages)
188 186
@@ -209,7 +207,7 @@ class ReproducibleTests(OESelftestTestCase):
209 207
210 def write_package_list(self, package_class, name, packages): 208 def write_package_list(self, package_class, name, packages):
211 self.extraresults['reproducible']['files'].setdefault(package_class, {})[name] = [ 209 self.extraresults['reproducible']['files'].setdefault(package_class, {})[name] = [
212 {'reference': p.reference, 'test': p.test} for p in packages] 210 p.reference.split("/./")[1] for p in packages]
213 211
214 def copy_file(self, source, dest): 212 def copy_file(self, source, dest):
215 bb.utils.mkdirhier(os.path.dirname(dest)) 213 bb.utils.mkdirhier(os.path.dirname(dest))
@@ -295,8 +293,6 @@ class ReproducibleTests(OESelftestTestCase):
295 293
296 self.logger.info('Reproducibility summary for %s: %s' % (c, result)) 294 self.logger.info('Reproducibility summary for %s: %s' % (c, result))
297 295
298 self.append_to_log('\n'.join("%s: %s" % (r.status, r.test) for r in result.total))
299
300 self.write_package_list(package_class, 'missing', result.missing) 296 self.write_package_list(package_class, 'missing', result.missing)
301 self.write_package_list(package_class, 'different', result.different) 297 self.write_package_list(package_class, 'different', result.different)
302 self.write_package_list(package_class, 'different_excluded', result.different_excluded) 298 self.write_package_list(package_class, 'different_excluded', result.different_excluded)
diff --git a/meta/lib/oeqa/selftest/cases/rust.py b/meta/lib/oeqa/selftest/cases/rust.py
index ad14189c6d..26f132edc4 100644
--- a/meta/lib/oeqa/selftest/cases/rust.py
+++ b/meta/lib/oeqa/selftest/cases/rust.py
@@ -3,6 +3,7 @@ import os
3import subprocess 3import subprocess
4import time 4import time
5from oeqa.core.decorator import OETestTag 5from oeqa.core.decorator import OETestTag
6from oeqa.core.decorator.data import skipIfArch
6from oeqa.core.case import OEPTestResultTestCase 7from oeqa.core.case import OEPTestResultTestCase
7from oeqa.selftest.case import OESelftestTestCase 8from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu, Command 9from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu, Command
@@ -38,15 +39,12 @@ def parse_results(filename):
38@OETestTag("toolchain-user") 39@OETestTag("toolchain-user")
39@OETestTag("runqemu") 40@OETestTag("runqemu")
40class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase): 41class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase):
42
43 @skipIfArch(['mips', 'mips64'])
41 def test_rust(self, *args, **kwargs): 44 def test_rust(self, *args, **kwargs):
42 # Disable Rust Oe-selftest 45 # Disable Rust Oe-selftest
43 #self.skipTest("The Rust Oe-selftest is disabled.") 46 #self.skipTest("The Rust Oe-selftest is disabled.")
44 47
45 # Skip mips32 target since it is unstable with rust tests
46 machine = get_bb_var('MACHINE')
47 if machine == "qemumips":
48 self.skipTest("The mips32 target is skipped for Rust Oe-selftest.")
49
50 # build remote-test-server before image build 48 # build remote-test-server before image build
51 recipe = "rust" 49 recipe = "rust"
52 start_time = time.time() 50 start_time = time.time()
@@ -210,9 +208,8 @@ class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase):
210 tmpdir = get_bb_var("TMPDIR", "rust") 208 tmpdir = get_bb_var("TMPDIR", "rust")
211 209
212 # Set path for target-poky-linux-gcc, RUST_TARGET_PATH and hosttools. 210 # Set path for target-poky-linux-gcc, RUST_TARGET_PATH and hosttools.
213 cmd = " export PATH=%s/recipe-sysroot-native/usr/bin:$PATH;" % rustlibpath 211 cmd = "export TARGET_VENDOR=\"-poky\";"
214 cmd = cmd + " export TARGET_VENDOR=\"-poky\";" 212 cmd = cmd + " export PATH=%s/recipe-sysroot-native/usr/bin/python3-native:%s/recipe-sysroot-native/usr/bin:%s/recipe-sysroot-native/usr/bin/%s:%s/hosttools:$PATH;" % (rustlibpath, rustlibpath, rustlibpath, tcpath, tmpdir)
215 cmd = cmd + " export PATH=%s/recipe-sysroot-native/usr/bin/%s:%s/hosttools:$PATH;" % (rustlibpath, tcpath, tmpdir)
216 cmd = cmd + " export RUST_TARGET_PATH=%s/rust-targets;" % rustlibpath 213 cmd = cmd + " export RUST_TARGET_PATH=%s/rust-targets;" % rustlibpath
217 # Trigger testing. 214 # Trigger testing.
218 cmd = cmd + " export TEST_DEVICE_ADDR=\"%s:12345\";" % qemu.ip 215 cmd = cmd + " export TEST_DEVICE_ADDR=\"%s:12345\";" % qemu.ip
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py
index 86d6cd7464..4a2c425ac8 100644
--- a/meta/lib/oeqa/selftest/cases/sstatetests.py
+++ b/meta/lib/oeqa/selftest/cases/sstatetests.py
@@ -977,7 +977,7 @@ class SStateMirrors(SStateBase):
977 self.append_config(""" 977 self.append_config("""
978MACHINE = "{}" 978MACHINE = "{}"
979BB_HASHSERVE_UPSTREAM = "hashserv.yocto.io:8687" 979BB_HASHSERVE_UPSTREAM = "hashserv.yocto.io:8687"
980SSTATE_MIRRORS ?= "file://.* http://cdn.jsdelivr.net/yocto/sstate/all/PATH;downloadfilename=PATH" 980SSTATE_MIRRORS ?= "file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH"
981""".format(machine)) 981""".format(machine))
982 else: 982 else:
983 self.append_config(""" 983 self.append_config("""
diff --git a/meta/lib/oeqa/utils/gitarchive.py b/meta/lib/oeqa/utils/gitarchive.py
index 10cb267dfa..a826646059 100644
--- a/meta/lib/oeqa/utils/gitarchive.py
+++ b/meta/lib/oeqa/utils/gitarchive.py
@@ -67,7 +67,7 @@ def git_commit_data(repo, data_dir, branch, message, exclude, notes, log):
67 67
68 # Remove files that are excluded 68 # Remove files that are excluded
69 if exclude: 69 if exclude:
70 repo.run_cmd(['rm', '--cached'] + [f for f in exclude], env_update) 70 repo.run_cmd(['rm', '--cached', '--ignore-unmatch'] + [f for f in exclude], env_update)
71 71
72 tree = repo.run_cmd('write-tree', env_update) 72 tree = repo.run_cmd('write-tree', env_update)
73 73
@@ -202,6 +202,8 @@ def gitarchive(data_dir, git_dir, no_create, bare, commit_msg_subject, commit_ms
202 log.info("Pushing data to remote") 202 log.info("Pushing data to remote")
203 data_repo.run_cmd(cmd) 203 data_repo.run_cmd(cmd)
204 204
205 return tag_name
206
205# Container class for tester revisions 207# Container class for tester revisions
206TestedRev = namedtuple('TestedRev', 'commit commit_number tags') 208TestedRev = namedtuple('TestedRev', 'commit commit_number tags')
207 209
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index cda43aad8c..f1c2d2b5c9 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -519,7 +519,6 @@ class QemuRunner:
519 except Exception as e: 519 except Exception as e:
520 self.logger.warning('Extra log data exception %s' % repr(e)) 520 self.logger.warning('Extra log data exception %s' % repr(e))
521 data = None 521 data = None
522 self.thread.serial_lock.release()
523 return False 522 return False
524 523
525 with self.thread.serial_lock: 524 with self.thread.serial_lock:
@@ -822,10 +821,12 @@ class LoggingThread(threading.Thread):
822 self.logfunc(data, ".stdout") 821 self.logfunc(data, ".stdout")
823 elif self.serialsock and self.serialsock.fileno() == fd: 822 elif self.serialsock and self.serialsock.fileno() == fd:
824 if self.serial_lock.acquire(blocking=False): 823 if self.serial_lock.acquire(blocking=False):
825 data = self.recv(1024, self.serialsock) 824 try:
826 self.logger.debug("Data received serial thread %s" % data.decode('utf-8', 'replace')) 825 data = self.recv(1024, self.serialsock)
827 self.logfunc(data, ".2") 826 self.logger.debug("Data received serial thread %s" % data.decode('utf-8', 'replace'))
828 self.serial_lock.release() 827 self.logfunc(data, ".2")
828 finally:
829 self.serial_lock.release()
829 else: 830 else:
830 serial_registered = False 831 serial_registered = False
831 poll.unregister(self.serialsock.fileno()) 832 poll.unregister(self.serialsock.fileno())