247 lines
12 KiB
Python
247 lines
12 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
import logging
|
|
logger = logging.getLogger('__unittest__')
|
|
|
|
REPORT_LEVEL_FAIL = logging.ERROR
|
|
REPORT_LEVEL_INSPECT = logging.WARNING
|
|
REPORT_LEVEL_PASS = logging.INFO
|
|
|
|
|
|
def __get_repr__(value, data_filter=repr):
|
|
if type(value) == dict:
|
|
return '{ ' + ', '.join(['%s: %s' % (repr(key), __get_repr__(value.get(key))) for key in value.keys()]) + ' }'
|
|
elif type(value) == list:
|
|
return '[ ' + ', '.join(['%s' % (__get_repr__(v)) for v in value]) + ' ]'
|
|
else:
|
|
return data_filter(value)
|
|
|
|
|
|
def __report_result__(result, description, data_filter=repr):
|
|
logger.debug('Result (%s): %s (%s)', description, __get_repr__(result, data_filter), repr(type(result)))
|
|
|
|
|
|
def __report_expectation_equivalency__(expectation, description, data_filter=repr):
|
|
logger.debug('Expectation (%s): result = %s (%s)', description, __get_repr__(expectation, data_filter), repr(type(expectation)))
|
|
|
|
|
|
def __report_expectation_inlist__(expectation, description, data_filter=repr):
|
|
logger.debug('Expectation (%s): %s in result', description, __get_repr__(expectation, data_filter))
|
|
|
|
|
|
def __report_expectation_range__(min_expectation, max_expectation, description):
|
|
logger.debug('Expectation (%s): %s <= result <= %s', description, __get_repr__(min_expectation), __get_repr__(max_expectation))
|
|
|
|
|
|
def __equivalent_dict__(result, expectation, report_comment_fail=None, dict_key='test_variable'):
|
|
result_keys = set(result.keys())
|
|
expect_keys = set(expectation.keys())
|
|
#
|
|
log_lvl = REPORT_LEVEL_PASS
|
|
#
|
|
# missing elements
|
|
#
|
|
missing_keys = expect_keys - result_keys
|
|
if len(missing_keys) > 0:
|
|
logger.error('Missing key(s) in dict (%s): %s.' + report_comment_fail, dict_key, ', '.join(['%s' % repr(key) for key in missing_keys]))
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
#
|
|
# odd elements
|
|
#
|
|
odd_keys = result_keys - expect_keys
|
|
if len(odd_keys) > 0:
|
|
logger.error('Odd key(s) in dict (%s): %s.' + report_comment_fail, dict_key, ', '.join(['%s' % repr(key) for key in odd_keys]))
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
#
|
|
# differences
|
|
#
|
|
common_keys = result_keys - missing_keys - odd_keys
|
|
for key in common_keys:
|
|
ll = __equivalent__(result[key], expectation[key], report_comment_fail=report_comment_fail, dict_key=dict_key + ('.' if dict_key != '' else '') + str(key))
|
|
if log_lvl < ll:
|
|
log_lvl = ll
|
|
return log_lvl
|
|
|
|
|
|
def __equivalent_list__(result, expectation, report_comment_fail=None, list_key='test_variable'):
|
|
_odd_ = []
|
|
_result_ = result[:]
|
|
e_index = list(range(0, len(expectation)))
|
|
log_lvl = REPORT_LEVEL_PASS
|
|
r = 0
|
|
while len(_result_) > 0:
|
|
value = _result_.pop(0)
|
|
just_type_diff = None
|
|
for e in e_index:
|
|
ll = __equivalent__(value, expectation[e], None)
|
|
if ll == REPORT_LEVEL_PASS:
|
|
e_index.pop(e_index.index(e))
|
|
break
|
|
elif ll == REPORT_LEVEL_INSPECT:
|
|
just_type_diff = e
|
|
else:
|
|
if just_type_diff is None:
|
|
_odd_.append(value)
|
|
else:
|
|
log_lvl = __equivalent__(value, expectation[just_type_diff], report_comment_fail, dict_key='%s[%d]' % (list_key, r))
|
|
e_index.pop(e_index.index(just_type_diff))
|
|
r += 1
|
|
#
|
|
# missing elements
|
|
#
|
|
if len(e_index) > 0:
|
|
logger.error('Missing value(s) in list (%s): %s.' + report_comment_fail, list_key, ', '.join(['%s' % repr(expectation[e]) for e in e_index]))
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
#
|
|
# odd elements
|
|
#
|
|
if len(_odd_) > 0:
|
|
logger.error('Odd value(s) in list (%s): %s.' + report_comment_fail, list_key, ', '.join(['%s' % repr(v) for v in _odd_]))
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
return log_lvl
|
|
|
|
|
|
def __equivalent__(result, expectation, report_comment_fail=None, dict_key='test_variable'):
|
|
report_comment_fail = (' ' + report_comment_fail) if report_comment_fail is not None else ''
|
|
log_lvl = REPORT_LEVEL_PASS
|
|
if type(result) == dict and type(expectation) == dict:
|
|
ll = __equivalent_dict__(result, expectation, report_comment_fail, dict_key)
|
|
if log_lvl < ll:
|
|
log_lvl = ll
|
|
elif type(result) == list and type(expectation) == list:
|
|
ll = __equivalent_list__(result, expectation, report_comment_fail, dict_key)
|
|
if log_lvl < ll:
|
|
log_lvl = ll
|
|
else:
|
|
if result != expectation:
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
logger.error('Content %s is incorrect' + (' for %s' % dict_key if dict_key != '' else '') + '.' + report_comment_fail, __get_repr__(result))
|
|
if type(result) != type(expectation):
|
|
if log_lvl < REPORT_LEVEL_INSPECT:
|
|
log_lvl = REPORT_LEVEL_INSPECT
|
|
logger.warning('Type %s is NOT %s%s (%s). ' + report_comment_fail.strip() or '', __get_repr__(type(result)), __get_repr__(type(expectation)), (' for %s' % dict_key if dict_key != '' else ''), __get_repr__(result))
|
|
return log_lvl
|
|
|
|
|
|
def equivalency_chk(result, expectation, tcl, description='Variable', report_comment_fail=None, data_filter=repr):
|
|
"""
|
|
Routine to check values for equivalency inside a test run and report to a testCaseLogger.
|
|
|
|
:param result: The result of a test execution of a module
|
|
:type result: All types are supported
|
|
:param expectation: The expected value (shall be equivalent to result)
|
|
:type expectation: All types are supported
|
|
:param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
|
|
:type description: str
|
|
:param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
|
|
:type report_comment_fail: str
|
|
"""
|
|
__report_result__(result, description, data_filter=data_filter)
|
|
__report_expectation_equivalency__(expectation, description, data_filter=data_filter)
|
|
report_level = __equivalent__(result, expectation, report_comment_fail=report_comment_fail, dict_key='result')
|
|
if report_level == REPORT_LEVEL_PASS:
|
|
tcl.log(report_level, description + ' is correct (Content %s and Type is %s).', data_filter(result), repr(type(result)))
|
|
else:
|
|
tcl.log(report_level, description + ' is NOT correct. See detailed log for more information.')
|
|
return report_level
|
|
|
|
|
|
class equivalency_order_chk(object):
|
|
def __init__(self, ordered_values, tcl, description='Variable', report_comment_fail=None):
|
|
self._expected_values = ordered_values
|
|
self._tcl = tcl
|
|
self._description = description
|
|
self._report_comment_fail = report_comment_fail
|
|
self._reported_values = []
|
|
|
|
def report_value(self, value):
|
|
self._reported_values.append(value)
|
|
|
|
def report(self):
|
|
__report_result__(self._reported_values, self._description)
|
|
__report_expectation_equivalency__(self._expected_values, self._description)
|
|
report_lvl = REPORT_LEVEL_PASS
|
|
for i in range(0, min(len(self._expected_values), len(self._reported_values))):
|
|
report_lvl = max(report_lvl, equivalency_chk(self._reported_values[i], self._expected_values[i], logger, 'Submitted value number %d' % (i + 1), self._report_comment_fail))
|
|
if report_lvl <= REPORT_LEVEL_PASS:
|
|
self._tcl.log(report_lvl, self._description + ': Values and number of submitted values is correct. See detailed log for more information.')
|
|
else:
|
|
self._tcl.log(report_lvl, self._description + ': Values and number of submitted values is NOT correct. See detailed log for more information.')
|
|
return report_lvl
|
|
|
|
def report_range_check(self, minus_tollerance, plus_tollerance):
|
|
__report_result__(self._reported_values, self._description)
|
|
report_lvl = REPORT_LEVEL_PASS
|
|
report_lvl = max(report_lvl, equivalency_chk(len(self._reported_values), len(self._reported_values), self._tcl, 'Number of submitted values', self._report_comment_fail))
|
|
for i in range(0, min(len(self._expected_values), len(self._reported_values))):
|
|
report_lvl = max(report_lvl, range_chk(self._reported_values[i], self._expected_values[i] - minus_tollerance, self._expected_values[i] + plus_tollerance, logger, 'Submitted value number %d' % (i + 1), self._report_comment_fail))
|
|
if report_lvl <= REPORT_LEVEL_PASS:
|
|
self._tcl.log(report_lvl, self._description + ': Valueaccuracy and number of submitted values is correct. See detailed log for more information.')
|
|
else:
|
|
self._tcl.log(report_lvl, self._description + ': Valueaccuracy and number of submitted values is NOT correct. See detailed log for more information.')
|
|
return report_lvl
|
|
|
|
|
|
def __range__(result, min_expectation, max_expectation, report_comment_fail):
|
|
report_comment_fail = (' ' + report_comment_fail) if report_comment_fail is not None else ''
|
|
log_lvl = REPORT_LEVEL_PASS
|
|
if result < min_expectation or result > max_expectation:
|
|
log_lvl = REPORT_LEVEL_FAIL
|
|
logger.error('Content %s is incorrect.' + report_comment_fail, __get_repr__(result))
|
|
if type(result) != type(min_expectation) or type(result) != type(max_expectation):
|
|
if log_lvl < REPORT_LEVEL_INSPECT:
|
|
log_lvl = REPORT_LEVEL_INSPECT
|
|
logger.warning('Type %s is incorrect.' + report_comment_fail, __get_repr__(type(result)))
|
|
return log_lvl
|
|
|
|
|
|
def range_chk(result, min_expectation, max_expectation, tcl, description='Value', report_comment_fail=None):
|
|
"""
|
|
Routine to check values to be in a range inside a test run and report to a testCaseLogger.
|
|
|
|
:param result: The result of a test execution of a module
|
|
:type result: All numeric types are supported
|
|
:param min: The result shall be more or equal
|
|
:type min: All numeric types are supported
|
|
:param max: The result shall be less or equivalent
|
|
:type max: All numeric types are supported
|
|
:param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
|
|
:type description: str
|
|
:param report_level_pass: The reporting level as defined in :class:`logging` (e.g.: logging.INFO)
|
|
:param report_level_fail: The reporting level as defined in :class:`logging` (e.g.: logging.ERROR)
|
|
:param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
|
|
:type report_comment_fail: str
|
|
"""
|
|
__report_result__(result, description)
|
|
__report_expectation_range__(min_expectation, max_expectation, description)
|
|
report_level = __range__(result, min_expectation, max_expectation, report_comment_fail=report_comment_fail)
|
|
if report_level == REPORT_LEVEL_PASS:
|
|
tcl.log(report_level, description + ' is correct (Content %s in [%s ... %s] and Type is %s).', repr(result), repr(min_expectation), repr(max_expectation), repr(type(result)))
|
|
else:
|
|
tcl.log(report_level, description + ' is NOT correct. See detailed log for more information.')
|
|
return report_level
|
|
|
|
|
|
def in_list_dict_chk(result_list, expectation_key, tcl, description='Value', report_comment_fail=None, data_filter=repr):
|
|
"""
|
|
Routine to check values to be in a range inside a test run and report to a testCaseLogger.
|
|
|
|
:param result_key: The result of a test execution of a module
|
|
:type result_key: All types are supported
|
|
:param expectation_list: The list or dict of allowed values
|
|
:type expectation_list: A list of all types or a dict is supported
|
|
:param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
|
|
:type description: str
|
|
:param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
|
|
:type report_comment_fail: str
|
|
"""
|
|
__report_result__(result_list, description)
|
|
__report_expectation_inlist__(expectation_key, description, data_filter=data_filter)
|
|
if expectation_key in result_list:
|
|
tcl.log(REPORT_LEVEL_PASS, description + ' is correct (%s is in the list or dict).', data_filter(expectation_key))
|
|
return REPORT_LEVEL_PASS
|
|
else:
|
|
tcl.log(REPORT_LEVEL_FAIL, description + ' is NOT correct (%s is NOT in the list or dict).', data_filter(expectation_key))
|
|
return REPORT_LEVEL_FAIL
|