User | Revision | Line number | New contents of line |
switches |
0:0e018d759a2a
|
1
|
"""
|
switches |
0:0e018d759a2a
|
2
|
mbed SDK
|
switches |
0:0e018d759a2a
|
3
|
Copyright (c) 2011-2014 ARM Limited
|
switches |
0:0e018d759a2a
|
4
|
|
switches |
0:0e018d759a2a
|
5
|
Licensed under the Apache License, Version 2.0 (the "License");
|
switches |
0:0e018d759a2a
|
6
|
you may not use this file except in compliance with the License.
|
switches |
0:0e018d759a2a
|
7
|
You may obtain a copy of the License at
|
switches |
0:0e018d759a2a
|
8
|
|
switches |
0:0e018d759a2a
|
9
|
http://www.apache.org/licenses/LICENSE-2.0
|
switches |
0:0e018d759a2a
|
10
|
|
switches |
0:0e018d759a2a
|
11
|
Unless required by applicable law or agreed to in writing, software
|
switches |
0:0e018d759a2a
|
12
|
distributed under the License is distributed on an "AS IS" BASIS,
|
switches |
0:0e018d759a2a
|
13
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
switches |
0:0e018d759a2a
|
14
|
See the License for the specific language governing permissions and
|
switches |
0:0e018d759a2a
|
15
|
limitations under the License.
|
switches |
0:0e018d759a2a
|
16
|
|
switches |
0:0e018d759a2a
|
17
|
Author: Przemyslaw Wirkus <Przemyslaw.wirkus@arm.com>
|
switches |
0:0e018d759a2a
|
18
|
"""
|
switches |
0:0e018d759a2a
|
19
|
|
switches |
0:0e018d759a2a
|
20
|
from tools.utils import construct_enum, mkdir
|
switches |
0:0e018d759a2a
|
21
|
from prettytable import PrettyTable
|
switches |
0:0e018d759a2a
|
22
|
import os
|
switches |
0:0e018d759a2a
|
23
|
|
switches |
0:0e018d759a2a
|
24
|
ResultExporterType = construct_enum(HTML='Html_Exporter',
|
switches |
0:0e018d759a2a
|
25
|
JUNIT='JUnit_Exporter',
|
switches |
0:0e018d759a2a
|
26
|
JUNIT_OPER='JUnit_Exporter_Interoperability',
|
switches |
0:0e018d759a2a
|
27
|
BUILD='Build_Exporter',
|
switches |
0:0e018d759a2a
|
28
|
TEXT='Text_Exporter',
|
switches |
0:0e018d759a2a
|
29
|
PRINT='Print_Exporter')
|
switches |
0:0e018d759a2a
|
30
|
|
switches |
0:0e018d759a2a
|
31
|
|
switches |
0:0e018d759a2a
|
32
|
class ReportExporter():
|
switches |
0:0e018d759a2a
|
33
|
""" Class exports extended test result Python data structure to
|
switches |
0:0e018d759a2a
|
34
|
different formats like HTML, JUnit XML.
|
switches |
0:0e018d759a2a
|
35
|
|
switches |
0:0e018d759a2a
|
36
|
Parameter 'test_result_ext' format:
|
switches |
0:0e018d759a2a
|
37
|
|
switches |
0:0e018d759a2a
|
38
|
u'uARM': { u'LPC1768': { 'MBED_2': { 0: { 'copy_method': 'shutils.copy()',
|
switches |
0:0e018d759a2a
|
39
|
'duration': 20,
|
switches |
0:0e018d759a2a
|
40
|
'elapsed_time': 1.7929999828338623,
|
switches |
0:0e018d759a2a
|
41
|
'output': 'Host test instrumentation on ...\r\n',
|
switches |
0:0e018d759a2a
|
42
|
'result': 'OK',
|
switches |
0:0e018d759a2a
|
43
|
'target_name': u'LPC1768',
|
switches |
0:0e018d759a2a
|
44
|
'description': 'stdio',
|
switches |
0:0e018d759a2a
|
45
|
'id': u'MBED_2',
|
switches |
0:0e018d759a2a
|
46
|
'toolchain_name': u'uARM'}},
|
switches |
0:0e018d759a2a
|
47
|
"""
|
switches |
0:0e018d759a2a
|
48
|
CSS_STYLE = """<style>
|
switches |
0:0e018d759a2a
|
49
|
.name{
|
switches |
0:0e018d759a2a
|
50
|
border: 1px solid;
|
switches |
0:0e018d759a2a
|
51
|
border-radius: 25px;
|
switches |
0:0e018d759a2a
|
52
|
width: 100px;
|
switches |
0:0e018d759a2a
|
53
|
}
|
switches |
0:0e018d759a2a
|
54
|
.tooltip{
|
switches |
0:0e018d759a2a
|
55
|
position:absolute;
|
switches |
0:0e018d759a2a
|
56
|
background-color: #F5DA81;
|
switches |
0:0e018d759a2a
|
57
|
display:none;
|
switches |
0:0e018d759a2a
|
58
|
}
|
switches |
0:0e018d759a2a
|
59
|
</style>
|
switches |
0:0e018d759a2a
|
60
|
"""
|
switches |
0:0e018d759a2a
|
61
|
|
switches |
0:0e018d759a2a
|
62
|
JAVASCRIPT = """
|
switches |
0:0e018d759a2a
|
63
|
<script type="text/javascript">
|
switches |
0:0e018d759a2a
|
64
|
function show (elem) {
|
switches |
0:0e018d759a2a
|
65
|
elem.style.display = "block";
|
switches |
0:0e018d759a2a
|
66
|
}
|
switches |
0:0e018d759a2a
|
67
|
function hide (elem) {
|
switches |
0:0e018d759a2a
|
68
|
elem.style.display = "";
|
switches |
0:0e018d759a2a
|
69
|
}
|
switches |
0:0e018d759a2a
|
70
|
</script>
|
switches |
0:0e018d759a2a
|
71
|
"""
|
switches |
0:0e018d759a2a
|
72
|
|
switches |
0:0e018d759a2a
|
73
|
def __init__(self, result_exporter_type, package="test"):
|
switches |
0:0e018d759a2a
|
74
|
self.result_exporter_type = result_exporter_type
|
switches |
0:0e018d759a2a
|
75
|
self.package = package
|
switches |
0:0e018d759a2a
|
76
|
|
switches |
0:0e018d759a2a
|
77
|
def report(self, test_summary_ext, test_suite_properties=None,
|
switches |
0:0e018d759a2a
|
78
|
print_log_for_failures=True):
|
switches |
0:0e018d759a2a
|
79
|
""" Invokes report depending on exporter_type set in constructor
|
switches |
0:0e018d759a2a
|
80
|
"""
|
switches |
0:0e018d759a2a
|
81
|
if self.result_exporter_type == ResultExporterType.HTML:
|
switches |
0:0e018d759a2a
|
82
|
# HTML exporter
|
switches |
0:0e018d759a2a
|
83
|
return self.exporter_html(test_summary_ext, test_suite_properties)
|
switches |
0:0e018d759a2a
|
84
|
elif self.result_exporter_type == ResultExporterType.JUNIT:
|
switches |
0:0e018d759a2a
|
85
|
# JUNIT exporter for results from test suite
|
switches |
0:0e018d759a2a
|
86
|
return self.exporter_junit(test_summary_ext, test_suite_properties)
|
switches |
0:0e018d759a2a
|
87
|
elif self.result_exporter_type == ResultExporterType.JUNIT_OPER:
|
switches |
0:0e018d759a2a
|
88
|
# JUNIT exporter for interoperability test
|
switches |
0:0e018d759a2a
|
89
|
return self.exporter_junit_ioper(test_summary_ext, test_suite_properties)
|
switches |
0:0e018d759a2a
|
90
|
elif self.result_exporter_type == ResultExporterType.PRINT:
|
switches |
0:0e018d759a2a
|
91
|
# JUNIT exporter for interoperability test
|
switches |
0:0e018d759a2a
|
92
|
return self.exporter_print(test_summary_ext, print_log_for_failures=print_log_for_failures)
|
switches |
0:0e018d759a2a
|
93
|
elif self.result_exporter_type == ResultExporterType.TEXT:
|
switches |
0:0e018d759a2a
|
94
|
return self.exporter_text(test_summary_ext)
|
switches |
0:0e018d759a2a
|
95
|
return None
|
switches |
0:0e018d759a2a
|
96
|
|
switches |
0:0e018d759a2a
|
97
|
def report_to_file(self, test_summary_ext, file_name, test_suite_properties=None):
|
switches |
0:0e018d759a2a
|
98
|
""" Stores report to specified file
|
switches |
0:0e018d759a2a
|
99
|
"""
|
switches |
0:0e018d759a2a
|
100
|
report = self.report(test_summary_ext, test_suite_properties=test_suite_properties)
|
switches |
0:0e018d759a2a
|
101
|
self.write_to_file(report, file_name)
|
switches |
0:0e018d759a2a
|
102
|
|
switches |
0:0e018d759a2a
|
103
|
def write_to_file(self, report, file_name):
|
switches |
0:0e018d759a2a
|
104
|
if report is not None:
|
switches |
0:0e018d759a2a
|
105
|
dirname = os.path.dirname(file_name)
|
switches |
0:0e018d759a2a
|
106
|
if dirname:
|
switches |
0:0e018d759a2a
|
107
|
mkdir(dirname)
|
switches |
0:0e018d759a2a
|
108
|
with open(file_name, 'w') as f:
|
switches |
0:0e018d759a2a
|
109
|
f.write(report)
|
switches |
0:0e018d759a2a
|
110
|
|
switches |
0:0e018d759a2a
|
111
|
def get_tooltip_name(self, toolchain, target, test_id, loop_no):
|
switches |
0:0e018d759a2a
|
112
|
""" Generate simple unique tool-tip name which can be used.
|
switches |
0:0e018d759a2a
|
113
|
For example as HTML <div> section id attribute.
|
switches |
0:0e018d759a2a
|
114
|
"""
|
switches |
0:0e018d759a2a
|
115
|
return "target_test_%s_%s_%s_%s"% (toolchain.lower(), target.lower(), test_id.lower(), loop_no)
|
switches |
0:0e018d759a2a
|
116
|
|
switches |
0:0e018d759a2a
|
117
|
def get_result_div_sections(self, test, test_no):
|
switches |
0:0e018d759a2a
|
118
|
""" Generates separate <DIV> sections which contains test results output.
|
switches |
0:0e018d759a2a
|
119
|
"""
|
switches |
0:0e018d759a2a
|
120
|
|
switches |
0:0e018d759a2a
|
121
|
RESULT_COLORS = {'OK': 'LimeGreen',
|
switches |
0:0e018d759a2a
|
122
|
'FAIL': 'Orange',
|
switches |
0:0e018d759a2a
|
123
|
'ERROR': 'LightCoral',
|
switches |
0:0e018d759a2a
|
124
|
'OTHER': 'LightGray',
|
switches |
0:0e018d759a2a
|
125
|
}
|
switches |
0:0e018d759a2a
|
126
|
|
switches |
0:0e018d759a2a
|
127
|
tooltip_name = self.get_tooltip_name(test['toolchain_name'], test['target_name'], test['id'], test_no)
|
switches |
0:0e018d759a2a
|
128
|
background_color = RESULT_COLORS[test['result'] if test['result'] in RESULT_COLORS else 'OTHER']
|
switches |
0:0e018d759a2a
|
129
|
result_div_style = "background-color: %s"% background_color
|
switches |
0:0e018d759a2a
|
130
|
|
switches |
0:0e018d759a2a
|
131
|
result = """<div class="name" style="%s" onmouseover="show(%s)" onmouseout="hide(%s)">
|
switches |
0:0e018d759a2a
|
132
|
<center>%s</center>
|
switches |
0:0e018d759a2a
|
133
|
<div class = "tooltip" id= "%s">
|
switches |
0:0e018d759a2a
|
134
|
<b>%s</b><br />
|
switches |
0:0e018d759a2a
|
135
|
<hr />
|
switches |
0:0e018d759a2a
|
136
|
<b>%s</b> in <b>%.2f sec</b><br />
|
switches |
0:0e018d759a2a
|
137
|
<hr />
|
switches |
0:0e018d759a2a
|
138
|
<small>
|
switches |
0:0e018d759a2a
|
139
|
%s
|
switches |
0:0e018d759a2a
|
140
|
</small>
|
switches |
0:0e018d759a2a
|
141
|
</div>
|
switches |
0:0e018d759a2a
|
142
|
</div>
|
switches |
0:0e018d759a2a
|
143
|
"""% (result_div_style,
|
switches |
0:0e018d759a2a
|
144
|
tooltip_name,
|
switches |
0:0e018d759a2a
|
145
|
tooltip_name,
|
switches |
0:0e018d759a2a
|
146
|
test['result'],
|
switches |
0:0e018d759a2a
|
147
|
tooltip_name,
|
switches |
0:0e018d759a2a
|
148
|
test['target_name_unique'],
|
switches |
0:0e018d759a2a
|
149
|
test['description'],
|
switches |
0:0e018d759a2a
|
150
|
test['elapsed_time'],
|
switches |
0:0e018d759a2a
|
151
|
test['output'].replace('\n', '<br />'))
|
switches |
0:0e018d759a2a
|
152
|
return result
|
switches |
0:0e018d759a2a
|
153
|
|
switches |
0:0e018d759a2a
|
154
|
def get_result_tree(self, test_results):
|
switches |
0:0e018d759a2a
|
155
|
""" If test was run in a loop (we got few results from the same test)
|
switches |
0:0e018d759a2a
|
156
|
we will show it in a column to see all results.
|
switches |
0:0e018d759a2a
|
157
|
This function produces HTML table with corresponding results.
|
switches |
0:0e018d759a2a
|
158
|
"""
|
switches |
0:0e018d759a2a
|
159
|
result = ''
|
switches |
0:0e018d759a2a
|
160
|
for i, test_result in enumerate(test_results):
|
switches |
0:0e018d759a2a
|
161
|
result += '<table>'
|
switches |
0:0e018d759a2a
|
162
|
test_ids = sorted(test_result.keys())
|
switches |
0:0e018d759a2a
|
163
|
for test_no in test_ids:
|
switches |
0:0e018d759a2a
|
164
|
test = test_result[test_no]
|
switches |
0:0e018d759a2a
|
165
|
result += """<tr>
|
switches |
0:0e018d759a2a
|
166
|
<td valign="top">%s</td>
|
switches |
0:0e018d759a2a
|
167
|
</tr>"""% self.get_result_div_sections(test, "%d_%d" % (test_no, i))
|
switches |
0:0e018d759a2a
|
168
|
result += '</table>'
|
switches |
0:0e018d759a2a
|
169
|
return result
|
switches |
0:0e018d759a2a
|
170
|
|
switches |
0:0e018d759a2a
|
171
|
def get_all_unique_test_ids(self, test_result_ext):
|
switches |
0:0e018d759a2a
|
172
|
""" Gets all unique test ids from all ran tests.
|
switches |
0:0e018d759a2a
|
173
|
We need this to create complete list of all test ran.
|
switches |
0:0e018d759a2a
|
174
|
"""
|
switches |
0:0e018d759a2a
|
175
|
result = []
|
switches |
0:0e018d759a2a
|
176
|
targets = test_result_ext.keys()
|
switches |
0:0e018d759a2a
|
177
|
for target in targets:
|
switches |
0:0e018d759a2a
|
178
|
toolchains = test_result_ext[target].keys()
|
switches |
0:0e018d759a2a
|
179
|
for toolchain in toolchains:
|
switches |
0:0e018d759a2a
|
180
|
tests = test_result_ext[target][toolchain].keys()
|
switches |
0:0e018d759a2a
|
181
|
result.extend(tests)
|
switches |
0:0e018d759a2a
|
182
|
return sorted(list(set(result)))
|
switches |
0:0e018d759a2a
|
183
|
|
switches |
0:0e018d759a2a
|
184
|
#
|
switches |
0:0e018d759a2a
|
185
|
# Exporters functions
|
switches |
0:0e018d759a2a
|
186
|
#
|
switches |
0:0e018d759a2a
|
187
|
|
switches |
0:0e018d759a2a
|
188
|
def exporter_html(self, test_result_ext, test_suite_properties=None):
|
switches |
0:0e018d759a2a
|
189
|
""" Export test results in proprietary HTML format.
|
switches |
0:0e018d759a2a
|
190
|
"""
|
switches |
0:0e018d759a2a
|
191
|
result = """<html>
|
switches |
0:0e018d759a2a
|
192
|
<head>
|
switches |
0:0e018d759a2a
|
193
|
<title>mbed SDK test suite test result report</title>
|
switches |
0:0e018d759a2a
|
194
|
%s
|
switches |
0:0e018d759a2a
|
195
|
%s
|
switches |
0:0e018d759a2a
|
196
|
</head>
|
switches |
0:0e018d759a2a
|
197
|
<body>
|
switches |
0:0e018d759a2a
|
198
|
"""% (self.CSS_STYLE, self.JAVASCRIPT)
|
switches |
0:0e018d759a2a
|
199
|
|
switches |
0:0e018d759a2a
|
200
|
unique_test_ids = self.get_all_unique_test_ids(test_result_ext)
|
switches |
0:0e018d759a2a
|
201
|
targets = sorted(test_result_ext.keys())
|
switches |
0:0e018d759a2a
|
202
|
result += '<table>'
|
switches |
0:0e018d759a2a
|
203
|
for target in targets:
|
switches |
0:0e018d759a2a
|
204
|
toolchains = sorted(test_result_ext[target].keys())
|
switches |
0:0e018d759a2a
|
205
|
for toolchain in toolchains:
|
switches |
0:0e018d759a2a
|
206
|
result += '<tr>'
|
switches |
0:0e018d759a2a
|
207
|
result += '<td></td>'
|
switches |
0:0e018d759a2a
|
208
|
result += '<td></td>'
|
switches |
0:0e018d759a2a
|
209
|
|
switches |
0:0e018d759a2a
|
210
|
tests = sorted(test_result_ext[target][toolchain].keys())
|
switches |
0:0e018d759a2a
|
211
|
for test in unique_test_ids:
|
switches |
0:0e018d759a2a
|
212
|
result += """<td align="center">%s</td>"""% test
|
switches |
0:0e018d759a2a
|
213
|
result += """</tr>
|
switches |
0:0e018d759a2a
|
214
|
<tr>
|
switches |
0:0e018d759a2a
|
215
|
<td valign="center">%s</td>
|
switches |
0:0e018d759a2a
|
216
|
<td valign="center"><b>%s</b></td>
|
switches |
0:0e018d759a2a
|
217
|
"""% (toolchain, target)
|
switches |
0:0e018d759a2a
|
218
|
|
switches |
0:0e018d759a2a
|
219
|
for test in unique_test_ids:
|
switches |
0:0e018d759a2a
|
220
|
test_result = self.get_result_tree(test_result_ext[target][toolchain][test]) if test in tests else ''
|
switches |
0:0e018d759a2a
|
221
|
result += '<td>%s</td>'% (test_result)
|
switches |
0:0e018d759a2a
|
222
|
|
switches |
0:0e018d759a2a
|
223
|
result += '</tr>'
|
switches |
0:0e018d759a2a
|
224
|
result += '</table>'
|
switches |
0:0e018d759a2a
|
225
|
result += '</body></html>'
|
switches |
0:0e018d759a2a
|
226
|
return result
|
switches |
0:0e018d759a2a
|
227
|
|
switches |
0:0e018d759a2a
|
228
|
def exporter_junit_ioper(self, test_result_ext, test_suite_properties=None):
|
switches |
0:0e018d759a2a
|
229
|
from junit_xml import TestSuite, TestCase
|
switches |
0:0e018d759a2a
|
230
|
test_suites = []
|
switches |
0:0e018d759a2a
|
231
|
test_cases = []
|
switches |
0:0e018d759a2a
|
232
|
|
switches |
0:0e018d759a2a
|
233
|
for platform in sorted(test_result_ext.keys()):
|
switches |
0:0e018d759a2a
|
234
|
# {platform : ['Platform', 'Result', 'Scope', 'Description'])
|
switches |
0:0e018d759a2a
|
235
|
test_cases = []
|
switches |
0:0e018d759a2a
|
236
|
for tr_result in test_result_ext[platform]:
|
switches |
0:0e018d759a2a
|
237
|
result, name, scope, description = tr_result
|
switches |
0:0e018d759a2a
|
238
|
|
switches |
0:0e018d759a2a
|
239
|
classname = 'test.ioper.%s.%s.%s' % (platform, name, scope)
|
switches |
0:0e018d759a2a
|
240
|
elapsed_sec = 0
|
switches |
0:0e018d759a2a
|
241
|
_stdout = description
|
switches |
0:0e018d759a2a
|
242
|
_stderr = ''
|
switches |
0:0e018d759a2a
|
243
|
# Test case
|
switches |
0:0e018d759a2a
|
244
|
tc = TestCase(name, classname, elapsed_sec, _stdout, _stderr)
|
switches |
0:0e018d759a2a
|
245
|
# Test case extra failure / error info
|
switches |
0:0e018d759a2a
|
246
|
if result == 'FAIL':
|
switches |
0:0e018d759a2a
|
247
|
tc.add_failure_info(description, _stdout)
|
switches |
0:0e018d759a2a
|
248
|
elif result == 'ERROR':
|
switches |
0:0e018d759a2a
|
249
|
tc.add_error_info(description, _stdout)
|
switches |
0:0e018d759a2a
|
250
|
elif result == 'SKIP' or result == 'NOT_SUPPORTED':
|
switches |
0:0e018d759a2a
|
251
|
tc.add_skipped_info(description, _stdout)
|
switches |
0:0e018d759a2a
|
252
|
|
switches |
0:0e018d759a2a
|
253
|
test_cases.append(tc)
|
switches |
0:0e018d759a2a
|
254
|
ts = TestSuite("test.suite.ioper.%s" % (platform), test_cases)
|
switches |
0:0e018d759a2a
|
255
|
test_suites.append(ts)
|
switches |
0:0e018d759a2a
|
256
|
return TestSuite.to_xml_string(test_suites)
|
switches |
0:0e018d759a2a
|
257
|
|
switches |
0:0e018d759a2a
|
258
|
def exporter_junit(self, test_result_ext, test_suite_properties=None):
|
switches |
0:0e018d759a2a
|
259
|
""" Export test results in JUnit XML compliant format
|
switches |
0:0e018d759a2a
|
260
|
"""
|
switches |
0:0e018d759a2a
|
261
|
from junit_xml import TestSuite, TestCase
|
switches |
0:0e018d759a2a
|
262
|
test_suites = []
|
switches |
0:0e018d759a2a
|
263
|
test_cases = []
|
switches |
0:0e018d759a2a
|
264
|
|
switches |
0:0e018d759a2a
|
265
|
targets = sorted(test_result_ext.keys())
|
switches |
0:0e018d759a2a
|
266
|
for target in targets:
|
switches |
0:0e018d759a2a
|
267
|
toolchains = sorted(test_result_ext[target].keys())
|
switches |
0:0e018d759a2a
|
268
|
for toolchain in toolchains:
|
switches |
0:0e018d759a2a
|
269
|
test_cases = []
|
switches |
0:0e018d759a2a
|
270
|
tests = sorted(test_result_ext[target][toolchain].keys())
|
switches |
0:0e018d759a2a
|
271
|
for test in tests:
|
switches |
0:0e018d759a2a
|
272
|
test_results = test_result_ext[target][toolchain][test]
|
switches |
0:0e018d759a2a
|
273
|
for test_res in test_results:
|
switches |
0:0e018d759a2a
|
274
|
test_ids = sorted(test_res.keys())
|
switches |
0:0e018d759a2a
|
275
|
for test_no in test_ids:
|
switches |
0:0e018d759a2a
|
276
|
test_result = test_res[test_no]
|
switches |
0:0e018d759a2a
|
277
|
name = test_result['description']
|
switches |
0:0e018d759a2a
|
278
|
classname = '%s.%s.%s.%s'% (self.package, target, toolchain, test_result['id'])
|
switches |
0:0e018d759a2a
|
279
|
elapsed_sec = test_result['elapsed_time']
|
switches |
0:0e018d759a2a
|
280
|
_stdout = test_result['output']
|
switches |
0:0e018d759a2a
|
281
|
|
switches |
0:0e018d759a2a
|
282
|
if 'target_name_unique' in test_result:
|
switches |
0:0e018d759a2a
|
283
|
_stderr = test_result['target_name_unique']
|
switches |
0:0e018d759a2a
|
284
|
else:
|
switches |
0:0e018d759a2a
|
285
|
_stderr = test_result['target_name']
|
switches |
0:0e018d759a2a
|
286
|
|
switches |
0:0e018d759a2a
|
287
|
# Test case
|
switches |
0:0e018d759a2a
|
288
|
tc = TestCase(name, classname, elapsed_sec, _stdout, _stderr)
|
switches |
0:0e018d759a2a
|
289
|
|
switches |
0:0e018d759a2a
|
290
|
# Test case extra failure / error info
|
switches |
0:0e018d759a2a
|
291
|
message = test_result['result']
|
switches |
0:0e018d759a2a
|
292
|
if test_result['result'] == 'FAIL':
|
switches |
0:0e018d759a2a
|
293
|
tc.add_failure_info(message, _stdout)
|
switches |
0:0e018d759a2a
|
294
|
elif test_result['result'] == 'SKIP' or test_result["result"] == 'NOT_SUPPORTED':
|
switches |
0:0e018d759a2a
|
295
|
tc.add_skipped_info(message, _stdout)
|
switches |
0:0e018d759a2a
|
296
|
elif test_result['result'] != 'OK':
|
switches |
0:0e018d759a2a
|
297
|
tc.add_error_info(message, _stdout)
|
switches |
0:0e018d759a2a
|
298
|
|
switches |
0:0e018d759a2a
|
299
|
test_cases.append(tc)
|
switches |
0:0e018d759a2a
|
300
|
|
switches |
0:0e018d759a2a
|
301
|
ts = TestSuite("test.suite.%s.%s"% (target, toolchain), test_cases, properties=test_suite_properties[target][toolchain])
|
switches |
0:0e018d759a2a
|
302
|
test_suites.append(ts)
|
switches |
0:0e018d759a2a
|
303
|
return TestSuite.to_xml_string(test_suites)
|
switches |
0:0e018d759a2a
|
304
|
|
switches |
0:0e018d759a2a
|
305
|
def exporter_print_helper(self, array, print_log=False):
|
switches |
0:0e018d759a2a
|
306
|
for item in array:
|
switches |
0:0e018d759a2a
|
307
|
print " * %s::%s::%s" % (item["target_name"], item["toolchain_name"], item["id"])
|
switches |
0:0e018d759a2a
|
308
|
if print_log:
|
switches |
0:0e018d759a2a
|
309
|
log_lines = item["output"].split("\n")
|
switches |
0:0e018d759a2a
|
310
|
for log_line in log_lines:
|
switches |
0:0e018d759a2a
|
311
|
print " %s" % log_line
|
switches |
0:0e018d759a2a
|
312
|
|
switches |
0:0e018d759a2a
|
313
|
def exporter_print(self, test_result_ext, print_log_for_failures=False):
|
switches |
0:0e018d759a2a
|
314
|
""" Export test results in print format.
|
switches |
0:0e018d759a2a
|
315
|
"""
|
switches |
0:0e018d759a2a
|
316
|
failures = []
|
switches |
0:0e018d759a2a
|
317
|
skips = []
|
switches |
0:0e018d759a2a
|
318
|
successes = []
|
switches |
0:0e018d759a2a
|
319
|
|
switches |
0:0e018d759a2a
|
320
|
unique_test_ids = self.get_all_unique_test_ids(test_result_ext)
|
switches |
0:0e018d759a2a
|
321
|
targets = sorted(test_result_ext.keys())
|
switches |
0:0e018d759a2a
|
322
|
|
switches |
0:0e018d759a2a
|
323
|
for target in targets:
|
switches |
0:0e018d759a2a
|
324
|
toolchains = sorted(test_result_ext[target].keys())
|
switches |
0:0e018d759a2a
|
325
|
for toolchain in toolchains:
|
switches |
0:0e018d759a2a
|
326
|
tests = sorted(test_result_ext[target][toolchain].keys())
|
switches |
0:0e018d759a2a
|
327
|
for test in tests:
|
switches |
0:0e018d759a2a
|
328
|
test_runs = test_result_ext[target][toolchain][test]
|
switches |
0:0e018d759a2a
|
329
|
for test_runner in test_runs:
|
switches |
0:0e018d759a2a
|
330
|
#test_run = test_result_ext[target][toolchain][test][test_run_number][0]
|
switches |
0:0e018d759a2a
|
331
|
test_run = test_runner[0]
|
switches |
0:0e018d759a2a
|
332
|
|
switches |
0:0e018d759a2a
|
333
|
if "result" in test_run:
|
switches |
0:0e018d759a2a
|
334
|
if test_run["result"] == "FAIL":
|
switches |
0:0e018d759a2a
|
335
|
failures.append(test_run)
|
switches |
0:0e018d759a2a
|
336
|
elif test_run["result"] == "SKIP" or test_run["result"] == "NOT_SUPPORTED":
|
switches |
0:0e018d759a2a
|
337
|
skips.append(test_run)
|
switches |
0:0e018d759a2a
|
338
|
elif test_run["result"] == "OK":
|
switches |
0:0e018d759a2a
|
339
|
successes.append(test_run)
|
switches |
0:0e018d759a2a
|
340
|
else:
|
switches |
0:0e018d759a2a
|
341
|
raise Exception("Unhandled result type: %s" % (test_run["result"]))
|
switches |
0:0e018d759a2a
|
342
|
else:
|
switches |
0:0e018d759a2a
|
343
|
raise Exception("'test_run' did not have a 'result' value")
|
switches |
0:0e018d759a2a
|
344
|
|
switches |
0:0e018d759a2a
|
345
|
if successes:
|
switches |
0:0e018d759a2a
|
346
|
print "\n\nBuild successes:"
|
switches |
0:0e018d759a2a
|
347
|
self.exporter_print_helper(successes)
|
switches |
0:0e018d759a2a
|
348
|
|
switches |
0:0e018d759a2a
|
349
|
if skips:
|
switches |
0:0e018d759a2a
|
350
|
print "\n\nBuild skips:"
|
switches |
0:0e018d759a2a
|
351
|
self.exporter_print_helper(skips)
|
switches |
0:0e018d759a2a
|
352
|
|
switches |
0:0e018d759a2a
|
353
|
if failures:
|
switches |
0:0e018d759a2a
|
354
|
print "\n\nBuild failures:"
|
switches |
0:0e018d759a2a
|
355
|
self.exporter_print_helper(failures, print_log=print_log_for_failures)
|
switches |
0:0e018d759a2a
|
356
|
return False
|
switches |
0:0e018d759a2a
|
357
|
else:
|
switches |
0:0e018d759a2a
|
358
|
return True
|
switches |
0:0e018d759a2a
|
359
|
|
switches |
0:0e018d759a2a
|
360
|
def exporter_text(self, test_result_ext):
|
switches |
0:0e018d759a2a
|
361
|
""" Prints well-formed summary with results (SQL table like)
|
switches |
0:0e018d759a2a
|
362
|
table shows target x test results matrix across
|
switches |
0:0e018d759a2a
|
363
|
"""
|
switches |
0:0e018d759a2a
|
364
|
success_code = 0 # Success code that can be leter returned to
|
switches |
0:0e018d759a2a
|
365
|
# Pretty table package is used to print results
|
switches |
0:0e018d759a2a
|
366
|
pt = PrettyTable(["Result", "Target", "Toolchain", "Test ID", "Test Description",
|
switches |
0:0e018d759a2a
|
367
|
"Elapsed Time", "Timeout"])
|
switches |
0:0e018d759a2a
|
368
|
pt.align["Result"] = "l" # Left align
|
switches |
0:0e018d759a2a
|
369
|
pt.align["Target"] = "l" # Left align
|
switches |
0:0e018d759a2a
|
370
|
pt.align["Toolchain"] = "l" # Left align
|
switches |
0:0e018d759a2a
|
371
|
pt.align["Test ID"] = "l" # Left align
|
switches |
0:0e018d759a2a
|
372
|
pt.align["Test Description"] = "l" # Left align
|
switches |
0:0e018d759a2a
|
373
|
pt.padding_width = 1 # One space between column edges and contents (default)
|
switches |
0:0e018d759a2a
|
374
|
|
switches |
0:0e018d759a2a
|
375
|
result_dict = {"OK" : 0,
|
switches |
0:0e018d759a2a
|
376
|
"FAIL" : 0,
|
switches |
0:0e018d759a2a
|
377
|
"ERROR" : 0,
|
switches |
0:0e018d759a2a
|
378
|
"UNDEF" : 0,
|
switches |
0:0e018d759a2a
|
379
|
"IOERR_COPY" : 0,
|
switches |
0:0e018d759a2a
|
380
|
"IOERR_DISK" : 0,
|
switches |
0:0e018d759a2a
|
381
|
"IOERR_SERIAL" : 0,
|
switches |
0:0e018d759a2a
|
382
|
"TIMEOUT" : 0,
|
switches |
0:0e018d759a2a
|
383
|
"NO_IMAGE" : 0,
|
switches |
0:0e018d759a2a
|
384
|
"MBED_ASSERT" : 0,
|
switches |
0:0e018d759a2a
|
385
|
"BUILD_FAILED" : 0,
|
switches |
0:0e018d759a2a
|
386
|
"NOT_SUPPORTED" : 0
|
switches |
0:0e018d759a2a
|
387
|
}
|
switches |
0:0e018d759a2a
|
388
|
unique_test_ids = self.get_all_unique_test_ids(test_result_ext)
|
switches |
0:0e018d759a2a
|
389
|
targets = sorted(test_result_ext.keys())
|
switches |
0:0e018d759a2a
|
390
|
for target in targets:
|
switches |
0:0e018d759a2a
|
391
|
toolchains = sorted(test_result_ext[target].keys())
|
switches |
0:0e018d759a2a
|
392
|
for toolchain in toolchains:
|
switches |
0:0e018d759a2a
|
393
|
test_cases = []
|
switches |
0:0e018d759a2a
|
394
|
tests = sorted(test_result_ext[target][toolchain].keys())
|
switches |
0:0e018d759a2a
|
395
|
for test in tests:
|
switches |
0:0e018d759a2a
|
396
|
test_results = test_result_ext[target][toolchain][test]
|
switches |
0:0e018d759a2a
|
397
|
for test_res in test_results:
|
switches |
0:0e018d759a2a
|
398
|
test_ids = sorted(test_res.keys())
|
switches |
0:0e018d759a2a
|
399
|
for test_no in test_ids:
|
switches |
0:0e018d759a2a
|
400
|
test_result = test_res[test_no]
|
switches |
0:0e018d759a2a
|
401
|
result_dict[test_result['result']] += 1
|
switches |
0:0e018d759a2a
|
402
|
pt.add_row([test_result['result'],
|
switches |
0:0e018d759a2a
|
403
|
test_result['target_name'],
|
switches |
0:0e018d759a2a
|
404
|
test_result['toolchain_name'],
|
switches |
0:0e018d759a2a
|
405
|
test_result['id'],
|
switches |
0:0e018d759a2a
|
406
|
test_result['description'],
|
switches |
0:0e018d759a2a
|
407
|
test_result['elapsed_time'],
|
switches |
0:0e018d759a2a
|
408
|
test_result['duration']])
|
switches |
0:0e018d759a2a
|
409
|
result = pt.get_string()
|
switches |
0:0e018d759a2a
|
410
|
result += "\n"
|
switches |
0:0e018d759a2a
|
411
|
|
switches |
0:0e018d759a2a
|
412
|
# Print result count
|
switches |
0:0e018d759a2a
|
413
|
result += "Result: " + ' / '.join(['%s %s' % (value, key) for (key, value) in {k: v for k, v in result_dict.items() if v != 0}.iteritems()])
|
switches |
0:0e018d759a2a
|
414
|
return result
|