blob: d8c2a879d17204fd9044f2187113f73e37517654 [file] [log] [blame]
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +00001"""Template test runner class for running TOSA tests."""
2# Copyright (c) 2020-2022, ARM Limited.
3# SPDX-License-Identifier: Apache-2.0
Eric Kunzee5e26762020-10-13 16:11:07 -07004import json
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +00005from enum import IntEnum
6from pathlib import Path
7
8from checker.tosa_result_checker import LogColors
9from checker.tosa_result_checker import print_color
Jeremy Johnson015c3552022-02-23 12:15:03 +000010from checker.tosa_result_checker import set_print_in_color
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000011from checker.tosa_result_checker import test_check
12from json2fbbin import json2fbbin
Eric Kunzee5e26762020-10-13 16:11:07 -070013
Kevin Cheng550ccc52021-03-03 11:21:43 -080014
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000015class TosaTestInvalid(Exception):
16 """Exception raised for errors loading test description.
Eric Kunzee5e26762020-10-13 16:11:07 -070017
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000018 Attributes:
19 path - full path to missing test description file
20 exception = underlying exception
21 """
Eric Kunzee5e26762020-10-13 16:11:07 -070022
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000023 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 Cheng550ccc52021-03-03 11:21:43 -080031
Eric Kunzee5e26762020-10-13 16:11:07 -070032
33class TosaTestRunner:
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000034 """TOSA Test Runner template class for systems under test."""
Eric Kunzee5e26762020-10-13 16:11:07 -070035
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010036 def __init__(self, args, runnerArgs, testDirPath):
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000037 """Initialize and load JSON meta data file."""
Eric Kunzee5e26762020-10-13 16:11:07 -070038 self.args = args
39 self.runnerArgs = runnerArgs
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010040 self.testDir = str(testDirPath)
41 self.testDirPath = testDirPath
42 self.testName = self.testDirPath.name
Eric Kunzee5e26762020-10-13 16:11:07 -070043
Jeremy Johnson015c3552022-02-23 12:15:03 +000044 set_print_in_color(not args.no_color)
45
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000046 # Check if we want to run binary and if its already converted
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010047 descFilePath = testDirPath / "desc.json"
48 descBinFilePath = testDirPath / "desc_binary.json"
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000049 if args.binary:
50 if descBinFilePath.is_file():
51 descFilePath = descBinFilePath
Eric Kunzee5e26762020-10-13 16:11:07 -070052
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000053 try:
54 # Load the json test file
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010055 with descFilePath.open("r") as fd:
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000056 self.testDesc = json.load(fd)
57 except Exception as e:
58 raise TosaTestInvalid(str(descFilePath), e)
59
60 # Convert to binary if needed
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010061 tosaFilePath = testDirPath / self.testDesc["tosa_file"]
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000062 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 Johnsone4b08ff2022-09-15 10:38:17 +010068 testDirPath,
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000069 )
70 # Write new desc_binary file
71 self.testDesc["tosa_file"] = tosaFilePath.stem + ".tosa"
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010072 with descBinFilePath.open("w") as fd:
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000073 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 Johnsone4b08ff2022-09-15 10:38:17 +010078 self.descFilePath = descFilePath
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000079
80 def skipTest(self):
Jeremy Johnson88588622022-07-12 16:42:29 +010081 """Check if the test is skipped due to test type or profile selection."""
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000082 expectedFailure = self.testDesc["expected_failure"]
83 if self.args.test_type == "negative" and not expectedFailure:
Jeremy Johnson88588622022-07-12 16:42:29 +010084 return True, "non-negative type"
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000085 elif self.args.test_type == "positive" and expectedFailure:
Jeremy Johnson88588622022-07-12 16:42:29 +010086 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 Johnsonbe1a9402021-12-15 17:14:56 +000092
93 def runTestGraph(self):
94 """Override with function that calls system under test."""
Eric Kunzee5e26762020-10-13 16:11:07 -070095 pass
96
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000097 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 Johnsone4b08ff2022-09-15 10:38:17 +0100114 conformanceFilePath = (
115 self.testDirPath
116 / self.testDesc["expected_result_file"][resultNum]
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000117 )
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 Johnsone4b08ff2022-09-15 10:38:17 +0100127 conformanceFilePath = None
128 resultFilePath = self.testDirPath / resultFileName
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000129
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100130 if conformanceFilePath:
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000131 print_result_line = False # Checker will print one for us
132 chkResult, tolerance, msg = test_check(
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100133 conformanceFilePath,
134 resultFilePath,
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000135 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 Johnsone4b08ff2022-09-15 10:38:17 +0100145 if not resultFilePath.is_file():
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000146 result = TosaTestRunner.Result.UNEXPECTED_FAILURE
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100147 msg = "Results file is missing: {}".format(resultFilePath)
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000148 messages.append(msg)
149 print(msg)
150
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100151 if resultFilePath.is_file():
152 # Move the resultFilePath to allow subsequent system under
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000153 # tests to create them and to test they have been created
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100154 resultFilePath = resultFilePath.rename(
155 resultFilePath.with_suffix(
156 ".{}{}".format(self.__module__, resultFilePath.suffix)
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000157 )
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 Johnson015c3552022-02-23 12:15:03 +0000177 print_color(
178 LogColors.GREEN, "Result code PASS {}".format(self.testName)
179 )
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000180 else:
Jeremy Johnson015c3552022-02-23 12:15:03 +0000181 print_color(LogColors.RED, "Result code FAIL {}".format(self.testName))
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000182
183 return result, resultMessage
184
Eric Kunzee5e26762020-10-13 16:11:07 -0700185 class Result(IntEnum):
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000186 """Test result codes."""
187
Eric Kunzee5e26762020-10-13 16:11:07 -0700188 EXPECTED_PASS = 0
189 EXPECTED_FAILURE = 1
190 UNEXPECTED_PASS = 2
191 UNEXPECTED_FAILURE = 3
192 INTERNAL_ERROR = 4
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000193 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