test_generate_test_code.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699
  1. #!/usr/bin/env python3
  2. # Unit test for generate_test_code.py
  3. #
  4. # Copyright The Mbed TLS Contributors
  5. # SPDX-License-Identifier: Apache-2.0
  6. #
  7. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. # not use this file except in compliance with the License.
  9. # You may obtain a copy of the License at
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. # See the License for the specific language governing permissions and
  17. # limitations under the License.
  18. """
  19. Unit tests for generate_test_code.py
  20. """
  21. from io import StringIO
  22. from unittest import TestCase, main as unittest_main
  23. from unittest.mock import patch
  24. from generate_test_code import gen_dependencies, gen_dependencies_one_line
  25. from generate_test_code import gen_function_wrapper, gen_dispatch
  26. from generate_test_code import parse_until_pattern, GeneratorInputError
  27. from generate_test_code import parse_suite_dependencies
  28. from generate_test_code import parse_function_dependencies
  29. from generate_test_code import parse_function_arguments, parse_function_code
  30. from generate_test_code import parse_functions, END_HEADER_REGEX
  31. from generate_test_code import END_SUITE_HELPERS_REGEX, escaped_split
  32. from generate_test_code import parse_test_data, gen_dep_check
  33. from generate_test_code import gen_expression_check, write_dependencies
  34. from generate_test_code import write_parameters, gen_suite_dep_checks
  35. from generate_test_code import gen_from_test_data
  36. class GenDep(TestCase):
  37. """
  38. Test suite for function gen_dep()
  39. """
  40. def test_dependencies_list(self):
  41. """
  42. Test that gen_dep() correctly creates dependencies for given
  43. dependency list.
  44. :return:
  45. """
  46. dependencies = ['DEP1', 'DEP2']
  47. dep_start, dep_end = gen_dependencies(dependencies)
  48. preprocessor1, preprocessor2 = dep_start.splitlines()
  49. endif1, endif2 = dep_end.splitlines()
  50. self.assertEqual(preprocessor1, '#if defined(DEP1)',
  51. 'Preprocessor generated incorrectly')
  52. self.assertEqual(preprocessor2, '#if defined(DEP2)',
  53. 'Preprocessor generated incorrectly')
  54. self.assertEqual(endif1, '#endif /* DEP2 */',
  55. 'Preprocessor generated incorrectly')
  56. self.assertEqual(endif2, '#endif /* DEP1 */',
  57. 'Preprocessor generated incorrectly')
  58. def test_disabled_dependencies_list(self):
  59. """
  60. Test that gen_dep() correctly creates dependencies for given
  61. dependency list.
  62. :return:
  63. """
  64. dependencies = ['!DEP1', '!DEP2']
  65. dep_start, dep_end = gen_dependencies(dependencies)
  66. preprocessor1, preprocessor2 = dep_start.splitlines()
  67. endif1, endif2 = dep_end.splitlines()
  68. self.assertEqual(preprocessor1, '#if !defined(DEP1)',
  69. 'Preprocessor generated incorrectly')
  70. self.assertEqual(preprocessor2, '#if !defined(DEP2)',
  71. 'Preprocessor generated incorrectly')
  72. self.assertEqual(endif1, '#endif /* !DEP2 */',
  73. 'Preprocessor generated incorrectly')
  74. self.assertEqual(endif2, '#endif /* !DEP1 */',
  75. 'Preprocessor generated incorrectly')
  76. def test_mixed_dependencies_list(self):
  77. """
  78. Test that gen_dep() correctly creates dependencies for given
  79. dependency list.
  80. :return:
  81. """
  82. dependencies = ['!DEP1', 'DEP2']
  83. dep_start, dep_end = gen_dependencies(dependencies)
  84. preprocessor1, preprocessor2 = dep_start.splitlines()
  85. endif1, endif2 = dep_end.splitlines()
  86. self.assertEqual(preprocessor1, '#if !defined(DEP1)',
  87. 'Preprocessor generated incorrectly')
  88. self.assertEqual(preprocessor2, '#if defined(DEP2)',
  89. 'Preprocessor generated incorrectly')
  90. self.assertEqual(endif1, '#endif /* DEP2 */',
  91. 'Preprocessor generated incorrectly')
  92. self.assertEqual(endif2, '#endif /* !DEP1 */',
  93. 'Preprocessor generated incorrectly')
  94. def test_empty_dependencies_list(self):
  95. """
  96. Test that gen_dep() correctly creates dependencies for given
  97. dependency list.
  98. :return:
  99. """
  100. dependencies = []
  101. dep_start, dep_end = gen_dependencies(dependencies)
  102. self.assertEqual(dep_start, '', 'Preprocessor generated incorrectly')
  103. self.assertEqual(dep_end, '', 'Preprocessor generated incorrectly')
  104. def test_large_dependencies_list(self):
  105. """
  106. Test that gen_dep() correctly creates dependencies for given
  107. dependency list.
  108. :return:
  109. """
  110. dependencies = []
  111. count = 10
  112. for i in range(count):
  113. dependencies.append('DEP%d' % i)
  114. dep_start, dep_end = gen_dependencies(dependencies)
  115. self.assertEqual(len(dep_start.splitlines()), count,
  116. 'Preprocessor generated incorrectly')
  117. self.assertEqual(len(dep_end.splitlines()), count,
  118. 'Preprocessor generated incorrectly')
  119. class GenDepOneLine(TestCase):
  120. """
  121. Test Suite for testing gen_dependencies_one_line()
  122. """
  123. def test_dependencies_list(self):
  124. """
  125. Test that gen_dep() correctly creates dependencies for given
  126. dependency list.
  127. :return:
  128. """
  129. dependencies = ['DEP1', 'DEP2']
  130. dep_str = gen_dependencies_one_line(dependencies)
  131. self.assertEqual(dep_str, '#if defined(DEP1) && defined(DEP2)',
  132. 'Preprocessor generated incorrectly')
  133. def test_disabled_dependencies_list(self):
  134. """
  135. Test that gen_dep() correctly creates dependencies for given
  136. dependency list.
  137. :return:
  138. """
  139. dependencies = ['!DEP1', '!DEP2']
  140. dep_str = gen_dependencies_one_line(dependencies)
  141. self.assertEqual(dep_str, '#if !defined(DEP1) && !defined(DEP2)',
  142. 'Preprocessor generated incorrectly')
  143. def test_mixed_dependencies_list(self):
  144. """
  145. Test that gen_dep() correctly creates dependencies for given
  146. dependency list.
  147. :return:
  148. """
  149. dependencies = ['!DEP1', 'DEP2']
  150. dep_str = gen_dependencies_one_line(dependencies)
  151. self.assertEqual(dep_str, '#if !defined(DEP1) && defined(DEP2)',
  152. 'Preprocessor generated incorrectly')
  153. def test_empty_dependencies_list(self):
  154. """
  155. Test that gen_dep() correctly creates dependencies for given
  156. dependency list.
  157. :return:
  158. """
  159. dependencies = []
  160. dep_str = gen_dependencies_one_line(dependencies)
  161. self.assertEqual(dep_str, '', 'Preprocessor generated incorrectly')
  162. def test_large_dependencies_list(self):
  163. """
  164. Test that gen_dep() correctly creates dependencies for given
  165. dependency list.
  166. :return:
  167. """
  168. dependencies = []
  169. count = 10
  170. for i in range(count):
  171. dependencies.append('DEP%d' % i)
  172. dep_str = gen_dependencies_one_line(dependencies)
  173. expected = '#if ' + ' && '.join(['defined(%s)' %
  174. x for x in dependencies])
  175. self.assertEqual(dep_str, expected,
  176. 'Preprocessor generated incorrectly')
  177. class GenFunctionWrapper(TestCase):
  178. """
  179. Test Suite for testing gen_function_wrapper()
  180. """
  181. def test_params_unpack(self):
  182. """
  183. Test that params are properly unpacked in the function call.
  184. :return:
  185. """
  186. code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
  187. expected = '''
  188. void test_a_wrapper( void ** params )
  189. {
  190. test_a( a, b, c, d );
  191. }
  192. '''
  193. self.assertEqual(code, expected)
  194. def test_local(self):
  195. """
  196. Test that params are properly unpacked in the function call.
  197. :return:
  198. """
  199. code = gen_function_wrapper('test_a',
  200. 'int x = 1;', ('x', 'b', 'c', 'd'))
  201. expected = '''
  202. void test_a_wrapper( void ** params )
  203. {
  204. int x = 1;
  205. test_a( x, b, c, d );
  206. }
  207. '''
  208. self.assertEqual(code, expected)
  209. def test_empty_params(self):
  210. """
  211. Test that params are properly unpacked in the function call.
  212. :return:
  213. """
  214. code = gen_function_wrapper('test_a', '', ())
  215. expected = '''
  216. void test_a_wrapper( void ** params )
  217. {
  218. (void)params;
  219. test_a( );
  220. }
  221. '''
  222. self.assertEqual(code, expected)
  223. class GenDispatch(TestCase):
  224. """
  225. Test suite for testing gen_dispatch()
  226. """
  227. def test_dispatch(self):
  228. """
  229. Test that dispatch table entry is generated correctly.
  230. :return:
  231. """
  232. code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
  233. expected = '''
  234. #if defined(DEP1) && defined(DEP2)
  235. test_a_wrapper,
  236. #else
  237. NULL,
  238. #endif
  239. '''
  240. self.assertEqual(code, expected)
  241. def test_empty_dependencies(self):
  242. """
  243. Test empty dependency list.
  244. :return:
  245. """
  246. code = gen_dispatch('test_a', [])
  247. expected = '''
  248. test_a_wrapper,
  249. '''
  250. self.assertEqual(code, expected)
  251. class StringIOWrapper(StringIO):
  252. """
  253. file like class to mock file object in tests.
  254. """
  255. def __init__(self, file_name, data, line_no=0):
  256. """
  257. Init file handle.
  258. :param file_name:
  259. :param data:
  260. :param line_no:
  261. """
  262. super(StringIOWrapper, self).__init__(data)
  263. self.line_no = line_no
  264. self.name = file_name
  265. def next(self):
  266. """
  267. Iterator method. This method overrides base class's
  268. next method and extends the next method to count the line
  269. numbers as each line is read.
  270. :return: Line read from file.
  271. """
  272. parent = super(StringIOWrapper, self)
  273. line = parent.__next__()
  274. return line
  275. def readline(self, _length=0):
  276. """
  277. Wrap the base class readline.
  278. :param length:
  279. :return:
  280. """
  281. line = super(StringIOWrapper, self).readline()
  282. if line is not None:
  283. self.line_no += 1
  284. return line
  285. class ParseUntilPattern(TestCase):
  286. """
  287. Test Suite for testing parse_until_pattern().
  288. """
  289. def test_suite_headers(self):
  290. """
  291. Test that suite headers are parsed correctly.
  292. :return:
  293. """
  294. data = '''#include "mbedtls/ecp.h"
  295. #define ECP_PF_UNKNOWN -1
  296. /* END_HEADER */
  297. '''
  298. expected = '''#line 1 "test_suite_ut.function"
  299. #include "mbedtls/ecp.h"
  300. #define ECP_PF_UNKNOWN -1
  301. '''
  302. stream = StringIOWrapper('test_suite_ut.function', data, line_no=0)
  303. headers = parse_until_pattern(stream, END_HEADER_REGEX)
  304. self.assertEqual(headers, expected)
  305. def test_line_no(self):
  306. """
  307. Test that #line is set to correct line no. in source .function file.
  308. :return:
  309. """
  310. data = '''#include "mbedtls/ecp.h"
  311. #define ECP_PF_UNKNOWN -1
  312. /* END_HEADER */
  313. '''
  314. offset_line_no = 5
  315. expected = '''#line %d "test_suite_ut.function"
  316. #include "mbedtls/ecp.h"
  317. #define ECP_PF_UNKNOWN -1
  318. ''' % (offset_line_no + 1)
  319. stream = StringIOWrapper('test_suite_ut.function', data,
  320. offset_line_no)
  321. headers = parse_until_pattern(stream, END_HEADER_REGEX)
  322. self.assertEqual(headers, expected)
  323. def test_no_end_header_comment(self):
  324. """
  325. Test that InvalidFileFormat is raised when end header comment is
  326. missing.
  327. :return:
  328. """
  329. data = '''#include "mbedtls/ecp.h"
  330. #define ECP_PF_UNKNOWN -1
  331. '''
  332. stream = StringIOWrapper('test_suite_ut.function', data)
  333. self.assertRaises(GeneratorInputError, parse_until_pattern, stream,
  334. END_HEADER_REGEX)
  335. class ParseSuiteDependencies(TestCase):
  336. """
  337. Test Suite for testing parse_suite_dependencies().
  338. """
  339. def test_suite_dependencies(self):
  340. """
  341. :return:
  342. """
  343. data = '''
  344. * depends_on:MBEDTLS_ECP_C
  345. * END_DEPENDENCIES
  346. */
  347. '''
  348. expected = ['MBEDTLS_ECP_C']
  349. stream = StringIOWrapper('test_suite_ut.function', data)
  350. dependencies = parse_suite_dependencies(stream)
  351. self.assertEqual(dependencies, expected)
  352. def test_no_end_dep_comment(self):
  353. """
  354. Test that InvalidFileFormat is raised when end dep comment is missing.
  355. :return:
  356. """
  357. data = '''
  358. * depends_on:MBEDTLS_ECP_C
  359. '''
  360. stream = StringIOWrapper('test_suite_ut.function', data)
  361. self.assertRaises(GeneratorInputError, parse_suite_dependencies,
  362. stream)
  363. def test_dependencies_split(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:A:B: C : D :F : G: !H
  370. * END_DEPENDENCIES
  371. */
  372. '''
  373. expected = ['MBEDTLS_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
  374. stream = StringIOWrapper('test_suite_ut.function', data)
  375. dependencies = parse_suite_dependencies(stream)
  376. self.assertEqual(dependencies, expected)
  377. class ParseFuncDependencies(TestCase):
  378. """
  379. Test Suite for testing parse_function_dependencies()
  380. """
  381. def test_function_dependencies(self):
  382. """
  383. Test that parse_function_dependencies() correctly parses function
  384. dependencies.
  385. :return:
  386. """
  387. line = '/* BEGIN_CASE ' \
  388. 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */'
  389. expected = ['MBEDTLS_ENTROPY_NV_SEED', 'MBEDTLS_FS_IO']
  390. dependencies = parse_function_dependencies(line)
  391. self.assertEqual(dependencies, expected)
  392. def test_no_dependencies(self):
  393. """
  394. Test that parse_function_dependencies() correctly parses function
  395. dependencies.
  396. :return:
  397. """
  398. line = '/* BEGIN_CASE */'
  399. dependencies = parse_function_dependencies(line)
  400. self.assertEqual(dependencies, [])
  401. def test_tolerance(self):
  402. """
  403. Test that parse_function_dependencies() correctly parses function
  404. dependencies.
  405. :return:
  406. """
  407. line = '/* BEGIN_CASE depends_on:MBEDTLS_FS_IO: A : !B:C : F*/'
  408. dependencies = parse_function_dependencies(line)
  409. self.assertEqual(dependencies, ['MBEDTLS_FS_IO', 'A', '!B', 'C', 'F'])
  410. class ParseFuncSignature(TestCase):
  411. """
  412. Test Suite for parse_function_arguments().
  413. """
  414. def test_int_and_char_params(self):
  415. """
  416. Test int and char parameters parsing
  417. :return:
  418. """
  419. line = 'void entropy_threshold( char * a, int b, int result )'
  420. args, local, arg_dispatch = parse_function_arguments(line)
  421. self.assertEqual(args, ['char*', 'int', 'int'])
  422. self.assertEqual(local, '')
  423. self.assertEqual(arg_dispatch, ['(char *) params[0]',
  424. '*( (int *) params[1] )',
  425. '*( (int *) params[2] )'])
  426. def test_hex_params(self):
  427. """
  428. Test hex parameters parsing
  429. :return:
  430. """
  431. line = 'void entropy_threshold( char * a, data_t * h, int result )'
  432. args, local, arg_dispatch = parse_function_arguments(line)
  433. self.assertEqual(args, ['char*', 'hex', 'int'])
  434. self.assertEqual(local,
  435. ' data_t data1 = {(uint8_t *) params[1], '
  436. '*( (uint32_t *) params[2] )};\n')
  437. self.assertEqual(arg_dispatch, ['(char *) params[0]',
  438. '&data1',
  439. '*( (int *) params[3] )'])
  440. def test_unsupported_arg(self):
  441. """
  442. Test unsupported arguments (not among int, char * and data_t)
  443. :return:
  444. """
  445. line = 'void entropy_threshold( char * a, data_t * h, char result )'
  446. self.assertRaises(ValueError, parse_function_arguments, line)
  447. def test_no_params(self):
  448. """
  449. Test no parameters.
  450. :return:
  451. """
  452. line = 'void entropy_threshold()'
  453. args, local, arg_dispatch = parse_function_arguments(line)
  454. self.assertEqual(args, [])
  455. self.assertEqual(local, '')
  456. self.assertEqual(arg_dispatch, [])
  457. class ParseFunctionCode(TestCase):
  458. """
  459. Test suite for testing parse_function_code()
  460. """
  461. def test_no_function(self):
  462. """
  463. Test no test function found.
  464. :return:
  465. """
  466. data = '''
  467. No
  468. test
  469. function
  470. '''
  471. stream = StringIOWrapper('test_suite_ut.function', data)
  472. err_msg = 'file: test_suite_ut.function - Test functions not found!'
  473. self.assertRaisesRegex(GeneratorInputError, err_msg,
  474. parse_function_code, stream, [], [])
  475. def test_no_end_case_comment(self):
  476. """
  477. Test missing end case.
  478. :return:
  479. """
  480. data = '''
  481. void test_func()
  482. {
  483. }
  484. '''
  485. stream = StringIOWrapper('test_suite_ut.function', data)
  486. err_msg = r'file: test_suite_ut.function - '\
  487. 'end case pattern .*? not found!'
  488. self.assertRaisesRegex(GeneratorInputError, err_msg,
  489. parse_function_code, stream, [], [])
  490. @patch("generate_test_code.parse_function_arguments")
  491. def test_function_called(self,
  492. parse_function_arguments_mock):
  493. """
  494. Test parse_function_code()
  495. :return:
  496. """
  497. parse_function_arguments_mock.return_value = ([], '', [])
  498. data = '''
  499. void test_func()
  500. {
  501. }
  502. '''
  503. stream = StringIOWrapper('test_suite_ut.function', data)
  504. self.assertRaises(GeneratorInputError, parse_function_code,
  505. stream, [], [])
  506. self.assertTrue(parse_function_arguments_mock.called)
  507. parse_function_arguments_mock.assert_called_with('void test_func()\n')
  508. @patch("generate_test_code.gen_dispatch")
  509. @patch("generate_test_code.gen_dependencies")
  510. @patch("generate_test_code.gen_function_wrapper")
  511. @patch("generate_test_code.parse_function_arguments")
  512. def test_return(self, parse_function_arguments_mock,
  513. gen_function_wrapper_mock,
  514. gen_dependencies_mock,
  515. gen_dispatch_mock):
  516. """
  517. Test generated code.
  518. :return:
  519. """
  520. parse_function_arguments_mock.return_value = ([], '', [])
  521. gen_function_wrapper_mock.return_value = ''
  522. gen_dependencies_mock.side_effect = gen_dependencies
  523. gen_dispatch_mock.side_effect = gen_dispatch
  524. data = '''
  525. void func()
  526. {
  527. ba ba black sheep
  528. have you any wool
  529. }
  530. /* END_CASE */
  531. '''
  532. stream = StringIOWrapper('test_suite_ut.function', data)
  533. name, arg, code, dispatch_code = parse_function_code(stream, [], [])
  534. self.assertTrue(parse_function_arguments_mock.called)
  535. parse_function_arguments_mock.assert_called_with('void func()\n')
  536. gen_function_wrapper_mock.assert_called_with('test_func', '', [])
  537. self.assertEqual(name, 'test_func')
  538. self.assertEqual(arg, [])
  539. expected = '''#line 1 "test_suite_ut.function"
  540. void test_func()
  541. {
  542. ba ba black sheep
  543. have you any wool
  544. exit:
  545. ;
  546. }
  547. '''
  548. self.assertEqual(code, expected)
  549. self.assertEqual(dispatch_code, "\n test_func_wrapper,\n")
  550. @patch("generate_test_code.gen_dispatch")
  551. @patch("generate_test_code.gen_dependencies")
  552. @patch("generate_test_code.gen_function_wrapper")
  553. @patch("generate_test_code.parse_function_arguments")
  554. def test_with_exit_label(self, parse_function_arguments_mock,
  555. gen_function_wrapper_mock,
  556. gen_dependencies_mock,
  557. gen_dispatch_mock):
  558. """
  559. Test when exit label is present.
  560. :return:
  561. """
  562. parse_function_arguments_mock.return_value = ([], '', [])
  563. gen_function_wrapper_mock.return_value = ''
  564. gen_dependencies_mock.side_effect = gen_dependencies
  565. gen_dispatch_mock.side_effect = gen_dispatch
  566. data = '''
  567. void func()
  568. {
  569. ba ba black sheep
  570. have you any wool
  571. exit:
  572. yes sir yes sir
  573. 3 bags full
  574. }
  575. /* END_CASE */
  576. '''
  577. stream = StringIOWrapper('test_suite_ut.function', data)
  578. _, _, code, _ = parse_function_code(stream, [], [])
  579. expected = '''#line 1 "test_suite_ut.function"
  580. void test_func()
  581. {
  582. ba ba black sheep
  583. have you any wool
  584. exit:
  585. yes sir yes sir
  586. 3 bags full
  587. }
  588. '''
  589. self.assertEqual(code, expected)
  590. def test_non_void_function(self):
  591. """
  592. Test invalid signature (non void).
  593. :return:
  594. """
  595. data = 'int entropy_threshold( char * a, data_t * h, int result )'
  596. err_msg = 'file: test_suite_ut.function - Test functions not found!'
  597. stream = StringIOWrapper('test_suite_ut.function', data)
  598. self.assertRaisesRegex(GeneratorInputError, err_msg,
  599. parse_function_code, stream, [], [])
  600. @patch("generate_test_code.gen_dispatch")
  601. @patch("generate_test_code.gen_dependencies")
  602. @patch("generate_test_code.gen_function_wrapper")
  603. @patch("generate_test_code.parse_function_arguments")
  604. def test_functio_name_on_newline(self, parse_function_arguments_mock,
  605. gen_function_wrapper_mock,
  606. gen_dependencies_mock,
  607. gen_dispatch_mock):
  608. """
  609. Test when exit label is present.
  610. :return:
  611. """
  612. parse_function_arguments_mock.return_value = ([], '', [])
  613. gen_function_wrapper_mock.return_value = ''
  614. gen_dependencies_mock.side_effect = gen_dependencies
  615. gen_dispatch_mock.side_effect = gen_dispatch
  616. data = '''
  617. void
  618. func()
  619. {
  620. ba ba black sheep
  621. have you any wool
  622. exit:
  623. yes sir yes sir
  624. 3 bags full
  625. }
  626. /* END_CASE */
  627. '''
  628. stream = StringIOWrapper('test_suite_ut.function', data)
  629. _, _, code, _ = parse_function_code(stream, [], [])
  630. expected = '''#line 1 "test_suite_ut.function"
  631. void
  632. test_func()
  633. {
  634. ba ba black sheep
  635. have you any wool
  636. exit:
  637. yes sir yes sir
  638. 3 bags full
  639. }
  640. '''
  641. self.assertEqual(code, expected)
  642. class ParseFunction(TestCase):
  643. """
  644. Test Suite for testing parse_functions()
  645. """
  646. @patch("generate_test_code.parse_until_pattern")
  647. def test_begin_header(self, parse_until_pattern_mock):
  648. """
  649. Test that begin header is checked and parse_until_pattern() is called.
  650. :return:
  651. """
  652. def stop(*_unused):
  653. """Stop when parse_until_pattern is called."""
  654. raise Exception
  655. parse_until_pattern_mock.side_effect = stop
  656. data = '''/* BEGIN_HEADER */
  657. #include "mbedtls/ecp.h"
  658. #define ECP_PF_UNKNOWN -1
  659. /* END_HEADER */
  660. '''
  661. stream = StringIOWrapper('test_suite_ut.function', data)
  662. self.assertRaises(Exception, parse_functions, stream)
  663. parse_until_pattern_mock.assert_called_with(stream, END_HEADER_REGEX)
  664. self.assertEqual(stream.line_no, 1)
  665. @patch("generate_test_code.parse_until_pattern")
  666. def test_begin_helper(self, parse_until_pattern_mock):
  667. """
  668. Test that begin helper is checked and parse_until_pattern() is called.
  669. :return:
  670. """
  671. def stop(*_unused):
  672. """Stop when parse_until_pattern is called."""
  673. raise Exception
  674. parse_until_pattern_mock.side_effect = stop
  675. data = '''/* BEGIN_SUITE_HELPERS */
  676. void print_hello_world()
  677. {
  678. printf("Hello World!\n");
  679. }
  680. /* END_SUITE_HELPERS */
  681. '''
  682. stream = StringIOWrapper('test_suite_ut.function', data)
  683. self.assertRaises(Exception, parse_functions, stream)
  684. parse_until_pattern_mock.assert_called_with(stream,
  685. END_SUITE_HELPERS_REGEX)
  686. self.assertEqual(stream.line_no, 1)
  687. @patch("generate_test_code.parse_suite_dependencies")
  688. def test_begin_dep(self, parse_suite_dependencies_mock):
  689. """
  690. Test that begin dep is checked and parse_suite_dependencies() is
  691. called.
  692. :return:
  693. """
  694. def stop(*_unused):
  695. """Stop when parse_until_pattern is called."""
  696. raise Exception
  697. parse_suite_dependencies_mock.side_effect = stop
  698. data = '''/* BEGIN_DEPENDENCIES
  699. * depends_on:MBEDTLS_ECP_C
  700. * END_DEPENDENCIES
  701. */
  702. '''
  703. stream = StringIOWrapper('test_suite_ut.function', data)
  704. self.assertRaises(Exception, parse_functions, stream)
  705. parse_suite_dependencies_mock.assert_called_with(stream)
  706. self.assertEqual(stream.line_no, 1)
  707. @patch("generate_test_code.parse_function_dependencies")
  708. def test_begin_function_dep(self, func_mock):
  709. """
  710. Test that begin dep is checked and parse_function_dependencies() is
  711. called.
  712. :return:
  713. """
  714. def stop(*_unused):
  715. """Stop when parse_until_pattern is called."""
  716. raise Exception
  717. func_mock.side_effect = stop
  718. dependencies_str = '/* BEGIN_CASE ' \
  719. 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
  720. data = '''%svoid test_func()
  721. {
  722. }
  723. ''' % dependencies_str
  724. stream = StringIOWrapper('test_suite_ut.function', data)
  725. self.assertRaises(Exception, parse_functions, stream)
  726. func_mock.assert_called_with(dependencies_str)
  727. self.assertEqual(stream.line_no, 1)
  728. @patch("generate_test_code.parse_function_code")
  729. @patch("generate_test_code.parse_function_dependencies")
  730. def test_return(self, func_mock1, func_mock2):
  731. """
  732. Test that begin case is checked and parse_function_code() is called.
  733. :return:
  734. """
  735. func_mock1.return_value = []
  736. in_func_code = '''void test_func()
  737. {
  738. }
  739. '''
  740. func_dispatch = '''
  741. test_func_wrapper,
  742. '''
  743. func_mock2.return_value = 'test_func', [],\
  744. in_func_code, func_dispatch
  745. dependencies_str = '/* BEGIN_CASE ' \
  746. 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
  747. data = '''%svoid test_func()
  748. {
  749. }
  750. ''' % dependencies_str
  751. stream = StringIOWrapper('test_suite_ut.function', data)
  752. suite_dependencies, dispatch_code, func_code, func_info = \
  753. parse_functions(stream)
  754. func_mock1.assert_called_with(dependencies_str)
  755. func_mock2.assert_called_with(stream, [], [])
  756. self.assertEqual(stream.line_no, 5)
  757. self.assertEqual(suite_dependencies, [])
  758. expected_dispatch_code = '''/* Function Id: 0 */
  759. test_func_wrapper,
  760. '''
  761. self.assertEqual(dispatch_code, expected_dispatch_code)
  762. self.assertEqual(func_code, in_func_code)
  763. self.assertEqual(func_info, {'test_func': (0, [])})
  764. def test_parsing(self):
  765. """
  766. Test case parsing.
  767. :return:
  768. """
  769. data = '''/* BEGIN_HEADER */
  770. #include "mbedtls/ecp.h"
  771. #define ECP_PF_UNKNOWN -1
  772. /* END_HEADER */
  773. /* BEGIN_DEPENDENCIES
  774. * depends_on:MBEDTLS_ECP_C
  775. * END_DEPENDENCIES
  776. */
  777. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  778. void func1()
  779. {
  780. }
  781. /* END_CASE */
  782. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  783. void func2()
  784. {
  785. }
  786. /* END_CASE */
  787. '''
  788. stream = StringIOWrapper('test_suite_ut.function', data)
  789. suite_dependencies, dispatch_code, func_code, func_info = \
  790. parse_functions(stream)
  791. self.assertEqual(stream.line_no, 23)
  792. self.assertEqual(suite_dependencies, ['MBEDTLS_ECP_C'])
  793. expected_dispatch_code = '''/* Function Id: 0 */
  794. #if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
  795. test_func1_wrapper,
  796. #else
  797. NULL,
  798. #endif
  799. /* Function Id: 1 */
  800. #if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
  801. test_func2_wrapper,
  802. #else
  803. NULL,
  804. #endif
  805. '''
  806. self.assertEqual(dispatch_code, expected_dispatch_code)
  807. expected_func_code = '''#if defined(MBEDTLS_ECP_C)
  808. #line 2 "test_suite_ut.function"
  809. #include "mbedtls/ecp.h"
  810. #define ECP_PF_UNKNOWN -1
  811. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  812. #if defined(MBEDTLS_FS_IO)
  813. #line 13 "test_suite_ut.function"
  814. void test_func1()
  815. {
  816. exit:
  817. ;
  818. }
  819. void test_func1_wrapper( void ** params )
  820. {
  821. (void)params;
  822. test_func1( );
  823. }
  824. #endif /* MBEDTLS_FS_IO */
  825. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  826. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  827. #if defined(MBEDTLS_FS_IO)
  828. #line 19 "test_suite_ut.function"
  829. void test_func2()
  830. {
  831. exit:
  832. ;
  833. }
  834. void test_func2_wrapper( void ** params )
  835. {
  836. (void)params;
  837. test_func2( );
  838. }
  839. #endif /* MBEDTLS_FS_IO */
  840. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  841. #endif /* MBEDTLS_ECP_C */
  842. '''
  843. self.assertEqual(func_code, expected_func_code)
  844. self.assertEqual(func_info, {'test_func1': (0, []),
  845. 'test_func2': (1, [])})
  846. def test_same_function_name(self):
  847. """
  848. Test name conflict.
  849. :return:
  850. """
  851. data = '''/* BEGIN_HEADER */
  852. #include "mbedtls/ecp.h"
  853. #define ECP_PF_UNKNOWN -1
  854. /* END_HEADER */
  855. /* BEGIN_DEPENDENCIES
  856. * depends_on:MBEDTLS_ECP_C
  857. * END_DEPENDENCIES
  858. */
  859. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  860. void func()
  861. {
  862. }
  863. /* END_CASE */
  864. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  865. void func()
  866. {
  867. }
  868. /* END_CASE */
  869. '''
  870. stream = StringIOWrapper('test_suite_ut.function', data)
  871. self.assertRaises(GeneratorInputError, parse_functions, stream)
  872. class EscapedSplit(TestCase):
  873. """
  874. Test suite for testing escaped_split().
  875. Note: Since escaped_split() output is used to write back to the
  876. intermediate data file. Any escape characters in the input are
  877. retained in the output.
  878. """
  879. def test_invalid_input(self):
  880. """
  881. Test when input split character is not a character.
  882. :return:
  883. """
  884. self.assertRaises(ValueError, escaped_split, '', 'string')
  885. def test_empty_string(self):
  886. """
  887. Test empty string input.
  888. :return:
  889. """
  890. splits = escaped_split('', ':')
  891. self.assertEqual(splits, [])
  892. def test_no_escape(self):
  893. """
  894. Test with no escape character. The behaviour should be same as
  895. str.split()
  896. :return:
  897. """
  898. test_str = 'yahoo:google'
  899. splits = escaped_split(test_str, ':')
  900. self.assertEqual(splits, test_str.split(':'))
  901. def test_escaped_input(self):
  902. """
  903. Test input that has escaped delimiter.
  904. :return:
  905. """
  906. test_str = r'yahoo\:google:facebook'
  907. splits = escaped_split(test_str, ':')
  908. self.assertEqual(splits, [r'yahoo\:google', 'facebook'])
  909. def test_escaped_escape(self):
  910. """
  911. Test input that has escaped delimiter.
  912. :return:
  913. """
  914. test_str = r'yahoo\\:google:facebook'
  915. splits = escaped_split(test_str, ':')
  916. self.assertEqual(splits, [r'yahoo\\', 'google', 'facebook'])
  917. def test_all_at_once(self):
  918. """
  919. Test input that has escaped delimiter.
  920. :return:
  921. """
  922. test_str = r'yahoo\\:google:facebook\:instagram\\:bbc\\:wikipedia'
  923. splits = escaped_split(test_str, ':')
  924. self.assertEqual(splits, [r'yahoo\\', r'google',
  925. r'facebook\:instagram\\',
  926. r'bbc\\', r'wikipedia'])
  927. class ParseTestData(TestCase):
  928. """
  929. Test suite for parse test data.
  930. """
  931. def test_parser(self):
  932. """
  933. Test that tests are parsed correctly from data file.
  934. :return:
  935. """
  936. data = """
  937. Diffie-Hellman full exchange #1
  938. dhm_do_dhm:10:"23":10:"5"
  939. Diffie-Hellman full exchange #2
  940. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  941. Diffie-Hellman full exchange #3
  942. dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
  943. Diffie-Hellman selftest
  944. dhm_selftest:
  945. """
  946. stream = StringIOWrapper('test_suite_ut.function', data)
  947. # List of (name, function_name, dependencies, args)
  948. tests = list(parse_test_data(stream))
  949. test1, test2, test3, test4 = tests
  950. self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
  951. self.assertEqual(test1[1], 'dhm_do_dhm')
  952. self.assertEqual(test1[2], [])
  953. self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
  954. self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
  955. self.assertEqual(test2[1], 'dhm_do_dhm')
  956. self.assertEqual(test2[2], [])
  957. self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
  958. '10', '"9345098304850938450983409622"'])
  959. self.assertEqual(test3[0], 'Diffie-Hellman full exchange #3')
  960. self.assertEqual(test3[1], 'dhm_do_dhm')
  961. self.assertEqual(test3[2], [])
  962. self.assertEqual(test3[3], ['10',
  963. '"9345098382739712938719287391879381271"',
  964. '10',
  965. '"9345098792137312973297123912791271"'])
  966. self.assertEqual(test4[0], 'Diffie-Hellman selftest')
  967. self.assertEqual(test4[1], 'dhm_selftest')
  968. self.assertEqual(test4[2], [])
  969. self.assertEqual(test4[3], [])
  970. def test_with_dependencies(self):
  971. """
  972. Test that tests with dependencies are parsed.
  973. :return:
  974. """
  975. data = """
  976. Diffie-Hellman full exchange #1
  977. depends_on:YAHOO
  978. dhm_do_dhm:10:"23":10:"5"
  979. Diffie-Hellman full exchange #2
  980. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  981. """
  982. stream = StringIOWrapper('test_suite_ut.function', data)
  983. # List of (name, function_name, dependencies, args)
  984. tests = list(parse_test_data(stream))
  985. test1, test2 = tests
  986. self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
  987. self.assertEqual(test1[1], 'dhm_do_dhm')
  988. self.assertEqual(test1[2], ['YAHOO'])
  989. self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
  990. self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
  991. self.assertEqual(test2[1], 'dhm_do_dhm')
  992. self.assertEqual(test2[2], [])
  993. self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
  994. '10', '"9345098304850938450983409622"'])
  995. def test_no_args(self):
  996. """
  997. Test GeneratorInputError is raised when test function name and
  998. args line is missing.
  999. :return:
  1000. """
  1001. data = """
  1002. Diffie-Hellman full exchange #1
  1003. depends_on:YAHOO
  1004. Diffie-Hellman full exchange #2
  1005. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  1006. """
  1007. stream = StringIOWrapper('test_suite_ut.function', data)
  1008. err = None
  1009. try:
  1010. for _, _, _, _ in parse_test_data(stream):
  1011. pass
  1012. except GeneratorInputError as err:
  1013. self.assertEqual(type(err), GeneratorInputError)
  1014. def test_incomplete_data(self):
  1015. """
  1016. Test GeneratorInputError is raised when test function name
  1017. and args line is missing.
  1018. :return:
  1019. """
  1020. data = """
  1021. Diffie-Hellman full exchange #1
  1022. depends_on:YAHOO
  1023. """
  1024. stream = StringIOWrapper('test_suite_ut.function', data)
  1025. err = None
  1026. try:
  1027. for _, _, _, _ in parse_test_data(stream):
  1028. pass
  1029. except GeneratorInputError as err:
  1030. self.assertEqual(type(err), GeneratorInputError)
  1031. class GenDepCheck(TestCase):
  1032. """
  1033. Test suite for gen_dep_check(). It is assumed this function is
  1034. called with valid inputs.
  1035. """
  1036. def test_gen_dep_check(self):
  1037. """
  1038. Test that dependency check code generated correctly.
  1039. :return:
  1040. """
  1041. expected = """
  1042. case 5:
  1043. {
  1044. #if defined(YAHOO)
  1045. ret = DEPENDENCY_SUPPORTED;
  1046. #else
  1047. ret = DEPENDENCY_NOT_SUPPORTED;
  1048. #endif
  1049. }
  1050. break;"""
  1051. out = gen_dep_check(5, 'YAHOO')
  1052. self.assertEqual(out, expected)
  1053. def test_not_defined_dependency(self):
  1054. """
  1055. Test dependency with !.
  1056. :return:
  1057. """
  1058. expected = """
  1059. case 5:
  1060. {
  1061. #if !defined(YAHOO)
  1062. ret = DEPENDENCY_SUPPORTED;
  1063. #else
  1064. ret = DEPENDENCY_NOT_SUPPORTED;
  1065. #endif
  1066. }
  1067. break;"""
  1068. out = gen_dep_check(5, '!YAHOO')
  1069. self.assertEqual(out, expected)
  1070. def test_empty_dependency(self):
  1071. """
  1072. Test invalid dependency input.
  1073. :return:
  1074. """
  1075. self.assertRaises(GeneratorInputError, gen_dep_check, 5, '!')
  1076. def test_negative_dep_id(self):
  1077. """
  1078. Test invalid dependency input.
  1079. :return:
  1080. """
  1081. self.assertRaises(GeneratorInputError, gen_dep_check, -1, 'YAHOO')
  1082. class GenExpCheck(TestCase):
  1083. """
  1084. Test suite for gen_expression_check(). It is assumed this function
  1085. is called with valid inputs.
  1086. """
  1087. def test_gen_exp_check(self):
  1088. """
  1089. Test that expression check code generated correctly.
  1090. :return:
  1091. """
  1092. expected = """
  1093. case 5:
  1094. {
  1095. *out_value = YAHOO;
  1096. }
  1097. break;"""
  1098. out = gen_expression_check(5, 'YAHOO')
  1099. self.assertEqual(out, expected)
  1100. def test_invalid_expression(self):
  1101. """
  1102. Test invalid expression input.
  1103. :return:
  1104. """
  1105. self.assertRaises(GeneratorInputError, gen_expression_check, 5, '')
  1106. def test_negative_exp_id(self):
  1107. """
  1108. Test invalid expression id.
  1109. :return:
  1110. """
  1111. self.assertRaises(GeneratorInputError, gen_expression_check,
  1112. -1, 'YAHOO')
  1113. class WriteDependencies(TestCase):
  1114. """
  1115. Test suite for testing write_dependencies.
  1116. """
  1117. def test_no_test_dependencies(self):
  1118. """
  1119. Test when test dependencies input is empty.
  1120. :return:
  1121. """
  1122. stream = StringIOWrapper('test_suite_ut.data', '')
  1123. unique_dependencies = []
  1124. dep_check_code = write_dependencies(stream, [], unique_dependencies)
  1125. self.assertEqual(dep_check_code, '')
  1126. self.assertEqual(len(unique_dependencies), 0)
  1127. self.assertEqual(stream.getvalue(), '')
  1128. def test_unique_dep_ids(self):
  1129. """
  1130. :return:
  1131. """
  1132. stream = StringIOWrapper('test_suite_ut.data', '')
  1133. unique_dependencies = []
  1134. dep_check_code = write_dependencies(stream, ['DEP3', 'DEP2', 'DEP1'],
  1135. unique_dependencies)
  1136. expect_dep_check_code = '''
  1137. case 0:
  1138. {
  1139. #if defined(DEP3)
  1140. ret = DEPENDENCY_SUPPORTED;
  1141. #else
  1142. ret = DEPENDENCY_NOT_SUPPORTED;
  1143. #endif
  1144. }
  1145. break;
  1146. case 1:
  1147. {
  1148. #if defined(DEP2)
  1149. ret = DEPENDENCY_SUPPORTED;
  1150. #else
  1151. ret = DEPENDENCY_NOT_SUPPORTED;
  1152. #endif
  1153. }
  1154. break;
  1155. case 2:
  1156. {
  1157. #if defined(DEP1)
  1158. ret = DEPENDENCY_SUPPORTED;
  1159. #else
  1160. ret = DEPENDENCY_NOT_SUPPORTED;
  1161. #endif
  1162. }
  1163. break;'''
  1164. self.assertEqual(dep_check_code, expect_dep_check_code)
  1165. self.assertEqual(len(unique_dependencies), 3)
  1166. self.assertEqual(stream.getvalue(), 'depends_on:0:1:2\n')
  1167. def test_dep_id_repeat(self):
  1168. """
  1169. :return:
  1170. """
  1171. stream = StringIOWrapper('test_suite_ut.data', '')
  1172. unique_dependencies = []
  1173. dep_check_code = ''
  1174. dep_check_code += write_dependencies(stream, ['DEP3', 'DEP2'],
  1175. unique_dependencies)
  1176. dep_check_code += write_dependencies(stream, ['DEP2', 'DEP1'],
  1177. unique_dependencies)
  1178. dep_check_code += write_dependencies(stream, ['DEP1', 'DEP3'],
  1179. unique_dependencies)
  1180. expect_dep_check_code = '''
  1181. case 0:
  1182. {
  1183. #if defined(DEP3)
  1184. ret = DEPENDENCY_SUPPORTED;
  1185. #else
  1186. ret = DEPENDENCY_NOT_SUPPORTED;
  1187. #endif
  1188. }
  1189. break;
  1190. case 1:
  1191. {
  1192. #if defined(DEP2)
  1193. ret = DEPENDENCY_SUPPORTED;
  1194. #else
  1195. ret = DEPENDENCY_NOT_SUPPORTED;
  1196. #endif
  1197. }
  1198. break;
  1199. case 2:
  1200. {
  1201. #if defined(DEP1)
  1202. ret = DEPENDENCY_SUPPORTED;
  1203. #else
  1204. ret = DEPENDENCY_NOT_SUPPORTED;
  1205. #endif
  1206. }
  1207. break;'''
  1208. self.assertEqual(dep_check_code, expect_dep_check_code)
  1209. self.assertEqual(len(unique_dependencies), 3)
  1210. self.assertEqual(stream.getvalue(),
  1211. 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
  1212. class WriteParams(TestCase):
  1213. """
  1214. Test Suite for testing write_parameters().
  1215. """
  1216. def test_no_params(self):
  1217. """
  1218. Test with empty test_args
  1219. :return:
  1220. """
  1221. stream = StringIOWrapper('test_suite_ut.data', '')
  1222. unique_expressions = []
  1223. expression_code = write_parameters(stream, [], [], unique_expressions)
  1224. self.assertEqual(len(unique_expressions), 0)
  1225. self.assertEqual(expression_code, '')
  1226. self.assertEqual(stream.getvalue(), '\n')
  1227. def test_no_exp_param(self):
  1228. """
  1229. Test when there is no macro or expression in the params.
  1230. :return:
  1231. """
  1232. stream = StringIOWrapper('test_suite_ut.data', '')
  1233. unique_expressions = []
  1234. expression_code = write_parameters(stream, ['"Yahoo"', '"abcdef00"',
  1235. '0'],
  1236. ['char*', 'hex', 'int'],
  1237. unique_expressions)
  1238. self.assertEqual(len(unique_expressions), 0)
  1239. self.assertEqual(expression_code, '')
  1240. self.assertEqual(stream.getvalue(),
  1241. ':char*:"Yahoo":hex:"abcdef00":int:0\n')
  1242. def test_hex_format_int_param(self):
  1243. """
  1244. Test int parameter in hex format.
  1245. :return:
  1246. """
  1247. stream = StringIOWrapper('test_suite_ut.data', '')
  1248. unique_expressions = []
  1249. expression_code = write_parameters(stream,
  1250. ['"Yahoo"', '"abcdef00"', '0xAA'],
  1251. ['char*', 'hex', 'int'],
  1252. unique_expressions)
  1253. self.assertEqual(len(unique_expressions), 0)
  1254. self.assertEqual(expression_code, '')
  1255. self.assertEqual(stream.getvalue(),
  1256. ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
  1257. def test_with_exp_param(self):
  1258. """
  1259. Test when there is macro or expression in the params.
  1260. :return:
  1261. """
  1262. stream = StringIOWrapper('test_suite_ut.data', '')
  1263. unique_expressions = []
  1264. expression_code = write_parameters(stream,
  1265. ['"Yahoo"', '"abcdef00"', '0',
  1266. 'MACRO1', 'MACRO2', 'MACRO3'],
  1267. ['char*', 'hex', 'int',
  1268. 'int', 'int', 'int'],
  1269. unique_expressions)
  1270. self.assertEqual(len(unique_expressions), 3)
  1271. self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
  1272. expected_expression_code = '''
  1273. case 0:
  1274. {
  1275. *out_value = MACRO1;
  1276. }
  1277. break;
  1278. case 1:
  1279. {
  1280. *out_value = MACRO2;
  1281. }
  1282. break;
  1283. case 2:
  1284. {
  1285. *out_value = MACRO3;
  1286. }
  1287. break;'''
  1288. self.assertEqual(expression_code, expected_expression_code)
  1289. self.assertEqual(stream.getvalue(),
  1290. ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1'
  1291. ':exp:2\n')
  1292. def test_with_repeat_calls(self):
  1293. """
  1294. Test when write_parameter() is called with same macro or expression.
  1295. :return:
  1296. """
  1297. stream = StringIOWrapper('test_suite_ut.data', '')
  1298. unique_expressions = []
  1299. expression_code = ''
  1300. expression_code += write_parameters(stream,
  1301. ['"Yahoo"', 'MACRO1', 'MACRO2'],
  1302. ['char*', 'int', 'int'],
  1303. unique_expressions)
  1304. expression_code += write_parameters(stream,
  1305. ['"abcdef00"', 'MACRO2', 'MACRO3'],
  1306. ['hex', 'int', 'int'],
  1307. unique_expressions)
  1308. expression_code += write_parameters(stream,
  1309. ['0', 'MACRO3', 'MACRO1'],
  1310. ['int', 'int', 'int'],
  1311. unique_expressions)
  1312. self.assertEqual(len(unique_expressions), 3)
  1313. self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
  1314. expected_expression_code = '''
  1315. case 0:
  1316. {
  1317. *out_value = MACRO1;
  1318. }
  1319. break;
  1320. case 1:
  1321. {
  1322. *out_value = MACRO2;
  1323. }
  1324. break;
  1325. case 2:
  1326. {
  1327. *out_value = MACRO3;
  1328. }
  1329. break;'''
  1330. self.assertEqual(expression_code, expected_expression_code)
  1331. expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
  1332. :hex:"abcdef00":exp:1:exp:2
  1333. :int:0:exp:2:exp:0
  1334. '''
  1335. self.assertEqual(stream.getvalue(), expected_data_file)
  1336. class GenTestSuiteDependenciesChecks(TestCase):
  1337. """
  1338. Test suite for testing gen_suite_dep_checks()
  1339. """
  1340. def test_empty_suite_dependencies(self):
  1341. """
  1342. Test with empty suite_dependencies list.
  1343. :return:
  1344. """
  1345. dep_check_code, expression_code = \
  1346. gen_suite_dep_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
  1347. self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
  1348. self.assertEqual(expression_code, 'EXPRESSION_CODE')
  1349. def test_suite_dependencies(self):
  1350. """
  1351. Test with suite_dependencies list.
  1352. :return:
  1353. """
  1354. dep_check_code, expression_code = \
  1355. gen_suite_dep_checks(['SUITE_DEP'], 'DEP_CHECK_CODE',
  1356. 'EXPRESSION_CODE')
  1357. expected_dep_check_code = '''
  1358. #if defined(SUITE_DEP)
  1359. DEP_CHECK_CODE
  1360. #endif
  1361. '''
  1362. expected_expression_code = '''
  1363. #if defined(SUITE_DEP)
  1364. EXPRESSION_CODE
  1365. #endif
  1366. '''
  1367. self.assertEqual(dep_check_code, expected_dep_check_code)
  1368. self.assertEqual(expression_code, expected_expression_code)
  1369. def test_no_dep_no_exp(self):
  1370. """
  1371. Test when there are no dependency and expression code.
  1372. :return:
  1373. """
  1374. dep_check_code, expression_code = gen_suite_dep_checks([], '', '')
  1375. self.assertEqual(dep_check_code, '')
  1376. self.assertEqual(expression_code, '')
  1377. class GenFromTestData(TestCase):
  1378. """
  1379. Test suite for gen_from_test_data()
  1380. """
  1381. @staticmethod
  1382. @patch("generate_test_code.write_dependencies")
  1383. @patch("generate_test_code.write_parameters")
  1384. @patch("generate_test_code.gen_suite_dep_checks")
  1385. def test_intermediate_data_file(func_mock1,
  1386. write_parameters_mock,
  1387. write_dependencies_mock):
  1388. """
  1389. Test that intermediate data file is written with expected data.
  1390. :return:
  1391. """
  1392. data = '''
  1393. My test
  1394. depends_on:DEP1
  1395. func1:0
  1396. '''
  1397. data_f = StringIOWrapper('test_suite_ut.data', data)
  1398. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1399. func_info = {'test_func1': (1, ('int',))}
  1400. suite_dependencies = []
  1401. write_parameters_mock.side_effect = write_parameters
  1402. write_dependencies_mock.side_effect = write_dependencies
  1403. func_mock1.side_effect = gen_suite_dep_checks
  1404. gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies)
  1405. write_dependencies_mock.assert_called_with(out_data_f,
  1406. ['DEP1'], ['DEP1'])
  1407. write_parameters_mock.assert_called_with(out_data_f, ['0'],
  1408. ('int',), [])
  1409. expected_dep_check_code = '''
  1410. case 0:
  1411. {
  1412. #if defined(DEP1)
  1413. ret = DEPENDENCY_SUPPORTED;
  1414. #else
  1415. ret = DEPENDENCY_NOT_SUPPORTED;
  1416. #endif
  1417. }
  1418. break;'''
  1419. func_mock1.assert_called_with(
  1420. suite_dependencies, expected_dep_check_code, '')
  1421. def test_function_not_found(self):
  1422. """
  1423. Test that AssertError is raised when function info in not found.
  1424. :return:
  1425. """
  1426. data = '''
  1427. My test
  1428. depends_on:DEP1
  1429. func1:0
  1430. '''
  1431. data_f = StringIOWrapper('test_suite_ut.data', data)
  1432. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1433. func_info = {'test_func2': (1, ('int',))}
  1434. suite_dependencies = []
  1435. self.assertRaises(GeneratorInputError, gen_from_test_data,
  1436. data_f, out_data_f, func_info, suite_dependencies)
  1437. def test_different_func_args(self):
  1438. """
  1439. Test that AssertError is raised when no. of parameters and
  1440. function args differ.
  1441. :return:
  1442. """
  1443. data = '''
  1444. My test
  1445. depends_on:DEP1
  1446. func1:0
  1447. '''
  1448. data_f = StringIOWrapper('test_suite_ut.data', data)
  1449. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1450. func_info = {'test_func2': (1, ('int', 'hex'))}
  1451. suite_dependencies = []
  1452. self.assertRaises(GeneratorInputError, gen_from_test_data, data_f,
  1453. out_data_f, func_info, suite_dependencies)
  1454. def test_output(self):
  1455. """
  1456. Test that intermediate data file is written with expected data.
  1457. :return:
  1458. """
  1459. data = '''
  1460. My test 1
  1461. depends_on:DEP1
  1462. func1:0:0xfa:MACRO1:MACRO2
  1463. My test 2
  1464. depends_on:DEP1:DEP2
  1465. func2:"yahoo":88:MACRO1
  1466. '''
  1467. data_f = StringIOWrapper('test_suite_ut.data', data)
  1468. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1469. func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')),
  1470. 'test_func2': (1, ('char*', 'int', 'int'))}
  1471. suite_dependencies = []
  1472. dep_check_code, expression_code = \
  1473. gen_from_test_data(data_f, out_data_f, func_info,
  1474. suite_dependencies)
  1475. expected_dep_check_code = '''
  1476. case 0:
  1477. {
  1478. #if defined(DEP1)
  1479. ret = DEPENDENCY_SUPPORTED;
  1480. #else
  1481. ret = DEPENDENCY_NOT_SUPPORTED;
  1482. #endif
  1483. }
  1484. break;
  1485. case 1:
  1486. {
  1487. #if defined(DEP2)
  1488. ret = DEPENDENCY_SUPPORTED;
  1489. #else
  1490. ret = DEPENDENCY_NOT_SUPPORTED;
  1491. #endif
  1492. }
  1493. break;'''
  1494. expected_data = '''My test 1
  1495. depends_on:0
  1496. 0:int:0:int:0xfa:exp:0:exp:1
  1497. My test 2
  1498. depends_on:0:1
  1499. 1:char*:"yahoo":int:88:exp:0
  1500. '''
  1501. expected_expression_code = '''
  1502. case 0:
  1503. {
  1504. *out_value = MACRO1;
  1505. }
  1506. break;
  1507. case 1:
  1508. {
  1509. *out_value = MACRO2;
  1510. }
  1511. break;'''
  1512. self.assertEqual(dep_check_code, expected_dep_check_code)
  1513. self.assertEqual(out_data_f.getvalue(), expected_data)
  1514. self.assertEqual(expression_code, expected_expression_code)
  1515. if __name__ == '__main__':
  1516. unittest_main()