diff options
author | Alexis Lothoré <alexis.lothore@bootlin.com> | 2024-02-26 10:19:19 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-02-27 11:35:43 +0000 |
commit | 3add7b301e38d11a47b55abfb583a648e6a4ac04 (patch) | |
tree | dbcd07bdf6a44df0d0468d944860395f25dd5bbb /meta/classes-recipe | |
parent | fec128bd625dbbb5a239d6ff6999e1e4a41a5a9b (diff) | |
download | poky-3add7b301e38d11a47b55abfb583a648e6a4ac04.tar.gz |
testimage: create a list of failed test post actions
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 postactions.py file inherited by testimage.
This patch does not bring any functional change.
(From OE-Core rev: c01aa8df0613a103859b4431d3cc5056b2fef1b8)
Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes-recipe')
-rw-r--r-- | meta/classes-recipe/testimage.bbclass | 41 |
1 files changed, 2 insertions, 39 deletions
diff --git a/meta/classes-recipe/testimage.bbclass b/meta/classes-recipe/testimage.bbclass index 959c226072..ad040ee8f0 100644 --- a/meta/classes-recipe/testimage.bbclass +++ b/meta/classes-recipe/testimage.bbclass | |||
@@ -170,40 +170,6 @@ def get_testimage_boot_patterns(d): | |||
170 | boot_patterns[flag] = flagval.encode().decode('unicode-escape') | 170 | boot_patterns[flag] = flagval.encode().decode('unicode-escape') |
171 | return boot_patterns | 171 | return boot_patterns |
172 | 172 | ||
173 | def get_artifacts_list(target, raw_list): | ||
174 | result = [] | ||
175 | # Passed list may contains patterns in paths, expand them directly on target | ||
176 | for raw_path in raw_list.split(): | ||
177 | cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done" | ||
178 | try: | ||
179 | status, output = target.run(cmd) | ||
180 | if status != 0 or not output: | ||
181 | raise Exception() | ||
182 | result += output.split() | ||
183 | except: | ||
184 | bb.note(f"No file/directory matching path {raw_path}") | ||
185 | |||
186 | return result | ||
187 | |||
188 | def retrieve_test_artifacts(target, artifacts_list, target_dir): | ||
189 | import shutil | ||
190 | |||
191 | local_artifacts_dir = os.path.join(target_dir, "artifacts") | ||
192 | if os.path.isdir(local_artifacts_dir): | ||
193 | shutil.rmtree(local_artifacts_dir) | ||
194 | |||
195 | os.makedirs(local_artifacts_dir) | ||
196 | for artifact_path in artifacts_list: | ||
197 | if not os.path.isabs(artifact_path): | ||
198 | bb.warn(f"{artifact_path} is not an absolute path") | ||
199 | continue | ||
200 | try: | ||
201 | dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:])) | ||
202 | os.makedirs(dest_dir, exist_ok=True) | ||
203 | target.copyFrom(artifact_path, dest_dir) | ||
204 | except Exception as e: | ||
205 | bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") | ||
206 | |||
207 | def testimage_main(d): | 173 | def testimage_main(d): |
208 | import os | 174 | import os |
209 | import json | 175 | import json |
@@ -218,6 +184,7 @@ def testimage_main(d): | |||
218 | from oeqa.core.utils.test import getSuiteCases | 184 | from oeqa.core.utils.test import getSuiteCases |
219 | from oeqa.utils import make_logger_bitbake_compatible | 185 | from oeqa.utils import make_logger_bitbake_compatible |
220 | from oeqa.utils import get_json_result_dir | 186 | from oeqa.utils import get_json_result_dir |
187 | from oeqa.utils.postactions import run_failed_tests_post_actions | ||
221 | 188 | ||
222 | def sigterm_exception(signum, stackframe): | 189 | def sigterm_exception(signum, stackframe): |
223 | """ | 190 | """ |
@@ -400,11 +367,7 @@ def testimage_main(d): | |||
400 | results = tc.runTests() | 367 | results = tc.runTests() |
401 | complete = True | 368 | complete = True |
402 | if results.hasAnyFailingTest(): | 369 | if results.hasAnyFailingTest(): |
403 | artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS")) | 370 | run_failed_tests_post_actions(d, tc) |
404 | if not artifacts_list: | ||
405 | bb.warn("Could not load artifacts list, skip artifacts retrieval") | ||
406 | else: | ||
407 | retrieve_test_artifacts(tc.target, artifacts_list, get_testimage_json_result_dir(d)) | ||
408 | except (KeyboardInterrupt, BlockingIOError) as err: | 371 | except (KeyboardInterrupt, BlockingIOError) as err: |
409 | if isinstance(err, KeyboardInterrupt): | 372 | if isinstance(err, KeyboardInterrupt): |
410 | bb.error('testimage interrupted, shutting down...') | 373 | bb.error('testimage interrupted, shutting down...') |