summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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...')