diff options
Diffstat (limited to 'meta/lib/oeqa/utils/postactions.py')
-rw-r--r-- | meta/lib/oeqa/utils/postactions.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py new file mode 100644 index 0000000000..c69481db6c --- /dev/null +++ b/meta/lib/oeqa/utils/postactions.py | |||
@@ -0,0 +1,102 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | # Run a set of actions after tests. The runner provides internal data | ||
8 | # dictionary as well as test context to any action to run. | ||
9 | |||
10 | import datetime | ||
11 | import io | ||
12 | import os | ||
13 | import stat | ||
14 | import subprocess | ||
15 | import tempfile | ||
16 | from oeqa.utils import get_artefact_dir | ||
17 | |||
18 | ################################################################## | ||
19 | # Host/target statistics | ||
20 | ################################################################## | ||
21 | |||
22 | def get_target_disk_usage(d, tc, artifacts_list, outputdir): | ||
23 | output_file = os.path.join(outputdir, "target_disk_usage.txt") | ||
24 | try: | ||
25 | (status, output) = tc.target.run('df -h') | ||
26 | with open(output_file, 'w') as f: | ||
27 | f.write(output) | ||
28 | f.write("\n") | ||
29 | except Exception as e: | ||
30 | bb.warn(f"Can not get target disk usage: {e}") | ||
31 | |||
32 | def get_host_disk_usage(d, tc, artifacts_list, outputdir): | ||
33 | import subprocess | ||
34 | |||
35 | output_file = os.path.join(outputdir, "host_disk_usage.txt") | ||
36 | try: | ||
37 | with open(output_file, 'w') as f: | ||
38 | output = subprocess.run(['df', '-hl'], check=True, text=True, stdout=f, env={}) | ||
39 | except Exception as e: | ||
40 | bb.warn(f"Can not get host disk usage: {e}") | ||
41 | |||
42 | ################################################################## | ||
43 | # Artifacts retrieval | ||
44 | ################################################################## | ||
45 | |||
46 | def get_artifacts_list(target, raw_list): | ||
47 | result = [] | ||
48 | # Passed list may contains patterns in paths, expand them directly on target | ||
49 | for raw_path in raw_list.split(): | ||
50 | cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done" | ||
51 | try: | ||
52 | status, output = target.run(cmd) | ||
53 | if status != 0 or not output: | ||
54 | raise Exception() | ||
55 | result += output.split() | ||
56 | except: | ||
57 | bb.note(f"No file/directory matching path {raw_path}") | ||
58 | |||
59 | return result | ||
60 | |||
61 | def list_and_fetch_failed_tests_artifacts(d, tc, artifacts_list, outputdir): | ||
62 | artifacts_list = get_artifacts_list(tc.target, artifacts_list) | ||
63 | if not artifacts_list: | ||
64 | bb.warn("Could not load artifacts list, skip artifacts retrieval") | ||
65 | return | ||
66 | try: | ||
67 | # We need gnu tar for sparse files, not busybox | ||
68 | cmd = "tar --sparse -zcf - " + " ".join(artifacts_list) | ||
69 | (status, output) = tc.target.run(cmd, raw = True) | ||
70 | if status != 0 or not output: | ||
71 | raise Exception("Error while fetching compressed artifacts") | ||
72 | archive_name = os.path.join(outputdir, "tests_artifacts.tar.gz") | ||
73 | with open(archive_name, "wb") as f: | ||
74 | f.write(output) | ||
75 | except Exception as e: | ||
76 | bb.warn(f"Can not retrieve artifacts from test target: {e}") | ||
77 | |||
78 | |||
79 | ################################################################## | ||
80 | # General post actions runner | ||
81 | ################################################################## | ||
82 | |||
83 | def run_failed_tests_post_actions(d, tc): | ||
84 | artifacts = d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS") | ||
85 | # Allow all the code to be disabled by having no artifacts set, e.g. for systems with no ssh support | ||
86 | if not artifacts: | ||
87 | return | ||
88 | |||
89 | outputdir = get_artefact_dir(d) | ||
90 | os.makedirs(outputdir, exist_ok=True) | ||
91 | datestr = datetime.datetime.now().strftime('%Y%m%d') | ||
92 | outputdir = tempfile.mkdtemp(prefix='oeqa-target-artefacts-%s-' % datestr, dir=outputdir) | ||
93 | os.chmod(outputdir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) | ||
94 | |||
95 | post_actions=[ | ||
96 | list_and_fetch_failed_tests_artifacts, | ||
97 | get_target_disk_usage, | ||
98 | get_host_disk_usage | ||
99 | ] | ||
100 | |||
101 | for action in post_actions: | ||
102 | action(d, tc, artifacts, outputdir) | ||