|
@@ -2,6 +2,8 @@
|
2
|
2
|
# -*- coding: utf-8 -*-
|
3
|
3
|
#
|
4
|
4
|
import fstools
|
|
5
|
+from unittest import jsonlog
|
|
6
|
+from unittest import output
|
5
|
7
|
import report
|
6
|
8
|
import reqif
|
7
|
9
|
|
|
@@ -23,14 +25,6 @@ except ImportError:
|
23
|
25
|
jinja2 = None
|
24
|
26
|
import shutil
|
25
|
27
|
|
26
|
|
-HEADER = '\033[95m'
|
27
|
|
-OKBLUE = '\033[94m'
|
28
|
|
-OKGREEN = '\033[92m'
|
29
|
|
-WARNING = '\033[93m'
|
30
|
|
-FAIL = '\033[91m'
|
31
|
|
-ENDC = '\033[0m'
|
32
|
|
-BOLD = '\033[1m'
|
33
|
|
-UNDERLINE = '\033[4m'
|
34
|
28
|
|
35
|
29
|
ARG_CLEAN = 'clean'
|
36
|
30
|
ARG_RUN = 'run'
|
|
@@ -40,28 +34,29 @@ ARG_STATUS = 'status'
|
40
|
34
|
ARG_COPY = 'copy'
|
41
|
35
|
ARG_RELEASE = 'release'
|
42
|
36
|
|
43
|
|
-UNITTEST_KEY_SYSTEM_INFO = 'system_information'
|
44
|
|
-UNITTEST_KEY_UNITTEST_INFO = 'unittest_information'
|
45
|
|
-UNITTEST_KEY_TESTOBJECT_INFO = 'testobject_information'
|
46
|
|
-UNITTEST_KEY_TESTRUNS = 'testrun_list'
|
47
|
|
-UNITTEST_KEY_COVERAGE_INFO = 'coverage_information'
|
48
|
|
-UNITTEST_KEY_SPECIFICATION = 'specification'
|
|
37
|
+FN_DATA_COLLECTION = 'unittest.json'
|
|
38
|
+FN_TEX_REPORT = 'unittest.tex'
|
|
39
|
+FN_PDF_REPORT = 'unittest.pdf'
|
|
40
|
+FN_COVERAGE = 'coverage.xml'
|
49
|
41
|
|
50
|
|
-FILES = {
|
51
|
|
- 'data-collection': 'unittest.json',
|
52
|
|
- 'tex-report': 'unittest.tex',
|
53
|
|
- 'coverage-xml': 'coverage.xml'
|
54
|
|
-}
|
55
|
42
|
|
56
|
|
-REPORT_FILES = [FILES['data-collection'], FILES['coverage-xml'], 'unittest.pdf']
|
|
43
|
+REPORT_FILES = [FN_DATA_COLLECTION, FN_COVERAGE, FN_PDF_REPORT]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+def testresults_filename(ut_folder, filename):
|
|
47
|
+ return os.path.join(jsonlog.get_ut_testresult_folder(ut_folder), filename)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+def remove_file(filename):
|
|
51
|
+ if os.path.exists(filename) and not filename.endswith('.gitkeep'):
|
|
52
|
+ try:
|
|
53
|
+ output.print_info('Removing %s' % filename)
|
|
54
|
+ os.remove(filename)
|
|
55
|
+ except OSError:
|
|
56
|
+ pass
|
57
|
57
|
|
58
|
58
|
|
59
|
59
|
class coverage_info(list):
|
60
|
|
- KEY_NAME = 'name'
|
61
|
|
- KEY_FILEPATH = 'filepath'
|
62
|
|
- KEY_LINE_COVERAGE = 'line_coverage'
|
63
|
|
- KEY_BRANCH_COVERAGE = 'branch_coverage'
|
64
|
|
- KEY_FILES = 'files'
|
65
|
60
|
KEY_FRAGMENTS = 'fragments'
|
66
|
61
|
KEY_START_LINE = 'start'
|
67
|
62
|
KEY_END_LINE = 'end'
|
|
@@ -77,23 +72,23 @@ class coverage_info(list):
|
77
|
72
|
itemlist = xmldoc.getElementsByTagName('package')
|
78
|
73
|
for p in itemlist:
|
79
|
74
|
module = {}
|
80
|
|
- module[self.KEY_NAME] = p.attributes['name'].value[len(module_basepath) + 1:]
|
81
|
|
- module[self.KEY_FILEPATH] = p.attributes['name'].value.replace('.', os.path.sep)
|
82
|
|
- module[self.KEY_LINE_COVERAGE] = float(p.attributes['line-rate'].value) * 100.
|
|
75
|
+ module[jsonlog.COVI_KEY_NAME] = p.attributes['name'].value[len(module_basepath) + 1:]
|
|
76
|
+ module[jsonlog.COVI_KEY_FILEPATH] = p.attributes['name'].value.replace('.', os.path.sep)
|
|
77
|
+ module[jsonlog.COVI_KEY_LINE_COVERAGE] = float(p.attributes['line-rate'].value) * 100.
|
83
|
78
|
try:
|
84
|
|
- module[self.KEY_BRANCH_COVERAGE] = float(p.attributes['branch-rate'].value) * 100.
|
|
79
|
+ module[jsonlog.COVI_KEY_BRANCH_COVERAGE] = float(p.attributes['branch-rate'].value) * 100.
|
85
|
80
|
except AttributeError:
|
86
|
|
- module[self.KEY_BRANCH_COVERAGE] = None
|
87
|
|
- module[self.KEY_FILES] = []
|
|
81
|
+ module[jsonlog.COVI_KEY_BRANCH_COVERAGE] = None
|
|
82
|
+ module[jsonlog.COVI_KEY_FILES] = []
|
88
|
83
|
for c in p.getElementsByTagName('class'):
|
89
|
84
|
f = {}
|
90
|
|
- f[self.KEY_NAME] = c.attributes['filename'].value[len(module_basepath) + 1:].replace(os.path.sep, '.')
|
91
|
|
- f[self.KEY_FILEPATH] = c.attributes['filename'].value
|
92
|
|
- f[self.KEY_LINE_COVERAGE] = float(c.attributes['line-rate'].value) * 100.
|
|
85
|
+ f[jsonlog.COVI_KEY_NAME] = c.attributes['filename'].value[len(module_basepath) + 1:].replace(os.path.sep, '.')
|
|
86
|
+ f[jsonlog.COVI_KEY_FILEPATH] = c.attributes['filename'].value
|
|
87
|
+ f[jsonlog.COVI_KEY_LINE_COVERAGE] = float(c.attributes['line-rate'].value) * 100.
|
93
|
88
|
try:
|
94
|
|
- f[self.KEY_BRANCH_COVERAGE] = float(p.attributes['branch-rate'].value) * 100.
|
|
89
|
+ f[jsonlog.COVI_KEY_BRANCH_COVERAGE] = float(p.attributes['branch-rate'].value) * 100.
|
95
|
90
|
except Exception:
|
96
|
|
- f[self.KEY_BRANCH_COVERAGE] = None
|
|
91
|
+ f[jsonlog.COVI_KEY_BRANCH_COVERAGE] = None
|
97
|
92
|
f[self.KEY_FRAGMENTS] = []
|
98
|
93
|
last_hit = None
|
99
|
94
|
start_line = 1
|
|
@@ -146,52 +141,23 @@ class coverage_info(list):
|
146
|
141
|
line[self.KEY_END_LINE] = None
|
147
|
142
|
line[self.KEY_COVERAGE_STATE] = self.CLEAN
|
148
|
143
|
f[self.KEY_FRAGMENTS].append(line)
|
149
|
|
- module[self.KEY_FILES].append(f)
|
|
144
|
+ module[jsonlog.COVI_KEY_FILES].append(f)
|
150
|
145
|
self.append(module)
|
151
|
146
|
|
152
|
147
|
def __str__(self):
|
153
|
148
|
rv = ''
|
154
|
149
|
for module in self:
|
155
|
|
- rv += '%s (%.1f%% - %s)\n' % (module.get(self.KEY_NAME), module.get(self.KEY_LINE_COVERAGE), module.get(self.KEY_FILEPATH))
|
156
|
|
- for py_file in module.get(self.KEY_FILES):
|
157
|
|
- rv += ' %s (%.1f%% - %s)\n' % (py_file.get(self.KEY_NAME), py_file.get(self.KEY_LINE_COVERAGE), py_file.get(self.KEY_FILEPATH))
|
|
150
|
+ rv += '%s (%.1f%% - %s)\n' % (module.get(jsonlog.COVI_KEY_NAME), module.get(jsonlog.COVI_KEY_LINE_COVERAGE), module.get(jsonlog.COVI_KEY_FILEPATH))
|
|
151
|
+ for py_file in module.get(jsonlog.COVI_KEY_FILES):
|
|
152
|
+ rv += ' %s (%.1f%% - %s)\n' % (py_file.get(jsonlog.COVI_KEY_NAME), py_file.get(jsonlog.COVI_KEY_LINE_COVERAGE), py_file.get(jsonlog.COVI_KEY_FILEPATH))
|
158
|
153
|
for fragment in py_file.get(self.KEY_FRAGMENTS):
|
159
|
154
|
if fragment.get(self.KEY_END_LINE) is not None:
|
160
|
155
|
rv += ' %d - %d: %s\n' % (fragment.get(self.KEY_START_LINE), fragment.get(self.KEY_END_LINE), repr(fragment.get(self.KEY_COVERAGE_STATE)))
|
161
|
156
|
else:
|
162
|
|
- rv += ' %d - : %s\n' % (fragment.get(self.KEY_START_LINE), repr(fragment.get(self.KEY_COVERAGE_STATE)))
|
|
157
|
+ rv += ' %d - : %s\n' % (fragment.get(self.KEY_START_LINE), repr(fragment.get(self.COVERAGE_STATE)))
|
163
|
158
|
return rv
|
164
|
159
|
|
165
|
160
|
|
166
|
|
-def unittest_filename(base_folder, filename):
|
167
|
|
- return os.path.join(base_folder, 'testresults', filename)
|
168
|
|
-
|
169
|
|
-
|
170
|
|
-def print_header(txt, color=BOLD + WARNING):
|
171
|
|
- print(color + txt + ENDC)
|
172
|
|
-
|
173
|
|
-
|
174
|
|
-def print_action(txt, color=BOLD):
|
175
|
|
- print(color + ' * ' + txt + ENDC)
|
176
|
|
-
|
177
|
|
-
|
178
|
|
-def print_info(txt, color=ENDC):
|
179
|
|
- print(' ' + color + txt + ENDC)
|
180
|
|
-
|
181
|
|
-
|
182
|
|
-def remove_file(filename):
|
183
|
|
- if os.path.exists(filename) and not filename.endswith('.gitkeep'):
|
184
|
|
- try:
|
185
|
|
- print_info('Removing %s' % filename)
|
186
|
|
- os.remove(filename)
|
187
|
|
- except OSError:
|
188
|
|
- pass
|
189
|
|
-
|
190
|
|
-
|
191
|
|
-def module_uid(path):
|
192
|
|
- return fstools.uid_filelist(path, '*.py', rekursive=True)
|
193
|
|
-
|
194
|
|
-
|
195
|
161
|
def unittest(options, args, unittest_folder):
|
196
|
162
|
if 'release_testcases' in args:
|
197
|
163
|
unittest_release_testcases(unittest_folder)
|
|
@@ -209,13 +175,13 @@ def unittest(options, args, unittest_folder):
|
209
|
175
|
unittest_publish(unittest_folder)
|
210
|
176
|
|
211
|
177
|
|
212
|
|
-def unittest_release_testcases(unittest_folder):
|
213
|
|
- unittest_uid = module_uid(os.path.join(unittest_folder, 'src', 'tests'))
|
214
|
|
- config_file = os.path.join(unittest_folder, 'src', 'config.py')
|
215
|
|
- print_header('Releasing unittest')
|
|
178
|
+def unittest_release_testcases(ut_folder):
|
|
179
|
+ unittest_uid = jsonlog.module_uid(jsonlog.get_ut_testcase_folder(ut_folder))
|
|
180
|
+ output.print_header('Releasing unittest')
|
|
181
|
+ config_file = jsonlog.get_ut_config(ut_folder)
|
216
|
182
|
with open(config_file, 'r') as fh:
|
217
|
183
|
conf_file = fh.read()
|
218
|
|
- print_action('Setting release_unittest_version = %s in %s' % (unittest_uid, config_file))
|
|
184
|
+ output.print_action('Setting release_unittest_version = %s in %s' % (unittest_uid, config_file))
|
219
|
185
|
with open(config_file, 'w') as fh:
|
220
|
186
|
for line in conf_file.splitlines():
|
221
|
187
|
if line.startswith('release_unittest_version'):
|
|
@@ -224,85 +190,83 @@ def unittest_release_testcases(unittest_folder):
|
224
|
190
|
fh.write(line + '\n')
|
225
|
191
|
|
226
|
192
|
|
227
|
|
-def unittest_clean(unittest_folder):
|
228
|
|
- print_header('Cleaning up...')
|
229
|
|
- print_action('Testresults from last testrun')
|
230
|
|
- for fn in os.listdir(unittest_filename(unittest_folder, '')):
|
231
|
|
- remove_file(unittest_filename(unittest_folder, fn))
|
232
|
|
- remove_file(unittest_filename(unittest_folder, FILES['coverage-xml']))
|
|
193
|
+def unittest_clean(ut_folder):
|
|
194
|
+ output.print_header('Cleaning up...')
|
|
195
|
+ output.print_action('Testresults from last testrun')
|
|
196
|
+ for fn in os.listdir(testresults_filename(ut_folder, '')):
|
|
197
|
+ remove_file(testresults_filename(ut_folder, fn))
|
233
|
198
|
|
234
|
199
|
|
235
|
|
-def unittest_prepare(unittest_folder):
|
236
|
|
- config = imp.load_source('', os.path.join(unittest_folder, 'src', 'config.py'))
|
|
200
|
+def unittest_prepare(ut_folder):
|
|
201
|
+ config = imp.load_source('', jsonlog.get_ut_config(ut_folder))
|
237
|
202
|
#
|
238
|
|
- print_header("Initiating unittest for first testrun...")
|
239
|
|
- if not os.path.exists(unittest_filename(unittest_folder, '')):
|
240
|
|
- print_action('Creating outpout folder %s' % unittest_filename(unittest_folder, ''))
|
241
|
|
- fstools.mkdir(unittest_filename(unittest_folder, ''))
|
|
203
|
+ output.print_header("Initiating unittest for first testrun...")
|
|
204
|
+ if not os.path.exists(testresults_filename(ut_folder, '')):
|
|
205
|
+ output.print_action('Creating outpout folder %s' % testresults_filename(ut_folder, ''))
|
|
206
|
+ fstools.mkdir(testresults_filename(ut_folder, ''))
|
242
|
207
|
#
|
243
|
|
- print_action('Creating unittest data-collection: %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
|
208
|
+ output.print_action('Creating unittest data-collection: %s' % testresults_filename(ut_folder, FN_DATA_COLLECTION))
|
244
|
209
|
#
|
245
|
210
|
system_info = {}
|
246
|
|
- system_info['Architecture'] = platform.architecture()[0]
|
247
|
|
- system_info['Machine'] = platform.machine()
|
248
|
|
- system_info['Hostname'] = platform.node()
|
249
|
|
- system_info['Distribution'] = ' '.join(dist())
|
250
|
|
- system_info['System'] = platform.system()
|
251
|
|
- system_info['Kernel'] = platform.release() + ' (%s)' % platform.version()
|
252
|
|
- system_info['Username'] = getpass.getuser()
|
253
|
|
- system_info['Path'] = unittest_folder
|
|
211
|
+ system_info[jsonlog.SYSI_ARCHITECTURE] = platform.architecture()[0]
|
|
212
|
+ system_info[jsonlog.SYSI_MACHINE] = platform.machine()
|
|
213
|
+ system_info[jsonlog.SYSI_HOSTNAME] = platform.node()
|
|
214
|
+ system_info[jsonlog.SYSI_DISTRIBUTION] = ' '.join(dist())
|
|
215
|
+ system_info[jsonlog.SYSI_SYSTEM] = platform.system()
|
|
216
|
+ system_info[jsonlog.SYSI_KERNEL] = platform.release() + ' (%s)' % platform.version()
|
|
217
|
+ system_info[jsonlog.SYSI_USERNAME] = getpass.getuser()
|
|
218
|
+ system_info[jsonlog.SYSI_PATH] = ut_folder
|
254
|
219
|
#
|
255
|
220
|
unittest_info = {}
|
256
|
|
- unittest_info['Version'] = module_uid(os.path.join(unittest_folder, 'src', 'tests'))
|
|
221
|
+ unittest_info[jsonlog.UTEI_VERSION] = jsonlog.module_uid(jsonlog.get_ut_testcase_folder(ut_folder))
|
257
|
222
|
#
|
258
|
223
|
testobject_info = {}
|
259
|
|
- testobject_info['Name'] = config.lib.__name__
|
260
|
|
- testobject_info['Version'] = module_uid(config.lib.__path__[0])
|
261
|
|
- testobject_info['Description'] = config.lib.__DESCRIPTION__
|
262
|
|
- testobject_info['Supported Interpreters'] = ', '.join(['python%d' % vers for vers in config.lib.__INTERPRETER__])
|
263
|
|
- testobject_info['State'] = 'Released' if config.release_unittest_version == module_uid(os.path.join(unittest_folder, 'src', 'tests')) else 'In development'
|
264
|
|
- testobject_info['Dependencies'] = []
|
|
224
|
+ testobject_info[jsonlog.TOBI_NAME] = config.lib.__name__
|
|
225
|
+ testobject_info[jsonlog.TOBI_VERSION] = jsonlog.module_uid(config.lib.__path__[0])
|
|
226
|
+ testobject_info[jsonlog.TOBI_DESCRIPTION] = config.lib.__DESCRIPTION__
|
|
227
|
+ testobject_info[jsonlog.TOBI_SUPP_INTERP] = ', '.join(['python%d' % vers for vers in config.lib.__INTERPRETER__])
|
|
228
|
+ testobject_info[jsonlog.TOBI_STATE] = jsonlog.TOBI_STATE_RELESED if config.release_unittest_version == unittest_info[jsonlog.UTEI_VERSION] else jsonlog.TOBI_STATE_IN_DEVELOPMENT
|
|
229
|
+ testobject_info[jsonlog.TOBI_DEPENDENCIES] = []
|
265
|
230
|
for dependency in config.lib.__DEPENDENCIES__:
|
266
|
|
- testobject_info['Dependencies'].append((dependency, module_uid(os.path.join(unittest_folder, 'src', dependency))))
|
|
231
|
+ testobject_info[jsonlog.TOBI_DEPENDENCIES].append((dependency, jsonlog.module_uid(os.path.join(jsonlog.get_ut_src_folder(ut_folder), dependency))))
|
267
|
232
|
#
|
268
|
|
- spec_filename = os.path.join(unittest_folder, '..', 'requirements', 'specification.reqif')
|
269
|
|
- print_action("Adding Requirement Specification from %s" % spec_filename)
|
|
233
|
+ spec_filename = os.path.join(ut_folder, 'requirements', 'specification.reqif')
|
|
234
|
+ output.print_action("Adding Requirement Specification from %s" % spec_filename)
|
270
|
235
|
try:
|
271
|
236
|
spec = reqif.reqif_dict(spec_filename, 'Heading', 'Software Specification')
|
272
|
237
|
except FileNotFoundError:
|
273
|
|
- print_info('FAILED', FAIL)
|
|
238
|
+ output.print_info(output.STATUS_FAILED)
|
274
|
239
|
spec = {}
|
275
|
240
|
else:
|
276
|
|
- print_info('SUCCESS', OKGREEN)
|
|
241
|
+ output.print_info(output.STATUS_SUCCESS)
|
277
|
242
|
#
|
278
|
243
|
data_collection = {
|
279
|
|
- UNITTEST_KEY_SYSTEM_INFO: system_info,
|
280
|
|
- UNITTEST_KEY_UNITTEST_INFO: unittest_info,
|
281
|
|
- UNITTEST_KEY_TESTOBJECT_INFO: testobject_info,
|
282
|
|
- UNITTEST_KEY_SPECIFICATION: spec,
|
283
|
|
- UNITTEST_KEY_TESTRUNS: [],
|
|
244
|
+ jsonlog.MAIN_KEY_SYSTEM_INFO: system_info,
|
|
245
|
+ jsonlog.MAIN_KEY_UNITTEST_INFO: unittest_info,
|
|
246
|
+ jsonlog.MAIN_KEY_TESTOBJECT_INFO: testobject_info,
|
|
247
|
+ jsonlog.MAIN_KEY_SPECIFICATION: spec,
|
|
248
|
+ jsonlog.MAIN_KEY_TESTRUNS: [],
|
284
|
249
|
}
|
285
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'w') as fh:
|
|
250
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'w') as fh:
|
286
|
251
|
fh.write(json.dumps(data_collection, indent=4, sort_keys=True))
|
287
|
252
|
|
288
|
253
|
|
289
|
|
-def unittest_testrun(unittest_folder, options):
|
290
|
|
- tests = imp.load_source('', os.path.join(unittest_folder, 'src', 'tests', '__init__.py'))
|
291
|
|
- config = imp.load_source('', os.path.join(unittest_folder, 'src', 'config.py'))
|
|
254
|
+def unittest_testrun(ut_folder, options):
|
|
255
|
+ tests = imp.load_source('', os.path.join(jsonlog.get_ut_testcase_folder(ut_folder), '__init__.py'))
|
|
256
|
+ config = imp.load_source('', jsonlog.get_ut_config(ut_folder))
|
292
|
257
|
#
|
293
|
258
|
interpreter_version = 'python ' + '.'.join(['%d' % n for n in sys.version_info[:3]]) + ' (%s)' % sys.version_info[3]
|
294
|
259
|
#
|
295
|
260
|
execution_level = report.TCEL_REVERSE_NAMED.get(options.execution_level, report.TCEL_FULL)
|
296
|
261
|
#
|
297
|
262
|
if sys.version_info.major in config.lib.__INTERPRETER__:
|
298
|
|
- print_header("Running \"%s\" Unittest with %s" % (options.execution_level, interpreter_version))
|
299
|
|
- print_action('Loading Testrun data from %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
300
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'r') as fh:
|
|
263
|
+ output.print_header("Running \"%s\" Unittest with %s" % (options.execution_level, interpreter_version))
|
|
264
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'r') as fh:
|
301
|
265
|
data_collection = json.loads(fh.read())
|
302
|
|
- print_action('Executing Testcases')
|
|
266
|
+ output.print_action('Executing Testcases')
|
303
|
267
|
heading_dict = {}
|
304
|
|
- for key in data_collection[UNITTEST_KEY_SPECIFICATION].get('item_dict', {}):
|
305
|
|
- heading_dict[key] = data_collection[UNITTEST_KEY_SPECIFICATION]['item_dict'][key]['Heading']
|
|
268
|
+ for key in data_collection[jsonlog.MAIN_KEY_SPECIFICATION].get(jsonlog.SPEC_ITEM_DICT, {}):
|
|
269
|
+ heading_dict[key] = data_collection[jsonlog.MAIN_KEY_SPECIFICATION][jsonlog.SPEC_ITEM_DICT][key]['Heading']
|
306
|
270
|
test_session = report.testSession(
|
307
|
271
|
['__unittest__', 'root'],
|
308
|
272
|
interpreter=interpreter_version,
|
|
@@ -312,63 +276,61 @@ def unittest_testrun(unittest_folder, options):
|
312
|
276
|
)
|
313
|
277
|
tests.testrun(test_session)
|
314
|
278
|
#
|
315
|
|
- print_action('Adding Testrun data to %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
316
|
|
- data_collection[UNITTEST_KEY_TESTRUNS].append(test_session)
|
317
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'w') as fh:
|
|
279
|
+ output.print_action('Adding Testrun data to %s' % testresults_filename(ut_folder, FN_DATA_COLLECTION))
|
|
280
|
+ data_collection[jsonlog.MAIN_KEY_TESTRUNS].append(test_session)
|
|
281
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'w') as fh:
|
318
|
282
|
fh.write(json.dumps(data_collection, indent=4, sort_keys=True))
|
319
|
283
|
else:
|
320
|
|
- print_header("Library does not support %s." % interpreter_version)
|
|
284
|
+ output.print_header("Library does not support %s." % interpreter_version)
|
321
|
285
|
|
322
|
286
|
|
323
|
|
-def unittest_finalise(unittest_folder):
|
324
|
|
- config = imp.load_source('', os.path.join(unittest_folder, 'src', 'config.py'))
|
|
287
|
+def unittest_finalise(ut_folder):
|
|
288
|
+ config = imp.load_source('', jsonlog.get_ut_config(ut_folder))
|
325
|
289
|
#
|
326
|
|
- print_header("Adding Requirement information")
|
|
290
|
+ output.print_header("Adding Requirement information")
|
327
|
291
|
#
|
328
|
|
- print_action('Loading Testrun data from %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
329
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'r') as fh:
|
|
292
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'r') as fh:
|
330
|
293
|
data_collection = json.loads(fh.read())
|
331
|
294
|
#
|
332
|
|
- data_collection['lost_souls'] = {}
|
|
295
|
+ data_collection[jsonlog.MAIN_KEY_LOST_SOULS] = {}
|
333
|
296
|
#
|
334
|
|
- print_action("Adding Lost Requirement Soul")
|
335
|
|
- data_collection['lost_souls']['item_list'] = []
|
336
|
|
- for req_id in data_collection[UNITTEST_KEY_SPECIFICATION].get('item_dict', {}):
|
337
|
|
- item = data_collection[UNITTEST_KEY_SPECIFICATION]['item_dict'][req_id]
|
|
297
|
+ output.print_action("Adding Lost Requirement Soul")
|
|
298
|
+ data_collection[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_ITEMLIST] = []
|
|
299
|
+ for req_id in data_collection[jsonlog.MAIN_KEY_SPECIFICATION].get(jsonlog.SPEC_ITEM_DICT, {}):
|
|
300
|
+ item = data_collection[jsonlog.MAIN_KEY_SPECIFICATION][jsonlog.SPEC_ITEM_DICT][req_id]
|
338
|
301
|
if item['system_type_uid'] == '_MR7eNHYYEem_kd-7nxt1sg':
|
339
|
302
|
testcase_available = False
|
340
|
|
- for testrun in data_collection[UNITTEST_KEY_TESTRUNS]:
|
341
|
|
- if req_id in testrun['testcases']:
|
|
303
|
+ for testrun in data_collection[jsonlog.MAIN_KEY_TESTRUNS]:
|
|
304
|
+ if req_id in testrun[jsonlog.TRUN_TESTCASES]:
|
342
|
305
|
testcase_available = True
|
343
|
306
|
break
|
344
|
307
|
if not testcase_available:
|
345
|
|
- data_collection['lost_souls']['item_list'].append(req_id)
|
346
|
|
- print_info('%s - "%s" has no corresponding testcase' % (item['system_uid'], item['Heading']), FAIL)
|
|
308
|
+ data_collection[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_ITEMLIST].append(req_id)
|
|
309
|
+ output.print_info('%s - "%s" has no corresponding testcase' % (item['system_uid'], item['Heading']), output.termcolors.FAIL)
|
347
|
310
|
#
|
348
|
|
- print_action("Adding Lost Testcase Soul")
|
349
|
|
- data_collection['lost_souls']['testcase_list'] = []
|
350
|
|
- for testrun in data_collection[UNITTEST_KEY_TESTRUNS]:
|
351
|
|
- for tc_id in testrun.get('testcases', {}):
|
352
|
|
- if tc_id not in data_collection[UNITTEST_KEY_SPECIFICATION].get('item_dict', {}) and tc_id not in data_collection['lost_souls']['testcase_list']:
|
353
|
|
- data_collection['lost_souls']['testcase_list'].append(tc_id)
|
354
|
|
- print_info('"%s" has no corresponding testcase' % tc_id, FAIL)
|
|
311
|
+ output.print_action("Adding Lost Testcase Soul")
|
|
312
|
+ data_collection[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_TESTCASELIST] = []
|
|
313
|
+ for testrun in data_collection[jsonlog.MAIN_KEY_TESTRUNS]:
|
|
314
|
+ for tc_id in testrun.get(jsonlog.TRUN_TESTCASES, {}):
|
|
315
|
+ if tc_id not in data_collection[jsonlog.MAIN_KEY_SPECIFICATION].get(jsonlog.SPEC_ITEM_DICT, {}) and tc_id not in data_collection[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_TESTCASELIST]:
|
|
316
|
+ data_collection[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_TESTCASELIST].append(tc_id)
|
|
317
|
+ output.print_info('"%s" has no corresponding testcase' % tc_id, output.termcolors.FAIL)
|
355
|
318
|
#
|
356
|
|
- print_header("Adding Coverage information")
|
357
|
|
- print_action('Adding Coverage Information to %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
358
|
|
- data_collection[UNITTEST_KEY_COVERAGE_INFO] = coverage_info(unittest_filename(unittest_folder, 'coverage.xml'), os.path.dirname(config.lib_path))
|
359
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'w') as fh:
|
|
319
|
+ output.print_header("Adding Coverage information")
|
|
320
|
+ output.print_action('Adding Coverage Information to %s' % testresults_filename(ut_folder, FN_DATA_COLLECTION))
|
|
321
|
+ data_collection[jsonlog.MAIN_KEY_COVERAGE_INFO] = coverage_info(testresults_filename(ut_folder, FN_COVERAGE), os.path.dirname(config.lib_path))
|
|
322
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'w') as fh:
|
360
|
323
|
fh.write(json.dumps(data_collection, indent=4, sort_keys=True))
|
361
|
324
|
#
|
362
|
|
- print_header("Creating LaTeX-Report of Unittest")
|
363
|
|
- print_action('Loading Testrun data from %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
364
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'r') as fh:
|
|
325
|
+ output.print_header("Creating LaTeX-Report of Unittest")
|
|
326
|
+ with open(testresults_filename(ut_folder, FN_DATA_COLLECTION), 'r') as fh:
|
365
|
327
|
data_collection = json.loads(fh.read())
|
366
|
328
|
|
367
|
329
|
if jinja2 is None:
|
368
|
|
- print_action('You need to install jinja2 to create a LaTeX-Report!', FAIL)
|
|
330
|
+ output.print_action('You need to install jinja2 to create a LaTeX-Report!', output.termcolors.FAIL)
|
369
|
331
|
else:
|
370
|
|
- fn = unittest_filename(unittest_folder, FILES['tex-report'])
|
371
|
|
- print_action('Creating LaTeX-File %s' % fn)
|
|
332
|
+ fn = testresults_filename(ut_folder, FN_TEX_REPORT)
|
|
333
|
+ output.print_action('Creating LaTeX-File %s' % fn)
|
372
|
334
|
with open(fn, 'w') as fh:
|
373
|
335
|
#
|
374
|
336
|
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
|
@@ -378,37 +340,44 @@ def unittest_finalise(unittest_folder):
|
378
|
340
|
fh.write(template.render(data=data_collection))
|
379
|
341
|
|
380
|
342
|
|
381
|
|
-def unittest_publish(unittest_folder):
|
382
|
|
- config = imp.load_source('', os.path.join(unittest_folder, 'src', 'config.py'))
|
|
343
|
+def unittest_publish(ut_folder):
|
|
344
|
+ config = imp.load_source('', jsonlog.get_ut_config(ut_folder))
|
383
|
345
|
#
|
384
|
|
- print_header('Copy unittest files to library')
|
|
346
|
+ output.print_header('Copy unittest files to library')
|
385
|
347
|
target_folder = os.path.join(config.lib_path, '_testresults_')
|
386
|
|
- print_action('Copying Unittest Files to %s' % target_folder)
|
|
348
|
+ output.print_action('Copying Unittest Files to %s' % target_folder)
|
387
|
349
|
if not os.path.exists(target_folder):
|
388
|
|
- print_info('Creating folder %s' % target_folder)
|
|
350
|
+ output.print_info('Creating folder %s' % target_folder)
|
389
|
351
|
fstools.mkdir(target_folder)
|
390
|
352
|
else:
|
391
|
353
|
for fn in os.listdir(target_folder):
|
392
|
354
|
remove_file(os.path.join(target_folder, fn))
|
393
|
355
|
for fn in REPORT_FILES:
|
394
|
|
- src = unittest_filename(unittest_folder, fn)
|
|
356
|
+ src = testresults_filename(ut_folder, fn)
|
395
|
357
|
dst = os.path.join(target_folder, fn)
|
396
|
|
- print_info('copying %s -> %s' % (src, dst))
|
|
358
|
+ output.print_info('copying %s -> %s' % (src, dst))
|
397
|
359
|
shutil.copyfile(src, dst)
|
398
|
360
|
|
399
|
361
|
|
400
|
|
-def unittest_status(unittest_folder):
|
401
|
|
- print_header('Checking status of all submodules')
|
402
|
|
- print_action('Updating all submodules (fetch)')
|
403
|
|
- process = subprocess.Popen("LANGUAGE='en_US.UTF-8 git' git submodule foreach git fetch", cwd=os.path.dirname(unittest_folder), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
362
|
+def unittest_status(ut_folder):
|
|
363
|
+ #
|
|
364
|
+ # GIT STATUS
|
|
365
|
+ #
|
|
366
|
+ output.print_header('Checking GIT repository status')
|
|
367
|
+ # GIT FETCH
|
|
368
|
+ output.print_action('Fetching repository from server...')
|
|
369
|
+ process = subprocess.Popen("LANGUAGE='en_US.UTF-8 git' git submodule foreach git fetch", cwd=ut_folder, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
404
|
370
|
stderroutput = process.communicate()[1]
|
405
|
371
|
if stderroutput == b'':
|
406
|
|
- print_info('SUCCESS', color=OKGREEN)
|
|
372
|
+ output.print_info(output.STATUS_SUCCESS)
|
407
|
373
|
else:
|
408
|
|
- print_info('FAILED', color=FAIL)
|
409
|
|
-
|
410
|
|
- print_action('Checking status...')
|
411
|
|
- process = subprocess.Popen("LANGUAGE='en_US.UTF-8 git' git submodule foreach git status", cwd=os.path.dirname(unittest_folder), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
374
|
+ output.print_info(output.STATUS_FAILED)
|
|
375
|
+ # GIT_REPO
|
|
376
|
+ output.print_action('Analysing repository status...')
|
|
377
|
+ output.print_info(jsonlog.status_git(ut_folder))
|
|
378
|
+ # SUBMODULES
|
|
379
|
+ output.print_action('Analysing submodule status...')
|
|
380
|
+ process = subprocess.Popen("LANGUAGE='en_US.UTF-8 git' git submodule foreach git status", cwd=ut_folder, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
412
|
381
|
stdoutput, stderroutput = process.communicate()
|
413
|
382
|
if stderroutput == b'':
|
414
|
383
|
module = None
|
|
@@ -425,36 +394,41 @@ def unittest_status(unittest_folder):
|
425
|
394
|
data[m] += line
|
426
|
395
|
for key in data:
|
427
|
396
|
if "working tree clean" not in data[key] and "working directory clean" not in data[key]:
|
428
|
|
- data[key] = ("local changes", FAIL)
|
|
397
|
+ data[key] = ("LOCAL CHANGES", output.termcolors.WARNING)
|
429
|
398
|
elif "Your branch is behind" in data[key]:
|
430
|
|
- data[key] = ("no up to date (try git pull)", FAIL)
|
|
399
|
+ data[key] = ("OUTDATED (try git pull)", output.termcolors.WARNING)
|
431
|
400
|
elif "HEAD detached at" in data[key]:
|
432
|
|
- data[key] = ("no up to date (try git checkout master)", FAIL)
|
|
401
|
+ data[key] = ("OUTDATED (try git checkout master)", output.termcolors.WARNING)
|
433
|
402
|
elif "Your branch is ahead of" in data[key]:
|
434
|
|
- data[key] = ("push required", WARNING)
|
|
403
|
+ data[key] = ("CHANGED (try git push)", output.termcolors.WARNING)
|
435
|
404
|
elif "nothing to commit" in data[key]:
|
436
|
|
- data[key] = ("clean", OKGREEN)
|
|
405
|
+ data[key] = ("CLEAN", output.termcolors.OKGREEN)
|
437
|
406
|
else:
|
438
|
|
- data[key] = ("unknown", FAIL)
|
439
|
|
- print_info('Submodule %s... %s' % (key, data[key][1] + data[key][0]))
|
|
407
|
+ data[key] = ("UNKNOWN", output.termcolors.FAIL)
|
|
408
|
+ output.print_info('Submodule %s... %s' % (key, data[key][1] + data[key][0]))
|
440
|
409
|
else:
|
441
|
|
- print_info('FAILED', color=FAIL)
|
|
410
|
+ output.print_info(output.STATUS_FAILED)
|
442
|
411
|
#
|
443
|
|
- print_header('Checking status of unittest and testresults in the library')
|
444
|
|
- print_action('Loading Testrun data from %s' % unittest_filename(unittest_folder, FILES['data-collection']))
|
445
|
|
- with open(unittest_filename(unittest_folder, FILES['data-collection']), 'r') as fh:
|
446
|
|
- data_collection = json.loads(fh.read())
|
447
|
|
- print_action('Checking release state of this testrun... ')
|
448
|
|
- if data_collection[UNITTEST_KEY_TESTOBJECT_INFO]['State'] != 'Released':
|
449
|
|
- print_info("FAILED", FAIL)
|
450
|
|
- else:
|
451
|
|
- print_info("SUCCESS", OKGREEN)
|
|
412
|
+ # TESTRUN STATUS
|
|
413
|
+ #
|
|
414
|
+ output.print_header('Checking status of unittest in the library')
|
|
415
|
+ for txt, fcn in (
|
|
416
|
+ ('Checking release state... ', jsonlog.get_lib_release_state),
|
|
417
|
+ ('Checking testcase integrity... ', jsonlog.get_lib_testcase_integrity),
|
|
418
|
+ ('Checking source integrity... ', jsonlog.get_lib_src_integrity)
|
|
419
|
+ ):
|
|
420
|
+ output.print_action(txt)
|
|
421
|
+ output.print_info(fcn(ut_folder))
|
|
422
|
+ output.print_action('Checking code coverage... ')
|
|
423
|
+ output.print_coverage(*jsonlog.lib_coverage(ut_folder))
|
452
|
424
|
#
|
453
|
|
- from unittest.module_status import module_unittest_status
|
454
|
|
- print_action('Checking status of testrults in library...')
|
455
|
|
- st = module_unittest_status(os.path.abspath(os.path.join(unittest_folder, '..')))
|
456
|
|
- stc = {
|
457
|
|
- 'RELEASED': OKGREEN,
|
458
|
|
- 'IN_WORK': OKBLUE,
|
459
|
|
- }.get(st, FAIL)
|
460
|
|
- print_info(st, stc)
|
|
425
|
+ output.print_header('Checking status of unittest for this testrun')
|
|
426
|
+ for txt, fcn in (
|
|
427
|
+ ('Checking release state... ', jsonlog.get_ut_release_state),
|
|
428
|
+ ('Checking testcase integrity... ', jsonlog.get_ut_testcase_integrity),
|
|
429
|
+ ('Checking source integrity... ', jsonlog.get_ut_src_integrity)
|
|
430
|
+ ):
|
|
431
|
+ output.print_action(txt)
|
|
432
|
+ output.print_info(fcn(ut_folder))
|
|
433
|
+ output.print_action('Checking code coverage... ')
|
|
434
|
+ output.print_coverage(*jsonlog.ut_coverage(ut_folder))
|