blob: bc9f6b6a5be86502e07f18829e5ff85479ce772d [file] [log] [blame]
Azim Khanf0e42fb2017-08-02 14:47:13 +01001# Unit test for generate_code.py
2#
3# Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
4# 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
23from generate_code import *
24
25
26"""
27Unit tests for generate_code.py
28"""
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.
39 :return:
40 """
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.
53 :return:
54 """
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.
67 :return:
68 """
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.
81 :return:
82 """
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.
91 :return:
92 """
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.
110 :return:
111 """
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.
165
166 :return:
167 """
168 code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
169 expected = '''
170void test_a_wrapper( void ** params )
171{
172
173
174 test_a( a, b, c, d );
175}
176'''
177 self.assertEqual(code, expected)
178
179 def test_local(self):
180 """
181 Test that params are properly unpacked in the function call.
182
183 :return:
184 """
185 code = gen_function_wrapper('test_a', 'int x = 1;', ('x', 'b', 'c', 'd'))
186 expected = '''
187void test_a_wrapper( void ** params )
188{
189
190int x = 1;
191 test_a( x, b, c, d );
192}
193'''
194 self.assertEqual(code, expected)
195
196 def test_empty_params(self):
197 """
198 Test that params are properly unpacked in the function call.
199
200 :return:
201 """
202 code = gen_function_wrapper('test_a', '', ())
203 expected = '''
204void test_a_wrapper( void ** params )
205{
206 (void)params;
207
208 test_a( );
209}
210'''
211 self.assertEqual(code, expected)
212
213
214class GenDispatch(TestCase):
215 """
216 Test suite for testing gen_dispatch()
217 """
218
219 def test_dispatch(self):
220 """
221 Test that dispatch table entry is generated correctly.
222 :return:
223 """
224 code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
225 expected = '''
226#if defined(DEP1) && defined(DEP2)
227 test_a_wrapper,
228#else
229 NULL,
230#endif
231'''
232 self.assertEqual(code, expected)
233
234 def test_empty_deps(self):
235 """
236 Test empty dependency list.
237 :return:
238 """
239 code = gen_dispatch('test_a', [])
240 expected = '''
241 test_a_wrapper,
242'''
243 self.assertEqual(code, expected)
244
245
246class StringIOWrapper(StringIO, object):
247 """
248 file like class to mock file object in tests.
249 """
250 def __init__(self, file_name, data, line_no = 1):
251 """
252 Init file handle.
253
254 :param file_name:
255 :param data:
256 :param line_no:
257 """
258 super(StringIOWrapper, self).__init__(data)
259 self.line_no = line_no
260 self.name = file_name
261
262 def next(self):
263 """
264 Iterator return impl.
265 :return:
266 """
267 line = super(StringIOWrapper, self).next()
268 return line
269
270 def readline(self, limit=0):
271 """
272 Wrap the base class readline.
273
274 :param limit:
275 :return:
276 """
277 line = super(StringIOWrapper, self).readline()
278 if line:
279 self.line_no += 1
280 return line
281
282
283class ParseSuiteHeaders(TestCase):
284 """
285 Test Suite for testing parse_suite_headers().
286 """
287
288 def test_suite_headers(self):
289 """
290 Test that suite headers are parsed correctly.
291
292 :return:
293 """
294 data = '''#include "mbedtls/ecp.h"
295
296#define ECP_PF_UNKNOWN -1
297/* END_HEADER */
298'''
299 expected = '''#line 1 "test_suite_ut.function"
300#include "mbedtls/ecp.h"
301
302#define ECP_PF_UNKNOWN -1
303'''
304 s = StringIOWrapper('test_suite_ut.function', data, line_no=0)
305 headers = parse_suite_headers(s)
306 self.assertEqual(headers, expected)
307
308 def test_line_no(self):
309 """
310 Test that #line is set to correct line no. in source .function file.
311
312 :return:
313 """
314 data = '''#include "mbedtls/ecp.h"
315
316#define ECP_PF_UNKNOWN -1
317/* END_HEADER */
318'''
319 offset_line_no = 5
320 expected = '''#line %d "test_suite_ut.function"
321#include "mbedtls/ecp.h"
322
323#define ECP_PF_UNKNOWN -1
324''' % (offset_line_no + 1)
325 s = StringIOWrapper('test_suite_ut.function', data, offset_line_no)
326 headers = parse_suite_headers(s)
327 self.assertEqual(headers, expected)
328
329 def test_no_end_header_comment(self):
330 """
331 Test that InvalidFileFormat is raised when end header comment is missing.
332 :return:
333 """
334 data = '''#include "mbedtls/ecp.h"
335
336#define ECP_PF_UNKNOWN -1
337
338'''
339 s = StringIOWrapper('test_suite_ut.function', data)
340 self.assertRaises(InvalidFileFormat, parse_suite_headers, s)
341
342
343class ParseSuiteDeps(TestCase):
344 """
345 Test Suite for testing parse_suite_deps().
346 """
347
348 def test_suite_deps(self):
349 """
350
351 :return:
352 """
353 data = '''
354 * depends_on:MBEDTLS_ECP_C
355 * END_DEPENDENCIES
356 */
357'''
358 expected = ['MBEDTLS_ECP_C']
359 s = StringIOWrapper('test_suite_ut.function', data)
360 deps = parse_suite_deps(s)
361 self.assertEqual(deps, expected)
362
363 def test_no_end_dep_comment(self):
364 """
365 Test that InvalidFileFormat is raised when end dep comment is missing.
366 :return:
367 """
368 data = '''
369* depends_on:MBEDTLS_ECP_C
370'''
371 s = StringIOWrapper('test_suite_ut.function', data)
372 self.assertRaises(InvalidFileFormat, parse_suite_deps, s)
373
374 def test_deps_split(self):
375 """
376 Test that InvalidFileFormat is raised when end dep comment is missing.
377 :return:
378 """
379 data = '''
380 * depends_on:MBEDTLS_ECP_C:A:B: C : D :F : G: !H
381 * END_DEPENDENCIES
382 */
383'''
384 expected = ['MBEDTLS_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
385 s = StringIOWrapper('test_suite_ut.function', data)
386 deps = parse_suite_deps(s)
387 self.assertEqual(deps, expected)
388
389
390class ParseFuncDeps(TestCase):
391 """
392 Test Suite for testing parse_function_deps()
393 """
394
395 def test_function_deps(self):
396 """
397 Test that parse_function_deps() correctly parses function dependencies.
398 :return:
399 """
400 line = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */'
401 expected = ['MBEDTLS_ENTROPY_NV_SEED', 'MBEDTLS_FS_IO']
402 deps = parse_function_deps(line)
403 self.assertEqual(deps, expected)
404
405 def test_no_deps(self):
406 """
407 Test that parse_function_deps() correctly parses function dependencies.
408 :return:
409 """
410 line = '/* BEGIN_CASE */'
411 deps = parse_function_deps(line)
412 self.assertEqual(deps, [])
413
414 def test_poorly_defined_deps(self):
415 """
416 Test that parse_function_deps() correctly parses function dependencies.
417 :return:
418 """
419 line = '/* BEGIN_CASE depends_on:MBEDTLS_FS_IO: A : !B:C : F*/'
420 deps = parse_function_deps(line)
421 self.assertEqual(deps, ['MBEDTLS_FS_IO', 'A', '!B', 'C', 'F'])
422
423
424class ParseFuncSignature(TestCase):
425 """
426 Test Suite for parse_function_signature().
427 """
428
429 def test_int_and_char_params(self):
430 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100431 Test int and char parameters parsing
Azim Khan4b543232017-06-30 09:35:21 +0100432 :return:
433 """
434 line = 'void entropy_threshold( char * a, int b, int result )'
435 name, args, local, arg_dispatch = parse_function_signature(line)
436 self.assertEqual(name, 'entropy_threshold')
437 self.assertEqual(args, ['char*', 'int', 'int'])
438 self.assertEqual(local, '')
439 self.assertEqual(arg_dispatch, ['(char *) params[0]', '*( (int *) params[1] )', '*( (int *) params[2] )'])
440
441 def test_hex_params(self):
442 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100443 Test hex parameters parsing
Azim Khan4b543232017-06-30 09:35:21 +0100444 :return:
445 """
446 line = 'void entropy_threshold( char * a, HexParam_t * h, int result )'
447 name, args, local, arg_dispatch = parse_function_signature(line)
448 self.assertEqual(name, 'entropy_threshold')
449 self.assertEqual(args, ['char*', 'hex', 'int'])
450 self.assertEqual(local, ' HexParam_t hex1 = {(uint8_t *) params[1], *( (uint32_t *) params[2] )};\n')
451 self.assertEqual(arg_dispatch, ['(char *) params[0]', '&hex1', '*( (int *) params[3] )'])
452
453 def test_non_void_function(self):
454 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100455 Test invalid signature (non void).
Azim Khan4b543232017-06-30 09:35:21 +0100456 :return:
457 """
458 line = 'int entropy_threshold( char * a, HexParam_t * h, int result )'
459 self.assertRaises(ValueError, parse_function_signature, line)
460
461 def test_unsupported_arg(self):
462 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100463 Test unsupported arguments (not among int, char * and HexParam_t)
Azim Khan4b543232017-06-30 09:35:21 +0100464 :return:
465 """
466 line = 'int entropy_threshold( char * a, HexParam_t * h, int * result )'
467 self.assertRaises(ValueError, parse_function_signature, line)
468
469 def test_no_params(self):
470 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100471 Test no parameters.
Azim Khan4b543232017-06-30 09:35:21 +0100472 :return:
473 """
474 line = 'void entropy_threshold()'
475 name, args, local, arg_dispatch = parse_function_signature(line)
476 self.assertEqual(name, 'entropy_threshold')
477 self.assertEqual(args, [])
478 self.assertEqual(local, '')
479 self.assertEqual(arg_dispatch, [])
480
481
482class ParseFunctionCode(TestCase):
483 """
484 Test suite for testing parse_function_code()
485 """
486
487 def test_no_function(self):
488 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100489 Test no test function found.
Azim Khan4b543232017-06-30 09:35:21 +0100490 :return:
491 """
492 data = '''
493No
494test
495function
496'''
497 s = StringIOWrapper('test_suite_ut.function', data)
498 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
499
500 def test_no_end_case_comment(self):
501 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100502 Test missing end case.
Azim Khan4b543232017-06-30 09:35:21 +0100503 :return:
504 """
505 data = '''
506void test_func()
507{
508}
509'''
510 s = StringIOWrapper('test_suite_ut.function', data)
511 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
512
513 @patch("generate_code.parse_function_signature")
514 def test_parse_function_signature_called(self, parse_function_signature_mock):
515 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100516 Test parse_function_code()
Azim Khan4b543232017-06-30 09:35:21 +0100517 :return:
518 """
519 parse_function_signature_mock.return_value = ('test_func', [], '', [])
520 data = '''
521void test_func()
522{
523}
524'''
525 s = StringIOWrapper('test_suite_ut.function', data)
526 self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
527 self.assertTrue(parse_function_signature_mock.called)
528 parse_function_signature_mock.assert_called_with('void test_func()\n')
529
530 @patch("generate_code.gen_dispatch")
531 @patch("generate_code.gen_deps")
532 @patch("generate_code.gen_function_wrapper")
533 @patch("generate_code.parse_function_signature")
534 def test_return(self, parse_function_signature_mock,
535 gen_function_wrapper_mock,
536 gen_deps_mock,
537 gen_dispatch_mock):
538 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100539 Test generated code.
Azim Khan4b543232017-06-30 09:35:21 +0100540 :return:
541 """
542 parse_function_signature_mock.return_value = ('func', [], '', [])
543 gen_function_wrapper_mock.return_value = ''
544 gen_deps_mock.side_effect = gen_deps
545 gen_dispatch_mock.side_effect = gen_dispatch
546 data = '''
547void func()
548{
549 ba ba black sheep
550 have you any wool
551}
552/* END_CASE */
553'''
554 s = StringIOWrapper('test_suite_ut.function', data)
555 name, arg, code, dispatch_code = parse_function_code(s, [], [])
556
557 #self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
558 self.assertTrue(parse_function_signature_mock.called)
559 parse_function_signature_mock.assert_called_with('void func()\n')
560 gen_function_wrapper_mock.assert_called_with('test_func', '', [])
561 self.assertEqual(name, 'test_func')
562 self.assertEqual(arg, [])
563 expected = '''#line 2 "test_suite_ut.function"
564void test_func()
565{
566 ba ba black sheep
567 have you any wool
568exit:
569 ;;
570}
571'''
572 self.assertEqual(code, expected)
573 self.assertEqual(dispatch_code, "\n test_func_wrapper,\n")
574
575 @patch("generate_code.gen_dispatch")
576 @patch("generate_code.gen_deps")
577 @patch("generate_code.gen_function_wrapper")
578 @patch("generate_code.parse_function_signature")
579 def test_with_exit_label(self, parse_function_signature_mock,
580 gen_function_wrapper_mock,
581 gen_deps_mock,
582 gen_dispatch_mock):
583 """
Azim Khanf0e42fb2017-08-02 14:47:13 +0100584 Test when exit label is present.
Azim Khan4b543232017-06-30 09:35:21 +0100585 :return:
586 """
587 parse_function_signature_mock.return_value = ('func', [], '', [])
588 gen_function_wrapper_mock.return_value = ''
589 gen_deps_mock.side_effect = gen_deps
590 gen_dispatch_mock.side_effect = gen_dispatch
591 data = '''
592void func()
593{
594 ba ba black sheep
595 have you any wool
596exit:
597 yes sir yes sir
598 3 bags full
599}
600/* END_CASE */
601'''
602 s = StringIOWrapper('test_suite_ut.function', data)
603 name, arg, code, dispatch_code = parse_function_code(s, [], [])
604
605 expected = '''#line 2 "test_suite_ut.function"
606void test_func()
607{
608 ba ba black sheep
609 have you any wool
610exit:
611 yes sir yes sir
612 3 bags full
613}
614'''
615 self.assertEqual(code, expected)
616
617
618class ParseFunction(TestCase):
619 """
620 Test Suite for testing parse_functions()
621 """
622
623 @patch("generate_code.parse_suite_headers")
624 def test_begin_header(self, parse_suite_headers_mock):
625 """
626 Test that begin header is checked and parse_suite_headers() is called.
627 :return:
628 """
629 def stop(this):
630 raise Exception
631 parse_suite_headers_mock.side_effect = stop
632 data = '''/* BEGIN_HEADER */
633#include "mbedtls/ecp.h"
634
635#define ECP_PF_UNKNOWN -1
636/* END_HEADER */
637'''
638 s = StringIOWrapper('test_suite_ut.function', data)
639 self.assertRaises(Exception, parse_functions, s)
640 parse_suite_headers_mock.assert_called_with(s)
641 self.assertEqual(s.line_no, 2)
642
643 @patch("generate_code.parse_suite_deps")
644 def test_begin_dep(self, parse_suite_deps_mock):
645 """
646 Test that begin header is checked and parse_suite_headers() is called.
647 :return:
648 """
649 def stop(this):
650 raise Exception
651 parse_suite_deps_mock.side_effect = stop
652 data = '''/* BEGIN_DEPENDENCIES
653 * depends_on:MBEDTLS_ECP_C
654 * END_DEPENDENCIES
655 */
656'''
657 s = StringIOWrapper('test_suite_ut.function', data)
658 self.assertRaises(Exception, parse_functions, s)
659 parse_suite_deps_mock.assert_called_with(s)
660 self.assertEqual(s.line_no, 2)
661
662 @patch("generate_code.parse_function_deps")
663 def test_begin_function_dep(self, parse_function_deps_mock):
664 """
665 Test that begin header is checked and parse_suite_headers() is called.
666 :return:
667 """
668 def stop(this):
669 raise Exception
670 parse_function_deps_mock.side_effect = stop
671
672 deps_str = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
673 data = '''%svoid test_func()
674{
675}
676''' % deps_str
677 s = StringIOWrapper('test_suite_ut.function', data)
678 self.assertRaises(Exception, parse_functions, s)
679 parse_function_deps_mock.assert_called_with(deps_str)
680 self.assertEqual(s.line_no, 2)
681
682 @patch("generate_code.parse_function_code")
683 @patch("generate_code.parse_function_deps")
684 def test_return(self, parse_function_deps_mock, parse_function_code_mock):
685 """
686 Test that begin header is checked and parse_suite_headers() is called.
687 :return:
688 """
689 def stop(this):
690 raise Exception
691 parse_function_deps_mock.return_value = []
692 in_func_code= '''void test_func()
693{
694}
695'''
696 func_dispatch = '''
697 test_func_wrapper,
698'''
699 parse_function_code_mock.return_value = 'test_func', [], in_func_code, func_dispatch
700 deps_str = '/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
701 data = '''%svoid test_func()
702{
703}
704''' % deps_str
705 s = StringIOWrapper('test_suite_ut.function', data)
706 suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
707 parse_function_deps_mock.assert_called_with(deps_str)
708 parse_function_code_mock.assert_called_with(s, [], [])
709 self.assertEqual(s.line_no, 5)
710 self.assertEqual(suite_deps, [])
711 expected_dispatch_code = '''/* Function Id: 0 */
712
713 test_func_wrapper,
714'''
715 self.assertEqual(dispatch_code, expected_dispatch_code)
716 self.assertEqual(func_code, in_func_code)
717 self.assertEqual(func_info, {'test_func': (0, [])})
718
719 def test_parsing(self):
720 """
721 Test that begin header is checked and parse_suite_headers() is called.
722 :return:
723 """
724 data = '''/* BEGIN_HEADER */
725#include "mbedtls/ecp.h"
726
727#define ECP_PF_UNKNOWN -1
728/* END_HEADER */
729
730/* BEGIN_DEPENDENCIES
731 * depends_on:MBEDTLS_ECP_C
732 * END_DEPENDENCIES
733 */
734
735/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
736void func1()
737{
738}
739/* END_CASE */
740
741/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
742void func2()
743{
744}
745/* END_CASE */
746'''
747 s = StringIOWrapper('test_suite_ut.function', data)
748 suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
749 self.assertEqual(s.line_no, 23)
750 self.assertEqual(suite_deps, ['MBEDTLS_ECP_C'])
751
752 expected_dispatch_code = '''/* Function Id: 0 */
753
754#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
755 test_func1_wrapper,
756#else
757 NULL,
758#endif
759/* Function Id: 1 */
760
761#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
762 test_func2_wrapper,
763#else
764 NULL,
765#endif
766'''
767 self.assertEqual(dispatch_code, expected_dispatch_code)
768 expected_func_code = '''#if defined(MBEDTLS_ECP_C)
769#line 3 "test_suite_ut.function"
770#include "mbedtls/ecp.h"
771
772#define ECP_PF_UNKNOWN -1
773#if defined(MBEDTLS_ENTROPY_NV_SEED)
774#if defined(MBEDTLS_FS_IO)
775#line 14 "test_suite_ut.function"
776void test_func1()
777{
778exit:
779 ;;
780}
781
782void test_func1_wrapper( void ** params )
783{
784 (void)params;
785
786 test_func1( );
787}
788#endif /* MBEDTLS_FS_IO */
789#endif /* MBEDTLS_ENTROPY_NV_SEED */
790#if defined(MBEDTLS_ENTROPY_NV_SEED)
791#if defined(MBEDTLS_FS_IO)
792#line 20 "test_suite_ut.function"
793void test_func2()
794{
795exit:
796 ;;
797}
798
799void test_func2_wrapper( void ** params )
800{
801 (void)params;
802
803 test_func2( );
804}
805#endif /* MBEDTLS_FS_IO */
806#endif /* MBEDTLS_ENTROPY_NV_SEED */
807#endif /* MBEDTLS_ECP_C */
808'''
809 self.assertEqual(func_code, expected_func_code)
810 self.assertEqual(func_info, {'test_func1': (0, []), 'test_func2': (1, [])})
811
812 def test_same_function_name(self):
813 """
814 Test that begin header is checked and parse_suite_headers() is called.
815 :return:
816 """
817 data = '''/* BEGIN_HEADER */
818#include "mbedtls/ecp.h"
819
820#define ECP_PF_UNKNOWN -1
821/* END_HEADER */
822
823/* BEGIN_DEPENDENCIES
824 * depends_on:MBEDTLS_ECP_C
825 * END_DEPENDENCIES
826 */
827
828/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
829void func()
830{
831}
832/* END_CASE */
833
834/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
835void func()
836{
837}
838/* END_CASE */
839'''
840 s = StringIOWrapper('test_suite_ut.function', data)
841 self.assertRaises(AssertionError, parse_functions, s)
842
843
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100844class ExcapedSplit(TestCase):
845 """
Azim Khan599cd242017-07-06 17:34:27 +0100846 Test suite for testing escaped_split().
847 Note: Since escaped_split() output is used to write back to the intermediate data file. Any escape characters
848 in the input are retained in the output.
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100849 """
850
851 def test_invalid_input(self):
852 """
853 Test when input split character is not a character.
854 :return:
855 """
856 self.assertRaises(ValueError, escaped_split, '', 'string')
857
858 def test_empty_string(self):
859 """
860 Test empty strig input.
861 :return:
862 """
863 splits = escaped_split('', ':')
864 self.assertEqual(splits, [])
865
866 def test_no_escape(self):
867 """
868 Test with no escape character. The behaviour should be same as str.split()
869 :return:
870 """
871 s = 'yahoo:google'
872 splits = escaped_split(s, ':')
873 self.assertEqual(splits, s.split(':'))
874
875 def test_escaped_input(self):
876 """
877 Test imput that has escaped delimiter.
878 :return:
879 """
880 s = 'yahoo\:google:facebook'
881 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100882 self.assertEqual(splits, ['yahoo\:google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100883
884 def test_escaped_escape(self):
885 """
886 Test imput that has escaped delimiter.
887 :return:
888 """
889 s = 'yahoo\\\:google:facebook'
890 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100891 self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook'])
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100892
893 def test_all_at_once(self):
894 """
895 Test imput that has escaped delimiter.
896 :return:
897 """
898 s = 'yahoo\\\:google:facebook\:instagram\\\:bbc\\\\:wikipedia'
899 splits = escaped_split(s, ':')
Azim Khan599cd242017-07-06 17:34:27 +0100900 self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook\:instagram\\\\', 'bbc\\\\', 'wikipedia'])
901
Azim Khan5e2ac1f2017-07-03 13:58:20 +0100902
903class ParseTestData(TestCase):
904 """
905 Test suite for parse test data.
906 """
907
908 def test_parser(self):
909 """
910 Test that tests are parsed correctly from data file.
911 :return:
912 """
913 data = """
914Diffie-Hellman full exchange #1
915dhm_do_dhm:10:"23":10:"5"
916
917Diffie-Hellman full exchange #2
918dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
919
920Diffie-Hellman full exchange #3
921dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
922
923Diffie-Hellman selftest
924dhm_selftest:
925"""
926 s = StringIOWrapper('test_suite_ut.function', data)
927 tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
928 t1, t2, t3, t4 = tests
929 self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
930 self.assertEqual(t1[1], 'dhm_do_dhm')
931 self.assertEqual(t1[2], [])
932 self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
933
934 self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
935 self.assertEqual(t2[1], 'dhm_do_dhm')
936 self.assertEqual(t2[2], [])
937 self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
938
939 self.assertEqual(t3[0], 'Diffie-Hellman full exchange #3')
940 self.assertEqual(t3[1], 'dhm_do_dhm')
941 self.assertEqual(t3[2], [])
942 self.assertEqual(t3[3], ['10', '"9345098382739712938719287391879381271"', '10', '"9345098792137312973297123912791271"'])
943
944 self.assertEqual(t4[0], 'Diffie-Hellman selftest')
945 self.assertEqual(t4[1], 'dhm_selftest')
946 self.assertEqual(t4[2], [])
947 self.assertEqual(t4[3], [])
948
949 def test_with_dependencies(self):
950 """
951 Test that tests with dependencies are parsed.
952 :return:
953 """
954 data = """
955Diffie-Hellman full exchange #1
956depends_on:YAHOO
957dhm_do_dhm:10:"23":10:"5"
958
959Diffie-Hellman full exchange #2
960dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
961
962"""
963 s = StringIOWrapper('test_suite_ut.function', data)
964 tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
965 t1, t2 = tests
966 self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
967 self.assertEqual(t1[1], 'dhm_do_dhm')
968 self.assertEqual(t1[2], ['YAHOO'])
969 self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
970
971 self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
972 self.assertEqual(t2[1], 'dhm_do_dhm')
973 self.assertEqual(t2[2], [])
974 self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
975
976 def test_no_args(self):
977 """
978 Test AssertionError is raised when test function name and args line is missing.
979 :return:
980 """
981 data = """
982Diffie-Hellman full exchange #1
983depends_on:YAHOO
984
985
986Diffie-Hellman full exchange #2
987dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
988
989"""
990 s = StringIOWrapper('test_suite_ut.function', data)
991 e = None
992 try:
993 for x, y, z, a in parse_test_data(s):
994 pass
995 except AssertionError, e:
996 pass
997 self.assertEqual(type(e), AssertionError)
998
999 def test_incomplete_data(self):
1000 """
1001 Test AssertionError is raised when test function name and args line is missing.
1002 :return:
1003 """
1004 data = """
1005Diffie-Hellman full exchange #1
1006depends_on:YAHOO
1007"""
1008 s = StringIOWrapper('test_suite_ut.function', data)
1009 e = None
1010 try:
1011 for x, y, z, a in parse_test_data(s):
1012 pass
1013 except AssertionError, e:
1014 pass
1015 self.assertEqual(type(e), AssertionError)
1016
1017
1018class GenDepCheck(TestCase):
1019 """
1020 Test suite for gen_dep_check(). It is assumed this function is called with valid inputs.
1021 """
1022
1023 def test_gen_dep_check(self):
1024 """
1025 Test that dependency check code generated correctly.
1026 :return:
1027 """
1028 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001029 case 5:
1030 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001031#if defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001032 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001033#else
Azim Khand61b8372017-07-10 11:54:01 +01001034 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001035#endif
Azim Khand61b8372017-07-10 11:54:01 +01001036 }
1037 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001038 out = gen_dep_check(5, 'YAHOO')
1039 self.assertEqual(out, expected)
1040
1041 def test_noT(self):
1042 """
1043 Test dependency with !.
1044 :return:
1045 """
1046 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001047 case 5:
1048 {
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001049#if !defined(YAHOO)
Azim Khand61b8372017-07-10 11:54:01 +01001050 ret = DEPENDENCY_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001051#else
Azim Khand61b8372017-07-10 11:54:01 +01001052 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001053#endif
Azim Khand61b8372017-07-10 11:54:01 +01001054 }
1055 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001056 out = gen_dep_check(5, '!YAHOO')
1057 self.assertEqual(out, expected)
1058
1059 def test_empty_dependency(self):
1060 """
1061 Test invalid dependency input.
1062 :return:
1063 """
1064 self.assertRaises(AssertionError, gen_dep_check, 5, '!')
1065
1066 def test_negative_dep_id(self):
1067 """
1068 Test invalid dependency input.
1069 :return:
1070 """
1071 self.assertRaises(AssertionError, gen_dep_check, -1, 'YAHOO')
1072
1073
1074class GenExpCheck(TestCase):
1075 """
1076 Test suite for gen_expression_check(). It is assumed this function is called with valid inputs.
1077 """
1078
1079 def test_gen_exp_check(self):
1080 """
1081 Test that expression check code generated correctly.
1082 :return:
1083 """
1084 expected = """
Azim Khand61b8372017-07-10 11:54:01 +01001085 case 5:
1086 {
1087 *out_value = YAHOO;
1088 }
1089 break;"""
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001090 out = gen_expression_check(5, 'YAHOO')
1091 self.assertEqual(out, expected)
1092
1093 def test_invalid_expression(self):
1094 """
1095 Test invalid expression input.
1096 :return:
1097 """
1098 self.assertRaises(AssertionError, gen_expression_check, 5, '')
1099
1100 def test_negative_exp_id(self):
1101 """
1102 Test invalid expression id.
1103 :return:
1104 """
1105 self.assertRaises(AssertionError, gen_expression_check, -1, 'YAHOO')
1106
1107
Azim Khan599cd242017-07-06 17:34:27 +01001108class WriteDeps(TestCase):
1109 """
1110 Test suite for testing write_deps.
1111 """
1112
1113 def test_no_test_deps(self):
1114 """
1115 Test when test_deps is empty.
1116 :return:
1117 """
1118 s = StringIOWrapper('test_suite_ut.data', '')
1119 unique_deps = []
1120 dep_check_code = write_deps(s, [], unique_deps)
1121 self.assertEqual(dep_check_code, '')
1122 self.assertEqual(len(unique_deps), 0)
1123 self.assertEqual(s.getvalue(), '')
1124
1125 def test_unique_dep_ids(self):
1126 """
1127
1128 :return:
1129 """
1130 s = StringIOWrapper('test_suite_ut.data', '')
1131 unique_deps = []
1132 dep_check_code = write_deps(s, ['DEP3', 'DEP2', 'DEP1'], unique_deps)
1133 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001134 case 0:
1135 {
Azim Khan599cd242017-07-06 17:34:27 +01001136#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001137 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001138#else
Azim Khand61b8372017-07-10 11:54:01 +01001139 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001140#endif
Azim Khand61b8372017-07-10 11:54:01 +01001141 }
1142 break;
1143 case 1:
1144 {
Azim Khan599cd242017-07-06 17:34:27 +01001145#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001146 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001147#else
Azim Khand61b8372017-07-10 11:54:01 +01001148 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001149#endif
Azim Khand61b8372017-07-10 11:54:01 +01001150 }
1151 break;
1152 case 2:
1153 {
Azim Khan599cd242017-07-06 17:34:27 +01001154#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001155 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001156#else
Azim Khand61b8372017-07-10 11:54:01 +01001157 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001158#endif
Azim Khand61b8372017-07-10 11:54:01 +01001159 }
1160 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001161 self.assertEqual(dep_check_code, expect_dep_check_code)
1162 self.assertEqual(len(unique_deps), 3)
1163 self.assertEqual(s.getvalue(), 'depends_on:0:1:2\n')
1164
1165 def test_dep_id_repeat(self):
1166 """
1167
1168 :return:
1169 """
1170 s = StringIOWrapper('test_suite_ut.data', '')
1171 unique_deps = []
1172 dep_check_code = ''
1173 dep_check_code += write_deps(s, ['DEP3', 'DEP2'], unique_deps)
1174 dep_check_code += write_deps(s, ['DEP2', 'DEP1'], unique_deps)
1175 dep_check_code += write_deps(s, ['DEP1', 'DEP3'], unique_deps)
1176 expect_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001177 case 0:
1178 {
Azim Khan599cd242017-07-06 17:34:27 +01001179#if defined(DEP3)
Azim Khand61b8372017-07-10 11:54:01 +01001180 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001181#else
Azim Khand61b8372017-07-10 11:54:01 +01001182 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001183#endif
Azim Khand61b8372017-07-10 11:54:01 +01001184 }
1185 break;
1186 case 1:
1187 {
Azim Khan599cd242017-07-06 17:34:27 +01001188#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001189 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001190#else
Azim Khand61b8372017-07-10 11:54:01 +01001191 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001192#endif
Azim Khand61b8372017-07-10 11:54:01 +01001193 }
1194 break;
1195 case 2:
1196 {
Azim Khan599cd242017-07-06 17:34:27 +01001197#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001198 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001199#else
Azim Khand61b8372017-07-10 11:54:01 +01001200 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001201#endif
Azim Khand61b8372017-07-10 11:54:01 +01001202 }
1203 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001204 self.assertEqual(dep_check_code, expect_dep_check_code)
1205 self.assertEqual(len(unique_deps), 3)
1206 self.assertEqual(s.getvalue(), 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
1207
1208
1209class WriteParams(TestCase):
1210 """
1211 Test Suite for testing write_parameters().
1212 """
1213
1214 def test_no_params(self):
1215 """
1216 Test with empty test_args
1217 :return:
1218 """
1219 s = StringIOWrapper('test_suite_ut.data', '')
1220 unique_expressions = []
1221 expression_code = write_parameters(s, [], [], unique_expressions)
1222 self.assertEqual(len(unique_expressions), 0)
1223 self.assertEqual(expression_code, '')
1224 self.assertEqual(s.getvalue(), '\n')
1225
1226 def test_no_exp_param(self):
1227 """
1228 Test when there is no macro or expression in the params.
1229 :return:
1230 """
1231 s = StringIOWrapper('test_suite_ut.data', '')
1232 unique_expressions = []
1233 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0'], ['char*', 'hex', 'int'],
1234 unique_expressions)
1235 self.assertEqual(len(unique_expressions), 0)
1236 self.assertEqual(expression_code, '')
1237 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0\n')
1238
1239 def test_hex_format_int_param(self):
1240 """
1241 Test int parameter in hex format.
1242 :return:
1243 """
1244 s = StringIOWrapper('test_suite_ut.data', '')
1245 unique_expressions = []
1246 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0xAA'], ['char*', 'hex', 'int'],
1247 unique_expressions)
1248 self.assertEqual(len(unique_expressions), 0)
1249 self.assertEqual(expression_code, '')
1250 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
1251
1252 def test_with_exp_param(self):
1253 """
1254 Test when there is macro or expression in the params.
1255 :return:
1256 """
1257 s = StringIOWrapper('test_suite_ut.data', '')
1258 unique_expressions = []
1259 expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0', 'MACRO1', 'MACRO2', 'MACRO3'],
1260 ['char*', 'hex', 'int', 'int', 'int', 'int'],
1261 unique_expressions)
1262 self.assertEqual(len(unique_expressions), 3)
1263 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1264 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001265 case 0:
1266 {
1267 *out_value = MACRO1;
1268 }
1269 break;
1270 case 1:
1271 {
1272 *out_value = MACRO2;
1273 }
1274 break;
1275 case 2:
1276 {
1277 *out_value = MACRO3;
1278 }
1279 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001280 self.assertEqual(expression_code, expected_expression_code)
1281 self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1:exp:2\n')
1282
1283 def test_with_repeate_calls(self):
1284 """
1285 Test when write_parameter() is called with same macro or expression.
1286 :return:
1287 """
1288 s = StringIOWrapper('test_suite_ut.data', '')
1289 unique_expressions = []
1290 expression_code = ''
1291 expression_code += write_parameters(s, ['"Yahoo"', 'MACRO1', 'MACRO2'], ['char*', 'int', 'int'],
1292 unique_expressions)
1293 expression_code += write_parameters(s, ['"abcdef00"', 'MACRO2', 'MACRO3'], ['hex', 'int', 'int'],
1294 unique_expressions)
1295 expression_code += write_parameters(s, ['0', 'MACRO3', 'MACRO1'], ['int', 'int', 'int'],
1296 unique_expressions)
1297 self.assertEqual(len(unique_expressions), 3)
1298 self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
1299 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001300 case 0:
1301 {
1302 *out_value = MACRO1;
1303 }
1304 break;
1305 case 1:
1306 {
1307 *out_value = MACRO2;
1308 }
1309 break;
1310 case 2:
1311 {
1312 *out_value = MACRO3;
1313 }
1314 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001315 self.assertEqual(expression_code, expected_expression_code)
1316 expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
1317:hex:"abcdef00":exp:1:exp:2
1318:int:0:exp:2:exp:0
1319'''
1320 self.assertEqual(s.getvalue(), expected_data_file)
1321
1322
1323class GenTestSuiteDepsChecks(TestCase):
1324 """
1325
1326 """
1327 def test_empty_suite_deps(self):
1328 """
1329 Test with empty suite_deps list.
1330
1331 :return:
1332 """
1333 dep_check_code, expression_code = gen_suite_deps_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
1334 self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
1335 self.assertEqual(expression_code, 'EXPRESSION_CODE')
1336
1337 def test_suite_deps(self):
1338 """
1339 Test with suite_deps list.
1340
1341 :return:
1342 """
1343 dep_check_code, expression_code = gen_suite_deps_checks(['SUITE_DEP'], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
1344 exprectd_dep_check_code = '''
1345#if defined(SUITE_DEP)
1346DEP_CHECK_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001347#endif
1348'''
1349 expected_expression_code = '''
1350#if defined(SUITE_DEP)
1351EXPRESSION_CODE
Azim Khan599cd242017-07-06 17:34:27 +01001352#endif
1353'''
1354 self.assertEqual(dep_check_code, exprectd_dep_check_code)
1355 self.assertEqual(expression_code, expected_expression_code)
1356
1357 def test_no_dep_no_exp(self):
1358 """
1359 Test when there are no dependency and expression code.
1360 :return:
1361 """
1362 dep_check_code, expression_code = gen_suite_deps_checks([], '', '')
Azim Khand61b8372017-07-10 11:54:01 +01001363 self.assertEqual(dep_check_code, '')
1364 self.assertEqual(expression_code, '')
Azim Khan599cd242017-07-06 17:34:27 +01001365
1366
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001367class GenFromTestData(TestCase):
1368 """
1369 Test suite for gen_from_test_data()
1370 """
1371
Azim Khan599cd242017-07-06 17:34:27 +01001372 @patch("generate_code.write_deps")
1373 @patch("generate_code.write_parameters")
1374 @patch("generate_code.gen_suite_deps_checks")
1375 def test_intermediate_data_file(self, gen_suite_deps_checks_mock, write_parameters_mock, write_deps_mock):
1376 """
1377 Test that intermediate data file is written with expected data.
1378 :return:
1379 """
1380 data = '''
1381My test
1382depends_on:DEP1
1383func1:0
1384'''
1385 data_f = StringIOWrapper('test_suite_ut.data', data)
1386 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1387 func_info = {'test_func1': (1, ('int',))}
1388 suite_deps = []
1389 write_parameters_mock.side_effect = write_parameters
1390 write_deps_mock.side_effect = write_deps
1391 gen_suite_deps_checks_mock.side_effect = gen_suite_deps_checks
1392 gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
1393 write_deps_mock.assert_called_with(out_data_f, ['DEP1'], ['DEP1'])
1394 write_parameters_mock.assert_called_with(out_data_f, ['0'], ('int',), [])
1395 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001396 case 0:
1397 {
Azim Khan599cd242017-07-06 17:34:27 +01001398#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001399 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001400#else
Azim Khand61b8372017-07-10 11:54:01 +01001401 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001402#endif
Azim Khand61b8372017-07-10 11:54:01 +01001403 }
1404 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001405 gen_suite_deps_checks_mock.assert_called_with(suite_deps, expected_dep_check_code, '')
1406
1407 def test_function_not_found(self):
1408 """
1409 Test that AssertError is raised when function info in not found.
1410 :return:
1411 """
1412 data = '''
1413My test
1414depends_on:DEP1
1415func1:0
1416'''
1417 data_f = StringIOWrapper('test_suite_ut.data', data)
1418 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1419 func_info = {'test_func2': (1, ('int',))}
1420 suite_deps = []
1421 self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
1422
1423 def test_different_func_args(self):
1424 """
1425 Test that AssertError is raised when no. of parameters and function args differ.
1426 :return:
1427 """
1428 data = '''
1429My test
1430depends_on:DEP1
1431func1:0
1432'''
1433 data_f = StringIOWrapper('test_suite_ut.data', data)
1434 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1435 func_info = {'test_func2': (1, ('int','hex'))}
1436 suite_deps = []
1437 self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
1438
1439 def test_output(self):
1440 """
1441 Test that intermediate data file is written with expected data.
1442 :return:
1443 """
1444 data = '''
1445My test 1
1446depends_on:DEP1
1447func1:0:0xfa:MACRO1:MACRO2
1448
1449My test 2
1450depends_on:DEP1:DEP2
1451func2:"yahoo":88:MACRO1
1452'''
1453 data_f = StringIOWrapper('test_suite_ut.data', data)
1454 out_data_f = StringIOWrapper('test_suite_ut.datax', '')
1455 func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')), 'test_func2': (1, ('char*', 'int', 'int'))}
1456 suite_deps = []
1457 dep_check_code, expression_code = gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
1458 expected_dep_check_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001459 case 0:
1460 {
Azim Khan599cd242017-07-06 17:34:27 +01001461#if defined(DEP1)
Azim Khand61b8372017-07-10 11:54:01 +01001462 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001463#else
Azim Khand61b8372017-07-10 11:54:01 +01001464 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001465#endif
Azim Khand61b8372017-07-10 11:54:01 +01001466 }
1467 break;
1468 case 1:
1469 {
Azim Khan599cd242017-07-06 17:34:27 +01001470#if defined(DEP2)
Azim Khand61b8372017-07-10 11:54:01 +01001471 ret = DEPENDENCY_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001472#else
Azim Khand61b8372017-07-10 11:54:01 +01001473 ret = DEPENDENCY_NOT_SUPPORTED;
Azim Khan599cd242017-07-06 17:34:27 +01001474#endif
Azim Khand61b8372017-07-10 11:54:01 +01001475 }
1476 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001477 expecrted_data = '''My test 1
1478depends_on:0
14790:int:0:int:0xfa:exp:0:exp:1
1480
1481My test 2
1482depends_on:0:1
14831:char*:"yahoo":int:88:exp:0
1484
1485'''
1486 expected_expression_code = '''
Azim Khand61b8372017-07-10 11:54:01 +01001487 case 0:
1488 {
1489 *out_value = MACRO1;
1490 }
1491 break;
1492 case 1:
1493 {
1494 *out_value = MACRO2;
1495 }
1496 break;'''
Azim Khan599cd242017-07-06 17:34:27 +01001497 self.assertEqual(dep_check_code, expected_dep_check_code)
1498 self.assertEqual(out_data_f.getvalue(), expecrted_data)
1499 self.assertEqual(expression_code, expected_expression_code)
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001500
1501
Azim Khan4b543232017-06-30 09:35:21 +01001502if __name__=='__main__':
Azim Khan5e2ac1f2017-07-03 13:58:20 +01001503 unittest_main()