From: "Alexis Lothoré" <alexis.lothore@bootlin.com>
To: <Openembedded-core@lists.openembedded.org>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Alexandre Belloni <alexandre.belloni@bootlin.com>
Subject: [OE-Core][PATCH 1/4] testimage: create a list of failed test post actions
Date: Tue, 20 Feb 2024 21:01:56 +0100 [thread overview]
Message-ID: <20240220200159.13419-2-alexis.lothore@bootlin.com> (raw)
In-Reply-To: <20240220200159.13419-1-alexis.lothore@bootlin.com>
From: Alexis Lothoré <alexis.lothore@bootlin.com>
testimage is able to detect whenever a test run leads to some tests
failing, and execute some actions in this case. The only action currently
defined in such case is to retrieve artifacts from the target under test,
as listed in TESTIMAGE_FAILED_QA_ARTIFACTS
In order to be able to add multiple actions, define a central function to
gather all "post actions" to run whenever a test has failed
(run_failed_tests_post_actions). This function contains a table listing all
functions to be called whenever a test fails. Any function in this table
will be provided with bitbake internal data dictionary ("d") and the
current runtime testing context ("tc"). Isolate all this feature in a
dedicated bbclass file inherited by testimage.
This patch does not bring any functional change.
Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
---
.../failed-tests-post-actions.bbclass | 64 +++++++++++++++++++
meta/classes-recipe/testimage.bbclass | 42 +-----------
2 files changed, 66 insertions(+), 40 deletions(-)
create mode 100644 meta/classes-recipe/failed-tests-post-actions.bbclass
diff --git a/meta/classes-recipe/failed-tests-post-actions.bbclass b/meta/classes-recipe/failed-tests-post-actions.bbclass
new file mode 100644
index 000000000000..7c7d3391298f
--- /dev/null
+++ b/meta/classes-recipe/failed-tests-post-actions.bbclass
@@ -0,0 +1,64 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+
+##################################################################
+# Artifacts retrieval
+##################################################################
+
+def get_artifacts_list(target, raw_list):
+ result = []
+ # Passed list may contains patterns in paths, expand them directly on target
+ for raw_path in raw_list.split():
+ cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done"
+ try:
+ status, output = target.run(cmd)
+ if status != 0 or not output:
+ raise Exception()
+ result += output.split()
+ except:
+ bb.note(f"No file/directory matching path {raw_path}")
+
+ return result
+
+def retrieve_test_artifacts(target, artifacts_list, target_dir):
+ import shutil
+
+ local_artifacts_dir = os.path.join(target_dir, "artifacts")
+ if os.path.isdir(local_artifacts_dir):
+ shutil.rmtree(local_artifacts_dir)
+
+ os.makedirs(local_artifacts_dir)
+ for artifact_path in artifacts_list:
+ if not os.path.isabs(artifact_path):
+ bb.warn(f"{artifact_path} is not an absolute path")
+ continue
+ try:
+ dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:]))
+ os.makedirs(dest_dir, exist_ok=True)
+ target.copyFrom(artifact_path, dest_dir)
+ except Exception as e:
+ bb.warn(f"Can not retrieve {artifact_path} from test target: {e}")
+
+def list_and_fetch_failed_tests_artifacts(d, tc):
+ artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS"))
+ if not artifacts_list:
+ bb.warn("Could not load artifacts list, skip artifacts retrieval")
+ else:
+ retrieve_test_artifacts(tc.target, artifacts_list, get_testimage_json_result_dir(d))
+
+
+##################################################################
+# General post actions runner
+##################################################################
+
+def run_failed_tests_post_actions(d, tc):
+ post_actions=[
+ list_and_fetch_failed_tests_artifacts
+ ]
+
+ for action in post_actions:
+ action(d, tc)
diff --git a/meta/classes-recipe/testimage.bbclass b/meta/classes-recipe/testimage.bbclass
index bee19674ef4f..d2b525d40f41 100644
--- a/meta/classes-recipe/testimage.bbclass
+++ b/meta/classes-recipe/testimage.bbclass
@@ -4,6 +4,7 @@
inherit metadata_scm
inherit image-artifact-names
+inherit failed-tests-post-actions
# testimage.bbclass enables testing of qemu images using python unittests.
# Most of the tests are commands run on target image over ssh.
@@ -177,40 +178,6 @@ def get_testimage_boot_patterns(d):
boot_patterns[flag] = flagval.encode().decode('unicode-escape')
return boot_patterns
-def get_artifacts_list(target, raw_list):
- result = []
- # Passed list may contains patterns in paths, expand them directly on target
- for raw_path in raw_list.split():
- cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done"
- try:
- status, output = target.run(cmd)
- if status != 0 or not output:
- raise Exception()
- result += output.split()
- except:
- bb.note(f"No file/directory matching path {raw_path}")
-
- return result
-
-def retrieve_test_artifacts(target, artifacts_list, target_dir):
- import shutil
-
- local_artifacts_dir = os.path.join(target_dir, "artifacts")
- if os.path.isdir(local_artifacts_dir):
- shutil.rmtree(local_artifacts_dir)
-
- os.makedirs(local_artifacts_dir)
- for artifact_path in artifacts_list:
- if not os.path.isabs(artifact_path):
- bb.warn(f"{artifact_path} is not an absolute path")
- continue
- try:
- dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:]))
- os.makedirs(dest_dir, exist_ok=True)
- target.copyFrom(artifact_path, dest_dir)
- except Exception as e:
- bb.warn(f"Can not retrieve {artifact_path} from test target: {e}")
-
def testimage_main(d):
import os
import json
@@ -406,12 +373,7 @@ def testimage_main(d):
results = tc.runTests()
complete = True
if results.hasAnyFailingTest():
- artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS"))
- if not artifacts_list:
- bb.warn("Could not load artifacts list, skip artifacts retrieval")
- else:
- bb.warn(f"Retrieving artifacts: {d.getVar('TESTIMAGE_FAILED_QA_ARTIFACTS')}")
- retrieve_test_artifacts(tc.target, artifacts_list, get_testimage_json_result_dir(d))
+ run_failed_tests_post_actions(d, tc)
except (KeyboardInterrupt, BlockingIOError) as err:
if isinstance(err, KeyboardInterrupt):
bb.error('testimage interrupted, shutting down...')
--
2.43.1
next prev parent reply other threads:[~2024-02-20 20:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-20 20:01 [OE-Core][PATCH 0/4] testimage: add failed test post actions and fetch more data Alexis Lothoré
2024-02-20 20:01 ` Alexis Lothoré [this message]
2024-02-21 7:34 ` [OE-Core][PATCH 1/4] testimage: create a list of failed test post actions Richard Purdie
2024-02-21 7:53 ` Alexis Lothoré
2024-02-21 7:56 ` Richard Purdie
2024-02-21 7:59 ` Alexis Lothoré
2024-02-20 20:01 ` [OE-Core][PATCH 2/4] testimage: isolate artifacts directory creation in dedicated post action Alexis Lothoré
2024-02-20 20:01 ` [OE-Core][PATCH 3/4] testimage: add target disk usage stat as " Alexis Lothoré
2024-02-20 20:01 ` [OE-Core][PATCH 4/4] testimage: add host " Alexis Lothoré
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240220200159.13419-2-alexis.lothore@bootlin.com \
--to=alexis.lothore@bootlin.com \
--cc=Openembedded-core@lists.openembedded.org \
--cc=alexandre.belloni@bootlin.com \
--cc=thomas.petazzoni@bootlin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox