Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 1 | """Template test runner class for running TOSA tests.""" |
| 2 | # Copyright (c) 2020-2022, ARM Limited. |
| 3 | # SPDX-License-Identifier: Apache-2.0 |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 4 | import json |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 5 | from enum import IntEnum |
| 6 | from pathlib import Path |
| 7 | |
| 8 | from checker.tosa_result_checker import LogColors |
| 9 | from checker.tosa_result_checker import print_color |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 10 | from checker.tosa_result_checker import set_print_in_color |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 11 | from checker.tosa_result_checker import test_check |
| 12 | from json2fbbin import json2fbbin |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 13 | |
Kevin Cheng | 550ccc5 | 2021-03-03 11:21:43 -0800 | [diff] [blame] | 14 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 15 | class TosaTestInvalid(Exception): |
| 16 | """Exception raised for errors loading test description. |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 17 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 18 | Attributes: |
| 19 | path - full path to missing test description file |
| 20 | exception = underlying exception |
| 21 | """ |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 22 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 23 | def __init__(self, path, exception): |
| 24 | """Initialize test not found error.""" |
| 25 | self.path = path |
| 26 | self.exception = exception |
| 27 | self.message = "Invalid test, could not read test description {}: {}".format( |
| 28 | self.path, str(self.exception) |
| 29 | ) |
| 30 | super().__init__(self.message) |
Kevin Cheng | 550ccc5 | 2021-03-03 11:21:43 -0800 | [diff] [blame] | 31 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 32 | |
| 33 | class TosaTestRunner: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 34 | """TOSA Test Runner template class for systems under test.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 35 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 36 | def __init__(self, args, runnerArgs, testDirPath): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 37 | """Initialize and load JSON meta data file.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 38 | self.args = args |
| 39 | self.runnerArgs = runnerArgs |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 40 | self.testDir = str(testDirPath) |
| 41 | self.testDirPath = testDirPath |
| 42 | self.testName = self.testDirPath.name |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 43 | |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 44 | set_print_in_color(not args.no_color) |
| 45 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 46 | # Check if we want to run binary and if its already converted |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 47 | descFilePath = testDirPath / "desc.json" |
| 48 | descBinFilePath = testDirPath / "desc_binary.json" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 49 | if args.binary: |
| 50 | if descBinFilePath.is_file(): |
| 51 | descFilePath = descBinFilePath |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 52 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 53 | try: |
| 54 | # Load the json test file |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 55 | with descFilePath.open("r") as fd: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 56 | self.testDesc = json.load(fd) |
| 57 | except Exception as e: |
| 58 | raise TosaTestInvalid(str(descFilePath), e) |
| 59 | |
| 60 | # Convert to binary if needed |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 61 | tosaFilePath = testDirPath / self.testDesc["tosa_file"] |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 62 | if args.binary and tosaFilePath.suffix == ".json": |
| 63 | # Convert tosa JSON to binary |
| 64 | json2fbbin.json_to_fbbin( |
| 65 | Path(args.flatc_path), |
| 66 | Path(args.operator_fbs), |
| 67 | tosaFilePath, |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 68 | testDirPath, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 69 | ) |
| 70 | # Write new desc_binary file |
| 71 | self.testDesc["tosa_file"] = tosaFilePath.stem + ".tosa" |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 72 | with descBinFilePath.open("w") as fd: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 73 | json.dump(self.testDesc, fd, indent=2) |
| 74 | descFilePath = descBinFilePath |
| 75 | |
| 76 | # Set location of desc.json (or desc_binary.json) file in use |
| 77 | self.descFile = str(descFilePath) |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 78 | self.descFilePath = descFilePath |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 79 | |
| 80 | def skipTest(self): |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 81 | """Check if the test is skipped due to test type or profile selection.""" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 82 | expectedFailure = self.testDesc["expected_failure"] |
| 83 | if self.args.test_type == "negative" and not expectedFailure: |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 84 | return True, "non-negative type" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 85 | elif self.args.test_type == "positive" and expectedFailure: |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 86 | return True, "non-positive type" |
| 87 | if self.args.profile: |
| 88 | profile = self.testDesc["profile"] if "profile" in self.testDesc else [] |
| 89 | if self.args.profile not in profile: |
| 90 | return True, "non-{} profile".format(self.args.profile) |
| 91 | return False, "" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 92 | |
| 93 | def runTestGraph(self): |
| 94 | """Override with function that calls system under test.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 95 | pass |
| 96 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 97 | def testResult(self, tosaGraphResult, graphMessage=None): |
| 98 | """Work out test result based on graph result and output files.""" |
| 99 | expectedFailure = self.testDesc["expected_failure"] |
| 100 | print_result_line = True |
| 101 | |
| 102 | if tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_VALID: |
| 103 | if expectedFailure: |
| 104 | result = TosaTestRunner.Result.UNEXPECTED_PASS |
| 105 | resultMessage = "Expected failure test incorrectly passed" |
| 106 | else: |
| 107 | # Work through all the results produced by the testing, assuming success |
| 108 | # but overriding this with any failures found |
| 109 | result = TosaTestRunner.Result.EXPECTED_PASS |
| 110 | messages = [] |
| 111 | for resultNum, resultFileName in enumerate(self.testDesc["ofm_file"]): |
| 112 | if "expected_result_file" in self.testDesc: |
| 113 | try: |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 114 | conformanceFilePath = ( |
| 115 | self.testDirPath |
| 116 | / self.testDesc["expected_result_file"][resultNum] |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 117 | ) |
| 118 | except IndexError: |
| 119 | result = TosaTestRunner.Result.INTERNAL_ERROR |
| 120 | msg = "Internal error: Missing expected_result_file {} in {}".format( |
| 121 | resultNum, self.descFile |
| 122 | ) |
| 123 | messages.append(msg) |
| 124 | print(msg) |
| 125 | break |
| 126 | else: |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 127 | conformanceFilePath = None |
| 128 | resultFilePath = self.testDirPath / resultFileName |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 129 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 130 | if conformanceFilePath: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 131 | print_result_line = False # Checker will print one for us |
| 132 | chkResult, tolerance, msg = test_check( |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 133 | conformanceFilePath, |
| 134 | resultFilePath, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 135 | test_name=self.testName, |
| 136 | ) |
| 137 | # Change EXPECTED_PASS assumption if we have any failures |
| 138 | if chkResult != 0: |
| 139 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
| 140 | messages.append(msg) |
| 141 | if self.args.verbose: |
| 142 | print(msg) |
| 143 | else: |
| 144 | # No conformance file to verify, just check results file exists |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 145 | if not resultFilePath.is_file(): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 146 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 147 | msg = "Results file is missing: {}".format(resultFilePath) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 148 | messages.append(msg) |
| 149 | print(msg) |
| 150 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 151 | if resultFilePath.is_file(): |
| 152 | # Move the resultFilePath to allow subsequent system under |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 153 | # tests to create them and to test they have been created |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 154 | resultFilePath = resultFilePath.rename( |
| 155 | resultFilePath.with_suffix( |
| 156 | ".{}{}".format(self.__module__, resultFilePath.suffix) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 157 | ) |
| 158 | ) |
| 159 | |
| 160 | resultMessage = "\n".join(messages) if len(messages) > 0 else None |
| 161 | else: |
| 162 | if ( |
| 163 | expectedFailure |
| 164 | and tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_ERROR |
| 165 | ): |
| 166 | result = TosaTestRunner.Result.EXPECTED_FAILURE |
| 167 | resultMessage = None |
| 168 | else: |
| 169 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
| 170 | resultMessage = graphMessage |
| 171 | |
| 172 | if print_result_line: |
| 173 | if ( |
| 174 | result == TosaTestRunner.Result.EXPECTED_FAILURE |
| 175 | or result == TosaTestRunner.Result.EXPECTED_PASS |
| 176 | ): |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 177 | print_color( |
| 178 | LogColors.GREEN, "Result code PASS {}".format(self.testName) |
| 179 | ) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 180 | else: |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 181 | print_color(LogColors.RED, "Result code FAIL {}".format(self.testName)) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 182 | |
| 183 | return result, resultMessage |
| 184 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 185 | class Result(IntEnum): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 186 | """Test result codes.""" |
| 187 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 188 | EXPECTED_PASS = 0 |
| 189 | EXPECTED_FAILURE = 1 |
| 190 | UNEXPECTED_PASS = 2 |
| 191 | UNEXPECTED_FAILURE = 3 |
| 192 | INTERNAL_ERROR = 4 |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 193 | SKIPPED = 5 |
| 194 | |
| 195 | class TosaGraphResult(IntEnum): |
| 196 | """The tosa_graph_result codes.""" |
| 197 | |
| 198 | TOSA_VALID = 0 |
| 199 | TOSA_UNPREDICTABLE = 1 |
| 200 | TOSA_ERROR = 2 |
| 201 | OTHER_ERROR = 3 |