Merge branch 'development' into sha3

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2023-05-05 16:01:18 +02:00
commit d06c6fc45b
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
405 changed files with 28422 additions and 16737 deletions

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,8 @@ import argparse
import sys
import traceback
import re
import subprocess
import os
import check_test_cases
@ -51,6 +53,26 @@ class TestCaseOutcomes:
"""
return len(self.successes) + len(self.failures)
def execute_reference_driver_tests(ref_component, driver_component, outcome_file):
"""Run the tests specified in ref_component and driver_component. Results
are stored in the output_file and they will be used for the following
coverage analysis"""
# If the outcome file already exists, we assume that the user wants to
# perform the comparison analysis again without repeating the tests.
if os.path.exists(outcome_file):
Results.log("Outcome file (" + outcome_file + ") already exists. " + \
"Tests will be skipped.")
return
shell_command = "tests/scripts/all.sh --outcome-file " + outcome_file + \
" " + ref_component + " " + driver_component
Results.log("Running: " + shell_command)
ret_val = subprocess.run(shell_command.split(), check=False).returncode
if ret_val != 0:
Results.log("Error: failed to run reference/driver components")
sys.exit(ret_val)
def analyze_coverage(results, outcomes):
"""Check that all available test cases are executed at least once."""
available = check_test_cases.collect_available_test_cases()
@ -82,7 +104,7 @@ def analyze_driver_vs_reference(outcomes, component_ref, component_driver,
full_test_suite = key.split(';')[0] # retrieve full test suite name
test_string = key.split(';')[1] # retrieve the text string of this test
test_suite = full_test_suite.split('.')[0] # retrieve main part of test suite name
if test_suite in ignored_suites:
if test_suite in ignored_suites or full_test_suite in ignored_suites:
continue
if ((full_test_suite in ignored_test) and
(test_string in ignored_test[full_test_suite])):
@ -96,7 +118,7 @@ def analyze_driver_vs_reference(outcomes, component_ref, component_driver,
if component_ref in entry:
reference_test_passed = True
if(reference_test_passed and not driver_test_passed):
print(key)
Results.log(key)
result = False
return result
@ -131,16 +153,19 @@ def do_analyze_coverage(outcome_file, args):
"""Perform coverage analysis."""
del args # unused
outcomes = read_outcome_file(outcome_file)
print("\n*** Analyze coverage ***\n")
Results.log("\n*** Analyze coverage ***\n")
results = analyze_outcomes(outcomes)
return results.error_count == 0
def do_analyze_driver_vs_reference(outcome_file, args):
"""Perform driver vs reference analyze."""
execute_reference_driver_tests(args['component_ref'], \
args['component_driver'], outcome_file)
ignored_suites = ['test_suite_' + x for x in args['ignored_suites']]
outcomes = read_outcome_file(outcome_file)
print("\n*** Analyze driver {} vs reference {} ***\n".format(
Results.log("\n*** Analyze driver {} vs reference {} ***\n".format(
args['component_driver'], args['component_ref']))
return analyze_driver_vs_reference(outcomes, args['component_ref'],
args['component_driver'], ignored_suites,
@ -152,9 +177,12 @@ TASKS = {
'test_function': do_analyze_coverage,
'args': {}
},
# How to use analyze_driver_vs_reference_xxx locally:
# 1. tests/scripts/all.sh --outcome-file "$PWD/out.csv" <component_ref> <component_driver>
# 2. tests/scripts/analyze_outcomes.py out.csv analyze_driver_vs_reference_xxx
# There are 2 options to use analyze_driver_vs_reference_xxx locally:
# 1. Run tests and then analysis:
# - tests/scripts/all.sh --outcome-file "$PWD/out.csv" <component_ref> <component_driver>
# - tests/scripts/analyze_outcomes.py out.csv analyze_driver_vs_reference_xxx
# 2. Let this script run both automatically:
# - tests/scripts/analyze_outcomes.py out.csv analyze_driver_vs_reference_xxx
'analyze_driver_vs_reference_hash': {
'test_function': do_analyze_driver_vs_reference,
'args': {
@ -162,24 +190,99 @@ TASKS = {
'component_driver': 'test_psa_crypto_config_accel_hash_use_psa',
'ignored_suites': [
'shax', 'mdx', # the software implementations that are being excluded
'md', # the legacy abstraction layer that's being excluded
'md.psa', # purposefully depends on whether drivers are present
],
'ignored_tests': {
}
}
},
'analyze_driver_vs_reference_ecdsa': {
'analyze_driver_vs_reference_all_ec_algs': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_config_reference_ecdsa_use_psa',
'component_driver': 'test_psa_crypto_config_accel_ecdsa_use_psa',
'component_ref': 'test_psa_crypto_config_reference_all_ec_algs_use_psa',
'component_driver': 'test_psa_crypto_config_accel_all_ec_algs_use_psa',
'ignored_suites': [
'ecdsa', # the software implementation that's excluded
'ecdsa',
'ecdh',
'ecjpake',
],
'ignored_tests': {
'test_suite_random': [
'PSA classic wrapper: ECDSA signature (SECP256R1)',
],
# In the accelerated test ECP_C is not set (only ECP_LIGHT is)
# so we must ignore disparities in the tests for which ECP_C
# is required.
'test_suite_ecp': [
'ECP check public-private #1 (OK)',
'ECP check public-private #2 (group none)',
'ECP check public-private #3 (group mismatch)',
'ECP check public-private #4 (Qx mismatch)',
'ECP check public-private #5 (Qy mismatch)',
'ECP check public-private #6 (wrong Qx)',
'ECP check public-private #7 (wrong Qy)',
'ECP gen keypair [#1]',
'ECP gen keypair [#2]',
'ECP gen keypair [#3]',
'ECP gen keypair wrapper',
'ECP point muladd secp256r1 #1',
'ECP point muladd secp256r1 #2',
'ECP point multiplication Curve25519 (element of order 2: origin) #3',
'ECP point multiplication Curve25519 (element of order 4: 1) #4',
'ECP point multiplication Curve25519 (element of order 8) #5',
'ECP point multiplication Curve25519 (normalized) #1',
'ECP point multiplication Curve25519 (not normalized) #2',
'ECP point multiplication rng fail Curve25519',
'ECP point multiplication rng fail secp256r1',
'ECP test vectors Curve25519',
'ECP test vectors Curve448 (RFC 7748 6.2, after decodeUCoordinate)',
'ECP test vectors brainpoolP256r1 rfc 7027',
'ECP test vectors brainpoolP384r1 rfc 7027',
'ECP test vectors brainpoolP512r1 rfc 7027',
'ECP test vectors secp192k1',
'ECP test vectors secp192r1 rfc 5114',
'ECP test vectors secp224k1',
'ECP test vectors secp224r1 rfc 5114',
'ECP test vectors secp256k1',
'ECP test vectors secp256r1 rfc 5114',
'ECP test vectors secp384r1 rfc 5114',
'ECP test vectors secp521r1 rfc 5114',
]
}
}
},
'analyze_driver_vs_reference_all_ec_algs_no_ecp': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_full_reference_all_ec_algs_no_ecp_use_psa',
'component_driver': 'test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa',
'ignored_suites': [
# Ignore test suites for the modules that are disabled in the
# accelerated test case.
'ecp',
'ecdsa',
'ecdh',
'ecjpake',
],
'ignored_tests': {
'test_suite_random': [
'PSA classic wrapper: ECDSA signature (SECP256R1)',
],
'test_suite_psa_crypto': [
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1',
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1 (1 redraw)',
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1, exercise ECDSA',
'PSA key derivation: HKDF-SHA-256 -> ECC secp384r1',
'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #0',
'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #1',
'PSA key derivation: bits=7 invalid for ECC BRAINPOOL_P_R1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECP_K1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECP_R1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECP_R2 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECT_K1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECT_R1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECT_R2 (ECC enabled)',
]
}
}
},
@ -201,7 +304,7 @@ def main():
if options.list:
for task in TASKS:
print(task)
Results.log(task)
sys.exit(0)
result = True
@ -213,7 +316,7 @@ def main():
for task in tasks:
if task not in TASKS:
print('Error: invalid task: {}'.format(task))
Results.log('Error: invalid task: {}'.format(task))
sys.exit(1)
for task in TASKS:
@ -223,7 +326,7 @@ def main():
if result is False:
sys.exit(1)
print("SUCCESS :-)")
Results.log("SUCCESS :-)")
except Exception: # pylint: disable=broad-except
# Print the backtrace and exit explicitly with our chosen status.
traceback.print_exc()

View file

@ -277,7 +277,7 @@ REVERSE_DEPENDENCIES = {
# if a given define is the only one enabled from an exclusive group.
EXCLUSIVE_GROUPS = {
'MBEDTLS_SHA512_C': ['-MBEDTLS_SSL_COOKIE_C',
'-MBEDTLS_SSL_PROTO_TLS1_3'],
'-MBEDTLS_SSL_TLS_C'],
'MBEDTLS_ECP_DP_CURVE448_ENABLED': ['-MBEDTLS_ECDSA_C',
'-MBEDTLS_ECDSA_DETERMINISTIC',
'-MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',

View file

@ -49,7 +49,7 @@ class TestData:
Take in test_suite_pkcs7.data file.
Allow for new tests to be added.
"""
mandatory_dep = "MBEDTLS_SHA256_C"
mandatory_dep = "MBEDTLS_MD_CAN_SHA256"
test_name = "PKCS7 Parse Failure Invalid ASN1"
test_function = "pkcs7_asn1_fail:"
def __init__(self, file_name):

View file

@ -171,6 +171,28 @@ import string
import argparse
# Types recognized as signed integer arguments in test functions.
SIGNED_INTEGER_TYPES = frozenset([
'char',
'short',
'short int',
'int',
'int8_t',
'int16_t',
'int32_t',
'int64_t',
'intmax_t',
'long',
'long int',
'long long int',
'mbedtls_mpi_sint',
'psa_status_t',
])
# Types recognized as string arguments in test functions.
STRING_TYPES = frozenset(['char*', 'const char*', 'char const*'])
# Types recognized as hex data arguments in test functions.
DATA_TYPES = frozenset(['data_t*', 'const data_t*', 'data_t const*'])
BEGIN_HEADER_REGEX = r'/\*\s*BEGIN_HEADER\s*\*/'
END_HEADER_REGEX = r'/\*\s*END_HEADER\s*\*/'
@ -192,9 +214,6 @@ CONDITION_REGEX = r'({})(?:\s*({})\s*({}))?$'.format(C_IDENTIFIER_REGEX,
CONDITION_OPERATOR_REGEX,
CONDITION_VALUE_REGEX)
TEST_FUNCTION_VALIDATION_REGEX = r'\s*void\s+(?P<func_name>\w+)\s*\('
INT_CHECK_REGEX = r'int\s+.*'
CHAR_CHECK_REGEX = r'char\s*\*\s*.*'
DATA_T_CHECK_REGEX = r'data_t\s*\*\s*.*'
FUNCTION_ARG_LIST_END_REGEX = r'.*\)'
EXIT_LABEL_REGEX = r'^exit:'
@ -303,7 +322,7 @@ def gen_function_wrapper(name, local_vars, args_dispatch):
:param name: Test function name
:param local_vars: Local variables declaration code
:param args_dispatch: List of dispatch arguments.
Ex: ['(char *)params[0]', '*((int *)params[1])']
Ex: ['(char *) params[0]', '*((int *) params[1])']
:return: Test function wrapper.
"""
# Then create the wrapper
@ -444,6 +463,49 @@ def parse_function_dependencies(line):
return dependencies
ARGUMENT_DECLARATION_REGEX = re.compile(r'(.+?) ?(?:\bconst\b)? ?(\w+)\Z', re.S)
def parse_function_argument(arg, arg_idx, args, local_vars, args_dispatch):
"""
Parses one test function's argument declaration.
:param arg: argument declaration.
:param arg_idx: current wrapper argument index.
:param args: accumulator of arguments' internal types.
:param local_vars: accumulator of internal variable declarations.
:param args_dispatch: accumulator of argument usage expressions.
:return: the number of new wrapper arguments,
or None if the argument declaration is invalid.
"""
# Normalize whitespace
arg = arg.strip()
arg = re.sub(r'\s*\*\s*', r'*', arg)
arg = re.sub(r'\s+', r' ', arg)
# Extract name and type
m = ARGUMENT_DECLARATION_REGEX.search(arg)
if not m:
# E.g. "int x[42]"
return None
typ, _ = m.groups()
if typ in SIGNED_INTEGER_TYPES:
args.append('int')
args_dispatch.append('((mbedtls_test_argument_t *) params[%d])->sint' % arg_idx)
return 1
if typ in STRING_TYPES:
args.append('char*')
args_dispatch.append('(char *) params[%d]' % arg_idx)
return 1
if typ in DATA_TYPES:
args.append('hex')
# create a structure
pointer_initializer = '(uint8_t *) params[%d]' % arg_idx
len_initializer = '((mbedtls_test_argument_t *) params[%d])->len' % (arg_idx+1)
local_vars.append(' data_t data%d = {%s, %s};\n' %
(arg_idx, pointer_initializer, len_initializer))
args_dispatch.append('&data%d' % arg_idx)
return 2
return None
ARGUMENT_LIST_REGEX = re.compile(r'\((.*?)\)', re.S)
def parse_function_arguments(line):
"""
Parses test function signature for validation and generates
@ -455,42 +517,27 @@ def parse_function_arguments(line):
:return: argument list, local variables for
wrapper function and argument dispatch code.
"""
args = []
local_vars = ''
args_dispatch = []
arg_idx = 0
# Remove characters before arguments
line = line[line.find('(') + 1:]
# Process arguments, ex: <type> arg1, <type> arg2 )
# This script assumes that the argument list is terminated by ')'
# i.e. the test functions will not have a function pointer
# argument.
for arg in line[:line.find(')')].split(','):
arg = arg.strip()
if arg == '':
continue
if re.search(INT_CHECK_REGEX, arg.strip()):
args.append('int')
args_dispatch.append('*( (int *) params[%d] )' % arg_idx)
elif re.search(CHAR_CHECK_REGEX, arg.strip()):
args.append('char*')
args_dispatch.append('(char *) params[%d]' % arg_idx)
elif re.search(DATA_T_CHECK_REGEX, arg.strip()):
args.append('hex')
# create a structure
pointer_initializer = '(uint8_t *) params[%d]' % arg_idx
len_initializer = '*( (uint32_t *) params[%d] )' % (arg_idx+1)
local_vars += """ data_t data%d = {%s, %s};
""" % (arg_idx, pointer_initializer, len_initializer)
args_dispatch.append('&data%d' % arg_idx)
arg_idx += 1
else:
m = ARGUMENT_LIST_REGEX.search(line)
arg_list = m.group(1).strip()
if arg_list in ['', 'void']:
return [], '', []
args = []
local_vars = []
args_dispatch = []
arg_idx = 0
for arg in arg_list.split(','):
indexes = parse_function_argument(arg, arg_idx,
args, local_vars, args_dispatch)
if indexes is None:
raise ValueError("Test function arguments can only be 'int', "
"'char *' or 'data_t'\n%s" % line)
arg_idx += 1
arg_idx += indexes
return args, local_vars, args_dispatch
return args, ''.join(local_vars), args_dispatch
def generate_function_code(name, code, local_vars, args_dispatch,
@ -705,7 +752,7 @@ def parse_test_data(data_f):
execution.
:param data_f: file object of the data file.
:return: Generator that yields test name, function name,
:return: Generator that yields line number, test name, function name,
dependency list and function argument list.
"""
__state_read_name = 0
@ -748,7 +795,7 @@ def parse_test_data(data_f):
parts = escaped_split(line, ':')
test_function = parts[0]
args = parts[1:]
yield name, test_function, dependencies, args
yield data_f.line_no, name, test_function, dependencies, args
dependencies = []
state = __state_read_name
if state == __state_read_args:
@ -846,6 +893,14 @@ def write_dependencies(out_data_f, test_dependencies, unique_dependencies):
return dep_check_code
INT_VAL_REGEX = re.compile(r'-?(\d+|0x[0-9a-f]+)$', re.I)
def val_is_int(val: str) -> bool:
"""Whether val is suitable as an 'int' parameter in the .datax file."""
if not INT_VAL_REGEX.match(val):
return False
# Limit the range to what is guaranteed to get through strtol()
return abs(int(val, 0)) <= 0x7fffffff
def write_parameters(out_data_f, test_args, func_args, unique_expressions):
"""
Writes test parameters to the intermediate data file, replacing
@ -864,9 +919,9 @@ def write_parameters(out_data_f, test_args, func_args, unique_expressions):
typ = func_args[i]
val = test_args[i]
# check if val is a non literal int val (i.e. an expression)
if typ == 'int' and not re.match(r'(\d+|0x[0-9a-f]+)$',
val, re.I):
# Pass small integer constants literally. This reduces the size of
# the C code. Register anything else as an expression.
if typ == 'int' and not val_is_int(val):
typ = 'exp'
if val not in unique_expressions:
unique_expressions.append(val)
@ -909,6 +964,24 @@ def gen_suite_dep_checks(suite_dependencies, dep_check_code, expression_code):
return dep_check_code, expression_code
def get_function_info(func_info, function_name, line_no):
"""Look up information about a test function by name.
Raise an informative expression if function_name is not found.
:param func_info: dictionary mapping function names to their information.
:param function_name: the function name as written in the .function and
.data files.
:param line_no: line number for error messages.
:return Function information (id, args).
"""
test_function_name = 'test_' + function_name
if test_function_name not in func_info:
raise GeneratorInputError("%d: Function %s not found!" %
(line_no, test_function_name))
return func_info[test_function_name]
def gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies):
"""
This function reads test case name, dependencies and test vectors
@ -931,7 +1004,7 @@ def gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies):
unique_expressions = []
dep_check_code = ''
expression_code = ''
for test_name, function_name, test_dependencies, test_args in \
for line_no, test_name, function_name, test_dependencies, test_args in \
parse_test_data(data_f):
out_data_f.write(test_name + '\n')
@ -940,18 +1013,15 @@ def gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies):
unique_dependencies)
# Write test function name
test_function_name = 'test_' + function_name
if test_function_name not in func_info:
raise GeneratorInputError("Function %s not found!" %
test_function_name)
func_id, func_args = func_info[test_function_name]
func_id, func_args = \
get_function_info(func_info, function_name, line_no)
out_data_f.write(str(func_id))
# Write parameters
if len(test_args) != len(func_args):
raise GeneratorInputError("Invalid number of arguments in test "
raise GeneratorInputError("%d: Invalid number of arguments in test "
"%s. See function %s signature." %
(test_name, function_name))
(line_no, test_name, function_name))
expression_code += write_parameters(out_data_f, test_args, func_args,
unique_expressions)

View file

@ -352,7 +352,6 @@ class MbedTLSBase(TLSProgram):
if self._named_groups:
named_groups = ','.join(self._named_groups)
ret += ["curves={named_groups}".format(named_groups=named_groups)]
ret += ['force_version=tls13']
return ret
def pre_checks(self):

View file

@ -485,9 +485,10 @@ class ParseFuncSignature(TestCase):
args, local, arg_dispatch = parse_function_arguments(line)
self.assertEqual(args, ['char*', 'int', 'int'])
self.assertEqual(local, '')
self.assertEqual(arg_dispatch, ['(char *) params[0]',
'*( (int *) params[1] )',
'*( (int *) params[2] )'])
self.assertEqual(arg_dispatch,
['(char *) params[0]',
'((mbedtls_test_argument_t *) params[1])->sint',
'((mbedtls_test_argument_t *) params[2])->sint'])
def test_hex_params(self):
"""
@ -499,22 +500,22 @@ class ParseFuncSignature(TestCase):
self.assertEqual(args, ['char*', 'hex', 'int'])
self.assertEqual(local,
' data_t data1 = {(uint8_t *) params[1], '
'*( (uint32_t *) params[2] )};\n')
'((mbedtls_test_argument_t *) params[2])->len};\n')
self.assertEqual(arg_dispatch, ['(char *) params[0]',
'&data1',
'*( (int *) params[3] )'])
'((mbedtls_test_argument_t *) params[3])->sint'])
def test_unsupported_arg(self):
"""
Test unsupported arguments (not among int, char * and data_t)
Test unsupported argument type
:return:
"""
line = 'void entropy_threshold( char * a, data_t * h, char result )'
line = 'void entropy_threshold( char * a, data_t * h, unknown_t result )'
self.assertRaises(ValueError, parse_function_arguments, line)
def test_no_params(self):
def test_empty_params(self):
"""
Test no parameters.
Test no parameters (nothing between parentheses).
:return:
"""
line = 'void entropy_threshold()'
@ -523,6 +524,39 @@ class ParseFuncSignature(TestCase):
self.assertEqual(local, '')
self.assertEqual(arg_dispatch, [])
def test_blank_params(self):
"""
Test no parameters (space between parentheses).
:return:
"""
line = 'void entropy_threshold( )'
args, local, arg_dispatch = parse_function_arguments(line)
self.assertEqual(args, [])
self.assertEqual(local, '')
self.assertEqual(arg_dispatch, [])
def test_void_params(self):
"""
Test no parameters (void keyword).
:return:
"""
line = 'void entropy_threshold(void)'
args, local, arg_dispatch = parse_function_arguments(line)
self.assertEqual(args, [])
self.assertEqual(local, '')
self.assertEqual(arg_dispatch, [])
def test_void_space_params(self):
"""
Test no parameters (void with spaces).
:return:
"""
line = 'void entropy_threshold( void )'
args, local, arg_dispatch = parse_function_arguments(line)
self.assertEqual(args, [])
self.assertEqual(local, '')
self.assertEqual(arg_dispatch, [])
class ParseFunctionCode(TestCase):
"""
@ -1264,29 +1298,33 @@ dhm_selftest:
# List of (name, function_name, dependencies, args)
tests = list(parse_test_data(stream))
test1, test2, test3, test4 = tests
self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
self.assertEqual(test1[1], 'dhm_do_dhm')
self.assertEqual(test1[2], [])
self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
self.assertEqual(test1[0], 3)
self.assertEqual(test1[1], 'Diffie-Hellman full exchange #1')
self.assertEqual(test1[2], 'dhm_do_dhm')
self.assertEqual(test1[3], [])
self.assertEqual(test1[4], ['10', '"23"', '10', '"5"'])
self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
self.assertEqual(test2[1], 'dhm_do_dhm')
self.assertEqual(test2[2], [])
self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
self.assertEqual(test2[0], 6)
self.assertEqual(test2[1], 'Diffie-Hellman full exchange #2')
self.assertEqual(test2[2], 'dhm_do_dhm')
self.assertEqual(test2[3], [])
self.assertEqual(test2[4], ['10', '"93450983094850938450983409623"',
'10', '"9345098304850938450983409622"'])
self.assertEqual(test3[0], 'Diffie-Hellman full exchange #3')
self.assertEqual(test3[1], 'dhm_do_dhm')
self.assertEqual(test3[2], [])
self.assertEqual(test3[3], ['10',
self.assertEqual(test3[0], 9)
self.assertEqual(test3[1], 'Diffie-Hellman full exchange #3')
self.assertEqual(test3[2], 'dhm_do_dhm')
self.assertEqual(test3[3], [])
self.assertEqual(test3[4], ['10',
'"9345098382739712938719287391879381271"',
'10',
'"9345098792137312973297123912791271"'])
self.assertEqual(test4[0], 'Diffie-Hellman selftest')
self.assertEqual(test4[1], 'dhm_selftest')
self.assertEqual(test4[2], [])
self.assertEqual(test4[0], 12)
self.assertEqual(test4[1], 'Diffie-Hellman selftest')
self.assertEqual(test4[2], 'dhm_selftest')
self.assertEqual(test4[3], [])
self.assertEqual(test4[4], [])
def test_with_dependencies(self):
"""
@ -1306,15 +1344,17 @@ dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
# List of (name, function_name, dependencies, args)
tests = list(parse_test_data(stream))
test1, test2 = tests
self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
self.assertEqual(test1[1], 'dhm_do_dhm')
self.assertEqual(test1[2], ['YAHOO'])
self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
self.assertEqual(test1[0], 4)
self.assertEqual(test1[1], 'Diffie-Hellman full exchange #1')
self.assertEqual(test1[2], 'dhm_do_dhm')
self.assertEqual(test1[3], ['YAHOO'])
self.assertEqual(test1[4], ['10', '"23"', '10', '"5"'])
self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
self.assertEqual(test2[1], 'dhm_do_dhm')
self.assertEqual(test2[2], [])
self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
self.assertEqual(test2[0], 7)
self.assertEqual(test2[1], 'Diffie-Hellman full exchange #2')
self.assertEqual(test2[2], 'dhm_do_dhm')
self.assertEqual(test2[3], [])
self.assertEqual(test2[4], ['10', '"93450983094850938450983409623"',
'10', '"9345098304850938450983409622"'])
def test_no_args(self):
@ -1335,7 +1375,7 @@ dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
stream = StringIOWrapper('test_suite_ut.function', data)
err = None
try:
for _, _, _, _ in parse_test_data(stream):
for _, _, _, _, _ in parse_test_data(stream):
pass
except GeneratorInputError as err:
self.assertEqual(type(err), GeneratorInputError)
@ -1353,7 +1393,7 @@ depends_on:YAHOO
stream = StringIOWrapper('test_suite_ut.function', data)
err = None
try:
for _, _, _, _ in parse_test_data(stream):
for _, _, _, _, _ in parse_test_data(stream):
pass
except GeneratorInputError as err:
self.assertEqual(type(err), GeneratorInputError)