diff options
| author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-07-17 14:29:20 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-07-18 17:21:39 +0100 |
| commit | fdcaf1cce908bf92fef2f64421c7331c1f4228a4 (patch) | |
| tree | 3c1ea8c55bf1a5fb7fb642ce2e15e5172234b830 | |
| parent | 00bb1202d28e3d7bc64e841e53c44dbd1eea8d64 (diff) | |
| download | poky-fdcaf1cce908bf92fef2f64421c7331c1f4228a4.tar.gz | |
oeqa/postactions: Separate artefact collection from test result collection
Combining the test result collection and artefact collection hasn't worked out
well as the data has different life cycles, the artefacts can be large and
we need to be able to clean them up on a different timescale.
Separate them out to be controlled by a separate variable, OEQA_ARTEFACT_DIR.
Also rework the code to inject a directory with a date/time and random component
to allow builds to run in parallel. Pass function arguments to avoid re-reading
variables.
(From OE-Core rev: e1cf7e94c3fcbe7dbc29e4286f0e1014b95964a9)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/lib/oeqa/utils/__init__.py | 8 | ||||
| -rw-r--r-- | meta/lib/oeqa/utils/postactions.py | 53 |
2 files changed, 32 insertions, 29 deletions
diff --git a/meta/lib/oeqa/utils/__init__.py b/meta/lib/oeqa/utils/__init__.py index 53bdcbf266..e03f7e33bb 100644 --- a/meta/lib/oeqa/utils/__init__.py +++ b/meta/lib/oeqa/utils/__init__.py | |||
| @@ -96,4 +96,10 @@ def get_json_result_dir(d): | |||
| 96 | custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") | 96 | custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") |
| 97 | if custom_json_result_dir: | 97 | if custom_json_result_dir: |
| 98 | json_result_dir = custom_json_result_dir | 98 | json_result_dir = custom_json_result_dir |
| 99 | return json_result_dir \ No newline at end of file | 99 | return json_result_dir |
| 100 | |||
| 101 | def get_artefact_dir(d): | ||
| 102 | custom_json_result_dir = d.getVar("OEQA_ARTEFACT_DIR") | ||
| 103 | if custom_json_result_dir: | ||
| 104 | return custom_json_result_dir | ||
| 105 | return os.path.join(d.getVar("LOG_DIR"), 'oeqa-artefacts') | ||
diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py index 15f423218e..2de2d18328 100644 --- a/meta/lib/oeqa/utils/postactions.py +++ b/meta/lib/oeqa/utils/postactions.py | |||
| @@ -7,23 +7,20 @@ | |||
| 7 | # Run a set of actions after tests. The runner provides internal data | 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. | 8 | # dictionary as well as test context to any action to run. |
| 9 | 9 | ||
| 10 | from oeqa.utils import get_json_result_dir | 10 | import datetime |
| 11 | 11 | import io | |
| 12 | def create_artifacts_directory(d, tc): | 12 | import os |
| 13 | import shutil | 13 | import stat |
| 14 | 14 | import subprocess | |
| 15 | local_artifacts_dir = os.path.join(get_json_result_dir(d), "artifacts") | 15 | import tempfile |
| 16 | if os.path.isdir(local_artifacts_dir): | 16 | from oeqa.utils import get_artefact_dir |
| 17 | shutil.rmtree(local_artifacts_dir) | ||
| 18 | |||
| 19 | os.makedirs(local_artifacts_dir) | ||
| 20 | 17 | ||
| 21 | ################################################################## | 18 | ################################################################## |
| 22 | # Host/target statistics | 19 | # Host/target statistics |
| 23 | ################################################################## | 20 | ################################################################## |
| 24 | 21 | ||
| 25 | def get_target_disk_usage(d, tc): | 22 | def get_target_disk_usage(d, tc, artifacts_list, outputdir): |
| 26 | output_file = os.path.join(get_json_result_dir(d), "artifacts", "target_disk_usage.txt") | 23 | output_file = os.path.join(outputdir, "target_disk_usage.txt") |
| 27 | try: | 24 | try: |
| 28 | (status, output) = tc.target.run('df -h') | 25 | (status, output) = tc.target.run('df -h') |
| 29 | with open(output_file, 'w') as f: | 26 | with open(output_file, 'w') as f: |
| @@ -32,10 +29,10 @@ def get_target_disk_usage(d, tc): | |||
| 32 | except Exception as e: | 29 | except Exception as e: |
| 33 | bb.warn(f"Can not get target disk usage: {e}") | 30 | bb.warn(f"Can not get target disk usage: {e}") |
| 34 | 31 | ||
| 35 | def get_host_disk_usage(d, tc): | 32 | def get_host_disk_usage(d, tc, artifacts_list, outputdir): |
| 36 | import subprocess | 33 | import subprocess |
| 37 | 34 | ||
| 38 | output_file = os.path.join(get_json_result_dir(d), "artifacts", "host_disk_usage.txt") | 35 | output_file = os.path.join(outputdir, "host_disk_usage.txt") |
| 39 | try: | 36 | try: |
| 40 | with open(output_file, 'w') as f: | 37 | with open(output_file, 'w') as f: |
| 41 | output = subprocess.run(['df', '-hl'], check=True, text=True, stdout=f, env={}) | 38 | output = subprocess.run(['df', '-hl'], check=True, text=True, stdout=f, env={}) |
| @@ -61,25 +58,20 @@ def get_artifacts_list(target, raw_list): | |||
| 61 | 58 | ||
| 62 | return result | 59 | return result |
| 63 | 60 | ||
| 64 | def retrieve_test_artifacts(target, artifacts_list, target_dir): | 61 | def list_and_fetch_failed_tests_artifacts(d, tc, artifacts_list, outputdir): |
| 65 | import io, subprocess | 62 | artifacts_list = get_artifacts_list(tc.target, artifacts_list) |
| 66 | local_artifacts_dir = os.path.join(target_dir, "artifacts") | 63 | if not artifacts_list: |
| 64 | bb.warn("Could not load artifacts list, skip artifacts retrieval") | ||
| 65 | return | ||
| 67 | try: | 66 | try: |
| 68 | cmd = "tar zcf - " + " ".join(artifacts_list) | 67 | cmd = "tar zcf - " + " ".join(artifacts_list) |
| 69 | (status, output) = target.run(cmd, raw = True) | 68 | (status, output) = tc.target.run(cmd, raw = True) |
| 70 | if status != 0 or not output: | 69 | if status != 0 or not output: |
| 71 | raise Exception("Error while fetching compressed artifacts") | 70 | raise Exception("Error while fetching compressed artifacts") |
| 72 | p = subprocess.run(["tar", "zxf", "-", "-C", local_artifacts_dir], input=output) | 71 | p = subprocess.run(["tar", "zxf", "-", "-C", outputdir], input=output) |
| 73 | except Exception as e: | 72 | except Exception as e: |
| 74 | bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") | 73 | bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") |
| 75 | 74 | ||
| 76 | def list_and_fetch_failed_tests_artifacts(d, tc): | ||
| 77 | artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS")) | ||
| 78 | if not artifacts_list: | ||
| 79 | bb.warn("Could not load artifacts list, skip artifacts retrieval") | ||
| 80 | else: | ||
| 81 | retrieve_test_artifacts(tc.target, artifacts_list, get_json_result_dir(d)) | ||
| 82 | |||
| 83 | 75 | ||
| 84 | ################################################################## | 76 | ################################################################## |
| 85 | # General post actions runner | 77 | # General post actions runner |
| @@ -91,12 +83,17 @@ def run_failed_tests_post_actions(d, tc): | |||
| 91 | if not artifacts: | 83 | if not artifacts: |
| 92 | return | 84 | return |
| 93 | 85 | ||
| 86 | outputdir = get_artefact_dir(d) | ||
| 87 | os.makedirs(outputdir, exist_ok=True) | ||
| 88 | datestr = datetime.datetime.now().strftime('%Y%m%d') | ||
| 89 | outputdir = tempfile.mkdtemp(prefix='oeqa-target-artefacts-%s-' % datestr, dir=outputdir) | ||
| 90 | os.chmod(outputdir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) | ||
| 91 | |||
| 94 | post_actions=[ | 92 | post_actions=[ |
| 95 | create_artifacts_directory, | ||
| 96 | list_and_fetch_failed_tests_artifacts, | 93 | list_and_fetch_failed_tests_artifacts, |
| 97 | get_target_disk_usage, | 94 | get_target_disk_usage, |
| 98 | get_host_disk_usage | 95 | get_host_disk_usage |
| 99 | ] | 96 | ] |
| 100 | 97 | ||
| 101 | for action in post_actions: | 98 | for action in post_actions: |
| 102 | action(d, tc) | 99 | action(d, tc, artifacts, outputdir) |
