blob: 65931d88b8892f9da1111cc2d7e92ab1d4120f14 [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 Johnsonbe1a9402021-12-15 17:14:56 +000036 def __init__(self, args, runnerArgs, testDir):
37 """Initialize and load JSON meta data file."""
Eric Kunzee5e26762020-10-13 16:11:07 -070038 self.args = args
39 self.runnerArgs = runnerArgs
40 self.testDir = testDir
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000041 self.testName = Path(self.testDir).name
Eric Kunzee5e26762020-10-13 16:11:07 -070042
Jeremy Johnson015c3552022-02-23 12:15:03 +000043 set_print_in_color(not args.no_color)
44
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000045 # Check if we want to run binary and if its already converted
46 descFilePath = Path(testDir, "desc.json")
47 descBinFilePath = Path(testDir, "desc_binary.json")
48 if args.binary:
49 if descBinFilePath.is_file():
50 descFilePath = descBinFilePath
Eric Kunzee5e26762020-10-13 16:11:07 -070051
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000052 try:
53 # Load the json test file
54 with open(descFilePath, "r") as fd:
55 self.testDesc = json.load(fd)
56 except Exception as e:
57 raise TosaTestInvalid(str(descFilePath), e)
58
59 # Convert to binary if needed
60 tosaFilePath = Path(testDir, self.testDesc["tosa_file"])
61 if args.binary and tosaFilePath.suffix == ".json":
62 # Convert tosa JSON to binary
63 json2fbbin.json_to_fbbin(
64 Path(args.flatc_path),
65 Path(args.operator_fbs),
66 tosaFilePath,
67 Path(testDir),
68 )
69 # Write new desc_binary file
70 self.testDesc["tosa_file"] = tosaFilePath.stem + ".tosa"
71 with open(descBinFilePath, "w") as fd:
72 json.dump(self.testDesc, fd, indent=2)
73 descFilePath = descBinFilePath
74
75 # Set location of desc.json (or desc_binary.json) file in use
76 self.descFile = str(descFilePath)
77
78 def skipTest(self):
Jeremy Johnson88588622022-07-12 16:42:29 +010079 """Check if the test is skipped due to test type or profile selection."""
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000080 expectedFailure = self.testDesc["expected_failure"]
81 if self.args.test_type == "negative" and not expectedFailure:
Jeremy Johnson88588622022-07-12 16:42:29 +010082 return True, "non-negative type"
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000083 elif self.args.test_type == "positive" and expectedFailure:
Jeremy Johnson88588622022-07-12 16:42:29 +010084 return True, "non-positive type"
85 if self.args.profile:
86 profile = self.testDesc["profile"] if "profile" in self.testDesc else []
87 if self.args.profile not in profile:
88 return True, "non-{} profile".format(self.args.profile)
89 return False, ""
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000090
91 def runTestGraph(self):
92 """Override with function that calls system under test."""
Eric Kunzee5e26762020-10-13 16:11:07 -070093 pass
94
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +000095 def testResult(self, tosaGraphResult, graphMessage=None):
96 """Work out test result based on graph result and output files."""
97 expectedFailure = self.testDesc["expected_failure"]
98 print_result_line = True
99
100 if tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_VALID:
101 if expectedFailure:
102 result = TosaTestRunner.Result.UNEXPECTED_PASS
103 resultMessage = "Expected failure test incorrectly passed"
104 else:
105 # Work through all the results produced by the testing, assuming success
106 # but overriding this with any failures found
107 result = TosaTestRunner.Result.EXPECTED_PASS
108 messages = []
109 for resultNum, resultFileName in enumerate(self.testDesc["ofm_file"]):
110 if "expected_result_file" in self.testDesc:
111 try:
112 conformanceFile = Path(
113 self.testDir,
114 self.testDesc["expected_result_file"][resultNum],
115 )
116 except IndexError:
117 result = TosaTestRunner.Result.INTERNAL_ERROR
118 msg = "Internal error: Missing expected_result_file {} in {}".format(
119 resultNum, self.descFile
120 )
121 messages.append(msg)
122 print(msg)
123 break
124 else:
125 conformanceFile = None
126 resultFile = Path(self.testDir, resultFileName)
127
128 if conformanceFile:
129 print_result_line = False # Checker will print one for us
130 chkResult, tolerance, msg = test_check(
131 str(conformanceFile),
132 str(resultFile),
133 test_name=self.testName,
134 )
135 # Change EXPECTED_PASS assumption if we have any failures
136 if chkResult != 0:
137 result = TosaTestRunner.Result.UNEXPECTED_FAILURE
138 messages.append(msg)
139 if self.args.verbose:
140 print(msg)
141 else:
142 # No conformance file to verify, just check results file exists
143 if not resultFile.is_file():
144 result = TosaTestRunner.Result.UNEXPECTED_FAILURE
145 msg = "Results file is missing: {}".format(resultFile)
146 messages.append(msg)
147 print(msg)
148
149 if resultFile.is_file():
150 # Move the resultFile to allow subsequent system under
151 # tests to create them and to test they have been created
152 resultFile = resultFile.rename(
153 resultFile.with_suffix(
154 ".{}{}".format(self.__module__, resultFile.suffix)
155 )
156 )
157
158 resultMessage = "\n".join(messages) if len(messages) > 0 else None
159 else:
160 if (
161 expectedFailure
162 and tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_ERROR
163 ):
164 result = TosaTestRunner.Result.EXPECTED_FAILURE
165 resultMessage = None
166 else:
167 result = TosaTestRunner.Result.UNEXPECTED_FAILURE
168 resultMessage = graphMessage
169
170 if print_result_line:
171 if (
172 result == TosaTestRunner.Result.EXPECTED_FAILURE
173 or result == TosaTestRunner.Result.EXPECTED_PASS
174 ):
Jeremy Johnson015c3552022-02-23 12:15:03 +0000175 print_color(
176 LogColors.GREEN, "Result code PASS {}".format(self.testName)
177 )
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000178 else:
Jeremy Johnson015c3552022-02-23 12:15:03 +0000179 print_color(LogColors.RED, "Result code FAIL {}".format(self.testName))
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000180
181 return result, resultMessage
182
Eric Kunzee5e26762020-10-13 16:11:07 -0700183 class Result(IntEnum):
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000184 """Test result codes."""
185
Eric Kunzee5e26762020-10-13 16:11:07 -0700186 EXPECTED_PASS = 0
187 EXPECTED_FAILURE = 1
188 UNEXPECTED_PASS = 2
189 UNEXPECTED_FAILURE = 3
190 INTERNAL_ERROR = 4
Jeremy Johnsonbe1a9402021-12-15 17:14:56 +0000191 SKIPPED = 5
192
193 class TosaGraphResult(IntEnum):
194 """The tosa_graph_result codes."""
195
196 TOSA_VALID = 0
197 TOSA_UNPREDICTABLE = 1
198 TOSA_ERROR = 2
199 OTHER_ERROR = 3