summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorAlexis Lothoré <alexis.lothore@bootlin.com>2023-06-09 08:48:01 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-06-17 11:50:57 +0100
commit58206ea8d94e30a61dbd732d652cd2cdeb9c8e4f (patch)
tree6923f614e1b982442182165a3c833cab2005706b /meta
parentcdac245fc288a5ecc8163325f4b1468d4bc643db (diff)
downloadpoky-58206ea8d94e30a61dbd732d652cd2cdeb9c8e4f.tar.gz
testimage: implement test artifacts retriever for failing tests
Add a basic artifacts retrievers in testimage class which: - triggers when at least one runtime test fails but tests execution encountered no major issue - reads a list of paths to retrieve from TESTIMAGE_FAILED_QA_ARTIFACTS - checks for artifacts presence on target - retrieve those files over scp thanks to existing ssh class - store those files in an "artifacts" directory in "tmp/log/oeqa/<image>" This implementation assumes that the SSH or Qemu target has run and finished gracefully. If tests do not finish because of an exception, artifacts will not be retrieved Bring partial solution to [YOCTO #14901] (From OE-Core rev: 36ef582b8c1c99e6af1ce79ea79f5b059d2a1aad) Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes-recipe/testimage.bbclass48
1 files changed, 48 insertions, 0 deletions
diff --git a/meta/classes-recipe/testimage.bbclass b/meta/classes-recipe/testimage.bbclass
index b48cd96575..765184c180 100644
--- a/meta/classes-recipe/testimage.bbclass
+++ b/meta/classes-recipe/testimage.bbclass
@@ -18,6 +18,15 @@ inherit image-artifact-names
18 18
19TESTIMAGE_AUTO ??= "0" 19TESTIMAGE_AUTO ??= "0"
20 20
21# When any test fails, TESTIMAGE_FAILED_QA ARTIFACTS will be parsed and for
22# each entry in it, if artifact pointed by path description exists on target,
23# it will be retrieved onto host
24
25TESTIMAGE_FAILED_QA_ARTIFACTS ??= "\
26 ${localstatedir}/log \
27 ${sysconfdir}/version \
28 ${sysconfdir}/os-release"
29
21# You can set (or append to) TEST_SUITES in local.conf to select the tests 30# You can set (or append to) TEST_SUITES in local.conf to select the tests
22# which you want to run for your target. 31# which you want to run for your target.
23# The test names are the module names in meta/lib/oeqa/runtime/cases. 32# The test names are the module names in meta/lib/oeqa/runtime/cases.
@@ -192,6 +201,39 @@ def get_testimage_boot_patterns(d):
192 boot_patterns[flag] = flagval.encode().decode('unicode-escape') 201 boot_patterns[flag] = flagval.encode().decode('unicode-escape')
193 return boot_patterns 202 return boot_patterns
194 203
204def get_artifacts_list(target, raw_list):
205 result = []
206 # Passed list may contains patterns in paths, expand them directly on target
207 for raw_path in raw_list.split():
208 cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done"
209 try:
210 status, output = target.run(cmd)
211 if status != 0 or not output:
212 raise Exception()
213 result += output.split()
214 except:
215 bb.warn(f"No file/directory matching path {raw_path}")
216
217 return result
218
219def retrieve_test_artifacts(target, artifacts_list, target_dir):
220 import shutil
221
222 local_artifacts_dir = os.path.join(target_dir, "artifacts")
223 if os.path.isdir(local_artifacts_dir):
224 shutil.rmtree(local_artifacts_dir)
225
226 os.makedirs(local_artifacts_dir)
227 for artifact_path in artifacts_list:
228 if not os.path.isabs(artifact_path):
229 bb.warn(f"{artifact_path} is not an absolute path")
230 continue
231 try:
232 dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:]))
233 os.makedirs(dest_dir, exist_ok=True)
234 target.copyFrom(artifact_path, dest_dir)
235 except:
236 bb.warn(f"Can not retrieve {artifact_path} from test target")
195 237
196def testimage_main(d): 238def testimage_main(d):
197 import os 239 import os
@@ -383,6 +425,12 @@ def testimage_main(d):
383 pass 425 pass
384 results = tc.runTests() 426 results = tc.runTests()
385 complete = True 427 complete = True
428 if results.hasAnyFailingTest():
429 artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS"))
430 if not artifacts_list:
431 bb.warn("Could not load artifacts list, skip artifacts retrieval")
432 else:
433 retrieve_test_artifacts(tc.target, artifacts_list, get_testimage_json_result_dir(d))
386 except (KeyboardInterrupt, BlockingIOError) as err: 434 except (KeyboardInterrupt, BlockingIOError) as err:
387 if isinstance(err, KeyboardInterrupt): 435 if isinstance(err, KeyboardInterrupt):
388 bb.error('testimage interrupted, shutting down...') 436 bb.error('testimage interrupted, shutting down...')