blob: 709bb1a3e0383a40143f370889791598e2747b89 [file] [log] [blame]
Gilles Peskinea1bb3f82020-03-24 18:20:59 +01001#!/usr/bin/env python3
2
Azim Khan951a2c82018-06-29 03:47:08 +01003# Greentea host test script for Mbed TLS on-target test suite testing.
Azim Khanf0e42fb2017-08-02 14:47:13 +01004#
Azim Khan8d686bf2018-07-04 23:29:46 +01005# Copyright (C) 2018, Arm Limited, All Rights Reserved
Azim Khanf0e42fb2017-08-02 14:47:13 +01006# SPDX-License-Identifier: Apache-2.0
7#
8# Licensed under the Apache License, Version 2.0 (the "License"); you may
9# not use this file except in compliance with the License.
10# You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17# See the License for the specific language governing permissions and
18# limitations under the License.
19#
Azim Khanb31aa442018-07-03 11:57:54 +010020# This file is part of Mbed TLS (https://tls.mbed.org)
Azim Khanf0e42fb2017-08-02 14:47:13 +010021
22
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010023"""
Azim Khan8d686bf2018-07-04 23:29:46 +010024Mbed TLS on-target test suite tests are implemented as Greentea
Azim Khan951a2c82018-06-29 03:47:08 +010025tests. Greentea tests are implemented in two parts: target test and
26host test. Target test is a C application that is built for the
27target platform and executes on the target. Host test is a Python
28class derived from mbed_host_tests.BaseHostTest. Target communicates
Azim Khan8d686bf2018-07-04 23:29:46 +010029with the host over serial for the test data and sends back the result.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010030
Azim Khanb31aa442018-07-03 11:57:54 +010031Python tool mbedgt (Greentea) is responsible for flashing the test
Azim Khan8d686bf2018-07-04 23:29:46 +010032binary on to the target and dynamically loading this host test module.
Azim Khan951a2c82018-06-29 03:47:08 +010033
Azim Khan8d686bf2018-07-04 23:29:46 +010034Greentea documentation can be found here:
35https://github.com/ARMmbed/greentea
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010036"""
37
Azim Khanf0e42fb2017-08-02 14:47:13 +010038
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010039import re
40import os
Azim Khan663d4702017-07-07 15:40:26 +010041import binascii
Gilles Peskineafd19dd2019-02-25 21:39:42 +010042
43from mbed_host_tests import BaseHostTest, event_callback # pylint: disable=import-error
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010044
45
Azim Khanb98e6ee2018-06-28 17:11:33 +010046class TestDataParserError(Exception):
47 """Indicates error in test data, read from .data file."""
48 pass
49
50
Gilles Peskinea1bb3f82020-03-24 18:20:59 +010051class TestDataParser:
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010052 """
Azim Khan951a2c82018-06-29 03:47:08 +010053 Parses test name, dependencies, test function name and test parameters
54 from the data file.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010055 """
56
57 def __init__(self):
58 """
59 Constructor
60 """
61 self.tests = []
62
63 def parse(self, data_file):
64 """
Azim Khanf0e42fb2017-08-02 14:47:13 +010065 Data file parser.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010066
Azim Khanf0e42fb2017-08-02 14:47:13 +010067 :param data_file: Data file path
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010068 """
Azim Khanb31aa442018-07-03 11:57:54 +010069 with open(data_file, 'r') as data_f:
70 self.__parse(data_f)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010071
72 @staticmethod
Azim Khanb31aa442018-07-03 11:57:54 +010073 def __escaped_split(inp_str, split_char):
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010074 """
Azim Khanb31aa442018-07-03 11:57:54 +010075 Splits inp_str on split_char except when escaped.
Azim Khanf0e42fb2017-08-02 14:47:13 +010076
Azim Khanb31aa442018-07-03 11:57:54 +010077 :param inp_str: String to split
78 :param split_char: Split character
Azim Khanf0e42fb2017-08-02 14:47:13 +010079 :return: List of splits
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010080 """
Ron Eldor111ba0e2018-11-18 17:05:05 +020081 split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x)
Azim Khanb31aa442018-07-03 11:57:54 +010082 if len(split_char) > 1:
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010083 raise ValueError('Expected split character. Found string!')
Ron Eldor56b6e522019-05-29 17:17:10 +030084 out = list(map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str)))
Ron Eldor7c52e222019-06-25 14:52:19 +030085 out = [x for x in out if x]
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010086 return out
87
Azim Khanb31aa442018-07-03 11:57:54 +010088 def __parse(self, data_f):
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010089 """
Azim Khanf0e42fb2017-08-02 14:47:13 +010090 Parses data file using supplied file object.
91
Azim Khanb31aa442018-07-03 11:57:54 +010092 :param data_f: Data file object
Azim Khanf0e42fb2017-08-02 14:47:13 +010093 :return:
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010094 """
Ron Eldorb43fe572019-06-03 11:38:42 +030095 for line in data_f:
96 line = line.strip()
Azim Khanb31aa442018-07-03 11:57:54 +010097 if not line:
Ron Eldorb43fe572019-06-03 11:38:42 +030098 continue
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +010099 # Read test name
100 name = line
101
102 # Check dependencies
Azim Khanb31aa442018-07-03 11:57:54 +0100103 dependencies = []
Ron Eldorb43fe572019-06-03 11:38:42 +0300104 line = next(data_f).strip()
Azim Khanb31aa442018-07-03 11:57:54 +0100105 match = re.search('depends_on:(.*)', line)
106 if match:
107 dependencies = [int(x) for x in match.group(1).split(':')]
Ron Eldorb43fe572019-06-03 11:38:42 +0300108 line = next(data_f).strip()
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100109
110 # Read test vectors
Azim Khan663d4702017-07-07 15:40:26 +0100111 line = line.replace('\\n', '\n')
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100112 parts = self.__escaped_split(line, ':')
Azim Khanb31aa442018-07-03 11:57:54 +0100113 function_name = int(parts[0])
114 args = parts[1:]
115 args_count = len(args)
116 if args_count % 2 != 0:
Ron Eldor111ba0e2018-11-18 17:05:05 +0200117 err_str_fmt = "Number of test arguments({}) should be even: {}"
118 raise TestDataParserError(err_str_fmt.format(args_count, line))
Azim Khanb31aa442018-07-03 11:57:54 +0100119 grouped_args = [(args[i * 2], args[(i * 2) + 1])
Ron Eldor56b6e522019-05-29 17:17:10 +0300120 for i in range(int(len(args)/2))]
Azim Khanb31aa442018-07-03 11:57:54 +0100121 self.tests.append((name, function_name, dependencies,
122 grouped_args))
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100123
124 def get_test_data(self):
125 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100126 Returns test data.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100127 """
128 return self.tests
129
130
131class MbedTlsTest(BaseHostTest):
132 """
Azim Khanb31aa442018-07-03 11:57:54 +0100133 Host test for Mbed TLS unit tests. This script is loaded at
134 run time by Greentea for executing Mbed TLS test suites. Each
Azim Khan951a2c82018-06-29 03:47:08 +0100135 communication from the target is received in this object as
136 an event, which is then handled by the event handler method
137 decorated by the associated event. Ex: @event_callback('GO').
138
139 Target test sends requests for dispatching next test. It reads
140 tests from the intermediate data file and sends test function
141 identifier, dependency identifiers, expression identifiers and
Azim Khanb31aa442018-07-03 11:57:54 +0100142 the test data in binary form. Target test checks dependencies
Azim Khan951a2c82018-06-29 03:47:08 +0100143 , evaluate integer constant expressions and dispatches the test
Azim Khan8d686bf2018-07-04 23:29:46 +0100144 function with received test parameters. After test function is
145 finished, target sends the result. This class handles the result
146 event and prints verdict in the form that Greentea understands.
Azim Khan951a2c82018-06-29 03:47:08 +0100147
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100148 """
Azim Khan951a2c82018-06-29 03:47:08 +0100149 # status/error codes from suites/helpers.function
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100150 DEPENDENCY_SUPPORTED = 0
151 KEY_VALUE_MAPPING_FOUND = DEPENDENCY_SUPPORTED
152 DISPATCH_TEST_SUCCESS = DEPENDENCY_SUPPORTED
153
Azim Khan951a2c82018-06-29 03:47:08 +0100154 KEY_VALUE_MAPPING_NOT_FOUND = -1 # Expression Id not found.
155 DEPENDENCY_NOT_SUPPORTED = -2 # Dependency not supported.
156 DISPATCH_TEST_FN_NOT_FOUND = -3 # Test function not found.
157 DISPATCH_INVALID_TEST_DATA = -4 # Invalid parameter type.
158 DISPATCH_UNSUPPORTED_SUITE = -5 # Test suite not supported/enabled.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100159
160 def __init__(self):
161 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100162 Constructor initialises test index to 0.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100163 """
164 super(MbedTlsTest, self).__init__()
165 self.tests = []
166 self.test_index = -1
167 self.dep_index = 0
Ron Eldor8672cb72018-11-13 18:42:35 +0200168 self.suite_passed = True
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100169 self.error_str = dict()
Azim Khanb31aa442018-07-03 11:57:54 +0100170 self.error_str[self.DEPENDENCY_SUPPORTED] = \
171 'DEPENDENCY_SUPPORTED'
172 self.error_str[self.KEY_VALUE_MAPPING_NOT_FOUND] = \
173 'KEY_VALUE_MAPPING_NOT_FOUND'
174 self.error_str[self.DEPENDENCY_NOT_SUPPORTED] = \
175 'DEPENDENCY_NOT_SUPPORTED'
176 self.error_str[self.DISPATCH_TEST_FN_NOT_FOUND] = \
177 'DISPATCH_TEST_FN_NOT_FOUND'
178 self.error_str[self.DISPATCH_INVALID_TEST_DATA] = \
179 'DISPATCH_INVALID_TEST_DATA'
180 self.error_str[self.DISPATCH_UNSUPPORTED_SUITE] = \
181 'DISPATCH_UNSUPPORTED_SUITE'
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100182
183 def setup(self):
184 """
Azim Khan951a2c82018-06-29 03:47:08 +0100185 Setup hook implementation. Reads test suite data file and parses out
186 tests.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100187 """
188 binary_path = self.get_config_item('image_path')
189 script_dir = os.path.split(os.path.abspath(__file__))[0]
190 suite_name = os.path.splitext(os.path.basename(binary_path))[0]
Ron Eldorc242eea2018-11-05 16:22:36 +0200191 data_file = ".".join((suite_name, 'datax'))
Azim Khan951a2c82018-06-29 03:47:08 +0100192 data_file = os.path.join(script_dir, '..', 'mbedtls',
193 suite_name, data_file)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100194 if os.path.exists(data_file):
195 self.log("Running tests from %s" % data_file)
196 parser = TestDataParser()
197 parser.parse(data_file)
198 self.tests = parser.get_test_data()
199 self.print_test_info()
200 else:
201 self.log("Data file not found: %s" % data_file)
202 self.notify_complete(False)
203
204 def print_test_info(self):
205 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100206 Prints test summary read by Greentea to detect test cases.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100207 """
208 self.log('{{__testcase_count;%d}}' % len(self.tests))
209 for name, _, _, _ in self.tests:
210 self.log('{{__testcase_name;%s}}' % name)
211
212 @staticmethod
Azim Khanb31aa442018-07-03 11:57:54 +0100213 def align_32bit(data_bytes):
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100214 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100215 4 byte aligns input byte array.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100216
217 :return:
218 """
Azim Khanb31aa442018-07-03 11:57:54 +0100219 data_bytes += bytearray((4 - (len(data_bytes))) % 4)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100220
Azim Khand59391a2017-06-01 14:04:17 +0100221 @staticmethod
222 def hex_str_bytes(hex_str):
223 """
224 Converts Hex string representation to byte array
225
Azim Khanf0e42fb2017-08-02 14:47:13 +0100226 :param hex_str: Hex in string format.
227 :return: Output Byte array
Azim Khand59391a2017-06-01 14:04:17 +0100228 """
Azim Khanb98e6ee2018-06-28 17:11:33 +0100229 if hex_str[0] != '"' or hex_str[len(hex_str) - 1] != '"':
230 raise TestDataParserError("HEX test parameter missing '\"':"
231 " %s" % hex_str)
Azim Khand59391a2017-06-01 14:04:17 +0100232 hex_str = hex_str.strip('"')
Azim Khanb98e6ee2018-06-28 17:11:33 +0100233 if len(hex_str) % 2 != 0:
234 raise TestDataParserError("HEX parameter len should be mod of "
235 "2: %s" % hex_str)
Azim Khand59391a2017-06-01 14:04:17 +0100236
Azim Khanb31aa442018-07-03 11:57:54 +0100237 data_bytes = binascii.unhexlify(hex_str)
238 return data_bytes
Azim Khand59391a2017-06-01 14:04:17 +0100239
Azim Khan663d4702017-07-07 15:40:26 +0100240 @staticmethod
Azim Khanb31aa442018-07-03 11:57:54 +0100241 def int32_to_big_endian_bytes(i):
Azim Khan663d4702017-07-07 15:40:26 +0100242 """
Azim Khanb31aa442018-07-03 11:57:54 +0100243 Coverts i to byte array in big endian format.
Azim Khan663d4702017-07-07 15:40:26 +0100244
Azim Khanf0e42fb2017-08-02 14:47:13 +0100245 :param i: Input integer
246 :return: Output bytes array in big endian or network order
Azim Khan663d4702017-07-07 15:40:26 +0100247 """
Azim Khanb31aa442018-07-03 11:57:54 +0100248 data_bytes = bytearray([((i >> x) & 0xff) for x in [24, 16, 8, 0]])
249 return data_bytes
Azim Khan663d4702017-07-07 15:40:26 +0100250
Azim Khanb31aa442018-07-03 11:57:54 +0100251 def test_vector_to_bytes(self, function_id, dependencies, parameters):
Azim Khan663d4702017-07-07 15:40:26 +0100252 """
253 Converts test vector into a byte array that can be sent to the target.
254
Azim Khanf0e42fb2017-08-02 14:47:13 +0100255 :param function_id: Test Function Identifier
Azim Khanb31aa442018-07-03 11:57:54 +0100256 :param dependencies: Dependency list
Azim Khanf0e42fb2017-08-02 14:47:13 +0100257 :param parameters: Test function input parameters
258 :return: Byte array and its length
Azim Khan663d4702017-07-07 15:40:26 +0100259 """
Azim Khanb31aa442018-07-03 11:57:54 +0100260 data_bytes = bytearray([len(dependencies)])
261 if dependencies:
262 data_bytes += bytearray(dependencies)
263 data_bytes += bytearray([function_id, len(parameters)])
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100264 for typ, param in parameters:
Gilles Peskine399b82f2020-03-24 18:36:56 +0100265 if typ in ('int', 'exp'):
Ron Eldor7c52e222019-06-25 14:52:19 +0300266 i = int(param, 0)
Ron Eldorb43fe572019-06-03 11:38:42 +0300267 data_bytes += b'I' if typ == 'int' else b'E'
Azim Khanb31aa442018-07-03 11:57:54 +0100268 self.align_32bit(data_bytes)
269 data_bytes += self.int32_to_big_endian_bytes(i)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100270 elif typ == 'char*':
271 param = param.strip('"')
272 i = len(param) + 1 # + 1 for null termination
Ron Eldorb43fe572019-06-03 11:38:42 +0300273 data_bytes += b'S'
Azim Khanb31aa442018-07-03 11:57:54 +0100274 self.align_32bit(data_bytes)
275 data_bytes += self.int32_to_big_endian_bytes(i)
Ron Eldor9d40da22019-06-03 13:39:21 +0300276 data_bytes += bytearray(param, encoding='ascii')
Ron Eldorb43fe572019-06-03 11:38:42 +0300277 data_bytes += b'\0' # Null terminate
Azim Khand59391a2017-06-01 14:04:17 +0100278 elif typ == 'hex':
Azim Khanb31aa442018-07-03 11:57:54 +0100279 binary_data = self.hex_str_bytes(param)
Ron Eldorb43fe572019-06-03 11:38:42 +0300280 data_bytes += b'H'
Azim Khanb31aa442018-07-03 11:57:54 +0100281 self.align_32bit(data_bytes)
282 i = len(binary_data)
283 data_bytes += self.int32_to_big_endian_bytes(i)
284 data_bytes += binary_data
285 length = self.int32_to_big_endian_bytes(len(data_bytes))
286 return data_bytes, length
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100287
288 def run_next_test(self):
289 """
Azim Khan951a2c82018-06-29 03:47:08 +0100290 Fetch next test information and execute the test.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100291
292 """
293 self.test_index += 1
294 self.dep_index = 0
295 if self.test_index < len(self.tests):
Azim Khanb31aa442018-07-03 11:57:54 +0100296 name, function_id, dependencies, args = self.tests[self.test_index]
297 self.run_test(name, function_id, dependencies, args)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100298 else:
Ron Eldor8672cb72018-11-13 18:42:35 +0200299 self.notify_complete(self.suite_passed)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100300
Azim Khanb31aa442018-07-03 11:57:54 +0100301 def run_test(self, name, function_id, dependencies, args):
Azim Khan663d4702017-07-07 15:40:26 +0100302 """
Azim Khan951a2c82018-06-29 03:47:08 +0100303 Execute the test on target by sending next test information.
Azim Khan663d4702017-07-07 15:40:26 +0100304
Azim Khanf0e42fb2017-08-02 14:47:13 +0100305 :param name: Test name
306 :param function_id: function identifier
Azim Khanb31aa442018-07-03 11:57:54 +0100307 :param dependencies: Dependencies list
Azim Khanf0e42fb2017-08-02 14:47:13 +0100308 :param args: test parameters
Azim Khan663d4702017-07-07 15:40:26 +0100309 :return:
310 """
311 self.log("Running: %s" % name)
312
Azim Khanb31aa442018-07-03 11:57:54 +0100313 param_bytes, length = self.test_vector_to_bytes(function_id,
314 dependencies, args)
Darryl Green349a0792019-12-17 10:17:20 +0000315 self.send_kv(
316 ''.join('{:02x}'.format(x) for x in length),
317 ''.join('{:02x}'.format(x) for x in param_bytes)
318 )
Azim Khan663d4702017-07-07 15:40:26 +0100319
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100320 @staticmethod
321 def get_result(value):
Azim Khanf0e42fb2017-08-02 14:47:13 +0100322 """
323 Converts result from string type to integer
324 :param value: Result code in string
Azim Khan8d686bf2018-07-04 23:29:46 +0100325 :return: Integer result code. Value is from the test status
326 constants defined under the MbedTlsTest class.
Azim Khanf0e42fb2017-08-02 14:47:13 +0100327 """
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100328 try:
329 return int(value)
330 except ValueError:
Azim Khanb31aa442018-07-03 11:57:54 +0100331 ValueError("Result should return error number. "
332 "Instead received %s" % value)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100333
334 @event_callback('GO')
Azim Khanb31aa442018-07-03 11:57:54 +0100335 def on_go(self, _key, _value, _timestamp):
Azim Khanf0e42fb2017-08-02 14:47:13 +0100336 """
Azim Khan951a2c82018-06-29 03:47:08 +0100337 Sent by the target to start first test.
Azim Khanf0e42fb2017-08-02 14:47:13 +0100338
Azim Khanb31aa442018-07-03 11:57:54 +0100339 :param _key: Event key
340 :param _value: Value. ignored
341 :param _timestamp: Timestamp ignored.
Azim Khanf0e42fb2017-08-02 14:47:13 +0100342 :return:
343 """
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100344 self.run_next_test()
345
346 @event_callback("R")
Azim Khanb31aa442018-07-03 11:57:54 +0100347 def on_result(self, _key, value, _timestamp):
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100348 """
Azim Khan951a2c82018-06-29 03:47:08 +0100349 Handle result. Prints test start, finish required by Greentea
350 to detect test execution.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100351
Azim Khanb31aa442018-07-03 11:57:54 +0100352 :param _key: Event key
Azim Khanf0e42fb2017-08-02 14:47:13 +0100353 :param value: Value. ignored
Azim Khanb31aa442018-07-03 11:57:54 +0100354 :param _timestamp: Timestamp ignored.
Azim Khanf0e42fb2017-08-02 14:47:13 +0100355 :return:
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100356 """
357 int_val = self.get_result(value)
Azim Khanb31aa442018-07-03 11:57:54 +0100358 name, _, _, _ = self.tests[self.test_index]
Azim Khan5e7f8df2017-05-31 20:33:39 +0100359 self.log('{{__testcase_start;%s}}' % name)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100360 self.log('{{__testcase_finish;%s;%d;%d}}' % (name, int_val == 0,
361 int_val != 0))
Ron Eldor8672cb72018-11-13 18:42:35 +0200362 if int_val != 0:
363 self.suite_passed = False
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100364 self.run_next_test()
365
366 @event_callback("F")
Azim Khanb31aa442018-07-03 11:57:54 +0100367 def on_failure(self, _key, value, _timestamp):
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100368 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100369 Handles test execution failure. That means dependency not supported or
370 Test function not supported. Hence marking test as skipped.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100371
Azim Khanb31aa442018-07-03 11:57:54 +0100372 :param _key: Event key
Azim Khanf0e42fb2017-08-02 14:47:13 +0100373 :param value: Value. ignored
Azim Khanb31aa442018-07-03 11:57:54 +0100374 :param _timestamp: Timestamp ignored.
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100375 :return:
376 """
377 int_val = self.get_result(value)
Mohammad Azim Khan7a0d84f2017-04-01 03:18:20 +0100378 if int_val in self.error_str:
379 err = self.error_str[int_val]
380 else:
381 err = 'Unknown error'
382 # For skip status, do not write {{__testcase_finish;...}}
383 self.log("Error: %s" % err)
384 self.run_next_test()