Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
Leonardo Sandoval | 579c737 | 2020-10-23 15:23:32 -0500 | [diff] [blame] | 3 | # Copyright (c) 2019-2020 Arm Limited. All rights reserved. |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 4 | # |
| 5 | # SPDX-License-Identifier: BSD-3-Clause |
| 6 | # |
| 7 | |
| 8 | # After lava job is dispatched, its results will be collected in |
| 9 | # $WORKSPACE/job_results.yaml file. Parse that file, and exit from this script |
| 10 | # with the respective exit status |
| 11 | |
| 12 | import argparse |
| 13 | import os |
| 14 | import sys |
| 15 | import yaml |
| 16 | |
| 17 | |
| 18 | def report_job_failure(): |
| 19 | job_url = os.environ["JOB_URL"] |
| 20 | build_number = os.environ["BUILD_NUMBER"] |
| 21 | print() |
| 22 | print("Job failed!") |
| 23 | print("See " + "/".join([job_url.rstrip("/"), build_number, "artifact", |
| 24 | "job_output.log"])) |
| 25 | print() |
| 26 | sys.exit(1) |
| 27 | |
| 28 | |
| 29 | def report_job_success(): |
| 30 | print() |
| 31 | print("Job success.") |
| 32 | print() |
| 33 | sys.exit(0) |
| 34 | |
Joel Goddard | 3e09183 | 2021-03-30 10:29:47 +0100 | [diff] [blame^] | 35 | def scmi_parse_phase(results, case, special_case, expected_skip_count): |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 36 | pass_count = 0 |
| 37 | fail_count = 0 |
| 38 | false_fail_count = 0 |
Joel Goddard | 3e09183 | 2021-03-30 10:29:47 +0100 | [diff] [blame^] | 39 | skip_count = 0 |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 40 | |
| 41 | for phase in results: |
| 42 | if phase["metadata"]["definition"] == case: |
| 43 | if phase["metadata"]["result"] == "pass": |
| 44 | pass_count += 1 |
Joel Goddard | 3e09183 | 2021-03-30 10:29:47 +0100 | [diff] [blame^] | 45 | elif phase["metadata"]["result"] == "skip": |
| 46 | skip_count += 1 |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 47 | else: |
| 48 | if special_case != "" and phase["metadata"]["case"] == special_case: |
| 49 | false_fail_count += 1 |
| 50 | else: |
| 51 | fail_count += 1 |
| 52 | |
| 53 | print(case) |
| 54 | print("pass_count " + str(pass_count)) |
| 55 | print("fail_count " + str(fail_count)) |
| 56 | if special_case != "": |
| 57 | print("false_fail_count " + str(false_fail_count)) |
Joel Goddard | 3e09183 | 2021-03-30 10:29:47 +0100 | [diff] [blame^] | 58 | print("skip_count " + str(skip_count) + " out of expected " + str(expected_skip_count)) |
| 59 | if (fail_count > 0) or (skip_count > expected_skip_count): |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 60 | report_job_failure() |
| 61 | |
| 62 | def parse_scp_scmi_results(): |
| 63 | # |
| 64 | # All protocols but sensor |
| 65 | # |
Joel Goddard | 3e09183 | 2021-03-30 10:29:47 +0100 | [diff] [blame^] | 66 | all_prot_expected_skip_count = 9 |
| 67 | scmi_parse_phase(results, "scp-scmi-all-protocol", "", all_prot_expected_skip_count) |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 68 | |
| 69 | def parse_cmd_line(): |
| 70 | parser = argparse.ArgumentParser(description="Parse results from LAVA. " |
| 71 | "The results must be provided as a YAML file.") |
| 72 | parser.add_argument("--payload-type", default="linux", type=str, |
| 73 | help="Type of payload that was used in the test (default: %(default)s)") |
| 74 | parser.add_argument("--file", |
| 75 | default=os.path.join(os.environ["WORKSPACE"], "job_results.yaml"), |
| 76 | type=str, help="YAML file to parse (default: %(default)s)") |
| 77 | args = parser.parse_args() |
| 78 | return args |
| 79 | |
| 80 | |
| 81 | args = parse_cmd_line() |
| 82 | |
| 83 | with open(args.file) as fd: |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 84 | results = yaml.safe_load(fd) |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 85 | |
| 86 | # Iterate through results. Find the element whose name is "job" in the |
| 87 | # "lava" suite. It contains the result of the overall LAVA run. |
| 88 | for phase in results: |
| 89 | if phase["name"] == "job" and phase["suite"] == "lava": |
| 90 | break |
| 91 | else: |
| 92 | raise Exception("Couldn't find 'job' phase in 'lava' suite in results") |
| 93 | |
| 94 | if phase["result"] != "pass": |
| 95 | report_job_failure() |
| 96 | |
| 97 | # If we've simply booted to the Linux shell prompt then we don't need to |
| 98 | # further analyze the results from LAVA. |
| 99 | if args.payload_type == "linux": |
| 100 | report_job_success() |
| 101 | |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 102 | # If we've run TFTF or SCMI tests instead, then do some further parsing. |
| 103 | elif args.payload_type == "tftf": |
| 104 | session = "TFTF" |
| 105 | suite = "tftf" |
| 106 | elif args.payload_type == "scp_tests_scmi": |
| 107 | session = "SCMI" |
| 108 | suite = "scp-scmi" |
| 109 | parse_scp_scmi_results() |
| 110 | |
| 111 | print("All tests passed.") |
| 112 | report_job_success() |
| 113 | else: |
| 114 | raise Exception("Payload not defined") |
| 115 | |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 116 | # First make sure the test session finished. |
| 117 | for phase in filter(lambda p: p["name"] == "lava-test-monitor", results): |
| 118 | if phase["result"] != "pass": |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 119 | print(session + " test session failed. Did it time out?") |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 120 | report_job_failure() |
| 121 | break |
| 122 | else: |
| 123 | raise Exception("Couldn't find 'lava-test-monitor' phase results") |
| 124 | |
| 125 | # Then count the number of tests that failed/skipped. |
| 126 | test_failures = 0 |
| 127 | test_skips = 0 |
Zelalem | 219df41 | 2020-05-17 19:21:20 -0500 | [diff] [blame] | 128 | for phase in filter(lambda p: p["suite"] == suite, results): |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 129 | metadata = phase["metadata"] |
| 130 | testcase_name = metadata["case"] |
| 131 | testcase_result = metadata["result"] |
| 132 | if testcase_result == "fail": |
| 133 | test_failures += 1 |
| 134 | print("=> FAILED: " + testcase_name) |
| 135 | elif testcase_result == "skip": |
| 136 | test_skips += 1 |
| 137 | print(" SKIPPED: " + testcase_name) |
| 138 | |
| 139 | # Print a test summary |
| 140 | print() |
| 141 | if test_failures == 0 and test_skips == 0: |
| 142 | print("All tests passed.") |
| 143 | else: |
| 144 | print("{} tests failed; {} skipped. All other tests passed.".format( |
| 145 | test_failures, test_skips)) |
| 146 | |
| 147 | if test_failures == 0: |
| 148 | report_job_success() |
| 149 | else: |
| 150 | report_job_failure() |