blob: a4debbae489a7500af20c7faadad827f863cb86c [file] [log] [blame]
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00001# Unit test for generate_test_code.py
Azim Khanf0e42fb2017-08-02 14:47:13 +01002#
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00003# Copyright (C) 2018, ARM Limited, All Rights Reserved
Azim Khanf0e42fb2017-08-02 14:47:13 +01004# SPDX-License-Identifier: Apache-2.0
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18# This file is part of mbed TLS (https://tls.mbed.org)
Azim Khan4b543232017-06-30 09:35:21 +010019
Azim Khan4b543232017-06-30 09:35:21 +010020from StringIO import StringIO
21from unittest import TestCase, main as unittest_main
22from mock import patch
Mohammad Azim Khan78befd92018-03-06 11:49:41 +000023from generate_test_code import *
Azim Khan4b543232017-06-30 09:35:21 +010024
25
26"""
Mohammad Azim Khan78befd92018-03-06 11:49:41 +000027Unit tests for generate_test_code.py
Azim Khan4b543232017-06-30 09:35:21 +010028"""
29
30
31class GenDep(TestCase):
32 """
33 Test suite for function gen_dep()
34 """
35
36 def test_deps_list(self):
37 """
38 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010039 :return:
Azim Khan4b543232017-06-30 09:35:21 +010040 """
41 deps = ['DEP1', 'DEP2']
42 dep_start, dep_end = gen_deps(deps)
43 ifdef1, ifdef2 = dep_start.splitlines()
44 endif1, endif2 = dep_end.splitlines()
45 self.assertEqual(ifdef1, '#if defined(DEP1)', 'ifdef generated incorrectly')
46 self.assertEqual(ifdef2, '#if defined(DEP2)', 'ifdef generated incorrectly')
47 self.assertEqual(endif1, '#endif /* DEP2 */', 'endif generated incorrectly')
48 self.assertEqual(endif2, '#endif /* DEP1 */', 'endif generated incorrectly')
49
50 def test_disabled_deps_list(self):
51 """
52 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010053 :return:
Azim Khan4b543232017-06-30 09:35:21 +010054 """
55 deps = ['!DEP1', '!DEP2']
56 dep_start, dep_end = gen_deps(deps)
57 ifdef1, ifdef2 = dep_start.splitlines()
58 endif1, endif2 = dep_end.splitlines()
59 self.assertEqual(ifdef1, '#if !defined(DEP1)', 'ifdef generated incorrectly')
60 self.assertEqual(ifdef2, '#if !defined(DEP2)', 'ifdef generated incorrectly')
61 self.assertEqual(endif1, '#endif /* !DEP2 */', 'endif generated incorrectly')
62 self.assertEqual(endif2, '#endif /* !DEP1 */', 'endif generated incorrectly')
63
64 def test_mixed_deps_list(self):
65 """
66 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010067 :return:
Azim Khan4b543232017-06-30 09:35:21 +010068 """
69 deps = ['!DEP1', 'DEP2']
70 dep_start, dep_end = gen_deps(deps)
71 ifdef1, ifdef2 = dep_start.splitlines()
72 endif1, endif2 = dep_end.splitlines()
73 self.assertEqual(ifdef1, '#if !defined(DEP1)', 'ifdef generated incorrectly')
74 self.assertEqual(ifdef2, '#if defined(DEP2)', 'ifdef generated incorrectly')
75 self.assertEqual(endif1, '#endif /* DEP2 */', 'endif generated incorrectly')
76 self.assertEqual(endif2, '#endif /* !DEP1 */', 'endif generated incorrectly')
77
78 def test_empty_deps_list(self):
79 """
80 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010081 :return:
Azim Khan4b543232017-06-30 09:35:21 +010082 """
83 deps = []
84 dep_start, dep_end = gen_deps(deps)
85 self.assertEqual(dep_start, '', 'ifdef generated incorrectly')
86 self.assertEqual(dep_end, '', 'ifdef generated incorrectly')
87
88 def test_large_deps_list(self):
89 """
90 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +010091 :return:
Azim Khan4b543232017-06-30 09:35:21 +010092 """
93 deps = []
94 count = 10
95 for i in range(count):
96 deps.append('DEP%d' % i)
97 dep_start, dep_end = gen_deps(deps)
98 self.assertEqual(len(dep_start.splitlines()), count, 'ifdef generated incorrectly')
99 self.assertEqual(len(dep_end.splitlines()), count, 'ifdef generated incorrectly')
100
101
102class GenDepOneLine(TestCase):
103 """
104 Test Suite for testing gen_deps_one_line()
105 """
106
107 def test_deps_list(self):
108 """
109 Test that gen_dep() correctly creates deps for given dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100110 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100111 """
112 deps = ['DEP1', 'DEP2']
113 dep_str = gen_deps_one_line(deps)
114 self.assertEqual(dep_str, '#if defined(DEP1) && defined(DEP2)', 'ifdef generated incorrectly')
115
116 def test_disabled_deps_list(self):
117 """
118 Test that gen_dep() correctly creates deps for given dependency list.
119 :return:
120 """
121 deps = ['!DEP1', '!DEP2']
122 dep_str = gen_deps_one_line(deps)
123 self.assertEqual(dep_str, '#if !defined(DEP1) && !defined(DEP2)', 'ifdef generated incorrectly')
124
125 def test_mixed_deps_list(self):
126 """
127 Test that gen_dep() correctly creates deps for given dependency list.
128 :return:
129 """
130 deps = ['!DEP1', 'DEP2']
131 dep_str = gen_deps_one_line(deps)
132 self.assertEqual(dep_str, '#if !defined(DEP1) && defined(DEP2)', 'ifdef generated incorrectly')
133
134 def test_empty_deps_list(self):
135 """
136 Test that gen_dep() correctly creates deps for given dependency list.
137 :return:
138 """
139 deps = []
140 dep_str = gen_deps_one_line(deps)
141 self.assertEqual(dep_str, '', 'ifdef generated incorrectly')
142
143 def test_large_deps_list(self):
144 """
145 Test that gen_dep() correctly creates deps for given dependency list.
146 :return:
147 """
148 deps = []
149 count = 10
150 for i in range(count):
151 deps.append('DEP%d' % i)
152 dep_str = gen_deps_one_line(deps)
153 expected = '#if ' + ' && '.join(['defined(%s)' % x for x in deps])
154 self.assertEqual(dep_str, expected, 'ifdef generated incorrectly')
155
156
157class GenFunctionWrapper(TestCase):
158 """
159 Test Suite for testing gen_function_wrapper()
160 """
161
162 def test_params_unpack(self):
163 """
164 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100165
166 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100167 """
168 code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
169 expected = '''
170void test_a_wrapper( void ** params )
171{
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100172
Azim Khan4b543232017-06-30 09:35:21 +0100173 test_a( a, b, c, d );
174}
175'''
176 self.assertEqual(code, expected)
177
178 def test_local(self):
179 """
180 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100181
182 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100183 """
184 code = gen_function_wrapper('test_a', 'int x = 1;', ('x', 'b', 'c', 'd'))
185 expected = '''
186void test_a_wrapper( void ** params )
187{
Azim Khan4b543232017-06-30 09:35:21 +0100188int x = 1;
189 test_a( x, b, c, d );
190}
191'''
192 self.assertEqual(code, expected)
193
194 def test_empty_params(self):
195 """
196 Test that params are properly unpacked in the function call.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100197
198 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100199 """
200 code = gen_function_wrapper('test_a', '', ())
201 expected = '''
202void test_a_wrapper( void ** params )
203{
204 (void)params;
205
206 test_a( );
207}
208'''
209 self.assertEqual(code, expected)
210
211
212class GenDispatch(TestCase):
213 """
214 Test suite for testing gen_dispatch()
215 """
216
217 def test_dispatch(self):
218 """
219 Test that dispatch table entry is generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100220 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100221 """
222 code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
223 expected = '''
224#if defined(DEP1) && defined(DEP2)
225 test_a_wrapper,
226#else
227 NULL,
228#endif
229'''
230 self.assertEqual(code, expected)
231
232 def test_empty_deps(self):
233 """
234 Test empty dependency list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100235 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100236 """
237 code = gen_dispatch('test_a', [])
238 expected = '''
239 test_a_wrapper,
240'''
241 self.assertEqual(code, expected)
242
243
244class StringIOWrapper(StringIO, object):
245 """
246 file like class to mock file object in tests.
247 """
248 def __init__(self, file_name, data, line_no = 1):
249 """
250 Init file handle.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100251
252 :param file_name:
Azim Khan4b543232017-06-30 09:35:21 +0100253 :param data:
254 :param line_no:
255 """
256 super(StringIOWrapper, self).__init__(data)
257 self.line_no = line_no
258 self.name = file_name
259
260 def next(self):
261 """
262 Iterator return impl.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100263 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100264 """
265 line = super(StringIOWrapper, self).next()
266 return line
267
268 def readline(self, limit=0):
269 """
270 Wrap the base class readline.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100271
272 :param limit:
273 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100274 """
275 line = super(StringIOWrapper, self).readline()
276 if line:
277 self.line_no += 1
278 return line
279
280
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000281class ParseUntilPattern(TestCase):
Azim Khan4b543232017-06-30 09:35:21 +0100282 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000283 Test Suite for testing parse_until_pattern().
Azim Khan4b543232017-06-30 09:35:21 +0100284 """
285
286 def test_suite_headers(self):
287 """
288 Test that suite headers are parsed correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100289
290 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100291 """
292 data = '''#include "mbedtls/ecp.h"
293
294#define ECP_PF_UNKNOWN -1
295/* END_HEADER */
296'''
297 expected = '''#line 1 "test_suite_ut.function"
298#include "mbedtls/ecp.h"
299
300#define ECP_PF_UNKNOWN -1
301'''
302 s = StringIOWrapper('test_suite_ut.function', data, line_no=0)
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000303 headers = parse_until_pattern(s, END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100304 self.assertEqual(headers, expected)
305
306 def test_line_no(self):
307 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100308 Test that #line is set to correct line no. in source .function file.
309
310 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100311 """
312 data = '''#include "mbedtls/ecp.h"
313
314#define ECP_PF_UNKNOWN -1
315/* END_HEADER */
316'''
317 offset_line_no = 5
318 expected = '''#line %d "test_suite_ut.function"
319#include "mbedtls/ecp.h"
320
321#define ECP_PF_UNKNOWN -1
322''' % (offset_line_no + 1)
323 s = StringIOWrapper('test_suite_ut.function', data, offset_line_no)
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000324 headers = parse_until_pattern(s, END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100325 self.assertEqual(headers, expected)
326
327 def test_no_end_header_comment(self):
328 """
329 Test that InvalidFileFormat is raised when end header comment is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100330 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100331 """
332 data = '''#include "mbedtls/ecp.h"
333
334#define ECP_PF_UNKNOWN -1
335
336'''
337 s = StringIOWrapper('test_suite_ut.function', data)
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000338 self.assertRaises(InvalidFileFormat, parse_until_pattern, s, END_HEADER_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100339
340
341class ParseSuiteDeps(TestCase):
342 """
343 Test Suite for testing parse_suite_deps().
344 """
345
346 def test_suite_deps(self):
347 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100348
349 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100350 """
351 data = '''
352 * depends_on:MBEDTLS_ECP_C
353 * END_DEPENDENCIES
354 */
355'''
356 expected = ['MBEDTLS_ECP_C']
357 s = StringIOWrapper('test_suite_ut.function', data)
358 deps = parse_suite_deps(s)
359 self.assertEqual(deps, expected)
360
361 def test_no_end_dep_comment(self):
362 """
363 Test that InvalidFileFormat is raised when end dep comment is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100364 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100365 """
366 data = '''
367* depends_on:MBEDTLS_ECP_C
368'''
369 s = StringIOWrapper('test_suite_ut.function', data)
370 self.assertRaises(InvalidFileFormat, parse_suite_deps, s)
371
372 def test_deps_split(self):
373 """
374 Test that InvalidFileFormat is raised when end dep comment is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100375 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100376 """
377 data = '''
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100378 * depends_on:MBEDTLS_ECP_C:A:B: C : D :F : G: !H
Azim Khan4b543232017-06-30 09:35:21 +0100379 * END_DEPENDENCIES
380 */
381'''
382 expected = ['MBEDTLS_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
383 s = StringIOWrapper('test_suite_ut.function', data)
384 deps = parse_suite_deps(s)
385 self.assertEqual(deps, expected)
386
387
388class ParseFuncDeps(TestCase):
389 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100390 Test Suite for testing parse_function_deps()
Azim Khan4b543232017-06-30 09:35:21 +0100391 """
392
393 def test_function_deps(self):
394 """
395 Test that parse_function_deps() correctly parses function dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100396 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100397 """
398 line = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */'
399 expected = ['MBEDTLS_ENTROPY_NV_SEED', 'MBEDTLS_FS_IO']
400 deps = parse_function_deps(line)
401 self.assertEqual(deps, expected)
402
403 def test_no_deps(self):
404 """
405 Test that parse_function_deps() correctly parses function dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100406 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100407 """
408 line = '/* BEGIN_CASE */'
409 deps = parse_function_deps(line)
410 self.assertEqual(deps, [])
411
412 def test_poorly_defined_deps(self):
413 """
414 Test that parse_function_deps() correctly parses function dependencies.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100415 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100416 """
417 line = '/* BEGIN_CASE depends_on:MBEDTLS_FS_IO: A : !B:C : F*/'
418 deps = parse_function_deps(line)
419 self.assertEqual(deps, ['MBEDTLS_FS_IO', 'A', '!B', 'C', 'F'])
420
421
422class ParseFuncSignature(TestCase):
423 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100424 Test Suite for parse_function_signature().
Azim Khan4b543232017-06-30 09:35:21 +0100425 """
426
427 def test_int_and_char_params(self):
428 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100429 Test int and char parameters parsing
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100430 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100431 """
432 line = 'void entropy_threshold( char * a, int b, int result )'
433 name, args, local, arg_dispatch = parse_function_signature(line)
434 self.assertEqual(name, 'entropy_threshold')
435 self.assertEqual(args, ['char*', 'int', 'int'])
436 self.assertEqual(local, '')
437 self.assertEqual(arg_dispatch, ['(char *) params[0]', '*( (int *) params[1] )', '*( (int *) params[2] )'])
438
439 def test_hex_params(self):
440 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100441 Test hex parameters parsing
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100442 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100443 """
444 line = 'void entropy_threshold( char * a, HexParam_t * h, int result )'
445 name, args, local, arg_dispatch = parse_function_signature(line)
446 self.assertEqual(name, 'entropy_threshold')
447 self.assertEqual(args, ['char*', 'hex', 'int'])
448 self.assertEqual(local, ' HexParam_t hex1 = {(uint8_t *) params[1], *( (uint32_t *) params[2] )};\n')
449 self.assertEqual(arg_dispatch, ['(char *) params[0]', '&hex1', '*( (int *) params[3] )'])
450
451 def test_non_void_function(self):
452 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100453 Test invalid signature (non void).
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100454 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100455 """
456 line = 'int entropy_threshold( char * a, HexParam_t * h, int result )'
457 self.assertRaises(ValueError, parse_function_signature, line)
458
459 def test_unsupported_arg(self):
460 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100461 Test unsupported arguments (not among int, char * and HexParam_t)
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100462 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100463 """
464 line = 'int entropy_threshold( char * a, HexParam_t * h, int * result )'
465 self.assertRaises(ValueError, parse_function_signature, line)
466
467 def test_no_params(self):
468 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100469 Test no parameters.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100470 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100471 """
472 line = 'void entropy_threshold()'
473 name, args, local, arg_dispatch = parse_function_signature(line)
474 self.assertEqual(name, 'entropy_threshold')
475 self.assertEqual(args, [])
476 self.assertEqual(local, '')
477 self.assertEqual(arg_dispatch, [])
478
479
480class ParseFunctionCode(TestCase):
481 """
482 Test suite for testing parse_function_code()
483 """
484
485 def test_no_function(self):
486 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100487 Test no test function found.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100488 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100489 """
490 data = '''
491No
492test
493function
494'''
495 s = StringIOWrapper('test_suite_ut.function', data)
496 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
497
498 def test_no_end_case_comment(self):
499 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100500 Test missing end case.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100501 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100502 """
503 data = '''
504void test_func()
505{
506}
507'''
508 s = StringIOWrapper('test_suite_ut.function', data)
509 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
510
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000511 @patch("generate_test_code.parse_function_signature")
Azim Khan4b543232017-06-30 09:35:21 +0100512 def test_parse_function_signature_called(self, parse_function_signature_mock):
513 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100514 Test parse_function_code()
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100515 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100516 """
517 parse_function_signature_mock.return_value = ('test_func', [], '', [])
518 data = '''
519void test_func()
520{
521}
522'''
523 s = StringIOWrapper('test_suite_ut.function', data)
524 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
525 self.assertTrue(parse_function_signature_mock.called)
526 parse_function_signature_mock.assert_called_with('void test_func()\n')
527
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000528 @patch("generate_test_code.gen_dispatch")
529 @patch("generate_test_code.gen_deps")
530 @patch("generate_test_code.gen_function_wrapper")
531 @patch("generate_test_code.parse_function_signature")
Azim Khan4b543232017-06-30 09:35:21 +0100532 def test_return(self, parse_function_signature_mock,
533 gen_function_wrapper_mock,
534 gen_deps_mock,
535 gen_dispatch_mock):
536 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100537 Test generated code.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100538 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100539 """
540 parse_function_signature_mock.return_value = ('func', [], '', [])
541 gen_function_wrapper_mock.return_value = ''
542 gen_deps_mock.side_effect = gen_deps
543 gen_dispatch_mock.side_effect = gen_dispatch
544 data = '''
545void func()
546{
547 ba ba black sheep
548 have you any wool
549}
550/* END_CASE */
551'''
552 s = StringIOWrapper('test_suite_ut.function', data)
553 name, arg, code, dispatch_code = parse_function_code(s, [], [])
554
555 #self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
556 self.assertTrue(parse_function_signature_mock.called)
557 parse_function_signature_mock.assert_called_with('void func()\n')
558 gen_function_wrapper_mock.assert_called_with('test_func', '', [])
559 self.assertEqual(name, 'test_func')
560 self.assertEqual(arg, [])
561 expected = '''#line 2 "test_suite_ut.function"
562void test_func()
563{
564 ba ba black sheep
565 have you any wool
566exit:
567 ;;
568}
569'''
570 self.assertEqual(code, expected)
571 self.assertEqual(dispatch_code, "\n test_func_wrapper,\n")
572
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000573 @patch("generate_test_code.gen_dispatch")
574 @patch("generate_test_code.gen_deps")
575 @patch("generate_test_code.gen_function_wrapper")
576 @patch("generate_test_code.parse_function_signature")
Azim Khan4b543232017-06-30 09:35:21 +0100577 def test_with_exit_label(self, parse_function_signature_mock,
578 gen_function_wrapper_mock,
579 gen_deps_mock,
580 gen_dispatch_mock):
581 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100582 Test when exit label is present.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100583 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100584 """
585 parse_function_signature_mock.return_value = ('func', [], '', [])
586 gen_function_wrapper_mock.return_value = ''
587 gen_deps_mock.side_effect = gen_deps
588 gen_dispatch_mock.side_effect = gen_dispatch
589 data = '''
590void func()
591{
592 ba ba black sheep
593 have you any wool
594exit:
595 yes sir yes sir
596 3 bags full
597}
598/* END_CASE */
599'''
600 s = StringIOWrapper('test_suite_ut.function', data)
601 name, arg, code, dispatch_code = parse_function_code(s, [], [])
602
603 expected = '''#line 2 "test_suite_ut.function"
604void test_func()
605{
606 ba ba black sheep
607 have you any wool
608exit:
609 yes sir yes sir
610 3 bags full
611}
612'''
613 self.assertEqual(code, expected)
614
615
616class ParseFunction(TestCase):
617 """
618 Test Suite for testing parse_functions()
619 """
620
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000621 @patch("generate_test_code.parse_until_pattern")
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000622 def test_begin_header(self, parse_until_pattern_mock):
Azim Khan4b543232017-06-30 09:35:21 +0100623 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000624 Test that begin header is checked and parse_until_pattern() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100625 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100626 """
627 def stop(this):
628 raise Exception
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000629 parse_until_pattern_mock.side_effect = stop
Azim Khan4b543232017-06-30 09:35:21 +0100630 data = '''/* BEGIN_HEADER */
631#include "mbedtls/ecp.h"
632
633#define ECP_PF_UNKNOWN -1
634/* END_HEADER */
635'''
636 s = StringIOWrapper('test_suite_ut.function', data)
637 self.assertRaises(Exception, parse_functions, s)
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000638 parse_until_pattern_mock.assert_called_with(s, END_HEADER_REGEX)
639 self.assertEqual(s.line_no, 2)
640
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000641 @patch("generate_test_code.parse_until_pattern")
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000642 def test_begin_helper(self, parse_until_pattern_mock):
643 """
644 Test that begin helper is checked and parse_until_pattern() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100645 :return:
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000646 """
647 def stop(this):
648 raise Exception
649 parse_until_pattern_mock.side_effect = stop
650 data = '''/* BEGIN_SUITE_HELPERS */
651void print_helloworld()
652{
653 printf ("Hello World!\n");
654}
655/* END_SUITE_HELPERS */
656'''
657 s = StringIOWrapper('test_suite_ut.function', data)
658 self.assertRaises(Exception, parse_functions, s)
659 parse_until_pattern_mock.assert_called_with(s, END_SUITE_HELPERS_REGEX)
Azim Khan4b543232017-06-30 09:35:21 +0100660 self.assertEqual(s.line_no, 2)
661
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000662 @patch("generate_test_code.parse_suite_deps")
Azim Khan4b543232017-06-30 09:35:21 +0100663 def test_begin_dep(self, parse_suite_deps_mock):
664 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000665 Test that begin dep is checked and parse_suite_deps() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100666 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100667 """
668 def stop(this):
669 raise Exception
670 parse_suite_deps_mock.side_effect = stop
671 data = '''/* BEGIN_DEPENDENCIES
672 * depends_on:MBEDTLS_ECP_C
673 * END_DEPENDENCIES
674 */
675'''
676 s = StringIOWrapper('test_suite_ut.function', data)
677 self.assertRaises(Exception, parse_functions, s)
678 parse_suite_deps_mock.assert_called_with(s)
679 self.assertEqual(s.line_no, 2)
680
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000681 @patch("generate_test_code.parse_function_deps")
Azim Khan4b543232017-06-30 09:35:21 +0100682 def test_begin_function_dep(self, parse_function_deps_mock):
683 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000684 Test that begin dep is checked and parse_function_deps() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100685 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100686 """
687 def stop(this):
688 raise Exception
689 parse_function_deps_mock.side_effect = stop
690
691 deps_str = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
692 data = '''%svoid test_func()
693{
694}
695''' % deps_str
696 s = StringIOWrapper('test_suite_ut.function', data)
697 self.assertRaises(Exception, parse_functions, s)
698 parse_function_deps_mock.assert_called_with(deps_str)
699 self.assertEqual(s.line_no, 2)
700
Mohammad Azim Khan78befd92018-03-06 11:49:41 +0000701 @patch("generate_test_code.parse_function_code")
702 @patch("generate_test_code.parse_function_deps")
Azim Khan4b543232017-06-30 09:35:21 +0100703 def test_return(self, parse_function_deps_mock, parse_function_code_mock):
704 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000705 Test that begin case is checked and parse_function_code() is called.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100706 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100707 """
708 def stop(this):
709 raise Exception
710 parse_function_deps_mock.return_value = []
711 in_func_code= '''void test_func()
712{
713}
714'''
715 func_dispatch = '''
716 test_func_wrapper,
717'''
718 parse_function_code_mock.return_value = 'test_func', [], in_func_code, func_dispatch
719 deps_str = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
720 data = '''%svoid test_func()
721{
722}
723''' % deps_str
724 s = StringIOWrapper('test_suite_ut.function', data)
725 suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
726 parse_function_deps_mock.assert_called_with(deps_str)
727 parse_function_code_mock.assert_called_with(s, [], [])
728 self.assertEqual(s.line_no, 5)
729 self.assertEqual(suite_deps, [])
730 expected_dispatch_code = '''/* Function Id: 0 */
731
732 test_func_wrapper,
733'''
734 self.assertEqual(dispatch_code, expected_dispatch_code)
735 self.assertEqual(func_code, in_func_code)
736 self.assertEqual(func_info, {'test_func': (0, [])})
737
738 def test_parsing(self):
739 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000740 Test case parsing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100741 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100742 """
743 data = '''/* BEGIN_HEADER */
744#include "mbedtls/ecp.h"
745
746#define ECP_PF_UNKNOWN -1
747/* END_HEADER */
748
749/* BEGIN_DEPENDENCIES
750 * depends_on:MBEDTLS_ECP_C
751 * END_DEPENDENCIES
752 */
753
754/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
755void func1()
756{
757}
758/* END_CASE */
759
760/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
761void func2()
762{
763}
764/* END_CASE */
765'''
766 s = StringIOWrapper('test_suite_ut.function', data)
767 suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
768 self.assertEqual(s.line_no, 23)
769 self.assertEqual(suite_deps, ['MBEDTLS_ECP_C'])
770
771 expected_dispatch_code = '''/* Function Id: 0 */
772
773#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
774 test_func1_wrapper,
775#else
776 NULL,
777#endif
778/* Function Id: 1 */
779
780#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
781 test_func2_wrapper,
782#else
783 NULL,
784#endif
785'''
786 self.assertEqual(dispatch_code, expected_dispatch_code)
787 expected_func_code = '''#if defined(MBEDTLS_ECP_C)
788#line 3 "test_suite_ut.function"
789#include "mbedtls/ecp.h"
790
791#define ECP_PF_UNKNOWN -1
792#if defined(MBEDTLS_ENTROPY_NV_SEED)
793#if defined(MBEDTLS_FS_IO)
794#line 14 "test_suite_ut.function"
795void test_func1()
796{
797exit:
798 ;;
799}
800
801void test_func1_wrapper( void ** params )
802{
803 (void)params;
804
805 test_func1( );
806}
807#endif /* MBEDTLS_FS_IO */
808#endif /* MBEDTLS_ENTROPY_NV_SEED */
809#if defined(MBEDTLS_ENTROPY_NV_SEED)
810#if defined(MBEDTLS_FS_IO)
811#line 20 "test_suite_ut.function"
812void test_func2()
813{
814exit:
815 ;;
816}
817
818void test_func2_wrapper( void ** params )
819{
820 (void)params;
821
822 test_func2( );
823}
824#endif /* MBEDTLS_FS_IO */
825#endif /* MBEDTLS_ENTROPY_NV_SEED */
826#endif /* MBEDTLS_ECP_C */
827'''
828 self.assertEqual(func_code, expected_func_code)
829 self.assertEqual(func_info, {'test_func1': (0, []), 'test_func2': (1, [])})
830
831 def test_same_function_name(self):
832 """
Mohammad Azim Khanb5229292018-02-06 13:08:01 +0000833 Test name conflict.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100834 :return:
Azim Khan4b543232017-06-30 09:35:21 +0100835 """
836 data = '''/* BEGIN_HEADER */
837#include "mbedtls/ecp.h"
838
839#define ECP_PF_UNKNOWN -1
840/* END_HEADER */
841
842/* BEGIN_DEPENDENCIES
843 * depends_on:MBEDTLS_ECP_C
844 * END_DEPENDENCIES
845 */
846
847/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
848void func()
849{
850}
851/* END_CASE */
852
853/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
854void func()
855{
856}
857/* END_CASE */
858'''
859 s = StringIOWrapper('test_suite_ut.function', data)
860 self.assertRaises(AssertionError, parse_functions, s)
861
862
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100863class ExcapedSplit(TestCase):
864 """
Azim Khan599cd242017-07-06 17:34:27 +0100865 Test suite for testing escaped_split().
866 Note: Since escaped_split() output is used to write back to the intermediate data file. Any escape characters
867 in the input are retained in the output.
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100868 """
869
870 def test_invalid_input(self):
871 """
872 Test when input split character is not a character.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100873 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100874 """
875 self.assertRaises(ValueError, escaped_split, '', 'string')
876
877 def test_empty_string(self):
878 """
879 Test empty strig input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100880 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100881 """
882 splits = escaped_split('', ':')
883 self.assertEqual(splits, [])
884
885 def test_no_escape(self):
886 """
887 Test with no escape character. The behaviour should be same as str.split()
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100888 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100889 """
890 s = 'yahoo:google'
891 splits = escaped_split(s, ':')
892 self.assertEqual(splits, s.split(':'))
893
894 def test_escaped_input(self):
895 """
896 Test imput that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100897 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100898 """
899 s = 'yahoo\:google:facebook'
900 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100901 self.assertEqual(splits, ['yahoo\:google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100902
903 def test_escaped_escape(self):
904 """
905 Test imput that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100906 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100907 """
908 s = 'yahoo\\\:google:facebook'
909 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100910 self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100911
912 def test_all_at_once(self):
913 """
914 Test imput that has escaped delimiter.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100915 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100916 """
917 s = 'yahoo\\\:google:facebook\:instagram\\\:bbc\\\\:wikipedia'
918 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100919 self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook\:instagram\\\\', 'bbc\\\\', 'wikipedia'])
920
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100921
922class ParseTestData(TestCase):
923 """
924 Test suite for parse test data.
925 """
926
927 def test_parser(self):
928 """
929 Test that tests are parsed correctly from data file.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100930 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100931 """
932 data = """
933Diffie-Hellman full exchange #1
934dhm_do_dhm:10:"23":10:"5"
935
936Diffie-Hellman full exchange #2
937dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
938
939Diffie-Hellman full exchange #3
940dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
941
942Diffie-Hellman selftest
943dhm_selftest:
944"""
945 s = StringIOWrapper('test_suite_ut.function', data)
946 tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
947 t1, t2, t3, t4 = tests
948 self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
949 self.assertEqual(t1[1], 'dhm_do_dhm')
950 self.assertEqual(t1[2], [])
951 self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
952
953 self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
954 self.assertEqual(t2[1], 'dhm_do_dhm')
955 self.assertEqual(t2[2], [])
956 self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
957
958 self.assertEqual(t3[0], 'Diffie-Hellman full exchange #3')
959 self.assertEqual(t3[1], 'dhm_do_dhm')
960 self.assertEqual(t3[2], [])
961 self.assertEqual(t3[3], ['10', '"9345098382739712938719287391879381271"', '10', '"9345098792137312973297123912791271"'])
962
963 self.assertEqual(t4[0], 'Diffie-Hellman selftest')
964 self.assertEqual(t4[1], 'dhm_selftest')
965 self.assertEqual(t4[2], [])
966 self.assertEqual(t4[3], [])
967
968 def test_with_dependencies(self):
969 """
970 Test that tests with dependencies are parsed.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100971 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100972 """
973 data = """
974Diffie-Hellman full exchange #1
975depends_on:YAHOO
976dhm_do_dhm:10:"23":10:"5"
977
978Diffie-Hellman full exchange #2
979dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
980
981"""
982 s = StringIOWrapper('test_suite_ut.function', data)
983 tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
984 t1, t2 = tests
985 self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
986 self.assertEqual(t1[1], 'dhm_do_dhm')
987 self.assertEqual(t1[2], ['YAHOO'])
988 self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
989
990 self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
991 self.assertEqual(t2[1], 'dhm_do_dhm')
992 self.assertEqual(t2[2], [])
993 self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
994
995 def test_no_args(self):
996 """
997 Test AssertionError is raised when test function name and args line is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +0100998 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100999 """
1000 data = """
1001Diffie-Hellman full exchange #1
1002depends_on:YAHOO
1003
1004
1005Diffie-Hellman full exchange #2
1006dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
1007
1008"""
1009 s = StringIOWrapper('test_suite_ut.function', data)
1010 e = None
1011 try:
1012 for x, y, z, a in parse_test_data(s):
1013 pass
1014 except AssertionError, e:
1015 pass
1016 self.assertEqual(type(e), AssertionError)
1017
1018 def test_incomplete_data(self):
1019 """
1020 Test AssertionError is raised when test function name and args line is missing.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001021 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001022 """
1023 data = """
1024Diffie-Hellman full exchange #1
1025depends_on:YAHOO
1026"""
1027 s = StringIOWrapper('test_suite_ut.function', data)
1028 e = None
1029 try:
1030 for x, y, z, a in parse_test_data(s):
1031 pass
1032 except AssertionError, e:
1033 pass
1034 self.assertEqual(type(e), AssertionError)
1035
1036
1037class GenDepCheck(TestCase):
1038 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001039 Test suite for gen_dep_check(). It is assumed this function is called with valid inputs.
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001040 """
1041
1042 def test_gen_dep_check(self):
1043 """
1044 Test that dependency check code generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001045 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001046 """
1047 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001048 case 5:
1049 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001050#if defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001051 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001052#else
Azim Khand61b8372017-07-10 11:54:01 +01001053 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001054#endif
Azim Khand61b8372017-07-10 11:54:01 +01001055 }
1056 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001057 out = gen_dep_check(5, 'YAHOO')
1058 self.assertEqual(out, expected)
1059
1060 def test_noT(self):
1061 """
1062 Test dependency with !.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001063 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001064 """
1065 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001066 case 5:
1067 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001068#if !defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001069 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001070#else
Azim Khand61b8372017-07-10 11:54:01 +01001071 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001072#endif
Azim Khand61b8372017-07-10 11:54:01 +01001073 }
1074 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001075 out = gen_dep_check(5, '!YAHOO')
1076 self.assertEqual(out, expected)
1077
1078 def test_empty_dependency(self):
1079 """
1080 Test invalid dependency input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001081 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001082 """
1083 self.assertRaises(AssertionError, gen_dep_check, 5, '!')
1084
1085 def test_negative_dep_id(self):
1086 """
1087 Test invalid dependency input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001088 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001089 """
1090 self.assertRaises(AssertionError, gen_dep_check, -1, 'YAHOO')
1091
1092
1093class GenExpCheck(TestCase):
1094 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001095 Test suite for gen_expression_check(). It is assumed this function is called with valid inputs.
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001096 """
1097
1098 def test_gen_exp_check(self):
1099 """
1100 Test that expression check code generated correctly.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001101 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001102 """
1103 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001104 case 5:
1105 {
1106 *out_value = YAHOO;
1107 }
1108 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001109 out = gen_expression_check(5, 'YAHOO')
1110 self.assertEqual(out, expected)
1111
1112 def test_invalid_expression(self):
1113 """
1114 Test invalid expression input.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001115 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001116 """
1117 self.assertRaises(AssertionError, gen_expression_check, 5, '')
1118
1119 def test_negative_exp_id(self):
1120 """
1121 Test invalid expression id.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001122 :return:
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001123 """
1124 self.assertRaises(AssertionError, gen_expression_check, -1, 'YAHOO')
1125
1126
Azim Khan599cd242017-07-06 17:34:27 +01001127class WriteDeps(TestCase):
1128 """
1129 Test suite for testing write_deps.
1130 """
1131
1132 def test_no_test_deps(self):
1133 """
1134 Test when test_deps is empty.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001135 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001136 """
1137 s = StringIOWrapper('test_suite_ut.data', '')
1138 unique_deps = []
1139 dep_check_code = write_deps(s, [], unique_deps)
1140 self.assertEqual(dep_check_code, '')
1141 self.assertEqual(len(unique_deps), 0)
1142 self.assertEqual(s.getvalue(), '')
1143
1144 def test_unique_dep_ids(self):
1145 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001146
1147 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001148 """
1149 s = StringIOWrapper('test_suite_ut.data', '')
1150 unique_deps = []
1151 dep_check_code = write_deps(s, ['DEP3', 'DEP2', 'DEP1'], unique_deps)
1152 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001153 case 0:
1154 {
Azim Khan599cd242017-07-06 17:34:27 +01001155#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001156 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001157#else
Azim Khand61b8372017-07-10 11:54:01 +01001158 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001159#endif
Azim Khand61b8372017-07-10 11:54:01 +01001160 }
1161 break;
1162 case 1:
1163 {
Azim Khan599cd242017-07-06 17:34:27 +01001164#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001165 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001166#else
Azim Khand61b8372017-07-10 11:54:01 +01001167 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001168#endif
Azim Khand61b8372017-07-10 11:54:01 +01001169 }
1170 break;
1171 case 2:
1172 {
Azim Khan599cd242017-07-06 17:34:27 +01001173#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001174 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001175#else
Azim Khand61b8372017-07-10 11:54:01 +01001176 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001177#endif
Azim Khand61b8372017-07-10 11:54:01 +01001178 }
1179 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001180 self.assertEqual(dep_check_code, expect_dep_check_code)
1181 self.assertEqual(len(unique_deps), 3)
1182 self.assertEqual(s.getvalue(), 'depends_on:0:1:2\n')
1183
1184 def test_dep_id_repeat(self):
1185 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001186
1187 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001188 """
1189 s = StringIOWrapper('test_suite_ut.data', '')
1190 unique_deps = []
1191 dep_check_code = ''
1192 dep_check_code += write_deps(s, ['DEP3', 'DEP2'], unique_deps)
1193 dep_check_code += write_deps(s, ['DEP2', 'DEP1'], unique_deps)
1194 dep_check_code += write_deps(s, ['DEP1', 'DEP3'], unique_deps)
1195 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001196 case 0:
1197 {
Azim Khan599cd242017-07-06 17:34:27 +01001198#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001199 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001200#else
Azim Khand61b8372017-07-10 11:54:01 +01001201 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001202#endif
Azim Khand61b8372017-07-10 11:54:01 +01001203 }
1204 break;
1205 case 1:
1206 {
Azim Khan599cd242017-07-06 17:34:27 +01001207#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001208 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001209#else
Azim Khand61b8372017-07-10 11:54:01 +01001210 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001211#endif
Azim Khand61b8372017-07-10 11:54:01 +01001212 }
1213 break;
1214 case 2:
1215 {
Azim Khan599cd242017-07-06 17:34:27 +01001216#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001217 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001218#else
Azim Khand61b8372017-07-10 11:54:01 +01001219 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001220#endif
Azim Khand61b8372017-07-10 11:54:01 +01001221 }
1222 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001223 self.assertEqual(dep_check_code, expect_dep_check_code)
1224 self.assertEqual(len(unique_deps), 3)
1225 self.assertEqual(s.getvalue(), 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
1226
1227
1228class WriteParams(TestCase):
1229 """
1230 Test Suite for testing write_parameters().
1231 """
1232
1233 def test_no_params(self):
1234 """
1235 Test with empty test_args
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001236 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001237 """
1238 s = StringIOWrapper('test_suite_ut.data', '')
1239 unique_expressions = []
1240 expression_code = write_parameters(s, [], [], unique_expressions)
1241 self.assertEqual(len(unique_expressions), 0)
1242 self.assertEqual(expression_code, '')
1243 self.assertEqual(s.getvalue(), '\n')
1244
1245 def test_no_exp_param(self):
1246 """
1247 Test when there is no macro or expression in the params.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001248 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001249 """
1250 s = StringIOWrapper('test_suite_ut.data', '')
1251 unique_expressions = []
1252 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0'], ['char*', 'hex', 'int'],
1253 unique_expressions)
1254 self.assertEqual(len(unique_expressions), 0)
1255 self.assertEqual(expression_code, '')
1256 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0\n')
1257
1258 def test_hex_format_int_param(self):
1259 """
1260 Test int parameter in hex format.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001261 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001262 """
1263 s = StringIOWrapper('test_suite_ut.data', '')
1264 unique_expressions = []
1265 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0xAA'], ['char*', 'hex', 'int'],
1266 unique_expressions)
1267 self.assertEqual(len(unique_expressions), 0)
1268 self.assertEqual(expression_code, '')
1269 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
1270
1271 def test_with_exp_param(self):
1272 """
1273 Test when there is macro or expression in the params.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001274 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001275 """
1276 s = StringIOWrapper('test_suite_ut.data', '')
1277 unique_expressions = []
1278 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0', 'MACRO1', 'MACRO2', 'MACRO3'],
1279 ['char*', 'hex', 'int', 'int', 'int', 'int'],
1280 unique_expressions)
1281 self.assertEqual(len(unique_expressions), 3)
1282 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1283 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001284 case 0:
1285 {
1286 *out_value = MACRO1;
1287 }
1288 break;
1289 case 1:
1290 {
1291 *out_value = MACRO2;
1292 }
1293 break;
1294 case 2:
1295 {
1296 *out_value = MACRO3;
1297 }
1298 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001299 self.assertEqual(expression_code, expected_expression_code)
1300 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1:exp:2\n')
1301
1302 def test_with_repeate_calls(self):
1303 """
1304 Test when write_parameter() is called with same macro or expression.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001305 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001306 """
1307 s = StringIOWrapper('test_suite_ut.data', '')
1308 unique_expressions = []
1309 expression_code = ''
1310 expression_code += write_parameters(s, ['"Yahoo"', 'MACRO1', 'MACRO2'], ['char*', 'int', 'int'],
1311 unique_expressions)
1312 expression_code += write_parameters(s, ['"abcdef00"', 'MACRO2', 'MACRO3'], ['hex', 'int', 'int'],
1313 unique_expressions)
1314 expression_code += write_parameters(s, ['0', 'MACRO3', 'MACRO1'], ['int', 'int', 'int'],
1315 unique_expressions)
1316 self.assertEqual(len(unique_expressions), 3)
1317 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1318 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001319 case 0:
1320 {
1321 *out_value = MACRO1;
1322 }
1323 break;
1324 case 1:
1325 {
1326 *out_value = MACRO2;
1327 }
1328 break;
1329 case 2:
1330 {
1331 *out_value = MACRO3;
1332 }
1333 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001334 self.assertEqual(expression_code, expected_expression_code)
1335 expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
1336:hex:"abcdef00":exp:1:exp:2
1337:int:0:exp:2:exp:0
1338'''
1339 self.assertEqual(s.getvalue(), expected_data_file)
1340
1341
1342class GenTestSuiteDepsChecks(TestCase):
1343 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001344
Azim Khan599cd242017-07-06 17:34:27 +01001345 """
1346 def test_empty_suite_deps(self):
1347 """
1348 Test with empty suite_deps list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001349
1350 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001351 """
1352 dep_check_code, expression_code = gen_suite_deps_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
1353 self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
1354 self.assertEqual(expression_code, 'EXPRESSION_CODE')
1355
1356 def test_suite_deps(self):
1357 """
1358 Test with suite_deps list.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001359
1360 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001361 """
1362 dep_check_code, expression_code = gen_suite_deps_checks(['SUITE_DEP'], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
1363 exprectd_dep_check_code = '''
1364#if defined(SUITE_DEP)
1365DEP_CHECK_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001366#endif
1367'''
1368 expected_expression_code = '''
1369#if defined(SUITE_DEP)
1370EXPRESSION_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001371#endif
1372'''
1373 self.assertEqual(dep_check_code, exprectd_dep_check_code)
1374 self.assertEqual(expression_code, expected_expression_code)
1375
1376 def test_no_dep_no_exp(self):
1377 """
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001378 Test when there are no dependency and expression code.
1379 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001380 """
1381 dep_check_code, expression_code = gen_suite_deps_checks([], '', '')
Azim Khand61b8372017-07-10 11:54:01 +01001382 self.assertEqual(dep_check_code, '')
1383 self.assertEqual(expression_code, '')
Azim Khan599cd242017-07-06 17:34:27 +01001384
1385
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001386class GenFromTestData(TestCase):
1387 """
1388 Test suite for gen_from_test_data()
1389 """
1390
Mohammad Azim Khan78befd92018-03-06 11:49:41 +00001391 @patch("generate_test_code.write_deps")
1392 @patch("generate_test_code.write_parameters")
1393 @patch("generate_test_code.gen_suite_deps_checks")
Azim Khan599cd242017-07-06 17:34:27 +01001394 def test_intermediate_data_file(self, gen_suite_deps_checks_mock, write_parameters_mock, write_deps_mock):
1395 """
1396 Test that intermediate data file is written with expected data.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001397 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001398 """
1399 data = '''
1400My test
1401depends_on:DEP1
1402func1:0
1403'''
1404 data_f = StringIOWrapper('test_suite_ut.data', data)
1405 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1406 func_info = {'test_func1': (1, ('int',))}
1407 suite_deps = []
1408 write_parameters_mock.side_effect = write_parameters
1409 write_deps_mock.side_effect = write_deps
1410 gen_suite_deps_checks_mock.side_effect = gen_suite_deps_checks
1411 gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
1412 write_deps_mock.assert_called_with(out_data_f, ['DEP1'], ['DEP1'])
1413 write_parameters_mock.assert_called_with(out_data_f, ['0'], ('int',), [])
1414 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001415 case 0:
1416 {
Azim Khan599cd242017-07-06 17:34:27 +01001417#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001418 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001419#else
Azim Khand61b8372017-07-10 11:54:01 +01001420 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001421#endif
Azim Khand61b8372017-07-10 11:54:01 +01001422 }
1423 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001424 gen_suite_deps_checks_mock.assert_called_with(suite_deps, expected_dep_check_code, '')
1425
1426 def test_function_not_found(self):
1427 """
1428 Test that AssertError is raised when function info in not found.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001429 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001430 """
1431 data = '''
1432My test
1433depends_on:DEP1
1434func1:0
1435'''
1436 data_f = StringIOWrapper('test_suite_ut.data', data)
1437 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1438 func_info = {'test_func2': (1, ('int',))}
1439 suite_deps = []
1440 self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
1441
1442 def test_different_func_args(self):
1443 """
1444 Test that AssertError is raised when no. of parameters and function args differ.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001445 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001446 """
1447 data = '''
1448My test
1449depends_on:DEP1
1450func1:0
1451'''
1452 data_f = StringIOWrapper('test_suite_ut.data', data)
1453 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1454 func_info = {'test_func2': (1, ('int','hex'))}
1455 suite_deps = []
1456 self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
1457
1458 def test_output(self):
1459 """
1460 Test that intermediate data file is written with expected data.
Mohammad Azim Khanb73159d2018-06-13 16:31:26 +01001461 :return:
Azim Khan599cd242017-07-06 17:34:27 +01001462 """
1463 data = '''
1464My test 1
1465depends_on:DEP1
1466func1:0:0xfa:MACRO1:MACRO2
1467
1468My test 2
1469depends_on:DEP1:DEP2
1470func2:"yahoo":88:MACRO1
1471'''
1472 data_f = StringIOWrapper('test_suite_ut.data', data)
1473 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1474 func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')), 'test_func2': (1, ('char*', 'int', 'int'))}
1475 suite_deps = []
1476 dep_check_code, expression_code = gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
1477 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001478 case 0:
1479 {
Azim Khan599cd242017-07-06 17:34:27 +01001480#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001481 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001482#else
Azim Khand61b8372017-07-10 11:54:01 +01001483 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001484#endif
Azim Khand61b8372017-07-10 11:54:01 +01001485 }
1486 break;
1487 case 1:
1488 {
Azim Khan599cd242017-07-06 17:34:27 +01001489#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001490 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001491#else
Azim Khand61b8372017-07-10 11:54:01 +01001492 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001493#endif
Azim Khand61b8372017-07-10 11:54:01 +01001494 }
1495 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001496 expecrted_data = '''My test 1
1497depends_on:0
14980:int:0:int:0xfa:exp:0:exp:1
1499
1500My test 2
1501depends_on:0:1
15021:char*:"yahoo":int:88:exp:0
1503
1504'''
1505 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001506 case 0:
1507 {
1508 *out_value = MACRO1;
1509 }
1510 break;
1511 case 1:
1512 {
1513 *out_value = MACRO2;
1514 }
1515 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001516 self.assertEqual(dep_check_code, expected_dep_check_code)
1517 self.assertEqual(out_data_f.getvalue(), expecrted_data)
1518 self.assertEqual(expression_code, expected_expression_code)
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001519
1520
Azim Khan4b543232017-06-30 09:35:21 +01001521if __name__=='__main__':
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001522 unittest_main()