From 5e2ac1fb2934e531d28bb015ca5e053cb83397cc Mon Sep 17 00:00:00 2001 From: Azim Khan Date: Mon, 3 Jul 2017 13:58:20 +0100 Subject: [PATCH] Updated generate_code.py unit tests --- tests/scripts/generate_code.py | 37 ++-- tests/scripts/generate_code_ut.py | 274 +++++++++++++++++++++++++++++- 2 files changed, 299 insertions(+), 12 deletions(-) diff --git a/tests/scripts/generate_code.py b/tests/scripts/generate_code.py index b0b368650e..b344f8ce76 100644 --- a/tests/scripts/generate_code.py +++ b/tests/scripts/generate_code.py @@ -362,14 +362,15 @@ def escaped_split(str, ch): out.append(part) part = '' else: - part += str[i] escape = not escape and str[i] == '\\' + if not escape: + part += str[i] if len(part): out.append(part) return out -def parse_test_data(data_f): +def parse_test_data(data_f, debug=False): """ Parses .data file @@ -380,14 +381,16 @@ def parse_test_data(data_f): STATE_READ_ARGS = 1 state = STATE_READ_NAME deps = [] - + name = '' for line in data_f: line = line.strip() if len(line) and line[0] == '#': # Skip comments continue - # skip blank lines + # Blank line indicates end of test if len(line) == 0: + assert state != STATE_READ_ARGS, "Newline before arguments. " \ + "Test function and arguments missing for %s" % name continue if state == STATE_READ_NAME: @@ -398,7 +401,7 @@ def parse_test_data(data_f): # Check dependencies m = re.search('depends_on\:(.*)', line) if m: - deps = m.group(1).split(':') + deps = [x.strip() for x in m.group(1).split(':') if len(x.strip())] else: # Read test vectors parts = escaped_split(line, ':') @@ -407,6 +410,8 @@ def parse_test_data(data_f): yield name, function, deps, args deps = [] state = STATE_READ_NAME + assert state != STATE_READ_ARGS, "Newline before arguments. " \ + "Test function and arguments missing for %s" % name def gen_dep_check(dep_id, dep): @@ -417,11 +422,9 @@ def gen_dep_check(dep_id, dep): :param dep: :return: """ - if dep[0] == '!': - noT = '!' - dep = dep[1:] - else: - noT = '' + assert dep_id > -1, "Dependency Id should be a positive integer." + noT, dep = ('!', dep[1:]) if dep[0] == '!' else ('', dep) + assert len(dep) > 0, "Dependency should not be an empty string." dep_check = ''' if ( dep_id == {id} ) {{ @@ -433,7 +436,6 @@ if ( dep_id == {id} ) }} else '''.format(noT=noT, macro=dep, id=dep_id) - return dep_check @@ -445,6 +447,8 @@ def gen_expression_check(exp_id, exp): :param exp: :return: """ + assert exp_id > -1, "Expression Id should be a positive integer." + assert len(exp) > 0, "Expression should not be an empty string." exp_code = ''' if ( exp_id == {exp_id} ) {{ @@ -455,6 +459,17 @@ else return exp_code +def find_unique_id(val, vals): + """ + Check if val already in vals. Gives a unique Identifier for the val. + :param val: + :param vals: + :return: + """ + if val not in vals: + vals.append(val) + + def gen_from_test_data(data_f, out_data_f, func_info, suite_deps): """ Generates dependency checks, expression code and intermediate data file from test data file. diff --git a/tests/scripts/generate_code_ut.py b/tests/scripts/generate_code_ut.py index f941316ef3..c261b27423 100644 --- a/tests/scripts/generate_code_ut.py +++ b/tests/scripts/generate_code_ut.py @@ -838,5 +838,277 @@ void func() self.assertRaises(AssertionError, parse_functions, s) +class ExcapedSplit(TestCase): + """ + Test suite for testing escaped_split() + """ + + def test_invalid_input(self): + """ + Test when input split character is not a character. + :return: + """ + self.assertRaises(ValueError, escaped_split, '', 'string') + + def test_empty_string(self): + """ + Test empty strig input. + :return: + """ + splits = escaped_split('', ':') + self.assertEqual(splits, []) + + def test_no_escape(self): + """ + Test with no escape character. The behaviour should be same as str.split() + :return: + """ + s = 'yahoo:google' + splits = escaped_split(s, ':') + self.assertEqual(splits, s.split(':')) + + def test_escaped_input(self): + """ + Test imput that has escaped delimiter. + :return: + """ + s = 'yahoo\:google:facebook' + splits = escaped_split(s, ':') + self.assertEqual(splits, ['yahoo:google', 'facebook']) + + def test_escaped_escape(self): + """ + Test imput that has escaped delimiter. + :return: + """ + s = 'yahoo\\\:google:facebook' + splits = escaped_split(s, ':') + self.assertEqual(splits, ['yahoo\\', 'google', 'facebook']) + + def test_all_at_once(self): + """ + Test imput that has escaped delimiter. + :return: + """ + s = 'yahoo\\\:google:facebook\:instagram\\\:bbc\\\\:wikipedia' + splits = escaped_split(s, ':') + self.assertEqual(splits, ['yahoo\\', 'google', 'facebook:instagram\\', 'bbc\\', 'wikipedia']) + +class ParseTestData(TestCase): + """ + Test suite for parse test data. + """ + + def test_parser(self): + """ + Test that tests are parsed correctly from data file. + :return: + """ + data = """ +Diffie-Hellman full exchange #1 +dhm_do_dhm:10:"23":10:"5" + +Diffie-Hellman full exchange #2 +dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622" + +Diffie-Hellman full exchange #3 +dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271" + +Diffie-Hellman selftest +dhm_selftest: +""" + s = StringIOWrapper('test_suite_ut.function', data) + tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)] + t1, t2, t3, t4 = tests + self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1') + self.assertEqual(t1[1], 'dhm_do_dhm') + self.assertEqual(t1[2], []) + self.assertEqual(t1[3], ['10', '"23"', '10', '"5"']) + + self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2') + self.assertEqual(t2[1], 'dhm_do_dhm') + self.assertEqual(t2[2], []) + self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"']) + + self.assertEqual(t3[0], 'Diffie-Hellman full exchange #3') + self.assertEqual(t3[1], 'dhm_do_dhm') + self.assertEqual(t3[2], []) + self.assertEqual(t3[3], ['10', '"9345098382739712938719287391879381271"', '10', '"9345098792137312973297123912791271"']) + + self.assertEqual(t4[0], 'Diffie-Hellman selftest') + self.assertEqual(t4[1], 'dhm_selftest') + self.assertEqual(t4[2], []) + self.assertEqual(t4[3], []) + + def test_with_dependencies(self): + """ + Test that tests with dependencies are parsed. + :return: + """ + data = """ +Diffie-Hellman full exchange #1 +depends_on:YAHOO +dhm_do_dhm:10:"23":10:"5" + +Diffie-Hellman full exchange #2 +dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622" + +""" + s = StringIOWrapper('test_suite_ut.function', data) + tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)] + t1, t2 = tests + self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1') + self.assertEqual(t1[1], 'dhm_do_dhm') + self.assertEqual(t1[2], ['YAHOO']) + self.assertEqual(t1[3], ['10', '"23"', '10', '"5"']) + + self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2') + self.assertEqual(t2[1], 'dhm_do_dhm') + self.assertEqual(t2[2], []) + self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"']) + + def test_no_args(self): + """ + Test AssertionError is raised when test function name and args line is missing. + :return: + """ + data = """ +Diffie-Hellman full exchange #1 +depends_on:YAHOO + + +Diffie-Hellman full exchange #2 +dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622" + +""" + s = StringIOWrapper('test_suite_ut.function', data) + e = None + try: + for x, y, z, a in parse_test_data(s): + pass + except AssertionError, e: + pass + self.assertEqual(type(e), AssertionError) + + def test_incomplete_data(self): + """ + Test AssertionError is raised when test function name and args line is missing. + :return: + """ + data = """ +Diffie-Hellman full exchange #1 +depends_on:YAHOO +""" + s = StringIOWrapper('test_suite_ut.function', data) + e = None + try: + for x, y, z, a in parse_test_data(s): + pass + except AssertionError, e: + pass + self.assertEqual(type(e), AssertionError) + + +class GenDepCheck(TestCase): + """ + Test suite for gen_dep_check(). It is assumed this function is called with valid inputs. + """ + + def test_gen_dep_check(self): + """ + Test that dependency check code generated correctly. + :return: + """ + expected = """ +if ( dep_id == 5 ) +{ +#if defined(YAHOO) + return( DEPENDENCY_SUPPORTED ); +#else + return( DEPENDENCY_NOT_SUPPORTED ); +#endif +} +else +""" + out = gen_dep_check(5, 'YAHOO') + self.assertEqual(out, expected) + + def test_noT(self): + """ + Test dependency with !. + :return: + """ + expected = """ +if ( dep_id == 5 ) +{ +#if !defined(YAHOO) + return( DEPENDENCY_SUPPORTED ); +#else + return( DEPENDENCY_NOT_SUPPORTED ); +#endif +} +else +""" + out = gen_dep_check(5, '!YAHOO') + self.assertEqual(out, expected) + + def test_empty_dependency(self): + """ + Test invalid dependency input. + :return: + """ + self.assertRaises(AssertionError, gen_dep_check, 5, '!') + + def test_negative_dep_id(self): + """ + Test invalid dependency input. + :return: + """ + self.assertRaises(AssertionError, gen_dep_check, -1, 'YAHOO') + + +class GenExpCheck(TestCase): + """ + Test suite for gen_expression_check(). It is assumed this function is called with valid inputs. + """ + + def test_gen_exp_check(self): + """ + Test that expression check code generated correctly. + :return: + """ + expected = """ +if ( exp_id == 5 ) +{ + *out_value = YAHOO; +} +else +""" + out = gen_expression_check(5, 'YAHOO') + self.assertEqual(out, expected) + + def test_invalid_expression(self): + """ + Test invalid expression input. + :return: + """ + self.assertRaises(AssertionError, gen_expression_check, 5, '') + + def test_negative_exp_id(self): + """ + Test invalid expression id. + :return: + """ + self.assertRaises(AssertionError, gen_expression_check, -1, 'YAHOO') + + +class GenFromTestData(TestCase): + """ + Test suite for gen_from_test_data() + """ + + pass + + if __name__=='__main__': - unittest_main() \ No newline at end of file + unittest_main()