Patrick Williams | 3965356 | 2024-03-01 08:54:02 -0600 | [diff] [blame] | 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 | from oeqa.utils import get_json_result_dir |
| 11 | |
| 12 | def create_artifacts_directory(d, tc): |
| 13 | import shutil |
| 14 | |
| 15 | local_artifacts_dir = os.path.join(get_json_result_dir(d), "artifacts") |
| 16 | if os.path.isdir(local_artifacts_dir): |
| 17 | shutil.rmtree(local_artifacts_dir) |
| 18 | |
| 19 | os.makedirs(local_artifacts_dir) |
| 20 | |
| 21 | ################################################################## |
| 22 | # Host/target statistics |
| 23 | ################################################################## |
| 24 | |
| 25 | def get_target_disk_usage(d, tc): |
| 26 | output_file = os.path.join(get_json_result_dir(d), "artifacts", "target_disk_usage.txt") |
| 27 | try: |
| 28 | (status, output) = tc.target.run('df -hl') |
| 29 | with open(output_file, 'w') as f: |
| 30 | f.write(output) |
| 31 | f.write("\n") |
| 32 | except Exception as e: |
| 33 | bb.warn(f"Can not get target disk usage: {e}") |
| 34 | |
| 35 | def get_host_disk_usage(d, tc): |
| 36 | import subprocess |
| 37 | |
| 38 | output_file = os.path.join(get_json_result_dir(d), "artifacts", "host_disk_usage.txt") |
| 39 | try: |
| 40 | with open(output_file, 'w') as f: |
| 41 | output = subprocess.run(['df', '-hl'], check=True, text=True, stdout=f, env={}) |
| 42 | except Exception as e: |
| 43 | bb.warn(f"Can not get host disk usage: {e}") |
| 44 | |
| 45 | ################################################################## |
| 46 | # Artifacts retrieval |
| 47 | ################################################################## |
| 48 | |
| 49 | def get_artifacts_list(target, raw_list): |
| 50 | result = [] |
| 51 | # Passed list may contains patterns in paths, expand them directly on target |
| 52 | for raw_path in raw_list.split(): |
| 53 | cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done" |
| 54 | try: |
| 55 | status, output = target.run(cmd) |
| 56 | if status != 0 or not output: |
| 57 | raise Exception() |
| 58 | result += output.split() |
| 59 | except: |
| 60 | bb.note(f"No file/directory matching path {raw_path}") |
| 61 | |
| 62 | return result |
| 63 | |
| 64 | def retrieve_test_artifacts(target, artifacts_list, target_dir): |
| 65 | local_artifacts_dir = os.path.join(target_dir, "artifacts") |
| 66 | for artifact_path in artifacts_list: |
| 67 | if not os.path.isabs(artifact_path): |
| 68 | bb.warn(f"{artifact_path} is not an absolute path") |
| 69 | continue |
| 70 | try: |
| 71 | dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:])) |
| 72 | os.makedirs(dest_dir, exist_ok=True) |
| 73 | target.copyFrom(artifact_path, dest_dir) |
| 74 | except Exception as e: |
| 75 | bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") |
| 76 | |
| 77 | def list_and_fetch_failed_tests_artifacts(d, tc): |
| 78 | artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS")) |
| 79 | if not artifacts_list: |
| 80 | bb.warn("Could not load artifacts list, skip artifacts retrieval") |
| 81 | else: |
| 82 | retrieve_test_artifacts(tc.target, artifacts_list, get_json_result_dir(d)) |
| 83 | |
| 84 | |
| 85 | ################################################################## |
| 86 | # General post actions runner |
| 87 | ################################################################## |
| 88 | |
| 89 | def run_failed_tests_post_actions(d, tc): |
| 90 | post_actions=[ |
| 91 | create_artifacts_directory, |
| 92 | list_and_fetch_failed_tests_artifacts, |
| 93 | get_target_disk_usage, |
| 94 | get_host_disk_usage |
| 95 | ] |
| 96 | |
| 97 | for action in post_actions: |
| 98 | action(d, tc) |