blob: d23d742193c0bfc1bdd5a433336e04eec40b69a9 [file] [log] [blame]
Azim Khanb31aa442018-07-03 11:57:54 +01001#!/usr/bin/env python3
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00002# Unit test for generate_test_code.py
Azim Khanf0e42fb2017-08-02 14:47:13 +01003#
Bence Szépkúti1e148272020-08-07 13:07:28 +02004# Copyright The Mbed TLS Contributors
Azim Khanf0e42fb2017-08-02 14:47:13 +01005# SPDX-License-Identifier: Apache-2.0
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
Azim Khan4b543232017-06-30 09:35:21 +010018
19"""
Mohammad Azim Khan78befd92018-03-06 11:49:41 +000020Unit tests for generate_test_code.py
Azim Khan4b543232017-06-30 09:35:21 +010021"""
22
Gilles Peskine38b66df2020-08-12 02:11:38 +020023from io import StringIO
Azim Khanb31aa442018-07-03 11:57:54 +010024from unittest import TestCase, main as unittest_main
Gilles Peskine38b66df2020-08-12 02:11:38 +020025from unittest.mock import patch
26
Azim Khanb31aa442018-07-03 11:57:54 +010027from generate_test_code import gen_dependencies, gen_dependencies_one_line
28from generate_test_code import gen_function_wrapper, gen_dispatch
29from generate_test_code import parse_until_pattern, GeneratorInputError
30from generate_test_code import parse_suite_dependencies
31from generate_test_code import parse_function_dependencies
Azim Khanfcdf6852018-07-05 17:31:46 +010032from generate_test_code import parse_function_arguments, parse_function_code
Azim Khanb31aa442018-07-03 11:57:54 +010033from generate_test_code import parse_functions, END_HEADER_REGEX
34from generate_test_code import END_SUITE_HELPERS_REGEX, escaped_split
35from generate_test_code import parse_test_data, gen_dep_check
36from generate_test_code import gen_expression_check, write_dependencies
37from generate_test_code import write_parameters, gen_suite_dep_checks
38from generate_test_code import gen_from_test_data
39
40
Azim Khan4b543232017-06-30 09:35:21 +010041class GenDep(TestCase):
42 """
43 Test suite for function gen_dep()
44 """
45
Azim Khanb31aa442018-07-03 11:57:54 +010046 def test_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +010047 """
Azim Khanb31aa442018-07-03 11:57:54 +010048 Test that gen_dep() correctly creates dependencies for given
49 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010050 :return:
Azim Khan4b543232017-06-30 09:35:21 +010051 """
Azim Khanb31aa442018-07-03 11:57:54 +010052 dependencies = ['DEP1', 'DEP2']
53 dep_start, dep_end = gen_dependencies(dependencies)
54 preprocessor1, preprocessor2 = dep_start.splitlines()
Azim Khan4b543232017-06-30 09:35:21 +010055 endif1, endif2 = dep_end.splitlines()
Azim Khanb31aa442018-07-03 11:57:54 +010056 self.assertEqual(preprocessor1, '#if defined(DEP1)',
57 'Preprocessor generated incorrectly')
58 self.assertEqual(preprocessor2, '#if defined(DEP2)',
59 'Preprocessor generated incorrectly')
60 self.assertEqual(endif1, '#endif /* DEP2 */',
61 'Preprocessor generated incorrectly')
62 self.assertEqual(endif2, '#endif /* DEP1 */',
63 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +010064
Azim Khanb31aa442018-07-03 11:57:54 +010065 def test_disabled_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +010066 """
Azim Khanb31aa442018-07-03 11:57:54 +010067 Test that gen_dep() correctly creates dependencies for given
68 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010069 :return:
Azim Khan4b543232017-06-30 09:35:21 +010070 """
Azim Khanb31aa442018-07-03 11:57:54 +010071 dependencies = ['!DEP1', '!DEP2']
72 dep_start, dep_end = gen_dependencies(dependencies)
73 preprocessor1, preprocessor2 = dep_start.splitlines()
Azim Khan4b543232017-06-30 09:35:21 +010074 endif1, endif2 = dep_end.splitlines()
Azim Khanb31aa442018-07-03 11:57:54 +010075 self.assertEqual(preprocessor1, '#if !defined(DEP1)',
76 'Preprocessor generated incorrectly')
77 self.assertEqual(preprocessor2, '#if !defined(DEP2)',
78 'Preprocessor generated incorrectly')
79 self.assertEqual(endif1, '#endif /* !DEP2 */',
80 'Preprocessor generated incorrectly')
81 self.assertEqual(endif2, '#endif /* !DEP1 */',
82 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +010083
Azim Khanb31aa442018-07-03 11:57:54 +010084 def test_mixed_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +010085 """
Azim Khanb31aa442018-07-03 11:57:54 +010086 Test that gen_dep() correctly creates dependencies for given
87 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010088 :return:
Azim Khan4b543232017-06-30 09:35:21 +010089 """
Azim Khanb31aa442018-07-03 11:57:54 +010090 dependencies = ['!DEP1', 'DEP2']
91 dep_start, dep_end = gen_dependencies(dependencies)
92 preprocessor1, preprocessor2 = dep_start.splitlines()
Azim Khan4b543232017-06-30 09:35:21 +010093 endif1, endif2 = dep_end.splitlines()
Azim Khanb31aa442018-07-03 11:57:54 +010094 self.assertEqual(preprocessor1, '#if !defined(DEP1)',
95 'Preprocessor generated incorrectly')
96 self.assertEqual(preprocessor2, '#if defined(DEP2)',
97 'Preprocessor generated incorrectly')
98 self.assertEqual(endif1, '#endif /* DEP2 */',
99 'Preprocessor generated incorrectly')
100 self.assertEqual(endif2, '#endif /* !DEP1 */',
101 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100102
Azim Khanb31aa442018-07-03 11:57:54 +0100103 def test_empty_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100104 """
Azim Khanb31aa442018-07-03 11:57:54 +0100105 Test that gen_dep() correctly creates dependencies for given
106 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100107 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100108 """
Azim Khanb31aa442018-07-03 11:57:54 +0100109 dependencies = []
110 dep_start, dep_end = gen_dependencies(dependencies)
111 self.assertEqual(dep_start, '', 'Preprocessor generated incorrectly')
112 self.assertEqual(dep_end, '', 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100113
Azim Khanb31aa442018-07-03 11:57:54 +0100114 def test_large_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100115 """
Azim Khanb31aa442018-07-03 11:57:54 +0100116 Test that gen_dep() correctly creates dependencies for given
117 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100118 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100119 """
Azim Khanb31aa442018-07-03 11:57:54 +0100120 dependencies = []
Azim Khan4b543232017-06-30 09:35:21 +0100121 count = 10
122 for i in range(count):
Azim Khanb31aa442018-07-03 11:57:54 +0100123 dependencies.append('DEP%d' % i)
124 dep_start, dep_end = gen_dependencies(dependencies)
125 self.assertEqual(len(dep_start.splitlines()), count,
126 'Preprocessor generated incorrectly')
127 self.assertEqual(len(dep_end.splitlines()), count,
128 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100129
130
131class GenDepOneLine(TestCase):
132 """
Azim Khanb31aa442018-07-03 11:57:54 +0100133 Test Suite for testing gen_dependencies_one_line()
Azim Khan4b543232017-06-30 09:35:21 +0100134 """
135
Azim Khanb31aa442018-07-03 11:57:54 +0100136 def test_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100137 """
Azim Khanb31aa442018-07-03 11:57:54 +0100138 Test that gen_dep() correctly creates dependencies for given
139 dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100140 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100141 """
Azim Khanb31aa442018-07-03 11:57:54 +0100142 dependencies = ['DEP1', 'DEP2']
143 dep_str = gen_dependencies_one_line(dependencies)
144 self.assertEqual(dep_str, '#if defined(DEP1) && defined(DEP2)',
145 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100146
Azim Khanb31aa442018-07-03 11:57:54 +0100147 def test_disabled_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100148 """
Azim Khanb31aa442018-07-03 11:57:54 +0100149 Test that gen_dep() correctly creates dependencies for given
150 dependency list.
Azim Khan4b543232017-06-30 09:35:21 +0100151 :return:
152 """
Azim Khanb31aa442018-07-03 11:57:54 +0100153 dependencies = ['!DEP1', '!DEP2']
154 dep_str = gen_dependencies_one_line(dependencies)
155 self.assertEqual(dep_str, '#if !defined(DEP1) && !defined(DEP2)',
156 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100157
Azim Khanb31aa442018-07-03 11:57:54 +0100158 def test_mixed_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100159 """
Azim Khanb31aa442018-07-03 11:57:54 +0100160 Test that gen_dep() correctly creates dependencies for given
161 dependency list.
Azim Khan4b543232017-06-30 09:35:21 +0100162 :return:
163 """
Azim Khanb31aa442018-07-03 11:57:54 +0100164 dependencies = ['!DEP1', 'DEP2']
165 dep_str = gen_dependencies_one_line(dependencies)
166 self.assertEqual(dep_str, '#if !defined(DEP1) && defined(DEP2)',
167 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100168
Azim Khanb31aa442018-07-03 11:57:54 +0100169 def test_empty_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100170 """
Azim Khanb31aa442018-07-03 11:57:54 +0100171 Test that gen_dep() correctly creates dependencies for given
172 dependency list.
Azim Khan4b543232017-06-30 09:35:21 +0100173 :return:
174 """
Azim Khanb31aa442018-07-03 11:57:54 +0100175 dependencies = []
176 dep_str = gen_dependencies_one_line(dependencies)
177 self.assertEqual(dep_str, '', 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100178
Azim Khanb31aa442018-07-03 11:57:54 +0100179 def test_large_dependencies_list(self):
Azim Khan4b543232017-06-30 09:35:21 +0100180 """
Azim Khanb31aa442018-07-03 11:57:54 +0100181 Test that gen_dep() correctly creates dependencies for given
182 dependency list.
Azim Khan4b543232017-06-30 09:35:21 +0100183 :return:
184 """
Azim Khanb31aa442018-07-03 11:57:54 +0100185 dependencies = []
Azim Khan4b543232017-06-30 09:35:21 +0100186 count = 10
187 for i in range(count):
Azim Khanb31aa442018-07-03 11:57:54 +0100188 dependencies.append('DEP%d' % i)
189 dep_str = gen_dependencies_one_line(dependencies)
190 expected = '#if ' + ' && '.join(['defined(%s)' %
191 x for x in dependencies])
192 self.assertEqual(dep_str, expected,
193 'Preprocessor generated incorrectly')
Azim Khan4b543232017-06-30 09:35:21 +0100194
195
196class GenFunctionWrapper(TestCase):
197 """
198 Test Suite for testing gen_function_wrapper()
199 """
200
201 def test_params_unpack(self):
202 """
203 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100204
205 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100206 """
207 code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
208 expected = '''
209void test_a_wrapper( void ** params )
210{
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100211
Azim Khan4b543232017-06-30 09:35:21 +0100212 test_a( a, b, c, d );
213}
214'''
215 self.assertEqual(code, expected)
216
217 def test_local(self):
218 """
219 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100220
221 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100222 """
Azim Khanb31aa442018-07-03 11:57:54 +0100223 code = gen_function_wrapper('test_a',
224 'int x = 1;', ('x', 'b', 'c', 'd'))
Azim Khan4b543232017-06-30 09:35:21 +0100225 expected = '''
226void test_a_wrapper( void ** params )
227{
Azim Khan4b543232017-06-30 09:35:21 +0100228int x = 1;
229 test_a( x, b, c, d );
230}
231'''
232 self.assertEqual(code, expected)
233
234 def test_empty_params(self):
235 """
236 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100237
238 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100239 """
240 code = gen_function_wrapper('test_a', '', ())
241 expected = '''
242void test_a_wrapper( void ** params )
243{
244 (void)params;
245
246 test_a( );
247}
248'''
249 self.assertEqual(code, expected)
250
251
252class GenDispatch(TestCase):
253 """
254 Test suite for testing gen_dispatch()
255 """
256
257 def test_dispatch(self):
258 """
259 Test that dispatch table entry is generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100260 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100261 """
262 code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
263 expected = '''
264#if defined(DEP1) && defined(DEP2)
265 test_a_wrapper,
266#else
267 NULL,
268#endif
269'''
270 self.assertEqual(code, expected)
271
Azim Khanb31aa442018-07-03 11:57:54 +0100272 def test_empty_dependencies(self):
Azim Khan4b543232017-06-30 09:35:21 +0100273 """
274 Test empty dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100275 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100276 """
277 code = gen_dispatch('test_a', [])
278 expected = '''
279 test_a_wrapper,
280'''
281 self.assertEqual(code, expected)
282
283
Gilles Peskine184c0962020-03-24 18:25:17 +0100284class StringIOWrapper(StringIO):
Azim Khan4b543232017-06-30 09:35:21 +0100285 """
286 file like class to mock file object in tests.
287 """
Azim Khan4084ec72018-07-05 14:20:08 +0100288 def __init__(self, file_name, data, line_no=0):
Azim Khan4b543232017-06-30 09:35:21 +0100289 """
290 Init file handle.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100291
292 :param file_name:
Azim Khan4b543232017-06-30 09:35:21 +0100293 :param data:
294 :param line_no:
295 """
296 super(StringIOWrapper, self).__init__(data)
297 self.line_no = line_no
298 self.name = file_name
299
300 def next(self):
301 """
Azim Khanb31aa442018-07-03 11:57:54 +0100302 Iterator method. This method overrides base class's
303 next method and extends the next method to count the line
304 numbers as each line is read.
Azim Khan4b543232017-06-30 09:35:21 +0100305
Azim Khanb31aa442018-07-03 11:57:54 +0100306 :return: Line read from file.
307 """
Mohammad Azim Khan539aa062018-07-06 00:29:50 +0100308 parent = super(StringIOWrapper, self)
Gilles Peskine38b66df2020-08-12 02:11:38 +0200309 line = parent.__next__()
Azim Khan4084ec72018-07-05 14:20:08 +0100310 return line
Azim Khanb31aa442018-07-03 11:57:54 +0100311
Gilles Peskine38b66df2020-08-12 02:11:38 +0200312 def readline(self, _length=0):
Azim Khan4b543232017-06-30 09:35:21 +0100313 """
314 Wrap the base class readline.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100315
Azim Khanb31aa442018-07-03 11:57:54 +0100316 :param length:
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100317 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100318 """
319 line = super(StringIOWrapper, self).readline()
Azim Khan4084ec72018-07-05 14:20:08 +0100320 if line is not None:
Azim Khan4b543232017-06-30 09:35:21 +0100321 self.line_no += 1
322 return line
323
324
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000325class ParseUntilPattern(TestCase):
Azim Khan4b543232017-06-30 09:35:21 +0100326 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000327 Test Suite for testing parse_until_pattern().
Azim Khan4b543232017-06-30 09:35:21 +0100328 """
329
330 def test_suite_headers(self):
331 """
332 Test that suite headers are parsed correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100333
334 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100335 """
336 data = '''#include "mbedtls/ecp.h"
337
338#define ECP_PF_UNKNOWN -1
339/* END_HEADER */
340'''
341 expected = '''#line 1 "test_suite_ut.function"
342#include "mbedtls/ecp.h"
343
344#define ECP_PF_UNKNOWN -1
345'''
Azim Khanb31aa442018-07-03 11:57:54 +0100346 stream = StringIOWrapper('test_suite_ut.function', data, line_no=0)
347 headers = parse_until_pattern(stream, END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100348 self.assertEqual(headers, expected)
349
350 def test_line_no(self):
351 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100352 Test that #line is set to correct line no. in source .function file.
353
354 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100355 """
356 data = '''#include "mbedtls/ecp.h"
357
358#define ECP_PF_UNKNOWN -1
359/* END_HEADER */
360'''
361 offset_line_no = 5
362 expected = '''#line %d "test_suite_ut.function"
363#include "mbedtls/ecp.h"
364
365#define ECP_PF_UNKNOWN -1
366''' % (offset_line_no + 1)
Azim Khanb31aa442018-07-03 11:57:54 +0100367 stream = StringIOWrapper('test_suite_ut.function', data,
368 offset_line_no)
369 headers = parse_until_pattern(stream, END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100370 self.assertEqual(headers, expected)
371
372 def test_no_end_header_comment(self):
373 """
Azim Khanb31aa442018-07-03 11:57:54 +0100374 Test that InvalidFileFormat is raised when end header comment is
375 missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100376 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100377 """
378 data = '''#include "mbedtls/ecp.h"
379
380#define ECP_PF_UNKNOWN -1
381
382'''
Azim Khanb31aa442018-07-03 11:57:54 +0100383 stream = StringIOWrapper('test_suite_ut.function', data)
384 self.assertRaises(GeneratorInputError, parse_until_pattern, stream,
385 END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100386
387
Azim Khanb31aa442018-07-03 11:57:54 +0100388class ParseSuiteDependencies(TestCase):
Azim Khan4b543232017-06-30 09:35:21 +0100389 """
Azim Khanb31aa442018-07-03 11:57:54 +0100390 Test Suite for testing parse_suite_dependencies().
Azim Khan4b543232017-06-30 09:35:21 +0100391 """
392
Azim Khanb31aa442018-07-03 11:57:54 +0100393 def test_suite_dependencies(self):
Azim Khan4b543232017-06-30 09:35:21 +0100394 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100395
396 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100397 """
398 data = '''
399 * depends_on:MBEDTLS_ECP_C
400 * END_DEPENDENCIES
401 */
402'''
403 expected = ['MBEDTLS_ECP_C']
Azim Khanb31aa442018-07-03 11:57:54 +0100404 stream = StringIOWrapper('test_suite_ut.function', data)
405 dependencies = parse_suite_dependencies(stream)
406 self.assertEqual(dependencies, expected)
Azim Khan4b543232017-06-30 09:35:21 +0100407
408 def test_no_end_dep_comment(self):
409 """
410 Test that InvalidFileFormat is raised when end dep comment is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100411 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100412 """
413 data = '''
414* depends_on:MBEDTLS_ECP_C
415'''
Azim Khanb31aa442018-07-03 11:57:54 +0100416 stream = StringIOWrapper('test_suite_ut.function', data)
417 self.assertRaises(GeneratorInputError, parse_suite_dependencies,
418 stream)
Azim Khan4b543232017-06-30 09:35:21 +0100419
Azim Khanb31aa442018-07-03 11:57:54 +0100420 def test_dependencies_split(self):
Azim Khan4b543232017-06-30 09:35:21 +0100421 """
422 Test that InvalidFileFormat is raised when end dep comment is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100423 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100424 """
425 data = '''
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100426 * depends_on:MBEDTLS_ECP_C:A:B: C : D :F : G: !H
Azim Khan4b543232017-06-30 09:35:21 +0100427 * END_DEPENDENCIES
428 */
429'''
430 expected = ['MBEDTLS_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
Azim Khanb31aa442018-07-03 11:57:54 +0100431 stream = StringIOWrapper('test_suite_ut.function', data)
432 dependencies = parse_suite_dependencies(stream)
433 self.assertEqual(dependencies, expected)
Azim Khan4b543232017-06-30 09:35:21 +0100434
435
Azim Khanb31aa442018-07-03 11:57:54 +0100436class ParseFuncDependencies(TestCase):
Azim Khan4b543232017-06-30 09:35:21 +0100437 """
Azim Khanb31aa442018-07-03 11:57:54 +0100438 Test Suite for testing parse_function_dependencies()
Azim Khan4b543232017-06-30 09:35:21 +0100439 """
440
Azim Khanb31aa442018-07-03 11:57:54 +0100441 def test_function_dependencies(self):
Azim Khan4b543232017-06-30 09:35:21 +0100442 """
Azim Khanb31aa442018-07-03 11:57:54 +0100443 Test that parse_function_dependencies() correctly parses function
444 dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100445 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100446 """
Azim Khanb31aa442018-07-03 11:57:54 +0100447 line = '/* BEGIN_CASE ' \
448 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */'
Azim Khan4b543232017-06-30 09:35:21 +0100449 expected = ['MBEDTLS_ENTROPY_NV_SEED', 'MBEDTLS_FS_IO']
Azim Khanb31aa442018-07-03 11:57:54 +0100450 dependencies = parse_function_dependencies(line)
451 self.assertEqual(dependencies, expected)
Azim Khan4b543232017-06-30 09:35:21 +0100452
Azim Khanb31aa442018-07-03 11:57:54 +0100453 def test_no_dependencies(self):
Azim Khan4b543232017-06-30 09:35:21 +0100454 """
Azim Khanb31aa442018-07-03 11:57:54 +0100455 Test that parse_function_dependencies() correctly parses function
456 dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100457 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100458 """
459 line = '/* BEGIN_CASE */'
Azim Khanb31aa442018-07-03 11:57:54 +0100460 dependencies = parse_function_dependencies(line)
461 self.assertEqual(dependencies, [])
Azim Khan4b543232017-06-30 09:35:21 +0100462
Azim Khanb31aa442018-07-03 11:57:54 +0100463 def test_tolerance(self):
Azim Khan4b543232017-06-30 09:35:21 +0100464 """
Azim Khanb31aa442018-07-03 11:57:54 +0100465 Test that parse_function_dependencies() correctly parses function
466 dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100467 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100468 """
469 line = '/* BEGIN_CASE depends_on:MBEDTLS_FS_IO: A : !B:C : F*/'
Azim Khanb31aa442018-07-03 11:57:54 +0100470 dependencies = parse_function_dependencies(line)
471 self.assertEqual(dependencies, ['MBEDTLS_FS_IO', 'A', '!B', 'C', 'F'])
Azim Khan4b543232017-06-30 09:35:21 +0100472
473
474class ParseFuncSignature(TestCase):
475 """
Azim Khanfcdf6852018-07-05 17:31:46 +0100476 Test Suite for parse_function_arguments().
Azim Khan4b543232017-06-30 09:35:21 +0100477 """
478
479 def test_int_and_char_params(self):
480 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100481 Test int and char parameters parsing
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100482 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100483 """
484 line = 'void entropy_threshold( char * a, int b, int result )'
Azim Khanfcdf6852018-07-05 17:31:46 +0100485 args, local, arg_dispatch = parse_function_arguments(line)
Azim Khan4b543232017-06-30 09:35:21 +0100486 self.assertEqual(args, ['char*', 'int', 'int'])
487 self.assertEqual(local, '')
Azim Khanb31aa442018-07-03 11:57:54 +0100488 self.assertEqual(arg_dispatch, ['(char *) params[0]',
489 '*( (int *) params[1] )',
490 '*( (int *) params[2] )'])
Azim Khan4b543232017-06-30 09:35:21 +0100491
492 def test_hex_params(self):
493 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100494 Test hex parameters parsing
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100495 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100496 """
Azim Khan5fcca462018-06-29 11:05:32 +0100497 line = 'void entropy_threshold( char * a, data_t * h, int result )'
Azim Khanfcdf6852018-07-05 17:31:46 +0100498 args, local, arg_dispatch = parse_function_arguments(line)
Azim Khan4b543232017-06-30 09:35:21 +0100499 self.assertEqual(args, ['char*', 'hex', 'int'])
Azim Khanb31aa442018-07-03 11:57:54 +0100500 self.assertEqual(local,
Azim Khan4084ec72018-07-05 14:20:08 +0100501 ' data_t data1 = {(uint8_t *) params[1], '
Azim Khanb31aa442018-07-03 11:57:54 +0100502 '*( (uint32_t *) params[2] )};\n')
503 self.assertEqual(arg_dispatch, ['(char *) params[0]',
Azim Khan4084ec72018-07-05 14:20:08 +0100504 '&data1',
Azim Khanb31aa442018-07-03 11:57:54 +0100505 '*( (int *) params[3] )'])
Azim Khan4b543232017-06-30 09:35:21 +0100506
Azim Khan4b543232017-06-30 09:35:21 +0100507 def test_unsupported_arg(self):
508 """
Azim Khan5fcca462018-06-29 11:05:32 +0100509 Test unsupported arguments (not among int, char * and data_t)
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100510 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100511 """
Azim Khanfcdf6852018-07-05 17:31:46 +0100512 line = 'void entropy_threshold( char * a, data_t * h, char result )'
513 self.assertRaises(ValueError, parse_function_arguments, line)
Azim Khan4b543232017-06-30 09:35:21 +0100514
515 def test_no_params(self):
516 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100517 Test no parameters.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100518 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100519 """
520 line = 'void entropy_threshold()'
Azim Khanfcdf6852018-07-05 17:31:46 +0100521 args, local, arg_dispatch = parse_function_arguments(line)
Azim Khan4b543232017-06-30 09:35:21 +0100522 self.assertEqual(args, [])
523 self.assertEqual(local, '')
524 self.assertEqual(arg_dispatch, [])
525
526
527class ParseFunctionCode(TestCase):
528 """
529 Test suite for testing parse_function_code()
530 """
531
532 def test_no_function(self):
533 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100534 Test no test function found.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100535 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100536 """
537 data = '''
538No
539test
540function
541'''
Azim Khanb31aa442018-07-03 11:57:54 +0100542 stream = StringIOWrapper('test_suite_ut.function', data)
Azim Khanfcdf6852018-07-05 17:31:46 +0100543 err_msg = 'file: test_suite_ut.function - Test functions not found!'
Gilles Peskine38b66df2020-08-12 02:11:38 +0200544 self.assertRaisesRegex(GeneratorInputError, err_msg,
545 parse_function_code, stream, [], [])
Azim Khan4b543232017-06-30 09:35:21 +0100546
547 def test_no_end_case_comment(self):
548 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100549 Test missing end case.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100550 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100551 """
552 data = '''
553void test_func()
554{
555}
556'''
Azim Khanb31aa442018-07-03 11:57:54 +0100557 stream = StringIOWrapper('test_suite_ut.function', data)
Azim Khanfcdf6852018-07-05 17:31:46 +0100558 err_msg = r'file: test_suite_ut.function - '\
559 'end case pattern .*? not found!'
Gilles Peskine38b66df2020-08-12 02:11:38 +0200560 self.assertRaisesRegex(GeneratorInputError, err_msg,
561 parse_function_code, stream, [], [])
Azim Khan4b543232017-06-30 09:35:21 +0100562
Azim Khanfcdf6852018-07-05 17:31:46 +0100563 @patch("generate_test_code.parse_function_arguments")
Azim Khanb31aa442018-07-03 11:57:54 +0100564 def test_function_called(self,
Azim Khanfcdf6852018-07-05 17:31:46 +0100565 parse_function_arguments_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100566 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100567 Test parse_function_code()
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100568 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100569 """
Azim Khanfcdf6852018-07-05 17:31:46 +0100570 parse_function_arguments_mock.return_value = ([], '', [])
Azim Khan4b543232017-06-30 09:35:21 +0100571 data = '''
572void test_func()
573{
574}
575'''
Azim Khanb31aa442018-07-03 11:57:54 +0100576 stream = StringIOWrapper('test_suite_ut.function', data)
577 self.assertRaises(GeneratorInputError, parse_function_code,
578 stream, [], [])
Azim Khanfcdf6852018-07-05 17:31:46 +0100579 self.assertTrue(parse_function_arguments_mock.called)
580 parse_function_arguments_mock.assert_called_with('void test_func()\n')
Azim Khan4b543232017-06-30 09:35:21 +0100581
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000582 @patch("generate_test_code.gen_dispatch")
Azim Khanb31aa442018-07-03 11:57:54 +0100583 @patch("generate_test_code.gen_dependencies")
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000584 @patch("generate_test_code.gen_function_wrapper")
Azim Khanfcdf6852018-07-05 17:31:46 +0100585 @patch("generate_test_code.parse_function_arguments")
586 def test_return(self, parse_function_arguments_mock,
Azim Khanb31aa442018-07-03 11:57:54 +0100587 gen_function_wrapper_mock,
588 gen_dependencies_mock,
589 gen_dispatch_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100590 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100591 Test generated code.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100592 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100593 """
Azim Khanfcdf6852018-07-05 17:31:46 +0100594 parse_function_arguments_mock.return_value = ([], '', [])
Azim Khan4b543232017-06-30 09:35:21 +0100595 gen_function_wrapper_mock.return_value = ''
Azim Khanb31aa442018-07-03 11:57:54 +0100596 gen_dependencies_mock.side_effect = gen_dependencies
Azim Khan4b543232017-06-30 09:35:21 +0100597 gen_dispatch_mock.side_effect = gen_dispatch
598 data = '''
599void func()
600{
601 ba ba black sheep
602 have you any wool
603}
604/* END_CASE */
605'''
Azim Khanb31aa442018-07-03 11:57:54 +0100606 stream = StringIOWrapper('test_suite_ut.function', data)
607 name, arg, code, dispatch_code = parse_function_code(stream, [], [])
Azim Khan4b543232017-06-30 09:35:21 +0100608
Azim Khanfcdf6852018-07-05 17:31:46 +0100609 self.assertTrue(parse_function_arguments_mock.called)
610 parse_function_arguments_mock.assert_called_with('void func()\n')
Azim Khan4b543232017-06-30 09:35:21 +0100611 gen_function_wrapper_mock.assert_called_with('test_func', '', [])
612 self.assertEqual(name, 'test_func')
613 self.assertEqual(arg, [])
Azim Khan4084ec72018-07-05 14:20:08 +0100614 expected = '''#line 1 "test_suite_ut.function"
615
Azim Khan4b543232017-06-30 09:35:21 +0100616void test_func()
617{
618 ba ba black sheep
619 have you any wool
620exit:
Azim Khan4084ec72018-07-05 14:20:08 +0100621 ;
Azim Khan4b543232017-06-30 09:35:21 +0100622}
623'''
624 self.assertEqual(code, expected)
625 self.assertEqual(dispatch_code, "\n test_func_wrapper,\n")
626
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000627 @patch("generate_test_code.gen_dispatch")
Azim Khanb31aa442018-07-03 11:57:54 +0100628 @patch("generate_test_code.gen_dependencies")
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000629 @patch("generate_test_code.gen_function_wrapper")
Azim Khanfcdf6852018-07-05 17:31:46 +0100630 @patch("generate_test_code.parse_function_arguments")
631 def test_with_exit_label(self, parse_function_arguments_mock,
Azim Khanb31aa442018-07-03 11:57:54 +0100632 gen_function_wrapper_mock,
633 gen_dependencies_mock,
634 gen_dispatch_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100635 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100636 Test when exit label is present.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100637 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100638 """
Azim Khanfcdf6852018-07-05 17:31:46 +0100639 parse_function_arguments_mock.return_value = ([], '', [])
Azim Khan4b543232017-06-30 09:35:21 +0100640 gen_function_wrapper_mock.return_value = ''
Azim Khanb31aa442018-07-03 11:57:54 +0100641 gen_dependencies_mock.side_effect = gen_dependencies
Azim Khan4b543232017-06-30 09:35:21 +0100642 gen_dispatch_mock.side_effect = gen_dispatch
643 data = '''
644void func()
645{
646 ba ba black sheep
647 have you any wool
648exit:
649 yes sir yes sir
650 3 bags full
651}
652/* END_CASE */
653'''
Azim Khanb31aa442018-07-03 11:57:54 +0100654 stream = StringIOWrapper('test_suite_ut.function', data)
655 _, _, code, _ = parse_function_code(stream, [], [])
Azim Khan4b543232017-06-30 09:35:21 +0100656
Azim Khan4084ec72018-07-05 14:20:08 +0100657 expected = '''#line 1 "test_suite_ut.function"
658
Azim Khan4b543232017-06-30 09:35:21 +0100659void test_func()
660{
661 ba ba black sheep
662 have you any wool
663exit:
664 yes sir yes sir
665 3 bags full
666}
667'''
668 self.assertEqual(code, expected)
669
Azim Khanfcdf6852018-07-05 17:31:46 +0100670 def test_non_void_function(self):
671 """
672 Test invalid signature (non void).
673 :return:
674 """
675 data = 'int entropy_threshold( char * a, data_t * h, int result )'
676 err_msg = 'file: test_suite_ut.function - Test functions not found!'
677 stream = StringIOWrapper('test_suite_ut.function', data)
Gilles Peskine38b66df2020-08-12 02:11:38 +0200678 self.assertRaisesRegex(GeneratorInputError, err_msg,
679 parse_function_code, stream, [], [])
Azim Khanfcdf6852018-07-05 17:31:46 +0100680
681 @patch("generate_test_code.gen_dispatch")
682 @patch("generate_test_code.gen_dependencies")
683 @patch("generate_test_code.gen_function_wrapper")
684 @patch("generate_test_code.parse_function_arguments")
Gilles Peskine0cf42202022-11-11 16:36:51 +0100685 def test_function_name_on_newline(self, parse_function_arguments_mock,
686 gen_function_wrapper_mock,
687 gen_dependencies_mock,
688 gen_dispatch_mock):
Azim Khanfcdf6852018-07-05 17:31:46 +0100689 """
Gilles Peskine0cf42202022-11-11 16:36:51 +0100690 Test with line break before the function name.
Azim Khanfcdf6852018-07-05 17:31:46 +0100691 :return:
692 """
693 parse_function_arguments_mock.return_value = ([], '', [])
694 gen_function_wrapper_mock.return_value = ''
695 gen_dependencies_mock.side_effect = gen_dependencies
696 gen_dispatch_mock.side_effect = gen_dispatch
697 data = '''
698void
699
700
701func()
702{
703 ba ba black sheep
704 have you any wool
705exit:
706 yes sir yes sir
707 3 bags full
708}
709/* END_CASE */
710'''
711 stream = StringIOWrapper('test_suite_ut.function', data)
712 _, _, code, _ = parse_function_code(stream, [], [])
713
714 expected = '''#line 1 "test_suite_ut.function"
715
716void
717
718
719test_func()
720{
721 ba ba black sheep
722 have you any wool
723exit:
724 yes sir yes sir
725 3 bags full
726}
727'''
728 self.assertEqual(code, expected)
729
Gilles Peskine07510f52022-11-11 16:37:16 +0100730 @patch("generate_test_code.gen_dispatch")
731 @patch("generate_test_code.gen_dependencies")
732 @patch("generate_test_code.gen_function_wrapper")
733 @patch("generate_test_code.parse_function_arguments")
734 def test_case_starting_with_comment(self, parse_function_arguments_mock,
735 gen_function_wrapper_mock,
736 gen_dependencies_mock,
737 gen_dispatch_mock):
738 """
739 Test with comments before the function signature
740 :return:
741 """
742 parse_function_arguments_mock.return_value = ([], '', [])
743 gen_function_wrapper_mock.return_value = ''
744 gen_dependencies_mock.side_effect = gen_dependencies
745 gen_dispatch_mock.side_effect = gen_dispatch
746 data = '''/* comment */
747/* more
748 * comment */
Gilles Peskine18f48eb2022-11-18 22:24:56 +0100749// this is\\
750still \\
Gilles Peskine07510f52022-11-11 16:37:16 +0100751a comment
752void func()
753{
754 ba ba black sheep
755 have you any wool
756exit:
757 yes sir yes sir
758 3 bags full
759}
760/* END_CASE */
761'''
762 stream = StringIOWrapper('test_suite_ut.function', data)
763 _, _, code, _ = parse_function_code(stream, [], [])
764
765 expected = '''#line 1 "test_suite_ut.function"
766
767
768
Gilles Peskined8c08032022-11-29 22:03:32 +0100769
Gilles Peskine18f70282022-11-30 16:38:49 +0100770
771
Gilles Peskine07510f52022-11-11 16:37:16 +0100772void test_func()
773{
774 ba ba black sheep
775 have you any wool
776exit:
777 yes sir yes sir
778 3 bags full
779}
780'''
781 self.assertEqual(code, expected)
782
783 @patch("generate_test_code.gen_dispatch")
784 @patch("generate_test_code.gen_dependencies")
785 @patch("generate_test_code.gen_function_wrapper")
786 @patch("generate_test_code.parse_function_arguments")
787 def test_comment_in_prototype(self, parse_function_arguments_mock,
788 gen_function_wrapper_mock,
789 gen_dependencies_mock,
790 gen_dispatch_mock):
791 """
792 Test with comments in the function prototype
793 :return:
794 """
795 parse_function_arguments_mock.return_value = ([], '', [])
796 gen_function_wrapper_mock.return_value = ''
797 gen_dependencies_mock.side_effect = gen_dependencies
798 gen_dispatch_mock.side_effect = gen_dispatch
799 data = '''
800void func( int x, // (line \\
801 comment)
802 int y /* lone closing parenthesis) */ )
803{
804 ba ba black sheep
805 have you any wool
806exit:
807 yes sir yes sir
808 3 bags full
809}
810/* END_CASE */
811'''
812 stream = StringIOWrapper('test_suite_ut.function', data)
813 _, _, code, _ = parse_function_code(stream, [], [])
814
815 expected = '''#line 1 "test_suite_ut.function"
816
817void test_func( int x,
Gilles Peskine18f70282022-11-30 16:38:49 +0100818
Gilles Peskine07510f52022-11-11 16:37:16 +0100819 int y )
820{
821 ba ba black sheep
822 have you any wool
823exit:
824 yes sir yes sir
825 3 bags full
826}
827'''
828 self.assertEqual(code, expected)
829
Gilles Peskine45747a02022-11-18 22:25:18 +0100830 @patch("generate_test_code.gen_dispatch")
831 @patch("generate_test_code.gen_dependencies")
832 @patch("generate_test_code.gen_function_wrapper")
833 @patch("generate_test_code.parse_function_arguments")
834 def test_line_comment_in_block_comment(self, parse_function_arguments_mock,
835 gen_function_wrapper_mock,
836 gen_dependencies_mock,
837 gen_dispatch_mock):
838 """
839 Test with line comment in block comment.
840 :return:
841 """
842 parse_function_arguments_mock.return_value = ([], '', [])
843 gen_function_wrapper_mock.return_value = ''
844 gen_dependencies_mock.side_effect = gen_dependencies
845 gen_dispatch_mock.side_effect = gen_dispatch
846 data = '''
847void func( int x /* // */ )
848{
849 ba ba black sheep
850 have you any wool
851exit:
852 yes sir yes sir
853 3 bags full
854}
855/* END_CASE */
856'''
857 stream = StringIOWrapper('test_suite_ut.function', data)
858 _, _, code, _ = parse_function_code(stream, [], [])
859
860 expected = '''#line 1 "test_suite_ut.function"
861
862void test_func( int x )
863{
864 ba ba black sheep
865 have you any wool
866exit:
867 yes sir yes sir
868 3 bags full
869}
870'''
871 self.assertEqual(code, expected)
872
873 @patch("generate_test_code.gen_dispatch")
874 @patch("generate_test_code.gen_dependencies")
875 @patch("generate_test_code.gen_function_wrapper")
876 @patch("generate_test_code.parse_function_arguments")
877 def test_block_comment_in_line_comment(self, parse_function_arguments_mock,
878 gen_function_wrapper_mock,
879 gen_dependencies_mock,
880 gen_dispatch_mock):
881 """
882 Test with block comment in line comment.
883 :return:
884 """
885 parse_function_arguments_mock.return_value = ([], '', [])
886 gen_function_wrapper_mock.return_value = ''
887 gen_dependencies_mock.side_effect = gen_dependencies
888 gen_dispatch_mock.side_effect = gen_dispatch
889 data = '''
890// /*
891void func( int x )
892{
893 ba ba black sheep
894 have you any wool
895exit:
896 yes sir yes sir
897 3 bags full
898}
899/* END_CASE */
900'''
901 stream = StringIOWrapper('test_suite_ut.function', data)
902 _, _, code, _ = parse_function_code(stream, [], [])
903
904 expected = '''#line 1 "test_suite_ut.function"
905
906
907void test_func( int x )
908{
909 ba ba black sheep
910 have you any wool
911exit:
912 yes sir yes sir
913 3 bags full
914}
915'''
916 self.assertEqual(code, expected)
917
Azim Khan4b543232017-06-30 09:35:21 +0100918
919class ParseFunction(TestCase):
920 """
921 Test Suite for testing parse_functions()
922 """
923
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000924 @patch("generate_test_code.parse_until_pattern")
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000925 def test_begin_header(self, parse_until_pattern_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100926 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000927 Test that begin header is checked and parse_until_pattern() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100928 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100929 """
Azim Khanb31aa442018-07-03 11:57:54 +0100930 def stop(*_unused):
931 """Stop when parse_until_pattern is called."""
Azim Khan4b543232017-06-30 09:35:21 +0100932 raise Exception
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000933 parse_until_pattern_mock.side_effect = stop
Azim Khan4b543232017-06-30 09:35:21 +0100934 data = '''/* BEGIN_HEADER */
935#include "mbedtls/ecp.h"
936
937#define ECP_PF_UNKNOWN -1
938/* END_HEADER */
939'''
Azim Khanb31aa442018-07-03 11:57:54 +0100940 stream = StringIOWrapper('test_suite_ut.function', data)
941 self.assertRaises(Exception, parse_functions, stream)
942 parse_until_pattern_mock.assert_called_with(stream, END_HEADER_REGEX)
Azim Khan4084ec72018-07-05 14:20:08 +0100943 self.assertEqual(stream.line_no, 1)
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000944
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000945 @patch("generate_test_code.parse_until_pattern")
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000946 def test_begin_helper(self, parse_until_pattern_mock):
947 """
948 Test that begin helper is checked and parse_until_pattern() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100949 :return:
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000950 """
Azim Khanb31aa442018-07-03 11:57:54 +0100951 def stop(*_unused):
952 """Stop when parse_until_pattern is called."""
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000953 raise Exception
954 parse_until_pattern_mock.side_effect = stop
955 data = '''/* BEGIN_SUITE_HELPERS */
Azim Khanb31aa442018-07-03 11:57:54 +0100956void print_hello_world()
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000957{
Azim Khanb31aa442018-07-03 11:57:54 +0100958 printf("Hello World!\n");
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000959}
960/* END_SUITE_HELPERS */
961'''
Azim Khanb31aa442018-07-03 11:57:54 +0100962 stream = StringIOWrapper('test_suite_ut.function', data)
963 self.assertRaises(Exception, parse_functions, stream)
964 parse_until_pattern_mock.assert_called_with(stream,
965 END_SUITE_HELPERS_REGEX)
Azim Khan4084ec72018-07-05 14:20:08 +0100966 self.assertEqual(stream.line_no, 1)
Azim Khan4b543232017-06-30 09:35:21 +0100967
Azim Khanb31aa442018-07-03 11:57:54 +0100968 @patch("generate_test_code.parse_suite_dependencies")
969 def test_begin_dep(self, parse_suite_dependencies_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100970 """
Azim Khanb31aa442018-07-03 11:57:54 +0100971 Test that begin dep is checked and parse_suite_dependencies() is
972 called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100973 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100974 """
Azim Khanb31aa442018-07-03 11:57:54 +0100975 def stop(*_unused):
976 """Stop when parse_until_pattern is called."""
Azim Khan4b543232017-06-30 09:35:21 +0100977 raise Exception
Azim Khanb31aa442018-07-03 11:57:54 +0100978 parse_suite_dependencies_mock.side_effect = stop
Azim Khan4b543232017-06-30 09:35:21 +0100979 data = '''/* BEGIN_DEPENDENCIES
980 * depends_on:MBEDTLS_ECP_C
981 * END_DEPENDENCIES
982 */
983'''
Azim Khanb31aa442018-07-03 11:57:54 +0100984 stream = StringIOWrapper('test_suite_ut.function', data)
985 self.assertRaises(Exception, parse_functions, stream)
986 parse_suite_dependencies_mock.assert_called_with(stream)
Azim Khan4084ec72018-07-05 14:20:08 +0100987 self.assertEqual(stream.line_no, 1)
Azim Khan4b543232017-06-30 09:35:21 +0100988
Azim Khanb31aa442018-07-03 11:57:54 +0100989 @patch("generate_test_code.parse_function_dependencies")
990 def test_begin_function_dep(self, func_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100991 """
Azim Khanb31aa442018-07-03 11:57:54 +0100992 Test that begin dep is checked and parse_function_dependencies() is
993 called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100994 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100995 """
Azim Khanb31aa442018-07-03 11:57:54 +0100996 def stop(*_unused):
997 """Stop when parse_until_pattern is called."""
Azim Khan4b543232017-06-30 09:35:21 +0100998 raise Exception
Azim Khanb31aa442018-07-03 11:57:54 +0100999 func_mock.side_effect = stop
Azim Khan4b543232017-06-30 09:35:21 +01001000
Azim Khanb31aa442018-07-03 11:57:54 +01001001 dependencies_str = '/* BEGIN_CASE ' \
1002 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
Azim Khan4b543232017-06-30 09:35:21 +01001003 data = '''%svoid test_func()
1004{
1005}
Azim Khanb31aa442018-07-03 11:57:54 +01001006''' % dependencies_str
1007 stream = StringIOWrapper('test_suite_ut.function', data)
1008 self.assertRaises(Exception, parse_functions, stream)
1009 func_mock.assert_called_with(dependencies_str)
Azim Khan4084ec72018-07-05 14:20:08 +01001010 self.assertEqual(stream.line_no, 1)
Azim Khan4b543232017-06-30 09:35:21 +01001011
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00001012 @patch("generate_test_code.parse_function_code")
Azim Khanb31aa442018-07-03 11:57:54 +01001013 @patch("generate_test_code.parse_function_dependencies")
1014 def test_return(self, func_mock1, func_mock2):
Azim Khan4b543232017-06-30 09:35:21 +01001015 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +00001016 Test that begin case is checked and parse_function_code() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001017 :return:
Azim Khan4b543232017-06-30 09:35:21 +01001018 """
Azim Khanb31aa442018-07-03 11:57:54 +01001019 func_mock1.return_value = []
1020 in_func_code = '''void test_func()
Azim Khan4b543232017-06-30 09:35:21 +01001021{
1022}
1023'''
1024 func_dispatch = '''
1025 test_func_wrapper,
1026'''
Azim Khanb31aa442018-07-03 11:57:54 +01001027 func_mock2.return_value = 'test_func', [],\
1028 in_func_code, func_dispatch
1029 dependencies_str = '/* BEGIN_CASE ' \
1030 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
Azim Khan4b543232017-06-30 09:35:21 +01001031 data = '''%svoid test_func()
1032{
1033}
Azim Khanb31aa442018-07-03 11:57:54 +01001034''' % dependencies_str
1035 stream = StringIOWrapper('test_suite_ut.function', data)
1036 suite_dependencies, dispatch_code, func_code, func_info = \
1037 parse_functions(stream)
1038 func_mock1.assert_called_with(dependencies_str)
1039 func_mock2.assert_called_with(stream, [], [])
1040 self.assertEqual(stream.line_no, 5)
1041 self.assertEqual(suite_dependencies, [])
Azim Khan4b543232017-06-30 09:35:21 +01001042 expected_dispatch_code = '''/* Function Id: 0 */
1043
1044 test_func_wrapper,
1045'''
1046 self.assertEqual(dispatch_code, expected_dispatch_code)
1047 self.assertEqual(func_code, in_func_code)
1048 self.assertEqual(func_info, {'test_func': (0, [])})
1049
1050 def test_parsing(self):
1051 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +00001052 Test case parsing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001053 :return:
Azim Khan4b543232017-06-30 09:35:21 +01001054 """
1055 data = '''/* BEGIN_HEADER */
1056#include "mbedtls/ecp.h"
1057
1058#define ECP_PF_UNKNOWN -1
1059/* END_HEADER */
1060
1061/* BEGIN_DEPENDENCIES
1062 * depends_on:MBEDTLS_ECP_C
1063 * END_DEPENDENCIES
1064 */
1065
1066/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
1067void func1()
1068{
1069}
1070/* END_CASE */
1071
1072/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
1073void func2()
1074{
1075}
1076/* END_CASE */
1077'''
Azim Khanb31aa442018-07-03 11:57:54 +01001078 stream = StringIOWrapper('test_suite_ut.function', data)
1079 suite_dependencies, dispatch_code, func_code, func_info = \
1080 parse_functions(stream)
1081 self.assertEqual(stream.line_no, 23)
1082 self.assertEqual(suite_dependencies, ['MBEDTLS_ECP_C'])
Azim Khan4b543232017-06-30 09:35:21 +01001083
1084 expected_dispatch_code = '''/* Function Id: 0 */
1085
1086#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
1087 test_func1_wrapper,
1088#else
1089 NULL,
1090#endif
1091/* Function Id: 1 */
1092
1093#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
1094 test_func2_wrapper,
1095#else
1096 NULL,
1097#endif
1098'''
1099 self.assertEqual(dispatch_code, expected_dispatch_code)
1100 expected_func_code = '''#if defined(MBEDTLS_ECP_C)
Azim Khan4084ec72018-07-05 14:20:08 +01001101#line 2 "test_suite_ut.function"
Azim Khan4b543232017-06-30 09:35:21 +01001102#include "mbedtls/ecp.h"
1103
1104#define ECP_PF_UNKNOWN -1
1105#if defined(MBEDTLS_ENTROPY_NV_SEED)
1106#if defined(MBEDTLS_FS_IO)
Azim Khan4084ec72018-07-05 14:20:08 +01001107#line 13 "test_suite_ut.function"
Azim Khan4b543232017-06-30 09:35:21 +01001108void test_func1()
1109{
1110exit:
Azim Khan4084ec72018-07-05 14:20:08 +01001111 ;
Azim Khan4b543232017-06-30 09:35:21 +01001112}
1113
1114void test_func1_wrapper( void ** params )
1115{
1116 (void)params;
1117
1118 test_func1( );
1119}
1120#endif /* MBEDTLS_FS_IO */
1121#endif /* MBEDTLS_ENTROPY_NV_SEED */
1122#if defined(MBEDTLS_ENTROPY_NV_SEED)
1123#if defined(MBEDTLS_FS_IO)
Azim Khan4084ec72018-07-05 14:20:08 +01001124#line 19 "test_suite_ut.function"
Azim Khan4b543232017-06-30 09:35:21 +01001125void test_func2()
1126{
1127exit:
Azim Khan4084ec72018-07-05 14:20:08 +01001128 ;
Azim Khan4b543232017-06-30 09:35:21 +01001129}
1130
1131void test_func2_wrapper( void ** params )
1132{
1133 (void)params;
1134
1135 test_func2( );
1136}
1137#endif /* MBEDTLS_FS_IO */
1138#endif /* MBEDTLS_ENTROPY_NV_SEED */
1139#endif /* MBEDTLS_ECP_C */
1140'''
1141 self.assertEqual(func_code, expected_func_code)
Azim Khanb31aa442018-07-03 11:57:54 +01001142 self.assertEqual(func_info, {'test_func1': (0, []),
1143 'test_func2': (1, [])})
Azim Khan4b543232017-06-30 09:35:21 +01001144
1145 def test_same_function_name(self):
1146 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +00001147 Test name conflict.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001148 :return:
Azim Khan4b543232017-06-30 09:35:21 +01001149 """
1150 data = '''/* BEGIN_HEADER */
1151#include "mbedtls/ecp.h"
1152
1153#define ECP_PF_UNKNOWN -1
1154/* END_HEADER */
1155
1156/* BEGIN_DEPENDENCIES
1157 * depends_on:MBEDTLS_ECP_C
1158 * END_DEPENDENCIES
1159 */
1160
1161/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
1162void func()
1163{
1164}
1165/* END_CASE */
1166
1167/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
1168void func()
1169{
1170}
1171/* END_CASE */
1172'''
Azim Khanb31aa442018-07-03 11:57:54 +01001173 stream = StringIOWrapper('test_suite_ut.function', data)
1174 self.assertRaises(GeneratorInputError, parse_functions, stream)
Azim Khan4b543232017-06-30 09:35:21 +01001175
1176
Azim Khanb31aa442018-07-03 11:57:54 +01001177class EscapedSplit(TestCase):
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001178 """
Azim Khan599cd242017-07-06 17:34:27 +01001179 Test suite for testing escaped_split().
Azim Khanb31aa442018-07-03 11:57:54 +01001180 Note: Since escaped_split() output is used to write back to the
1181 intermediate data file. Any escape characters in the input are
1182 retained in the output.
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001183 """
1184
1185 def test_invalid_input(self):
1186 """
1187 Test when input split character is not a character.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001188 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001189 """
1190 self.assertRaises(ValueError, escaped_split, '', 'string')
1191
1192 def test_empty_string(self):
1193 """
Azim Khanb31aa442018-07-03 11:57:54 +01001194 Test empty string input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001195 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001196 """
1197 splits = escaped_split('', ':')
1198 self.assertEqual(splits, [])
1199
1200 def test_no_escape(self):
1201 """
Azim Khanb31aa442018-07-03 11:57:54 +01001202 Test with no escape character. The behaviour should be same as
1203 str.split()
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001204 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001205 """
Azim Khanb31aa442018-07-03 11:57:54 +01001206 test_str = 'yahoo:google'
1207 splits = escaped_split(test_str, ':')
1208 self.assertEqual(splits, test_str.split(':'))
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001209
1210 def test_escaped_input(self):
1211 """
Azim Khanb31aa442018-07-03 11:57:54 +01001212 Test input that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001213 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001214 """
Azim Khanb31aa442018-07-03 11:57:54 +01001215 test_str = r'yahoo\:google:facebook'
1216 splits = escaped_split(test_str, ':')
1217 self.assertEqual(splits, [r'yahoo\:google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001218
1219 def test_escaped_escape(self):
1220 """
Azim Khanb31aa442018-07-03 11:57:54 +01001221 Test input that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001222 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001223 """
Azim Khan4084ec72018-07-05 14:20:08 +01001224 test_str = r'yahoo\\:google:facebook'
Azim Khanb31aa442018-07-03 11:57:54 +01001225 splits = escaped_split(test_str, ':')
Azim Khan4084ec72018-07-05 14:20:08 +01001226 self.assertEqual(splits, [r'yahoo\\', 'google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001227
1228 def test_all_at_once(self):
1229 """
Azim Khanb31aa442018-07-03 11:57:54 +01001230 Test input that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001231 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001232 """
Azim Khan4084ec72018-07-05 14:20:08 +01001233 test_str = r'yahoo\\:google:facebook\:instagram\\:bbc\\:wikipedia'
Azim Khanb31aa442018-07-03 11:57:54 +01001234 splits = escaped_split(test_str, ':')
Azim Khan4084ec72018-07-05 14:20:08 +01001235 self.assertEqual(splits, [r'yahoo\\', r'google',
1236 r'facebook\:instagram\\',
1237 r'bbc\\', r'wikipedia'])
Azim Khan599cd242017-07-06 17:34:27 +01001238
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001239
1240class ParseTestData(TestCase):
1241 """
1242 Test suite for parse test data.
1243 """
1244
1245 def test_parser(self):
1246 """
1247 Test that tests are parsed correctly from data file.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001248 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001249 """
1250 data = """
1251Diffie-Hellman full exchange #1
1252dhm_do_dhm:10:"23":10:"5"
1253
1254Diffie-Hellman full exchange #2
1255dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
1256
1257Diffie-Hellman full exchange #3
1258dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
1259
1260Diffie-Hellman selftest
1261dhm_selftest:
1262"""
Azim Khanb31aa442018-07-03 11:57:54 +01001263 stream = StringIOWrapper('test_suite_ut.function', data)
Gilles Peskine8b022352020-03-24 18:36:56 +01001264 # List of (name, function_name, dependencies, args)
1265 tests = list(parse_test_data(stream))
Azim Khanb31aa442018-07-03 11:57:54 +01001266 test1, test2, test3, test4 = tests
1267 self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
1268 self.assertEqual(test1[1], 'dhm_do_dhm')
1269 self.assertEqual(test1[2], [])
1270 self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001271
Azim Khanb31aa442018-07-03 11:57:54 +01001272 self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
1273 self.assertEqual(test2[1], 'dhm_do_dhm')
1274 self.assertEqual(test2[2], [])
1275 self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
1276 '10', '"9345098304850938450983409622"'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001277
Azim Khanb31aa442018-07-03 11:57:54 +01001278 self.assertEqual(test3[0], 'Diffie-Hellman full exchange #3')
1279 self.assertEqual(test3[1], 'dhm_do_dhm')
1280 self.assertEqual(test3[2], [])
1281 self.assertEqual(test3[3], ['10',
1282 '"9345098382739712938719287391879381271"',
1283 '10',
1284 '"9345098792137312973297123912791271"'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001285
Azim Khanb31aa442018-07-03 11:57:54 +01001286 self.assertEqual(test4[0], 'Diffie-Hellman selftest')
1287 self.assertEqual(test4[1], 'dhm_selftest')
1288 self.assertEqual(test4[2], [])
1289 self.assertEqual(test4[3], [])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001290
1291 def test_with_dependencies(self):
1292 """
1293 Test that tests with dependencies are parsed.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001294 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001295 """
1296 data = """
1297Diffie-Hellman full exchange #1
1298depends_on:YAHOO
1299dhm_do_dhm:10:"23":10:"5"
1300
1301Diffie-Hellman full exchange #2
1302dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
1303
1304"""
Azim Khanb31aa442018-07-03 11:57:54 +01001305 stream = StringIOWrapper('test_suite_ut.function', data)
Gilles Peskine8b022352020-03-24 18:36:56 +01001306 # List of (name, function_name, dependencies, args)
1307 tests = list(parse_test_data(stream))
Azim Khanb31aa442018-07-03 11:57:54 +01001308 test1, test2 = tests
1309 self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
1310 self.assertEqual(test1[1], 'dhm_do_dhm')
1311 self.assertEqual(test1[2], ['YAHOO'])
1312 self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001313
Azim Khanb31aa442018-07-03 11:57:54 +01001314 self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
1315 self.assertEqual(test2[1], 'dhm_do_dhm')
1316 self.assertEqual(test2[2], [])
1317 self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
1318 '10', '"9345098304850938450983409622"'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001319
1320 def test_no_args(self):
1321 """
Azim Khanb31aa442018-07-03 11:57:54 +01001322 Test GeneratorInputError is raised when test function name and
1323 args line is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001324 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001325 """
1326 data = """
1327Diffie-Hellman full exchange #1
1328depends_on:YAHOO
1329
1330
1331Diffie-Hellman full exchange #2
1332dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
1333
1334"""
Azim Khanb31aa442018-07-03 11:57:54 +01001335 stream = StringIOWrapper('test_suite_ut.function', data)
1336 err = None
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001337 try:
Azim Khanb31aa442018-07-03 11:57:54 +01001338 for _, _, _, _ in parse_test_data(stream):
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001339 pass
Azim Khanb31aa442018-07-03 11:57:54 +01001340 except GeneratorInputError as err:
Mohammad Azim Khan539aa062018-07-06 00:29:50 +01001341 self.assertEqual(type(err), GeneratorInputError)
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001342
1343 def test_incomplete_data(self):
1344 """
Azim Khanb31aa442018-07-03 11:57:54 +01001345 Test GeneratorInputError is raised when test function name
1346 and args line is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001347 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001348 """
1349 data = """
1350Diffie-Hellman full exchange #1
1351depends_on:YAHOO
1352"""
Azim Khanb31aa442018-07-03 11:57:54 +01001353 stream = StringIOWrapper('test_suite_ut.function', data)
1354 err = None
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001355 try:
Azim Khanb31aa442018-07-03 11:57:54 +01001356 for _, _, _, _ in parse_test_data(stream):
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001357 pass
Azim Khanb31aa442018-07-03 11:57:54 +01001358 except GeneratorInputError as err:
Mohammad Azim Khan539aa062018-07-06 00:29:50 +01001359 self.assertEqual(type(err), GeneratorInputError)
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001360
1361
1362class GenDepCheck(TestCase):
1363 """
Azim Khanb31aa442018-07-03 11:57:54 +01001364 Test suite for gen_dep_check(). It is assumed this function is
1365 called with valid inputs.
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001366 """
1367
1368 def test_gen_dep_check(self):
1369 """
1370 Test that dependency check code generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001371 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001372 """
1373 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001374 case 5:
1375 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001376#if defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001377 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001378#else
Azim Khand61b8372017-07-10 11:54:01 +01001379 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001380#endif
Azim Khand61b8372017-07-10 11:54:01 +01001381 }
1382 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001383 out = gen_dep_check(5, 'YAHOO')
1384 self.assertEqual(out, expected)
1385
Azim Khanb31aa442018-07-03 11:57:54 +01001386 def test_not_defined_dependency(self):
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001387 """
1388 Test dependency with !.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001389 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001390 """
1391 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001392 case 5:
1393 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001394#if !defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001395 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001396#else
Azim Khand61b8372017-07-10 11:54:01 +01001397 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001398#endif
Azim Khand61b8372017-07-10 11:54:01 +01001399 }
1400 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001401 out = gen_dep_check(5, '!YAHOO')
1402 self.assertEqual(out, expected)
1403
1404 def test_empty_dependency(self):
1405 """
1406 Test invalid dependency input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001407 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001408 """
Mohammad Azim Khan3b06f222018-06-26 14:35:25 +01001409 self.assertRaises(GeneratorInputError, gen_dep_check, 5, '!')
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001410
1411 def test_negative_dep_id(self):
1412 """
1413 Test invalid dependency input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001414 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001415 """
Mohammad Azim Khan3b06f222018-06-26 14:35:25 +01001416 self.assertRaises(GeneratorInputError, gen_dep_check, -1, 'YAHOO')
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001417
1418
1419class GenExpCheck(TestCase):
1420 """
Azim Khanb31aa442018-07-03 11:57:54 +01001421 Test suite for gen_expression_check(). It is assumed this function
1422 is called with valid inputs.
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001423 """
1424
1425 def test_gen_exp_check(self):
1426 """
1427 Test that expression check code generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001428 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001429 """
1430 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001431 case 5:
1432 {
1433 *out_value = YAHOO;
1434 }
1435 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001436 out = gen_expression_check(5, 'YAHOO')
1437 self.assertEqual(out, expected)
1438
1439 def test_invalid_expression(self):
1440 """
1441 Test invalid expression input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001442 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001443 """
Mohammad Azim Khan3b06f222018-06-26 14:35:25 +01001444 self.assertRaises(GeneratorInputError, gen_expression_check, 5, '')
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001445
1446 def test_negative_exp_id(self):
1447 """
1448 Test invalid expression id.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001449 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001450 """
Azim Khanb31aa442018-07-03 11:57:54 +01001451 self.assertRaises(GeneratorInputError, gen_expression_check,
1452 -1, 'YAHOO')
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001453
1454
Azim Khanb31aa442018-07-03 11:57:54 +01001455class WriteDependencies(TestCase):
Azim Khan599cd242017-07-06 17:34:27 +01001456 """
Azim Khanb31aa442018-07-03 11:57:54 +01001457 Test suite for testing write_dependencies.
Azim Khan599cd242017-07-06 17:34:27 +01001458 """
1459
Azim Khanb31aa442018-07-03 11:57:54 +01001460 def test_no_test_dependencies(self):
Azim Khan599cd242017-07-06 17:34:27 +01001461 """
Azim Khanb31aa442018-07-03 11:57:54 +01001462 Test when test dependencies input is empty.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001463 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001464 """
Azim Khanb31aa442018-07-03 11:57:54 +01001465 stream = StringIOWrapper('test_suite_ut.data', '')
1466 unique_dependencies = []
1467 dep_check_code = write_dependencies(stream, [], unique_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001468 self.assertEqual(dep_check_code, '')
Azim Khanb31aa442018-07-03 11:57:54 +01001469 self.assertEqual(len(unique_dependencies), 0)
1470 self.assertEqual(stream.getvalue(), '')
Azim Khan599cd242017-07-06 17:34:27 +01001471
1472 def test_unique_dep_ids(self):
1473 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001474
1475 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001476 """
Azim Khanb31aa442018-07-03 11:57:54 +01001477 stream = StringIOWrapper('test_suite_ut.data', '')
1478 unique_dependencies = []
1479 dep_check_code = write_dependencies(stream, ['DEP3', 'DEP2', 'DEP1'],
1480 unique_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001481 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001482 case 0:
1483 {
Azim Khan599cd242017-07-06 17:34:27 +01001484#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001485 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001486#else
Azim Khand61b8372017-07-10 11:54:01 +01001487 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001488#endif
Azim Khand61b8372017-07-10 11:54:01 +01001489 }
1490 break;
1491 case 1:
1492 {
Azim Khan599cd242017-07-06 17:34:27 +01001493#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001494 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001495#else
Azim Khand61b8372017-07-10 11:54:01 +01001496 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001497#endif
Azim Khand61b8372017-07-10 11:54:01 +01001498 }
1499 break;
1500 case 2:
1501 {
Azim Khan599cd242017-07-06 17:34:27 +01001502#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001503 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001504#else
Azim Khand61b8372017-07-10 11:54:01 +01001505 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001506#endif
Azim Khand61b8372017-07-10 11:54:01 +01001507 }
1508 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001509 self.assertEqual(dep_check_code, expect_dep_check_code)
Azim Khanb31aa442018-07-03 11:57:54 +01001510 self.assertEqual(len(unique_dependencies), 3)
1511 self.assertEqual(stream.getvalue(), 'depends_on:0:1:2\n')
Azim Khan599cd242017-07-06 17:34:27 +01001512
1513 def test_dep_id_repeat(self):
1514 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001515
1516 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001517 """
Azim Khanb31aa442018-07-03 11:57:54 +01001518 stream = StringIOWrapper('test_suite_ut.data', '')
1519 unique_dependencies = []
Azim Khan599cd242017-07-06 17:34:27 +01001520 dep_check_code = ''
Azim Khanb31aa442018-07-03 11:57:54 +01001521 dep_check_code += write_dependencies(stream, ['DEP3', 'DEP2'],
1522 unique_dependencies)
1523 dep_check_code += write_dependencies(stream, ['DEP2', 'DEP1'],
1524 unique_dependencies)
1525 dep_check_code += write_dependencies(stream, ['DEP1', 'DEP3'],
1526 unique_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001527 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001528 case 0:
1529 {
Azim Khan599cd242017-07-06 17:34:27 +01001530#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001531 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001532#else
Azim Khand61b8372017-07-10 11:54:01 +01001533 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001534#endif
Azim Khand61b8372017-07-10 11:54:01 +01001535 }
1536 break;
1537 case 1:
1538 {
Azim Khan599cd242017-07-06 17:34:27 +01001539#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001540 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001541#else
Azim Khand61b8372017-07-10 11:54:01 +01001542 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001543#endif
Azim Khand61b8372017-07-10 11:54:01 +01001544 }
1545 break;
1546 case 2:
1547 {
Azim Khan599cd242017-07-06 17:34:27 +01001548#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001549 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001550#else
Azim Khand61b8372017-07-10 11:54:01 +01001551 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001552#endif
Azim Khand61b8372017-07-10 11:54:01 +01001553 }
1554 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001555 self.assertEqual(dep_check_code, expect_dep_check_code)
Azim Khanb31aa442018-07-03 11:57:54 +01001556 self.assertEqual(len(unique_dependencies), 3)
1557 self.assertEqual(stream.getvalue(),
1558 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
Azim Khan599cd242017-07-06 17:34:27 +01001559
1560
1561class WriteParams(TestCase):
1562 """
1563 Test Suite for testing write_parameters().
1564 """
1565
1566 def test_no_params(self):
1567 """
1568 Test with empty test_args
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001569 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001570 """
Azim Khanb31aa442018-07-03 11:57:54 +01001571 stream = StringIOWrapper('test_suite_ut.data', '')
Azim Khan599cd242017-07-06 17:34:27 +01001572 unique_expressions = []
Azim Khanb31aa442018-07-03 11:57:54 +01001573 expression_code = write_parameters(stream, [], [], unique_expressions)
Azim Khan599cd242017-07-06 17:34:27 +01001574 self.assertEqual(len(unique_expressions), 0)
1575 self.assertEqual(expression_code, '')
Azim Khanb31aa442018-07-03 11:57:54 +01001576 self.assertEqual(stream.getvalue(), '\n')
Azim Khan599cd242017-07-06 17:34:27 +01001577
1578 def test_no_exp_param(self):
1579 """
1580 Test when there is no macro or expression in the params.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001581 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001582 """
Azim Khanb31aa442018-07-03 11:57:54 +01001583 stream = StringIOWrapper('test_suite_ut.data', '')
Azim Khan599cd242017-07-06 17:34:27 +01001584 unique_expressions = []
Azim Khanb31aa442018-07-03 11:57:54 +01001585 expression_code = write_parameters(stream, ['"Yahoo"', '"abcdef00"',
1586 '0'],
1587 ['char*', 'hex', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001588 unique_expressions)
1589 self.assertEqual(len(unique_expressions), 0)
1590 self.assertEqual(expression_code, '')
Azim Khanb31aa442018-07-03 11:57:54 +01001591 self.assertEqual(stream.getvalue(),
1592 ':char*:"Yahoo":hex:"abcdef00":int:0\n')
Azim Khan599cd242017-07-06 17:34:27 +01001593
1594 def test_hex_format_int_param(self):
1595 """
1596 Test int parameter in hex format.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001597 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001598 """
Azim Khanb31aa442018-07-03 11:57:54 +01001599 stream = StringIOWrapper('test_suite_ut.data', '')
Azim Khan599cd242017-07-06 17:34:27 +01001600 unique_expressions = []
Azim Khanb31aa442018-07-03 11:57:54 +01001601 expression_code = write_parameters(stream,
1602 ['"Yahoo"', '"abcdef00"', '0xAA'],
1603 ['char*', 'hex', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001604 unique_expressions)
1605 self.assertEqual(len(unique_expressions), 0)
1606 self.assertEqual(expression_code, '')
Azim Khanb31aa442018-07-03 11:57:54 +01001607 self.assertEqual(stream.getvalue(),
1608 ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
Azim Khan599cd242017-07-06 17:34:27 +01001609
1610 def test_with_exp_param(self):
1611 """
1612 Test when there is macro or expression in the params.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001613 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001614 """
Azim Khanb31aa442018-07-03 11:57:54 +01001615 stream = StringIOWrapper('test_suite_ut.data', '')
Azim Khan599cd242017-07-06 17:34:27 +01001616 unique_expressions = []
Azim Khanb31aa442018-07-03 11:57:54 +01001617 expression_code = write_parameters(stream,
1618 ['"Yahoo"', '"abcdef00"', '0',
1619 'MACRO1', 'MACRO2', 'MACRO3'],
1620 ['char*', 'hex', 'int',
1621 'int', 'int', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001622 unique_expressions)
1623 self.assertEqual(len(unique_expressions), 3)
1624 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1625 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001626 case 0:
1627 {
1628 *out_value = MACRO1;
1629 }
1630 break;
1631 case 1:
1632 {
1633 *out_value = MACRO2;
1634 }
1635 break;
1636 case 2:
1637 {
1638 *out_value = MACRO3;
1639 }
1640 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001641 self.assertEqual(expression_code, expected_expression_code)
Azim Khanb31aa442018-07-03 11:57:54 +01001642 self.assertEqual(stream.getvalue(),
1643 ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1'
1644 ':exp:2\n')
Azim Khan599cd242017-07-06 17:34:27 +01001645
Azim Khanb31aa442018-07-03 11:57:54 +01001646 def test_with_repeat_calls(self):
Azim Khan599cd242017-07-06 17:34:27 +01001647 """
1648 Test when write_parameter() is called with same macro or expression.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001649 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001650 """
Azim Khanb31aa442018-07-03 11:57:54 +01001651 stream = StringIOWrapper('test_suite_ut.data', '')
Azim Khan599cd242017-07-06 17:34:27 +01001652 unique_expressions = []
1653 expression_code = ''
Azim Khanb31aa442018-07-03 11:57:54 +01001654 expression_code += write_parameters(stream,
1655 ['"Yahoo"', 'MACRO1', 'MACRO2'],
1656 ['char*', 'int', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001657 unique_expressions)
Azim Khanb31aa442018-07-03 11:57:54 +01001658 expression_code += write_parameters(stream,
1659 ['"abcdef00"', 'MACRO2', 'MACRO3'],
1660 ['hex', 'int', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001661 unique_expressions)
Azim Khanb31aa442018-07-03 11:57:54 +01001662 expression_code += write_parameters(stream,
1663 ['0', 'MACRO3', 'MACRO1'],
1664 ['int', 'int', 'int'],
Azim Khan599cd242017-07-06 17:34:27 +01001665 unique_expressions)
1666 self.assertEqual(len(unique_expressions), 3)
1667 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1668 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001669 case 0:
1670 {
1671 *out_value = MACRO1;
1672 }
1673 break;
1674 case 1:
1675 {
1676 *out_value = MACRO2;
1677 }
1678 break;
1679 case 2:
1680 {
1681 *out_value = MACRO3;
1682 }
1683 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001684 self.assertEqual(expression_code, expected_expression_code)
1685 expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
1686:hex:"abcdef00":exp:1:exp:2
1687:int:0:exp:2:exp:0
1688'''
Azim Khanb31aa442018-07-03 11:57:54 +01001689 self.assertEqual(stream.getvalue(), expected_data_file)
Azim Khan599cd242017-07-06 17:34:27 +01001690
1691
Azim Khanb31aa442018-07-03 11:57:54 +01001692class GenTestSuiteDependenciesChecks(TestCase):
Azim Khan599cd242017-07-06 17:34:27 +01001693 """
Azim Khanb31aa442018-07-03 11:57:54 +01001694 Test suite for testing gen_suite_dep_checks()
Azim Khan599cd242017-07-06 17:34:27 +01001695 """
Azim Khanb31aa442018-07-03 11:57:54 +01001696 def test_empty_suite_dependencies(self):
Azim Khan599cd242017-07-06 17:34:27 +01001697 """
Azim Khanb31aa442018-07-03 11:57:54 +01001698 Test with empty suite_dependencies list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001699
1700 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001701 """
Azim Khanb31aa442018-07-03 11:57:54 +01001702 dep_check_code, expression_code = \
1703 gen_suite_dep_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
Azim Khan599cd242017-07-06 17:34:27 +01001704 self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
1705 self.assertEqual(expression_code, 'EXPRESSION_CODE')
1706
Azim Khanb31aa442018-07-03 11:57:54 +01001707 def test_suite_dependencies(self):
Azim Khan599cd242017-07-06 17:34:27 +01001708 """
Azim Khanb31aa442018-07-03 11:57:54 +01001709 Test with suite_dependencies list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001710
1711 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001712 """
Azim Khanb31aa442018-07-03 11:57:54 +01001713 dep_check_code, expression_code = \
1714 gen_suite_dep_checks(['SUITE_DEP'], 'DEP_CHECK_CODE',
1715 'EXPRESSION_CODE')
1716 expected_dep_check_code = '''
Azim Khan599cd242017-07-06 17:34:27 +01001717#if defined(SUITE_DEP)
1718DEP_CHECK_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001719#endif
1720'''
1721 expected_expression_code = '''
1722#if defined(SUITE_DEP)
1723EXPRESSION_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001724#endif
1725'''
Azim Khanb31aa442018-07-03 11:57:54 +01001726 self.assertEqual(dep_check_code, expected_dep_check_code)
Azim Khan599cd242017-07-06 17:34:27 +01001727 self.assertEqual(expression_code, expected_expression_code)
1728
1729 def test_no_dep_no_exp(self):
1730 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001731 Test when there are no dependency and expression code.
1732 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001733 """
Azim Khanb31aa442018-07-03 11:57:54 +01001734 dep_check_code, expression_code = gen_suite_dep_checks([], '', '')
Azim Khand61b8372017-07-10 11:54:01 +01001735 self.assertEqual(dep_check_code, '')
1736 self.assertEqual(expression_code, '')
Azim Khan599cd242017-07-06 17:34:27 +01001737
1738
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001739class GenFromTestData(TestCase):
1740 """
1741 Test suite for gen_from_test_data()
1742 """
1743
Azim Khanb31aa442018-07-03 11:57:54 +01001744 @staticmethod
1745 @patch("generate_test_code.write_dependencies")
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00001746 @patch("generate_test_code.write_parameters")
Azim Khan4084ec72018-07-05 14:20:08 +01001747 @patch("generate_test_code.gen_suite_dep_checks")
Azim Khanb31aa442018-07-03 11:57:54 +01001748 def test_intermediate_data_file(func_mock1,
1749 write_parameters_mock,
1750 write_dependencies_mock):
Azim Khan599cd242017-07-06 17:34:27 +01001751 """
1752 Test that intermediate data file is written with expected data.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001753 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001754 """
1755 data = '''
1756My test
1757depends_on:DEP1
1758func1:0
1759'''
1760 data_f = StringIOWrapper('test_suite_ut.data', data)
1761 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1762 func_info = {'test_func1': (1, ('int',))}
Azim Khanb31aa442018-07-03 11:57:54 +01001763 suite_dependencies = []
Azim Khan599cd242017-07-06 17:34:27 +01001764 write_parameters_mock.side_effect = write_parameters
Azim Khanb31aa442018-07-03 11:57:54 +01001765 write_dependencies_mock.side_effect = write_dependencies
1766 func_mock1.side_effect = gen_suite_dep_checks
1767 gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies)
1768 write_dependencies_mock.assert_called_with(out_data_f,
1769 ['DEP1'], ['DEP1'])
1770 write_parameters_mock.assert_called_with(out_data_f, ['0'],
1771 ('int',), [])
Azim Khan599cd242017-07-06 17:34:27 +01001772 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001773 case 0:
1774 {
Azim Khan599cd242017-07-06 17:34:27 +01001775#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001776 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001777#else
Azim Khand61b8372017-07-10 11:54:01 +01001778 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001779#endif
Azim Khand61b8372017-07-10 11:54:01 +01001780 }
1781 break;'''
Azim Khanb31aa442018-07-03 11:57:54 +01001782 func_mock1.assert_called_with(
1783 suite_dependencies, expected_dep_check_code, '')
Azim Khan599cd242017-07-06 17:34:27 +01001784
1785 def test_function_not_found(self):
1786 """
1787 Test that AssertError is raised when function info in not found.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001788 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001789 """
1790 data = '''
1791My test
1792depends_on:DEP1
1793func1:0
1794'''
1795 data_f = StringIOWrapper('test_suite_ut.data', data)
1796 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1797 func_info = {'test_func2': (1, ('int',))}
Azim Khanb31aa442018-07-03 11:57:54 +01001798 suite_dependencies = []
1799 self.assertRaises(GeneratorInputError, gen_from_test_data,
1800 data_f, out_data_f, func_info, suite_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001801
1802 def test_different_func_args(self):
1803 """
Azim Khanb31aa442018-07-03 11:57:54 +01001804 Test that AssertError is raised when no. of parameters and
1805 function args differ.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001806 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001807 """
1808 data = '''
1809My test
1810depends_on:DEP1
1811func1:0
1812'''
1813 data_f = StringIOWrapper('test_suite_ut.data', data)
1814 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
Azim Khanb31aa442018-07-03 11:57:54 +01001815 func_info = {'test_func2': (1, ('int', 'hex'))}
1816 suite_dependencies = []
1817 self.assertRaises(GeneratorInputError, gen_from_test_data, data_f,
1818 out_data_f, func_info, suite_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001819
1820 def test_output(self):
1821 """
1822 Test that intermediate data file is written with expected data.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001823 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001824 """
1825 data = '''
1826My test 1
1827depends_on:DEP1
1828func1:0:0xfa:MACRO1:MACRO2
1829
1830My test 2
1831depends_on:DEP1:DEP2
1832func2:"yahoo":88:MACRO1
1833'''
1834 data_f = StringIOWrapper('test_suite_ut.data', data)
1835 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
Azim Khanb31aa442018-07-03 11:57:54 +01001836 func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')),
1837 'test_func2': (1, ('char*', 'int', 'int'))}
1838 suite_dependencies = []
1839 dep_check_code, expression_code = \
1840 gen_from_test_data(data_f, out_data_f, func_info,
1841 suite_dependencies)
Azim Khan599cd242017-07-06 17:34:27 +01001842 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001843 case 0:
1844 {
Azim Khan599cd242017-07-06 17:34:27 +01001845#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001846 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001847#else
Azim Khand61b8372017-07-10 11:54:01 +01001848 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001849#endif
Azim Khand61b8372017-07-10 11:54:01 +01001850 }
1851 break;
1852 case 1:
1853 {
Azim Khan599cd242017-07-06 17:34:27 +01001854#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001855 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001856#else
Azim Khand61b8372017-07-10 11:54:01 +01001857 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001858#endif
Azim Khand61b8372017-07-10 11:54:01 +01001859 }
1860 break;'''
Azim Khanb31aa442018-07-03 11:57:54 +01001861 expected_data = '''My test 1
Azim Khan599cd242017-07-06 17:34:27 +01001862depends_on:0
18630:int:0:int:0xfa:exp:0:exp:1
1864
1865My test 2
1866depends_on:0:1
18671:char*:"yahoo":int:88:exp:0
1868
1869'''
1870 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001871 case 0:
1872 {
1873 *out_value = MACRO1;
1874 }
1875 break;
1876 case 1:
1877 {
1878 *out_value = MACRO2;
1879 }
1880 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001881 self.assertEqual(dep_check_code, expected_dep_check_code)
Azim Khanb31aa442018-07-03 11:57:54 +01001882 self.assertEqual(out_data_f.getvalue(), expected_data)
Azim Khan599cd242017-07-06 17:34:27 +01001883 self.assertEqual(expression_code, expected_expression_code)
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001884
1885
Azim Khanb31aa442018-07-03 11:57:54 +01001886if __name__ == '__main__':
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001887 unittest_main()