Added JUNIT exporters to compliance testing functionality

pull/1139/head
Przemek Wirkus 2015-05-27 09:56:35 +01:00
parent a82ffbe904
commit 7b0b9e8f32
5 changed files with 68 additions and 23 deletions

View File

@ -56,7 +56,7 @@ class IOperTestRunner():
'basic' - just simple, passive tests (no device flashing)
"""
self.requested_scope = scope # Test scope given by user
self.raw_test_results = [] # Raw test results, can be used by exporters
self.raw_test_results = {} # Raw test results, can be used by exporters: { Platform: [test results]}
# Test scope definitions
self.SCOPE_BASIC = 'basic' # Basic tests, sanity checks
@ -84,6 +84,8 @@ class IOperTestRunner():
for i, mut in enumerate(muts_list):
result = []
self.raw_test_results[mut['platform_name']] = []
print "MBEDLS: Detected %s, port: %s, mounted: %s"% (mut['platform_name'],
mut['serial_port'],
mut['mount_point'])
@ -92,24 +94,25 @@ class IOperTestRunner():
if self.scopes[self.requested_scope] >= self.scopes[test_case.scope]:
res = test_case.test(param=mut)
result.extend(res)
self.raw_test_results.append(res)
self.raw_test_results[mut['platform_name']].extend(res)
columns = ['Platform', 'Result', 'Scope', 'Description']
columns = ['Platform', 'Test Case', 'Result', 'Scope', 'Description']
pt = PrettyTable(columns)
for col in columns:
pt.align[col] = 'l'
for tr in result:
severity, tr_scope, text = tr
severity, tr_name, tr_scope, text = tr
tr = (test_base.COLOR(severity, mut['platform_name']),
test_base.COLOR(severity, tr_name),
test_base.COLOR(severity, severity),
test_base.COLOR(severity, tr_scope),
test_base.COLOR(severity, text))
pt.add_row(list(tr))
print pt.get_string(border=True, sortby='Result')
if i+1 < len(muts_list):
if i + 1 < len(muts_list):
print
return self.raw_test_results
def get_available_oper_test_scopes():
""" Get list of available test scopes

View File

@ -30,10 +30,11 @@ class IOperTest_FileStructure(IOperTestCaseBase):
def if_file_exist(self, fname, fail_severity=None):
file_path = os.path.join(self.param['mount_point'], fname)
exist = os.path.isfile(file_path)
tr_name = "FILE_EXIST(%s)" % fname.upper()
if exist:
self.result.append((self.PASS, self.scope, "File '%s' exists" % file_path))
self.result.append((self.PASS, tr_name, self.scope, "File '%s' exists" % file_path))
else:
self.result.append((fail_severity if fail_severity else self.ERROR, self.scope, "File '%s' not found" % file_path))
self.result.append((fail_severity if fail_severity else self.ERROR, tr_name, self.scope, "File '%s' not found" % file_path))
def test(self, param=None):
self.result = []

View File

@ -34,24 +34,24 @@ class IOperTest_TargetID(IOperTestCaseBase):
result = []
target_id_len = len(target_id) if target_id else 0
if target_id_len == self.TARGET_ID_LEN:
result.append((self.PASS, self.scope, "%s '%s' is %d chars long " % (target_id_name, target_id, target_id_len)))
result.append((self.INFO, self.scope, "%s Version String is %s.%s.%s " % (target_id_name,
result.append((self.PASS, "TARGET_ID_LEN", self.scope, "%s '%s' is %d chars long " % (target_id_name, target_id, target_id_len)))
result.append((self.INFO, "FW_VER_STR", self.scope, "%s Version String is %s.%s.%s " % (target_id_name,
target_id[0:4],
target_id[4:8],
target_id[8:24],
)))
else:
result.append((self.ERROR, self.scope, "%s '%s' is %d chars long. Expected %d chars" % (target_id_name, target_id, target_id_len, self.TARGET_ID_LEN)))
result.append((self.ERROR, "TARGET_ID_LEN", self.scope, "%s '%s' is %d chars long. Expected %d chars" % (target_id_name, target_id, target_id_len, self.TARGET_ID_LEN)))
return result
def test_decode_target_id(self, target_id, target_id_name):
result = []
target_id_len = len(target_id) if target_id else 0
if target_id_len >= 4:
result.append((self.INFO, self.scope, "%s Vendor Code is '%s'" % (target_id_name, target_id[0:2])))
result.append((self.INFO, self.scope, "%s Platform Code is '%s'" % (target_id_name, target_id[2:4])))
result.append((self.INFO, self.scope, "%s Firmware Version is '%s'" % (target_id_name, target_id[4:8])))
result.append((self.INFO, self.scope, "%s Hash of secret is '%s'" % (target_id_name, target_id[8:24])))
result.append((self.INFO, "FW_VEN_CODE", self.scope, "%s Vendor Code is '%s'" % (target_id_name, target_id[0:2])))
result.append((self.INFO, "FW_PLAT_CODE", self.scope, "%s Platform Code is '%s'" % (target_id_name, target_id[2:4])))
result.append((self.INFO, "FW_VER", self.scope, "%s Firmware Version is '%s'" % (target_id_name, target_id[4:8])))
result.append((self.INFO, "FW_HASH_SEC", self.scope, "%s Hash of secret is '%s'" % (target_id_name, target_id[8:24])))
return result
def test(self, param=None):
@ -72,22 +72,22 @@ class IOperTest_TargetID_Basic(IOperTest_TargetID):
result = []
if param:
result.append((self.PASS, self.scope, "TargetID '%s' found" % param['target_id']))
result.append((self.PASS, "TARGET_ID", self.scope, "TargetID '%s' found" % param['target_id']))
# Check if target name can be decoded with mbed-ls
if param['platform_name']:
result.append((self.PASS, self.scope, "TargetID '%s' decoded as '%s'" % (param['target_id'][0:4], param['platform_name'])))
result.append((self.PASS, "TARGET_ID_DECODE", self.scope, "TargetID '%s' decoded as '%s'" % (param['target_id'][0:4], param['platform_name'])))
else:
result.append((self.ERROR, self.scope, "TargetID '%s'... not decoded" % (param['target_id'] if param['target_id'] else '')))
result.append((self.ERROR, "TARGET_ID_DECODE", self.scope, "TargetID '%s'... not decoded" % (param['target_id'] if param['target_id'] else '')))
# Test for USBID and mbed.htm consistency
if param['target_id_mbed_htm'] == param['target_id_usb_id']:
result.append((self.PASS, self.scope, "TargetID (USBID) and TargetID (mbed.htm) match"))
result.append((self.PASS, "TARGET_ID_MATCH", self.scope, "TargetID (USBID) and TargetID (mbed.htm) match"))
else:
text = "TargetID (USBID) and TargetID (mbed.htm) don't match: '%s' != '%s'" % (param['target_id_usb_id'], param['target_id_mbed_htm'])
result.append((self.WARN, self.scope, text))
result.append((self.WARN, "TARGET_ID_MATCH", self.scope, text))
else:
result.append((self.ERROR, self.scope, "TargetID not found"))
result.append((self.ERROR, "TARGET_ID", self.scope, "TargetID not found"))
return result
class IOperTest_TargetID_MbedEnabled(IOperTest_TargetID):

View File

@ -77,6 +77,7 @@ from workspace_tools.test_api import get_module_avail
from workspace_tools.compliance.ioper_runner import IOperTestRunner
from workspace_tools.compliance.ioper_runner import get_available_oper_test_scopes
from workspace_tools.test_exporters import ReportExporter, ResultExporterType
# Importing extra modules which can be not installed but if available they can extend test suite functionality
@ -201,6 +202,11 @@ if __name__ == '__main__':
if opts.operability_checks in test_scope:
tests = IOperTestRunner(scope=opts.operability_checks)
test_results = tests.run()
# Export results in form of JUnit XML report to separate file
if opts.report_junit_file_name:
report_exporter = ReportExporter(ResultExporterType.JUNIT_OPER)
report_exporter.report_to_file(test_results, opts.report_junit_file_name)
else:
print "Unknown interoperability test scope name: '%s'" % (opts.operability_checks)
print "Available test scopes: %s" % (','.join(["'%s'" % n for n in test_scope]))

View File

@ -22,7 +22,8 @@ from workspace_tools.utils import construct_enum
ResultExporterType = construct_enum(HTML='Html_Exporter',
JUNIT='JUnit_Exporter',
BUILD='Build_Exporter')
BUILD='Build_Exporter',
JUNIT_OPER='JUnit_Exporter_Interoperability')
class ReportExporter():
@ -76,14 +77,20 @@ class ReportExporter():
# HTML exporter
return self.exporter_html(test_summary_ext, test_suite_properties)
elif self.result_exporter_type == ResultExporterType.JUNIT:
# JUNIT exporter
# JUNIT exporter for results from test suite
return self.exporter_junit(test_summary_ext, test_suite_properties)
elif self.result_exporter_type == ResultExporterType.JUNIT_OPER:
# JUNIT exporter for interoperability test
return self.exporter_junit_ioper(test_summary_ext, test_suite_properties)
return None
def report_to_file(self, test_summary_ext, file_name, test_suite_properties=None):
""" Stores report to specified file
"""
report = self.report(test_summary_ext, test_suite_properties=test_suite_properties)
self.write_to_file(report, file_name)
def write_to_file(self, report, file_name):
if report is not None:
with open(file_name, 'w') as f:
f.write(report)
@ -204,6 +211,34 @@ class ReportExporter():
result += '</body></html>'
return result
def exporter_junit_ioper(self, test_result_ext, test_suite_properties=None):
from junit_xml import TestSuite, TestCase
test_suites = []
test_cases = []
for platform in sorted(test_result_ext.keys()):
# {platform : ['Platform', 'Result', 'Scope', 'Description'])
for tr_result in test_result_ext[platform]:
result, name, scope, description = tr_result
classname = 'test.ioper.%s.%s.%s' % (platform, name, scope)
elapsed_sec = 0
_stdout = description
_stderr = ''
# Test case
tc = TestCase(name, classname, elapsed_sec, _stdout, _stderr)
# Test case extra failure / error info
if result == 'FAIL':
tc.add_failure_info(description, _stdout)
elif result == 'ERROR':
tc.add_error_info(description, _stdout)
test_cases.append(tc)
ts = TestSuite("test.suite.ioper.%s" % (platform), test_cases)
test_suites.append(ts)
return TestSuite.to_xml_string(test_suites)
def exporter_junit(self, test_result_ext, test_suite_properties=None):
""" Export test results in JUnit XML compliant format
"""