test_generate_test_code.py 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  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_function_name_on_newline(self, parse_function_arguments_mock,
  605. gen_function_wrapper_mock,
  606. gen_dependencies_mock,
  607. gen_dispatch_mock):
  608. """
  609. Test with line break before the function name.
  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. @patch("generate_test_code.gen_dispatch")
  643. @patch("generate_test_code.gen_dependencies")
  644. @patch("generate_test_code.gen_function_wrapper")
  645. @patch("generate_test_code.parse_function_arguments")
  646. def test_case_starting_with_comment(self, parse_function_arguments_mock,
  647. gen_function_wrapper_mock,
  648. gen_dependencies_mock,
  649. gen_dispatch_mock):
  650. """
  651. Test with comments before the function signature
  652. :return:
  653. """
  654. parse_function_arguments_mock.return_value = ([], '', [])
  655. gen_function_wrapper_mock.return_value = ''
  656. gen_dependencies_mock.side_effect = gen_dependencies
  657. gen_dispatch_mock.side_effect = gen_dispatch
  658. data = '''/* comment */
  659. /* more
  660. * comment */
  661. // this is\\
  662. still \\
  663. a comment
  664. void func()
  665. {
  666. ba ba black sheep
  667. have you any wool
  668. exit:
  669. yes sir yes sir
  670. 3 bags full
  671. }
  672. /* END_CASE */
  673. '''
  674. stream = StringIOWrapper('test_suite_ut.function', data)
  675. _, _, code, _ = parse_function_code(stream, [], [])
  676. expected = '''#line 1 "test_suite_ut.function"
  677. void test_func()
  678. {
  679. ba ba black sheep
  680. have you any wool
  681. exit:
  682. yes sir yes sir
  683. 3 bags full
  684. }
  685. '''
  686. self.assertEqual(code, expected)
  687. @patch("generate_test_code.gen_dispatch")
  688. @patch("generate_test_code.gen_dependencies")
  689. @patch("generate_test_code.gen_function_wrapper")
  690. @patch("generate_test_code.parse_function_arguments")
  691. def test_comment_in_prototype(self, parse_function_arguments_mock,
  692. gen_function_wrapper_mock,
  693. gen_dependencies_mock,
  694. gen_dispatch_mock):
  695. """
  696. Test with comments in the function prototype
  697. :return:
  698. """
  699. parse_function_arguments_mock.return_value = ([], '', [])
  700. gen_function_wrapper_mock.return_value = ''
  701. gen_dependencies_mock.side_effect = gen_dependencies
  702. gen_dispatch_mock.side_effect = gen_dispatch
  703. data = '''
  704. void func( int x, // (line \\
  705. comment)
  706. int y /* lone closing parenthesis) */ )
  707. {
  708. ba ba black sheep
  709. have you any wool
  710. exit:
  711. yes sir yes sir
  712. 3 bags full
  713. }
  714. /* END_CASE */
  715. '''
  716. stream = StringIOWrapper('test_suite_ut.function', data)
  717. _, _, code, _ = parse_function_code(stream, [], [])
  718. expected = '''#line 1 "test_suite_ut.function"
  719. void test_func( int x,
  720. int y )
  721. {
  722. ba ba black sheep
  723. have you any wool
  724. exit:
  725. yes sir yes sir
  726. 3 bags full
  727. }
  728. '''
  729. self.assertEqual(code, expected)
  730. @patch("generate_test_code.gen_dispatch")
  731. @patch("generate_test_code.gen_dependencies")
  732. @patch("generate_test_code.gen_function_wrapper")
  733. @patch("generate_test_code.parse_function_arguments")
  734. def test_line_comment_in_block_comment(self, parse_function_arguments_mock,
  735. gen_function_wrapper_mock,
  736. gen_dependencies_mock,
  737. gen_dispatch_mock):
  738. """
  739. Test with line comment in block comment.
  740. :return:
  741. """
  742. parse_function_arguments_mock.return_value = ([], '', [])
  743. gen_function_wrapper_mock.return_value = ''
  744. gen_dependencies_mock.side_effect = gen_dependencies
  745. gen_dispatch_mock.side_effect = gen_dispatch
  746. data = '''
  747. void func( int x /* // */ )
  748. {
  749. ba ba black sheep
  750. have you any wool
  751. exit:
  752. yes sir yes sir
  753. 3 bags full
  754. }
  755. /* END_CASE */
  756. '''
  757. stream = StringIOWrapper('test_suite_ut.function', data)
  758. _, _, code, _ = parse_function_code(stream, [], [])
  759. expected = '''#line 1 "test_suite_ut.function"
  760. void test_func( int x )
  761. {
  762. ba ba black sheep
  763. have you any wool
  764. exit:
  765. yes sir yes sir
  766. 3 bags full
  767. }
  768. '''
  769. self.assertEqual(code, expected)
  770. @patch("generate_test_code.gen_dispatch")
  771. @patch("generate_test_code.gen_dependencies")
  772. @patch("generate_test_code.gen_function_wrapper")
  773. @patch("generate_test_code.parse_function_arguments")
  774. def test_block_comment_in_line_comment(self, parse_function_arguments_mock,
  775. gen_function_wrapper_mock,
  776. gen_dependencies_mock,
  777. gen_dispatch_mock):
  778. """
  779. Test with block comment in line comment.
  780. :return:
  781. """
  782. parse_function_arguments_mock.return_value = ([], '', [])
  783. gen_function_wrapper_mock.return_value = ''
  784. gen_dependencies_mock.side_effect = gen_dependencies
  785. gen_dispatch_mock.side_effect = gen_dispatch
  786. data = '''
  787. // /*
  788. void func( int x )
  789. {
  790. ba ba black sheep
  791. have you any wool
  792. exit:
  793. yes sir yes sir
  794. 3 bags full
  795. }
  796. /* END_CASE */
  797. '''
  798. stream = StringIOWrapper('test_suite_ut.function', data)
  799. _, _, code, _ = parse_function_code(stream, [], [])
  800. expected = '''#line 1 "test_suite_ut.function"
  801. void test_func( int x )
  802. {
  803. ba ba black sheep
  804. have you any wool
  805. exit:
  806. yes sir yes sir
  807. 3 bags full
  808. }
  809. '''
  810. self.assertEqual(code, expected)
  811. class ParseFunction(TestCase):
  812. """
  813. Test Suite for testing parse_functions()
  814. """
  815. @patch("generate_test_code.parse_until_pattern")
  816. def test_begin_header(self, parse_until_pattern_mock):
  817. """
  818. Test that begin header is checked and parse_until_pattern() is called.
  819. :return:
  820. """
  821. def stop(*_unused):
  822. """Stop when parse_until_pattern is called."""
  823. raise Exception
  824. parse_until_pattern_mock.side_effect = stop
  825. data = '''/* BEGIN_HEADER */
  826. #include "mbedtls/ecp.h"
  827. #define ECP_PF_UNKNOWN -1
  828. /* END_HEADER */
  829. '''
  830. stream = StringIOWrapper('test_suite_ut.function', data)
  831. self.assertRaises(Exception, parse_functions, stream)
  832. parse_until_pattern_mock.assert_called_with(stream, END_HEADER_REGEX)
  833. self.assertEqual(stream.line_no, 1)
  834. @patch("generate_test_code.parse_until_pattern")
  835. def test_begin_helper(self, parse_until_pattern_mock):
  836. """
  837. Test that begin helper is checked and parse_until_pattern() is called.
  838. :return:
  839. """
  840. def stop(*_unused):
  841. """Stop when parse_until_pattern is called."""
  842. raise Exception
  843. parse_until_pattern_mock.side_effect = stop
  844. data = '''/* BEGIN_SUITE_HELPERS */
  845. void print_hello_world()
  846. {
  847. printf("Hello World!\n");
  848. }
  849. /* END_SUITE_HELPERS */
  850. '''
  851. stream = StringIOWrapper('test_suite_ut.function', data)
  852. self.assertRaises(Exception, parse_functions, stream)
  853. parse_until_pattern_mock.assert_called_with(stream,
  854. END_SUITE_HELPERS_REGEX)
  855. self.assertEqual(stream.line_no, 1)
  856. @patch("generate_test_code.parse_suite_dependencies")
  857. def test_begin_dep(self, parse_suite_dependencies_mock):
  858. """
  859. Test that begin dep is checked and parse_suite_dependencies() is
  860. called.
  861. :return:
  862. """
  863. def stop(*_unused):
  864. """Stop when parse_until_pattern is called."""
  865. raise Exception
  866. parse_suite_dependencies_mock.side_effect = stop
  867. data = '''/* BEGIN_DEPENDENCIES
  868. * depends_on:MBEDTLS_ECP_C
  869. * END_DEPENDENCIES
  870. */
  871. '''
  872. stream = StringIOWrapper('test_suite_ut.function', data)
  873. self.assertRaises(Exception, parse_functions, stream)
  874. parse_suite_dependencies_mock.assert_called_with(stream)
  875. self.assertEqual(stream.line_no, 1)
  876. @patch("generate_test_code.parse_function_dependencies")
  877. def test_begin_function_dep(self, func_mock):
  878. """
  879. Test that begin dep is checked and parse_function_dependencies() is
  880. called.
  881. :return:
  882. """
  883. def stop(*_unused):
  884. """Stop when parse_until_pattern is called."""
  885. raise Exception
  886. func_mock.side_effect = stop
  887. dependencies_str = '/* BEGIN_CASE ' \
  888. 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
  889. data = '''%svoid test_func()
  890. {
  891. }
  892. ''' % dependencies_str
  893. stream = StringIOWrapper('test_suite_ut.function', data)
  894. self.assertRaises(Exception, parse_functions, stream)
  895. func_mock.assert_called_with(dependencies_str)
  896. self.assertEqual(stream.line_no, 1)
  897. @patch("generate_test_code.parse_function_code")
  898. @patch("generate_test_code.parse_function_dependencies")
  899. def test_return(self, func_mock1, func_mock2):
  900. """
  901. Test that begin case is checked and parse_function_code() is called.
  902. :return:
  903. """
  904. func_mock1.return_value = []
  905. in_func_code = '''void test_func()
  906. {
  907. }
  908. '''
  909. func_dispatch = '''
  910. test_func_wrapper,
  911. '''
  912. func_mock2.return_value = 'test_func', [],\
  913. in_func_code, func_dispatch
  914. dependencies_str = '/* BEGIN_CASE ' \
  915. 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
  916. data = '''%svoid test_func()
  917. {
  918. }
  919. ''' % dependencies_str
  920. stream = StringIOWrapper('test_suite_ut.function', data)
  921. suite_dependencies, dispatch_code, func_code, func_info = \
  922. parse_functions(stream)
  923. func_mock1.assert_called_with(dependencies_str)
  924. func_mock2.assert_called_with(stream, [], [])
  925. self.assertEqual(stream.line_no, 5)
  926. self.assertEqual(suite_dependencies, [])
  927. expected_dispatch_code = '''/* Function Id: 0 */
  928. test_func_wrapper,
  929. '''
  930. self.assertEqual(dispatch_code, expected_dispatch_code)
  931. self.assertEqual(func_code, in_func_code)
  932. self.assertEqual(func_info, {'test_func': (0, [])})
  933. def test_parsing(self):
  934. """
  935. Test case parsing.
  936. :return:
  937. """
  938. data = '''/* BEGIN_HEADER */
  939. #include "mbedtls/ecp.h"
  940. #define ECP_PF_UNKNOWN -1
  941. /* END_HEADER */
  942. /* BEGIN_DEPENDENCIES
  943. * depends_on:MBEDTLS_ECP_C
  944. * END_DEPENDENCIES
  945. */
  946. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  947. void func1()
  948. {
  949. }
  950. /* END_CASE */
  951. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  952. void func2()
  953. {
  954. }
  955. /* END_CASE */
  956. '''
  957. stream = StringIOWrapper('test_suite_ut.function', data)
  958. suite_dependencies, dispatch_code, func_code, func_info = \
  959. parse_functions(stream)
  960. self.assertEqual(stream.line_no, 23)
  961. self.assertEqual(suite_dependencies, ['MBEDTLS_ECP_C'])
  962. expected_dispatch_code = '''/* Function Id: 0 */
  963. #if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
  964. test_func1_wrapper,
  965. #else
  966. NULL,
  967. #endif
  968. /* Function Id: 1 */
  969. #if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
  970. test_func2_wrapper,
  971. #else
  972. NULL,
  973. #endif
  974. '''
  975. self.assertEqual(dispatch_code, expected_dispatch_code)
  976. expected_func_code = '''#if defined(MBEDTLS_ECP_C)
  977. #line 2 "test_suite_ut.function"
  978. #include "mbedtls/ecp.h"
  979. #define ECP_PF_UNKNOWN -1
  980. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  981. #if defined(MBEDTLS_FS_IO)
  982. #line 13 "test_suite_ut.function"
  983. void test_func1()
  984. {
  985. exit:
  986. ;
  987. }
  988. void test_func1_wrapper( void ** params )
  989. {
  990. (void)params;
  991. test_func1( );
  992. }
  993. #endif /* MBEDTLS_FS_IO */
  994. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  995. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  996. #if defined(MBEDTLS_FS_IO)
  997. #line 19 "test_suite_ut.function"
  998. void test_func2()
  999. {
  1000. exit:
  1001. ;
  1002. }
  1003. void test_func2_wrapper( void ** params )
  1004. {
  1005. (void)params;
  1006. test_func2( );
  1007. }
  1008. #endif /* MBEDTLS_FS_IO */
  1009. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  1010. #endif /* MBEDTLS_ECP_C */
  1011. '''
  1012. self.assertEqual(func_code, expected_func_code)
  1013. self.assertEqual(func_info, {'test_func1': (0, []),
  1014. 'test_func2': (1, [])})
  1015. def test_same_function_name(self):
  1016. """
  1017. Test name conflict.
  1018. :return:
  1019. """
  1020. data = '''/* BEGIN_HEADER */
  1021. #include "mbedtls/ecp.h"
  1022. #define ECP_PF_UNKNOWN -1
  1023. /* END_HEADER */
  1024. /* BEGIN_DEPENDENCIES
  1025. * depends_on:MBEDTLS_ECP_C
  1026. * END_DEPENDENCIES
  1027. */
  1028. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  1029. void func()
  1030. {
  1031. }
  1032. /* END_CASE */
  1033. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  1034. void func()
  1035. {
  1036. }
  1037. /* END_CASE */
  1038. '''
  1039. stream = StringIOWrapper('test_suite_ut.function', data)
  1040. self.assertRaises(GeneratorInputError, parse_functions, stream)
  1041. class EscapedSplit(TestCase):
  1042. """
  1043. Test suite for testing escaped_split().
  1044. Note: Since escaped_split() output is used to write back to the
  1045. intermediate data file. Any escape characters in the input are
  1046. retained in the output.
  1047. """
  1048. def test_invalid_input(self):
  1049. """
  1050. Test when input split character is not a character.
  1051. :return:
  1052. """
  1053. self.assertRaises(ValueError, escaped_split, '', 'string')
  1054. def test_empty_string(self):
  1055. """
  1056. Test empty string input.
  1057. :return:
  1058. """
  1059. splits = escaped_split('', ':')
  1060. self.assertEqual(splits, [])
  1061. def test_no_escape(self):
  1062. """
  1063. Test with no escape character. The behaviour should be same as
  1064. str.split()
  1065. :return:
  1066. """
  1067. test_str = 'yahoo:google'
  1068. splits = escaped_split(test_str, ':')
  1069. self.assertEqual(splits, test_str.split(':'))
  1070. def test_escaped_input(self):
  1071. """
  1072. Test input that has escaped delimiter.
  1073. :return:
  1074. """
  1075. test_str = r'yahoo\:google:facebook'
  1076. splits = escaped_split(test_str, ':')
  1077. self.assertEqual(splits, [r'yahoo\:google', 'facebook'])
  1078. def test_escaped_escape(self):
  1079. """
  1080. Test input that has escaped delimiter.
  1081. :return:
  1082. """
  1083. test_str = r'yahoo\\:google:facebook'
  1084. splits = escaped_split(test_str, ':')
  1085. self.assertEqual(splits, [r'yahoo\\', 'google', 'facebook'])
  1086. def test_all_at_once(self):
  1087. """
  1088. Test input that has escaped delimiter.
  1089. :return:
  1090. """
  1091. test_str = r'yahoo\\:google:facebook\:instagram\\:bbc\\:wikipedia'
  1092. splits = escaped_split(test_str, ':')
  1093. self.assertEqual(splits, [r'yahoo\\', r'google',
  1094. r'facebook\:instagram\\',
  1095. r'bbc\\', r'wikipedia'])
  1096. class ParseTestData(TestCase):
  1097. """
  1098. Test suite for parse test data.
  1099. """
  1100. def test_parser(self):
  1101. """
  1102. Test that tests are parsed correctly from data file.
  1103. :return:
  1104. """
  1105. data = """
  1106. Diffie-Hellman full exchange #1
  1107. dhm_do_dhm:10:"23":10:"5"
  1108. Diffie-Hellman full exchange #2
  1109. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  1110. Diffie-Hellman full exchange #3
  1111. dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
  1112. Diffie-Hellman selftest
  1113. dhm_selftest:
  1114. """
  1115. stream = StringIOWrapper('test_suite_ut.function', data)
  1116. # List of (name, function_name, dependencies, args)
  1117. tests = list(parse_test_data(stream))
  1118. test1, test2, test3, test4 = tests
  1119. self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
  1120. self.assertEqual(test1[1], 'dhm_do_dhm')
  1121. self.assertEqual(test1[2], [])
  1122. self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
  1123. self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
  1124. self.assertEqual(test2[1], 'dhm_do_dhm')
  1125. self.assertEqual(test2[2], [])
  1126. self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
  1127. '10', '"9345098304850938450983409622"'])
  1128. self.assertEqual(test3[0], 'Diffie-Hellman full exchange #3')
  1129. self.assertEqual(test3[1], 'dhm_do_dhm')
  1130. self.assertEqual(test3[2], [])
  1131. self.assertEqual(test3[3], ['10',
  1132. '"9345098382739712938719287391879381271"',
  1133. '10',
  1134. '"9345098792137312973297123912791271"'])
  1135. self.assertEqual(test4[0], 'Diffie-Hellman selftest')
  1136. self.assertEqual(test4[1], 'dhm_selftest')
  1137. self.assertEqual(test4[2], [])
  1138. self.assertEqual(test4[3], [])
  1139. def test_with_dependencies(self):
  1140. """
  1141. Test that tests with dependencies are parsed.
  1142. :return:
  1143. """
  1144. data = """
  1145. Diffie-Hellman full exchange #1
  1146. depends_on:YAHOO
  1147. dhm_do_dhm:10:"23":10:"5"
  1148. Diffie-Hellman full exchange #2
  1149. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  1150. """
  1151. stream = StringIOWrapper('test_suite_ut.function', data)
  1152. # List of (name, function_name, dependencies, args)
  1153. tests = list(parse_test_data(stream))
  1154. test1, test2 = tests
  1155. self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
  1156. self.assertEqual(test1[1], 'dhm_do_dhm')
  1157. self.assertEqual(test1[2], ['YAHOO'])
  1158. self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
  1159. self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
  1160. self.assertEqual(test2[1], 'dhm_do_dhm')
  1161. self.assertEqual(test2[2], [])
  1162. self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
  1163. '10', '"9345098304850938450983409622"'])
  1164. def test_no_args(self):
  1165. """
  1166. Test GeneratorInputError is raised when test function name and
  1167. args line is missing.
  1168. :return:
  1169. """
  1170. data = """
  1171. Diffie-Hellman full exchange #1
  1172. depends_on:YAHOO
  1173. Diffie-Hellman full exchange #2
  1174. dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
  1175. """
  1176. stream = StringIOWrapper('test_suite_ut.function', data)
  1177. err = None
  1178. try:
  1179. for _, _, _, _ in parse_test_data(stream):
  1180. pass
  1181. except GeneratorInputError as err:
  1182. self.assertEqual(type(err), GeneratorInputError)
  1183. def test_incomplete_data(self):
  1184. """
  1185. Test GeneratorInputError is raised when test function name
  1186. and args line is missing.
  1187. :return:
  1188. """
  1189. data = """
  1190. Diffie-Hellman full exchange #1
  1191. depends_on:YAHOO
  1192. """
  1193. stream = StringIOWrapper('test_suite_ut.function', data)
  1194. err = None
  1195. try:
  1196. for _, _, _, _ in parse_test_data(stream):
  1197. pass
  1198. except GeneratorInputError as err:
  1199. self.assertEqual(type(err), GeneratorInputError)
  1200. class GenDepCheck(TestCase):
  1201. """
  1202. Test suite for gen_dep_check(). It is assumed this function is
  1203. called with valid inputs.
  1204. """
  1205. def test_gen_dep_check(self):
  1206. """
  1207. Test that dependency check code generated correctly.
  1208. :return:
  1209. """
  1210. expected = """
  1211. case 5:
  1212. {
  1213. #if defined(YAHOO)
  1214. ret = DEPENDENCY_SUPPORTED;
  1215. #else
  1216. ret = DEPENDENCY_NOT_SUPPORTED;
  1217. #endif
  1218. }
  1219. break;"""
  1220. out = gen_dep_check(5, 'YAHOO')
  1221. self.assertEqual(out, expected)
  1222. def test_not_defined_dependency(self):
  1223. """
  1224. Test dependency with !.
  1225. :return:
  1226. """
  1227. expected = """
  1228. case 5:
  1229. {
  1230. #if !defined(YAHOO)
  1231. ret = DEPENDENCY_SUPPORTED;
  1232. #else
  1233. ret = DEPENDENCY_NOT_SUPPORTED;
  1234. #endif
  1235. }
  1236. break;"""
  1237. out = gen_dep_check(5, '!YAHOO')
  1238. self.assertEqual(out, expected)
  1239. def test_empty_dependency(self):
  1240. """
  1241. Test invalid dependency input.
  1242. :return:
  1243. """
  1244. self.assertRaises(GeneratorInputError, gen_dep_check, 5, '!')
  1245. def test_negative_dep_id(self):
  1246. """
  1247. Test invalid dependency input.
  1248. :return:
  1249. """
  1250. self.assertRaises(GeneratorInputError, gen_dep_check, -1, 'YAHOO')
  1251. class GenExpCheck(TestCase):
  1252. """
  1253. Test suite for gen_expression_check(). It is assumed this function
  1254. is called with valid inputs.
  1255. """
  1256. def test_gen_exp_check(self):
  1257. """
  1258. Test that expression check code generated correctly.
  1259. :return:
  1260. """
  1261. expected = """
  1262. case 5:
  1263. {
  1264. *out_value = YAHOO;
  1265. }
  1266. break;"""
  1267. out = gen_expression_check(5, 'YAHOO')
  1268. self.assertEqual(out, expected)
  1269. def test_invalid_expression(self):
  1270. """
  1271. Test invalid expression input.
  1272. :return:
  1273. """
  1274. self.assertRaises(GeneratorInputError, gen_expression_check, 5, '')
  1275. def test_negative_exp_id(self):
  1276. """
  1277. Test invalid expression id.
  1278. :return:
  1279. """
  1280. self.assertRaises(GeneratorInputError, gen_expression_check,
  1281. -1, 'YAHOO')
  1282. class WriteDependencies(TestCase):
  1283. """
  1284. Test suite for testing write_dependencies.
  1285. """
  1286. def test_no_test_dependencies(self):
  1287. """
  1288. Test when test dependencies input is empty.
  1289. :return:
  1290. """
  1291. stream = StringIOWrapper('test_suite_ut.data', '')
  1292. unique_dependencies = []
  1293. dep_check_code = write_dependencies(stream, [], unique_dependencies)
  1294. self.assertEqual(dep_check_code, '')
  1295. self.assertEqual(len(unique_dependencies), 0)
  1296. self.assertEqual(stream.getvalue(), '')
  1297. def test_unique_dep_ids(self):
  1298. """
  1299. :return:
  1300. """
  1301. stream = StringIOWrapper('test_suite_ut.data', '')
  1302. unique_dependencies = []
  1303. dep_check_code = write_dependencies(stream, ['DEP3', 'DEP2', 'DEP1'],
  1304. unique_dependencies)
  1305. expect_dep_check_code = '''
  1306. case 0:
  1307. {
  1308. #if defined(DEP3)
  1309. ret = DEPENDENCY_SUPPORTED;
  1310. #else
  1311. ret = DEPENDENCY_NOT_SUPPORTED;
  1312. #endif
  1313. }
  1314. break;
  1315. case 1:
  1316. {
  1317. #if defined(DEP2)
  1318. ret = DEPENDENCY_SUPPORTED;
  1319. #else
  1320. ret = DEPENDENCY_NOT_SUPPORTED;
  1321. #endif
  1322. }
  1323. break;
  1324. case 2:
  1325. {
  1326. #if defined(DEP1)
  1327. ret = DEPENDENCY_SUPPORTED;
  1328. #else
  1329. ret = DEPENDENCY_NOT_SUPPORTED;
  1330. #endif
  1331. }
  1332. break;'''
  1333. self.assertEqual(dep_check_code, expect_dep_check_code)
  1334. self.assertEqual(len(unique_dependencies), 3)
  1335. self.assertEqual(stream.getvalue(), 'depends_on:0:1:2\n')
  1336. def test_dep_id_repeat(self):
  1337. """
  1338. :return:
  1339. """
  1340. stream = StringIOWrapper('test_suite_ut.data', '')
  1341. unique_dependencies = []
  1342. dep_check_code = ''
  1343. dep_check_code += write_dependencies(stream, ['DEP3', 'DEP2'],
  1344. unique_dependencies)
  1345. dep_check_code += write_dependencies(stream, ['DEP2', 'DEP1'],
  1346. unique_dependencies)
  1347. dep_check_code += write_dependencies(stream, ['DEP1', 'DEP3'],
  1348. unique_dependencies)
  1349. expect_dep_check_code = '''
  1350. case 0:
  1351. {
  1352. #if defined(DEP3)
  1353. ret = DEPENDENCY_SUPPORTED;
  1354. #else
  1355. ret = DEPENDENCY_NOT_SUPPORTED;
  1356. #endif
  1357. }
  1358. break;
  1359. case 1:
  1360. {
  1361. #if defined(DEP2)
  1362. ret = DEPENDENCY_SUPPORTED;
  1363. #else
  1364. ret = DEPENDENCY_NOT_SUPPORTED;
  1365. #endif
  1366. }
  1367. break;
  1368. case 2:
  1369. {
  1370. #if defined(DEP1)
  1371. ret = DEPENDENCY_SUPPORTED;
  1372. #else
  1373. ret = DEPENDENCY_NOT_SUPPORTED;
  1374. #endif
  1375. }
  1376. break;'''
  1377. self.assertEqual(dep_check_code, expect_dep_check_code)
  1378. self.assertEqual(len(unique_dependencies), 3)
  1379. self.assertEqual(stream.getvalue(),
  1380. 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
  1381. class WriteParams(TestCase):
  1382. """
  1383. Test Suite for testing write_parameters().
  1384. """
  1385. def test_no_params(self):
  1386. """
  1387. Test with empty test_args
  1388. :return:
  1389. """
  1390. stream = StringIOWrapper('test_suite_ut.data', '')
  1391. unique_expressions = []
  1392. expression_code = write_parameters(stream, [], [], unique_expressions)
  1393. self.assertEqual(len(unique_expressions), 0)
  1394. self.assertEqual(expression_code, '')
  1395. self.assertEqual(stream.getvalue(), '\n')
  1396. def test_no_exp_param(self):
  1397. """
  1398. Test when there is no macro or expression in the params.
  1399. :return:
  1400. """
  1401. stream = StringIOWrapper('test_suite_ut.data', '')
  1402. unique_expressions = []
  1403. expression_code = write_parameters(stream, ['"Yahoo"', '"abcdef00"',
  1404. '0'],
  1405. ['char*', 'hex', 'int'],
  1406. unique_expressions)
  1407. self.assertEqual(len(unique_expressions), 0)
  1408. self.assertEqual(expression_code, '')
  1409. self.assertEqual(stream.getvalue(),
  1410. ':char*:"Yahoo":hex:"abcdef00":int:0\n')
  1411. def test_hex_format_int_param(self):
  1412. """
  1413. Test int parameter in hex format.
  1414. :return:
  1415. """
  1416. stream = StringIOWrapper('test_suite_ut.data', '')
  1417. unique_expressions = []
  1418. expression_code = write_parameters(stream,
  1419. ['"Yahoo"', '"abcdef00"', '0xAA'],
  1420. ['char*', 'hex', 'int'],
  1421. unique_expressions)
  1422. self.assertEqual(len(unique_expressions), 0)
  1423. self.assertEqual(expression_code, '')
  1424. self.assertEqual(stream.getvalue(),
  1425. ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
  1426. def test_with_exp_param(self):
  1427. """
  1428. Test when there is macro or expression in the params.
  1429. :return:
  1430. """
  1431. stream = StringIOWrapper('test_suite_ut.data', '')
  1432. unique_expressions = []
  1433. expression_code = write_parameters(stream,
  1434. ['"Yahoo"', '"abcdef00"', '0',
  1435. 'MACRO1', 'MACRO2', 'MACRO3'],
  1436. ['char*', 'hex', 'int',
  1437. 'int', 'int', 'int'],
  1438. unique_expressions)
  1439. self.assertEqual(len(unique_expressions), 3)
  1440. self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
  1441. expected_expression_code = '''
  1442. case 0:
  1443. {
  1444. *out_value = MACRO1;
  1445. }
  1446. break;
  1447. case 1:
  1448. {
  1449. *out_value = MACRO2;
  1450. }
  1451. break;
  1452. case 2:
  1453. {
  1454. *out_value = MACRO3;
  1455. }
  1456. break;'''
  1457. self.assertEqual(expression_code, expected_expression_code)
  1458. self.assertEqual(stream.getvalue(),
  1459. ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1'
  1460. ':exp:2\n')
  1461. def test_with_repeat_calls(self):
  1462. """
  1463. Test when write_parameter() is called with same macro or expression.
  1464. :return:
  1465. """
  1466. stream = StringIOWrapper('test_suite_ut.data', '')
  1467. unique_expressions = []
  1468. expression_code = ''
  1469. expression_code += write_parameters(stream,
  1470. ['"Yahoo"', 'MACRO1', 'MACRO2'],
  1471. ['char*', 'int', 'int'],
  1472. unique_expressions)
  1473. expression_code += write_parameters(stream,
  1474. ['"abcdef00"', 'MACRO2', 'MACRO3'],
  1475. ['hex', 'int', 'int'],
  1476. unique_expressions)
  1477. expression_code += write_parameters(stream,
  1478. ['0', 'MACRO3', 'MACRO1'],
  1479. ['int', 'int', 'int'],
  1480. unique_expressions)
  1481. self.assertEqual(len(unique_expressions), 3)
  1482. self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
  1483. expected_expression_code = '''
  1484. case 0:
  1485. {
  1486. *out_value = MACRO1;
  1487. }
  1488. break;
  1489. case 1:
  1490. {
  1491. *out_value = MACRO2;
  1492. }
  1493. break;
  1494. case 2:
  1495. {
  1496. *out_value = MACRO3;
  1497. }
  1498. break;'''
  1499. self.assertEqual(expression_code, expected_expression_code)
  1500. expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
  1501. :hex:"abcdef00":exp:1:exp:2
  1502. :int:0:exp:2:exp:0
  1503. '''
  1504. self.assertEqual(stream.getvalue(), expected_data_file)
  1505. class GenTestSuiteDependenciesChecks(TestCase):
  1506. """
  1507. Test suite for testing gen_suite_dep_checks()
  1508. """
  1509. def test_empty_suite_dependencies(self):
  1510. """
  1511. Test with empty suite_dependencies list.
  1512. :return:
  1513. """
  1514. dep_check_code, expression_code = \
  1515. gen_suite_dep_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
  1516. self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
  1517. self.assertEqual(expression_code, 'EXPRESSION_CODE')
  1518. def test_suite_dependencies(self):
  1519. """
  1520. Test with suite_dependencies list.
  1521. :return:
  1522. """
  1523. dep_check_code, expression_code = \
  1524. gen_suite_dep_checks(['SUITE_DEP'], 'DEP_CHECK_CODE',
  1525. 'EXPRESSION_CODE')
  1526. expected_dep_check_code = '''
  1527. #if defined(SUITE_DEP)
  1528. DEP_CHECK_CODE
  1529. #endif
  1530. '''
  1531. expected_expression_code = '''
  1532. #if defined(SUITE_DEP)
  1533. EXPRESSION_CODE
  1534. #endif
  1535. '''
  1536. self.assertEqual(dep_check_code, expected_dep_check_code)
  1537. self.assertEqual(expression_code, expected_expression_code)
  1538. def test_no_dep_no_exp(self):
  1539. """
  1540. Test when there are no dependency and expression code.
  1541. :return:
  1542. """
  1543. dep_check_code, expression_code = gen_suite_dep_checks([], '', '')
  1544. self.assertEqual(dep_check_code, '')
  1545. self.assertEqual(expression_code, '')
  1546. class GenFromTestData(TestCase):
  1547. """
  1548. Test suite for gen_from_test_data()
  1549. """
  1550. @staticmethod
  1551. @patch("generate_test_code.write_dependencies")
  1552. @patch("generate_test_code.write_parameters")
  1553. @patch("generate_test_code.gen_suite_dep_checks")
  1554. def test_intermediate_data_file(func_mock1,
  1555. write_parameters_mock,
  1556. write_dependencies_mock):
  1557. """
  1558. Test that intermediate data file is written with expected data.
  1559. :return:
  1560. """
  1561. data = '''
  1562. My test
  1563. depends_on:DEP1
  1564. func1:0
  1565. '''
  1566. data_f = StringIOWrapper('test_suite_ut.data', data)
  1567. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1568. func_info = {'test_func1': (1, ('int',))}
  1569. suite_dependencies = []
  1570. write_parameters_mock.side_effect = write_parameters
  1571. write_dependencies_mock.side_effect = write_dependencies
  1572. func_mock1.side_effect = gen_suite_dep_checks
  1573. gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies)
  1574. write_dependencies_mock.assert_called_with(out_data_f,
  1575. ['DEP1'], ['DEP1'])
  1576. write_parameters_mock.assert_called_with(out_data_f, ['0'],
  1577. ('int',), [])
  1578. expected_dep_check_code = '''
  1579. case 0:
  1580. {
  1581. #if defined(DEP1)
  1582. ret = DEPENDENCY_SUPPORTED;
  1583. #else
  1584. ret = DEPENDENCY_NOT_SUPPORTED;
  1585. #endif
  1586. }
  1587. break;'''
  1588. func_mock1.assert_called_with(
  1589. suite_dependencies, expected_dep_check_code, '')
  1590. def test_function_not_found(self):
  1591. """
  1592. Test that AssertError is raised when function info in not found.
  1593. :return:
  1594. """
  1595. data = '''
  1596. My test
  1597. depends_on:DEP1
  1598. func1:0
  1599. '''
  1600. data_f = StringIOWrapper('test_suite_ut.data', data)
  1601. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1602. func_info = {'test_func2': (1, ('int',))}
  1603. suite_dependencies = []
  1604. self.assertRaises(GeneratorInputError, gen_from_test_data,
  1605. data_f, out_data_f, func_info, suite_dependencies)
  1606. def test_different_func_args(self):
  1607. """
  1608. Test that AssertError is raised when no. of parameters and
  1609. function args differ.
  1610. :return:
  1611. """
  1612. data = '''
  1613. My test
  1614. depends_on:DEP1
  1615. func1:0
  1616. '''
  1617. data_f = StringIOWrapper('test_suite_ut.data', data)
  1618. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1619. func_info = {'test_func2': (1, ('int', 'hex'))}
  1620. suite_dependencies = []
  1621. self.assertRaises(GeneratorInputError, gen_from_test_data, data_f,
  1622. out_data_f, func_info, suite_dependencies)
  1623. def test_output(self):
  1624. """
  1625. Test that intermediate data file is written with expected data.
  1626. :return:
  1627. """
  1628. data = '''
  1629. My test 1
  1630. depends_on:DEP1
  1631. func1:0:0xfa:MACRO1:MACRO2
  1632. My test 2
  1633. depends_on:DEP1:DEP2
  1634. func2:"yahoo":88:MACRO1
  1635. '''
  1636. data_f = StringIOWrapper('test_suite_ut.data', data)
  1637. out_data_f = StringIOWrapper('test_suite_ut.datax', '')
  1638. func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')),
  1639. 'test_func2': (1, ('char*', 'int', 'int'))}
  1640. suite_dependencies = []
  1641. dep_check_code, expression_code = \
  1642. gen_from_test_data(data_f, out_data_f, func_info,
  1643. suite_dependencies)
  1644. expected_dep_check_code = '''
  1645. case 0:
  1646. {
  1647. #if defined(DEP1)
  1648. ret = DEPENDENCY_SUPPORTED;
  1649. #else
  1650. ret = DEPENDENCY_NOT_SUPPORTED;
  1651. #endif
  1652. }
  1653. break;
  1654. case 1:
  1655. {
  1656. #if defined(DEP2)
  1657. ret = DEPENDENCY_SUPPORTED;
  1658. #else
  1659. ret = DEPENDENCY_NOT_SUPPORTED;
  1660. #endif
  1661. }
  1662. break;'''
  1663. expected_data = '''My test 1
  1664. depends_on:0
  1665. 0:int:0:int:0xfa:exp:0:exp:1
  1666. My test 2
  1667. depends_on:0:1
  1668. 1:char*:"yahoo":int:88:exp:0
  1669. '''
  1670. expected_expression_code = '''
  1671. case 0:
  1672. {
  1673. *out_value = MACRO1;
  1674. }
  1675. break;
  1676. case 1:
  1677. {
  1678. *out_value = MACRO2;
  1679. }
  1680. break;'''
  1681. self.assertEqual(dep_check_code, expected_dep_check_code)
  1682. self.assertEqual(out_data_f.getvalue(), expected_data)
  1683. self.assertEqual(expression_code, expected_expression_code)
  1684. if __name__ == '__main__':
  1685. unittest_main()