Просмотр исходного кода

Unittest improvements (output)

master
Dirk Alders 3 лет назад
Родитель
Сommit
ecec65be06
6 измененных файлов: 578 добавлений и 359 удалений
  1. 297
    0
      jsonlog.py
  2. 16
    148
      module_status.py
  3. 81
    0
      output.py
  4. 173
    199
      run.py
  5. 10
    11
      scripts/Makefile
  6. 1
    1
      scripts/unittest.py

+ 297
- 0
jsonlog.py Просмотреть файл

@@ -0,0 +1,297 @@
1
+#!/usr/bin/env python
2
+# -*- coding: utf-8 -*-
3
+#
4
+
5
+import json
6
+import os
7
+import subprocess
8
+
9
+import fstools
10
+from unittest.output import STATUS_AVAILABLE, STATUS_CHANGED, STATUS_CLEAN, STATUS_EXISTS, STATUS_IN_WORK, STATUS_MISSING, STATUS_OLD, STATUS_RELEASED, STATUS_UNKNOWN
11
+
12
+JSONLOG_FNAME = 'unittest.json'
13
+
14
+
15
+#
16
+# MAIN KEYS
17
+#
18
+MAIN_KEY_COVERAGE_INFO = 'coverage_information'
19
+MAIN_KEY_LOST_SOULS = "lost_souls"
20
+MAIN_KEY_SPECIFICATION = 'specification'
21
+MAIN_KEY_SYSTEM_INFO = 'system_information'
22
+MAIN_KEY_TESTOBJECT_INFO = 'testobject_information'
23
+MAIN_KEY_TESTRUNS = 'testrun_list'
24
+MAIN_KEY_UNITTEST_INFO = 'unittest_information'
25
+#
26
+# SUBKEYS FOR MAIN_KEY_COVERAGE_INFO
27
+#
28
+COVI_KEY_NAME = 'name'
29
+COVI_KEY_FILEPATH = 'filepath'
30
+COVI_KEY_LINE_COVERAGE = 'line_coverage'
31
+COVI_KEY_BRANCH_COVERAGE = 'branch_coverage'
32
+COVI_KEY_FILES = 'files'
33
+#
34
+# SUBKEYS FOR MAIN_KEY_LOST_SOULS
35
+#
36
+LOST_ITEMLIST = "item_list"
37
+LOST_TESTCASELIST = "testcase_list"
38
+#
39
+# SUBKEYS FOR MAIN_KEY_SPECIFICATION
40
+#
41
+SPEC_ITEM_DICT = 'item_dict'
42
+#
43
+# SUBKEYS FOR MAIN_KEY_SYSTEM_INFO
44
+#
45
+SYSI_ARCHITECTURE = "Architecture"
46
+SYSI_DISTRIBUTION = "Distribution"
47
+SYSI_HOSTNAME = "Hostname"
48
+SYSI_KERNEL = "Kernel"
49
+SYSI_MACHINE = "Machine"
50
+SYSI_PATH = "Path"
51
+SYSI_SYSTEM = "System"
52
+SYSI_USERNAME = "Username"
53
+#
54
+# SUBKEYS FOR MAIN_KEY_TESTOBJECT_INFO
55
+#
56
+TOBI_DEPENDENCIES = "Dependencies"
57
+TOBI_DESCRIPTION = "Description"
58
+TOBI_NAME = "Name"
59
+TOBI_STATE = "State"
60
+TOBI_STATE_RELESED = 'Released'
61
+TOBI_STATE_IN_DEVELOPMENT = 'In development'
62
+TOBI_SUPP_INTERP = "Supported Interpreters"
63
+TOBI_VERSION = "Version"
64
+#
65
+# SUBKEYS FOR MAIN_KEY_TESTRUNS
66
+#
67
+TRUN_TESTCASES = 'testcases'
68
+#
69
+# SUBKEYS FOR MAIN_KEY_UNITTEST_INFO
70
+#
71
+UTEI_VERSION = TOBI_VERSION
72
+
73
+
74
+def get_lib_folder(ut_folder):
75
+    return os.path.join(ut_folder, 'pylibs', os.path.basename(ut_folder))
76
+
77
+
78
+def get_ut_config(ut_folder):
79
+    return os.path.join(get_ut_src_folder(ut_folder), 'config.py')
80
+
81
+
82
+def get_ut_testcase_folder(ut_folder):
83
+    return os.path.join(get_ut_src_folder(ut_folder), 'tests')
84
+
85
+
86
+def get_ut_testresult_folder(ut_folder):
87
+    return os.path.join(get_ut_subfolder(ut_folder), 'testresults')
88
+
89
+
90
+def get_lib_testresult_folder(ut_folder):
91
+    return os.path.join(get_lib_folder(ut_folder), '_testresults_')
92
+
93
+
94
+def get_lib_jsonlog(ut_folder):
95
+    return os.path.join(get_lib_testresult_folder(ut_folder), JSONLOG_FNAME)
96
+
97
+
98
+def get_ut_jsonlog(ut_folder):
99
+    return os.path.join(get_ut_testresult_folder(ut_folder), JSONLOG_FNAME)
100
+
101
+
102
+def get_ut_src_folder(ut_folder):
103
+    return os.path.join(get_ut_subfolder(ut_folder), 'src')
104
+
105
+
106
+def get_ut_subfolder(ut_folder):
107
+    return os.path.join(ut_folder, 'unittest')
108
+
109
+
110
+def module_uid(path):
111
+    return fstools.uid_filelist(path, '*.py', rekursive=True)
112
+
113
+
114
+def __get_release_state__(ut_folder, lib):
115
+    if lib:
116
+        fn = get_lib_jsonlog(ut_folder)
117
+    else:
118
+        fn = get_ut_jsonlog(ut_folder)
119
+    try:
120
+        with open(fn, 'r') as fh:
121
+            ut_data = json.loads(fh.read())
122
+    except IOError:
123
+        return STATUS_MISSING
124
+    else:
125
+        ut_status = ut_data.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_STATE, 'unknown')
126
+        if 'released' in ut_status.lower():
127
+            return STATUS_RELEASED
128
+        elif 'work' in ut_status.lower():
129
+            return STATUS_IN_WORK
130
+        else:
131
+            return STATUS_UNKNOWN
132
+
133
+
134
+def get_lib_release_state(ut_folder):
135
+    return __get_release_state__(ut_folder, True)
136
+
137
+
138
+def get_ut_release_state(ut_folder):
139
+    return __get_release_state__(ut_folder, False)
140
+
141
+
142
+def __get_testcase_integrity__(ut_folder, lib):
143
+    if lib:
144
+        fn = get_lib_jsonlog(ut_folder)
145
+    else:
146
+        fn = get_ut_jsonlog(ut_folder)
147
+    try:
148
+        with open(fn, 'r') as fh:
149
+            ut_data = json.loads(fh.read())
150
+    except IOError:
151
+        return STATUS_MISSING
152
+    else:
153
+        tc_version = ut_data.get(MAIN_KEY_UNITTEST_INFO, {}).get(UTEI_VERSION)
154
+        current_version = module_uid(get_ut_testcase_folder(ut_folder))
155
+        if tc_version == current_version:
156
+            return STATUS_CLEAN
157
+        else:
158
+            return STATUS_CHANGED
159
+
160
+
161
+def get_lib_testcase_integrity(ut_folder):
162
+    return __get_testcase_integrity__(ut_folder, True)
163
+
164
+
165
+def get_ut_testcase_integrity(ut_folder):
166
+    return __get_testcase_integrity__(ut_folder, False)
167
+
168
+
169
+def __get_src_integrity__(ut_folder, lib):
170
+    if lib:
171
+        fn = get_lib_jsonlog(ut_folder)
172
+    else:
173
+        fn = get_ut_jsonlog(ut_folder)
174
+    try:
175
+        with open(fn, 'r') as fh:
176
+            ut_data = json.loads(fh.read())
177
+    except IOError:
178
+        return STATUS_MISSING
179
+    else:
180
+        tested_version = ut_data.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_VERSION)
181
+        current_version = module_uid(get_lib_folder(ut_folder))
182
+        if tested_version == current_version:
183
+            return STATUS_CLEAN
184
+        else:
185
+            return STATUS_CHANGED
186
+
187
+
188
+def get_lib_src_integrity(ut_folder):
189
+    return __get_src_integrity__(ut_folder, True)
190
+
191
+
192
+def get_ut_src_integrity(ut_folder):
193
+    return __get_src_integrity__(ut_folder, False)
194
+
195
+
196
+def status_module(ut_folder):
197
+    try:
198
+        with open(get_lib_jsonlog(ut_folder), 'r') as fh:
199
+            ut_lib = json.loads(fh.read())
200
+    except IOError:
201
+        return STATUS_MISSING
202
+    else:
203
+        try:
204
+            with open(get_ut_jsonlog(ut_folder), 'r') as fh:
205
+                ut_ut = json.loads(fh.read())
206
+        except IOError:
207
+            return STATUS_UNKNOWN
208
+        else:
209
+            tested_version = ut_lib.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_VERSION)
210
+            current_version = module_uid(get_lib_folder(ut_folder))
211
+            if ut_ut[MAIN_KEY_TESTOBJECT_INFO] != ut_lib[MAIN_KEY_TESTOBJECT_INFO] or ut_ut[MAIN_KEY_UNITTEST_INFO] != ut_lib[MAIN_KEY_UNITTEST_INFO] or tested_version != current_version:
212
+                return STATUS_OLD
213
+            else:
214
+                ut_status = ut_lib.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_STATE, 'unknown')
215
+                if 'released' in ut_status.lower():
216
+                    return STATUS_RELEASED
217
+                elif 'work' in ut_status.lower():
218
+                    return STATUS_IN_WORK
219
+                else:
220
+                    return STATUS_UNKNOWN
221
+
222
+
223
+def versions_module(ut_folder):
224
+    try:
225
+        with open(get_ut_jsonlog(ut_folder), 'r') as fh:
226
+            ut = json.loads(fh.read())
227
+    except IOError:
228
+        return STATUS_UNKNOWN
229
+    else:
230
+        interpreters = ut.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_SUPP_INTERP, '')
231
+        interpreters = interpreters.split(',')
232
+        for i in range(len(interpreters)):
233
+            interpreters[i] = interpreters[i].strip()
234
+            interpreters[i] = interpreters[i][6:]
235
+        return ', '.join(interpreters)
236
+
237
+
238
+def __get_coverage__(ut_folder, lib):
239
+    if lib:
240
+        fn = get_lib_jsonlog(ut_folder)
241
+    else:
242
+        fn = get_ut_jsonlog(ut_folder)
243
+    try:
244
+        with open(fn, 'r') as fh:
245
+            ut = json.loads(fh.read())
246
+    except IOError:
247
+        return None, None
248
+    else:
249
+        lcov = ut.get(MAIN_KEY_COVERAGE_INFO, [{}])[0].get(COVI_KEY_LINE_COVERAGE)
250
+        bcov = ut.get(MAIN_KEY_COVERAGE_INFO, [{}])[0].get(COVI_KEY_BRANCH_COVERAGE)
251
+        return lcov, bcov
252
+
253
+
254
+def lib_coverage(ut_folder):
255
+    return __get_coverage__(ut_folder, True)
256
+
257
+
258
+def ut_coverage(ut_folder):
259
+    return __get_coverage__(ut_folder, False)
260
+
261
+
262
+def status_git(ut_folder):
263
+    p = subprocess.Popen("git -C %s status 2> /dev/null" % ut_folder, stdout=subprocess.PIPE, shell=True)
264
+    output = p.communicate()[0]
265
+    p_status = p.wait()
266
+    if p_status == 0:
267
+        if b"nichts zu committen" in output and b"um lokale Commits zu publizieren" not in output:
268
+            return STATUS_CLEAN
269
+        else:
270
+            return STATUS_CHANGED
271
+    else:
272
+        return STATUS_UNKNOWN
273
+
274
+
275
+def status_doc(ut_folder):
276
+    if os.path.exists(os.path.join(get_lib_folder(ut_folder), '_docs_', 'index.html')):
277
+        return STATUS_AVAILABLE
278
+    else:
279
+        if os.path.exists(os.path.join(ut_folder, 'docs', 'index.rst')):
280
+            return STATUS_IN_WORK
281
+        else:
282
+            return STATUS_MISSING
283
+
284
+
285
+def status_spec(ut_folder):
286
+    if os.path.exists(os.path.join(ut_folder, 'requirements', 'specification.reqif')):
287
+        try:
288
+            with open(get_ut_jsonlog(ut_folder), 'r') as fh:
289
+                ut = json.loads(fh.read())
290
+                if len(ut[MAIN_KEY_LOST_SOULS][LOST_ITEMLIST]) > 0 or len(ut[MAIN_KEY_LOST_SOULS][LOST_TESTCASELIST]) > 0:
291
+                    return STATUS_IN_WORK
292
+                else:
293
+                    return STATUS_CLEAN
294
+        except IOError:
295
+            return STATUS_EXISTS
296
+    else:
297
+        return STATUS_MISSING

+ 16
- 148
module_status.py Просмотреть файл

@@ -3,52 +3,19 @@
3 3
 #
4 4
 
5 5
 import os
6
-import json
7
-import subprocess
8 6
 
9
-from unittest.run import module_uid
10
-from unittest.run import UNITTEST_KEY_TESTOBJECT_INFO
11
-
12
-
13
-class termcolors:
14
-    HEADER = '\033[95m'
15
-    OKBLUE = '\033[94m'
16
-    OKGREEN = '\033[92m'
17
-    WARNING = '\033[93m'
18
-    FAIL = '\033[91m'
19
-    ENDC = '\033[0m'
20
-    BOLD = '\033[1m'
21
-    UNDERLINE = '\033[4m'
22
-
23
-
24
-STATUS_RELEASED = 'RELEASED'
25
-STATUS_AVAILABLE = 'AVAILABLE'
26
-STATUS_IN_WORK = 'IN_WORK'
27
-STATUS_EXISTS = 'EXISTS'
28
-STATUS_OLD = 'OLD'
29
-STATUS_MISSING = 'MISSING'
30
-#
31
-STATUS_CLEAN = 'CLEAN'
32
-STATUS_CHANGED = 'CHANGED'
33
-#
34
-STATUS_UNKNOWN = 'UNKNOWN'
7
+from unittest.output import termcolors, coverage_output
35 8
 
9
+from unittest.output import STATUS_COLORS, STATUS_UNKNOWN
10
+from unittest.jsonlog import lib_coverage, status_doc, status_git, status_module, status_spec, versions_module
36 11
 
37 12
 STATUS_LENGTH = 13
38 13
 
39
-STR_STATUS = {
40
-    STATUS_RELEASED: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_RELEASED)) * ' ' + STATUS_RELEASED + termcolors.ENDC,
41
-    STATUS_AVAILABLE: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_AVAILABLE)) * ' ' + STATUS_AVAILABLE + termcolors.ENDC,
42
-    STATUS_IN_WORK: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_IN_WORK)) * ' ' + STATUS_IN_WORK + termcolors.ENDC,
43
-    STATUS_OLD: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_OLD)) * ' ' + STATUS_OLD + termcolors.ENDC,
44
-    STATUS_EXISTS: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_EXISTS)) * ' ' + STATUS_EXISTS + termcolors.ENDC,
45
-    STATUS_MISSING: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_MISSING)) * ' ' + STATUS_MISSING + termcolors.ENDC,
46
-    #
47
-    STATUS_CLEAN: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_CLEAN)) * ' ' + STATUS_CLEAN + termcolors.ENDC,
48
-    STATUS_CHANGED: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_CHANGED)) * ' ' + STATUS_CHANGED + termcolors.ENDC,
49
-    #
50
-    STATUS_UNKNOWN: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_UNKNOWN)) * ' ' + STATUS_UNKNOWN + termcolors.ENDC,
51
-}
14
+
15
+def status_output(status_or_text, default_color=STATUS_COLORS[STATUS_UNKNOWN]):
16
+    if status_or_text in STATUS_COLORS:
17
+        default_color = STATUS_COLORS[status_or_text]
18
+    return default_color + (STATUS_LENGTH - len(status_or_text[:STATUS_LENGTH])) * ' ' + status_or_text[:STATUS_LENGTH] + termcolors.ENDC
52 19
 
53 20
 
54 21
 def module_status_head():
@@ -67,113 +34,14 @@ def module_status_head():
67 34
     return rv
68 35
 
69 36
 
70
-def module_status_line(module_folder):
37
+def module_status_line(ut_folder):
71 38
     rv = '%25s%s%s%s%s%s%s\n' % (
72
-        os.path.basename(module_folder) + ':',
73
-        STR_STATUS.get(module_unittest_status(module_folder), STATUS_UNKNOWN),
74
-        STR_STATUS.get(module_doc_status(module_folder), STATUS_UNKNOWN),
75
-        module_unittest_versions(module_folder),
76
-        module_unittest_coverage(module_folder),
77
-        STR_STATUS.get(module_spec_status(module_folder), STATUS_UNKNOWN),
78
-        STR_STATUS.get(module_git_status(module_folder), STATUS_UNKNOWN),
39
+        os.path.basename(ut_folder) + ':',
40
+        status_output(status_module(ut_folder)),
41
+        status_output(status_doc(ut_folder)),
42
+        status_output(versions_module(ut_folder), termcolors.BOLD),
43
+        coverage_output(*lib_coverage(ut_folder), length=STATUS_LENGTH),
44
+        status_output(status_spec(ut_folder)),
45
+        status_output(status_git(ut_folder)),
79 46
     )
80 47
     return rv
81
-
82
-
83
-def module_unittest_status(module_folder):
84
-    try:
85
-        with open(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_testresults_', 'unittest.json'), 'r') as fh:
86
-            ut_lib = json.loads(fh.read())
87
-    except IOError:
88
-        return STATUS_MISSING
89
-    else:
90
-        try:
91
-            with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
92
-                ut_ut = json.loads(fh.read())
93
-        except IOError:
94
-            return STATUS_UNKNOWN
95
-        else:
96
-            tested_version = ut_lib.get(UNITTEST_KEY_TESTOBJECT_INFO, {}).get('Version')
97
-            current_version = module_uid(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder)))
98
-            if ut_ut['testobject_information'] != ut_lib['testobject_information'] or ut_ut['unittest_information'] != ut_lib['unittest_information'] or tested_version != current_version:
99
-                return STATUS_OLD
100
-            else:
101
-                ut_status = ut_lib.get('testobject_information', {}).get('State', 'unknown')
102
-                if 'released' in ut_status.lower():
103
-                    return STATUS_RELEASED
104
-                elif 'work' in ut_status.lower():
105
-                    return STATUS_IN_WORK
106
-                else:
107
-                    return STATUS_UNKNOWN
108
-
109
-
110
-def module_unittest_versions(module_folder):
111
-    try:
112
-        with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
113
-            ut = json.loads(fh.read())
114
-    except IOError:
115
-        return STR_STATUS[STATUS_UNKNOWN]
116
-    else:
117
-        interpreters = ut.get('testobject_information', '').get('Supported Interpreters')
118
-        interpreters = interpreters.split(',')
119
-        for i in range(len(interpreters)):
120
-            interpreters[i] = interpreters[i].strip()
121
-            interpreters[i] = interpreters[i][6:]
122
-        rv = ', '.join(interpreters)
123
-        return (STATUS_LENGTH - len(rv)) * ' ' + rv
124
-
125
-
126
-def module_unittest_coverage(module_folder):
127
-    try:
128
-        with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
129
-            ut = json.loads(fh.read())
130
-    except IOError:
131
-        return STR_STATUS[STATUS_UNKNOWN]
132
-    else:
133
-        lcov = ut.get('coverage_information', [{}])[0].get('line_coverage')
134
-        bcov = ut.get('coverage_information', [{}])[0].get('branch_coverage')
135
-        if lcov is None or bcov is None:
136
-            return STR_STATUS[STATUS_UNKNOWN]
137
-        elif lcov > 90:
138
-            rv = termcolors.OKGREEN + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
139
-        else:
140
-            rv = termcolors.WARNING + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
141
-        return (STATUS_LENGTH - 11) * ' ' + rv
142
-
143
-
144
-def module_git_status(module_folder):
145
-    p = subprocess.Popen("git -C %s status 2> /dev/null" % module_folder, stdout=subprocess.PIPE, shell=True)
146
-    output = p.communicate()[0]
147
-    p_status = p.wait()
148
-    if p_status == 0:
149
-        if b"nichts zu committen" in output and b"um lokale Commits zu publizieren" not in output:
150
-            return STATUS_CLEAN
151
-        else:
152
-            return STATUS_CHANGED
153
-    else:
154
-        return STATUS_UNKNOWN
155
-
156
-
157
-def module_doc_status(module_folder):
158
-    if os.path.exists(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_docs_', 'index.html')):
159
-        return STATUS_AVAILABLE
160
-    else:
161
-        if os.path.exists(os.path.join(module_folder, 'docs', 'index.rst')):
162
-            return STATUS_IN_WORK
163
-        else:
164
-            return STATUS_MISSING
165
-
166
-
167
-def module_spec_status(module_folder):
168
-    if os.path.exists(os.path.join(module_folder, 'requirements', 'specification.reqif')):
169
-        try:
170
-            with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
171
-                ut = json.loads(fh.read())
172
-                if len(ut['lost_souls']['item_list']) > 0 or len(ut['lost_souls']['testcase_list']) > 0:
173
-                    return STATUS_IN_WORK
174
-                else:
175
-                    return STATUS_CLEAN
176
-        except IOError:
177
-            return STATUS_EXISTS
178
-    else:
179
-        return STATUS_MISSING

+ 81
- 0
output.py Просмотреть файл

@@ -0,0 +1,81 @@
1
+#!/usr/bin/env python
2
+# -*- coding: utf-8 -*-
3
+#
4
+
5
+#
6
+# STATUS_KEYS
7
+#
8
+STATUS_AVAILABLE = 'AVAILABLE'
9
+STATUS_CLEAN = 'CLEAN'
10
+STATUS_RELEASED = 'RELEASED'
11
+STATUS_SUCCESS = 'SUCCESS'
12
+#
13
+STATUS_CHANGED = 'CHANGED'
14
+STATUS_EXISTS = 'EXISTS'
15
+STATUS_IN_WORK = 'IN_WORK'
16
+STATUS_OLD = 'OLD'
17
+#
18
+STATUS_FAILED = 'FAILED'
19
+STATUS_MISSING = 'MISSING'
20
+STATUS_UNKNOWN = 'UNKNOWN'
21
+
22
+
23
+class termcolors:
24
+    HEADER = '\033[95m'
25
+    OKBLUE = '\033[94m'
26
+    OKGREEN = '\033[92m'
27
+    WARNING = '\033[93m'
28
+    FAIL = '\033[91m'
29
+    ENDC = '\033[0m'
30
+    BOLD = '\033[1m'
31
+    UNDERLINE = '\033[4m'
32
+
33
+
34
+STATUS_COLORS = {
35
+    STATUS_AVAILABLE: termcolors.OKGREEN,
36
+    STATUS_CLEAN: termcolors.OKGREEN,
37
+    STATUS_RELEASED: termcolors.OKGREEN,
38
+    STATUS_SUCCESS: termcolors.OKGREEN,
39
+    #
40
+    STATUS_CHANGED: termcolors.WARNING,
41
+    STATUS_EXISTS: termcolors.WARNING,
42
+    STATUS_IN_WORK: termcolors.WARNING,
43
+    STATUS_OLD: termcolors.WARNING,
44
+    #
45
+    STATUS_FAILED: termcolors.FAIL,
46
+    STATUS_MISSING: termcolors.FAIL,
47
+    STATUS_UNKNOWN: termcolors.FAIL,
48
+}
49
+
50
+
51
+def print_header(txt):
52
+    print(termcolors.BOLD + termcolors.WARNING + txt + termcolors.ENDC)
53
+
54
+
55
+def print_action(txt):
56
+    print(termcolors.BOLD + '  * ' + txt + termcolors.ENDC)
57
+
58
+
59
+def status_output(txt, default_color):
60
+    return STATUS_COLORS.get(txt, default_color) + txt + termcolors.ENDC
61
+
62
+
63
+def print_info(txt, default_color=termcolors.ENDC):
64
+    print('      ' + status_output(txt, default_color))
65
+
66
+
67
+def coverage_output(lcov, bcov, length=None):
68
+    if lcov is None or bcov is None:
69
+        return (length - len(STATUS_UNKNOWN)) * ' ' + status_output(STATUS_UNKNOWN, termcolors.FAIL)
70
+    elif lcov > 90:
71
+        rv = termcolors.OKGREEN + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
72
+    else:
73
+        rv = termcolors.WARNING + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
74
+    if length is None:
75
+        return rv
76
+    else:
77
+        return (length - 11) * ' ' + rv
78
+
79
+
80
+def print_coverage(lcov, bcov):
81
+    print('      ' + coverage_output(lcov, bcov))

+ 173
- 199
run.py Просмотреть файл

@@ -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))

+ 10
- 11
scripts/Makefile Просмотреть файл

@@ -27,11 +27,11 @@ help:
27 27
 	@echo "    - testrun_smoke: Run some testcases"
28 28
 	@echo "    - testrun_single: Run one testcases"
29 29
 
30
-release: clean prepare testrun_full coverage_analysis finalise compile publish status
31
-full: clean prepare testrun_full coverage_analysis finalise compile status
32
-short: clean prepare testrun_short coverage_analysis finalise compile status
33
-smoke: clean prepare testrun_smoke coverage_analysis finalise compile status
34
-single: clean prepare testrun_single coverage_analysis finalise compile status
30
+release: testrun_full coverage_analysis finalise compile publish status
31
+full: testrun_full finalise compile status
32
+short: testrun_short finalise compile status
33
+smoke: testrun_smoke finalise compile status
34
+single: testrun_single finalise compile status
35 35
 
36 36
 clean:
37 37
 	@$(PYT3_CMD) src/unittest/scripts/unittest.py clean
@@ -44,20 +44,19 @@ release_testcases:
44 44
 prepare:
45 45
 	@$(PYT3_CMD) src/unittest/scripts/unittest.py prepare
46 46
 
47
-testrun_full:
47
+testrun_full: clean prepare
48 48
 	@$(COV2_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e full
49 49
 	@$(COV3_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e full
50 50
 
51
-testrun_short:
51
+testrun_short: clean prepare
52 52
 	@$(COV2_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e short
53 53
 	@$(COV3_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e short
54 54
 
55
-testrun_smoke:
55
+testrun_smoke: clean prepare
56 56
 	@$(COV2_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e smoke
57 57
 	@$(COV3_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e smoke
58 58
 
59
-testrun_single:
60
-
59
+testrun_single: clean prepare
61 60
 	@$(COV2_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e single
62 61
 	@$(COV3_CMD) run -a --branch --source=`$(PYT3_CMD) src/config.py -p` src/unittest/scripts/unittest.py testrun -e single
63 62
 
@@ -65,7 +64,7 @@ coverage_analysis:
65 64
 	@echo "\e[1m\e[93mCreating Coverage-XML-File: $(pwd)/testresults/coverage.xml\e[0m"
66 65
 	@$(COV3_CMD) xml -o testresults/coverage.xml
67 66
 
68
-finalise:
67
+finalise: coverage_analysis
69 68
 	@$(PYT3_CMD) src/unittest/scripts/unittest.py finalise
70 69
 
71 70
 compile:

+ 1
- 1
scripts/unittest.py Просмотреть файл

@@ -19,4 +19,4 @@ parser.add_option("-e", "--execution-level", dest="execution_level", default="fu
19 19
 if report.TCEL_REVERSE_NAMED.get(tests.execution_level, report.TCEL_FULL) < report.TCEL_REVERSE_NAMED.get(options.execution_level, report.TCEL_FULL):
20 20
     options.execution_level = tests.execution_level
21 21
 
22
-unittest.run.unittest(options, args, BASEPATH)
22
+unittest.run.unittest(options, args, os.path.dirname(BASEPATH))

Загрузка…
Отмена
Сохранить