unittest/module_status.py

177 lines
6.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import os
import json
import fstools
import re
import subprocess
class termcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
STATUS_RELEASED = 'RELEASED'
STATUS_AVAILABLE = 'AVAILABLE'
STATUS_IN_WORK = 'IN_WORK'
STATUS_EXISTS = 'EXISTS'
STATUS_OLD = 'OLD'
STATUS_MISSING = 'MISSING'
#
STATUS_CLEAN = 'CLEAN'
STATUS_CHANGED = 'CHANGED'
#
STATUS_UNKNOWN = 'UNKNOWN'
STATUS_LENGTH = 13
STR_STATUS = {
STATUS_RELEASED: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_RELEASED)) * ' ' + STATUS_RELEASED + termcolors.ENDC,
STATUS_AVAILABLE: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_AVAILABLE)) * ' ' + STATUS_AVAILABLE + termcolors.ENDC,
STATUS_IN_WORK: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_IN_WORK)) * ' ' + STATUS_IN_WORK + termcolors.ENDC,
STATUS_OLD: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_OLD)) * ' ' + STATUS_OLD + termcolors.ENDC,
STATUS_EXISTS: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_EXISTS)) * ' ' + STATUS_EXISTS + termcolors.ENDC,
STATUS_MISSING: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_MISSING)) * ' ' + STATUS_MISSING + termcolors.ENDC,
#
STATUS_CLEAN: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_CLEAN)) * ' ' + STATUS_CLEAN + termcolors.ENDC,
STATUS_CHANGED: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_CHANGED)) * ' ' + STATUS_CHANGED + termcolors.ENDC,
#
STATUS_UNKNOWN: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_UNKNOWN)) * ' ' + STATUS_UNKNOWN + termcolors.ENDC,
}
def module_status_head():
rv = termcolors.BOLD + termcolors.UNDERLINE + 'Status of the unittests for pylibs:\n' + termcolors.ENDC
LINE_FORMAT = '%25s%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's\n'
rv += termcolors.BOLD + termcolors.HEADER + LINE_FORMAT % (
'Library',
'UT-Status',
'DOC-Status',
'Versions',
'UT-Coverage',
'SPEC-Status',
'GIT-Status',
)
rv += (25 + 6 * STATUS_LENGTH) * '-' + '\n' + termcolors.ENDC
return rv
def module_status_line(module_folder):
rv = '%25s%s%s%s%s%s%s\n' % (
os.path.basename(module_folder) + ':',
STR_STATUS.get(module_unittest_status(module_folder), STATUS_UNKNOWN),
STR_STATUS.get(module_doc_status(module_folder), STATUS_UNKNOWN),
module_unittest_versions(module_folder),
module_unittest_coverage(module_folder),
STR_STATUS.get(module_spec_status(module_folder), STATUS_UNKNOWN),
STR_STATUS.get(module_git_status(module_folder), STATUS_UNKNOWN),
)
return rv
def module_unittest_status(module_folder):
try:
with open(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_testresults_', 'unittest.json'), 'r') as fh:
ut_lib = json.loads(fh.read())
except IOError:
return STATUS_MISSING
else:
try:
with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
ut_ut = json.loads(fh.read())
except IOError:
return STATUS_UNKNOWN
else:
if ut_ut['testobject_information'] != ut_lib['testobject_information'] or ut_ut['unittest_information'] != ut_lib['unittest_information']:
return STATUS_OLD
else:
ut_status = ut_lib.get('testobject_information', {}).get('State', 'unknown')
if 'released' in ut_status.lower():
return STATUS_RELEASED
elif 'work' in ut_status.lower():
return STATUS_IN_WORK
else:
return STATUS_UNKNOWN
def module_unittest_versions(module_folder):
try:
with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
ut = json.loads(fh.read())
except IOError:
return STR_STATUS[STATUS_UNKNOWN]
else:
interpreters = ut.get('testobject_information', '').get('Supported Interpreters')
interpreters = interpreters.split(',')
for i in range(len(interpreters)):
interpreters[i] = interpreters[i].strip()
interpreters[i] = interpreters[i][6:]
rv = ', '.join(interpreters)
return (STATUS_LENGTH - len(rv)) * ' ' + rv
def module_unittest_coverage(module_folder):
try:
with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
ut = json.loads(fh.read())
except IOError:
return STR_STATUS[STATUS_UNKNOWN]
else:
lcov = ut.get('coverage_information', [{}])[0].get('line_coverage')
bcov = ut.get('coverage_information', [{}])[0].get('branch_coverage')
if lcov is None or bcov is None:
return STR_STATUS[STATUS_UNKNOWN]
elif lcov > 90:
rv = termcolors.OKGREEN + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
else:
rv = termcolors.WARNING + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC
return (STATUS_LENGTH - 11) * ' ' + rv
def module_git_status(module_folder):
p = subprocess.Popen("git -C %s status 2> /dev/null" % module_folder, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
p_status = p.wait()
if p_status == 0:
if b"nichts zu committen" in output and b"um lokale Commits zu publizieren" not in output:
return STATUS_CLEAN
else:
return STATUS_CHANGED
else:
return STATUS_UNKNOWN
def module_doc_status(module_folder):
if os.path.exists(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_docs_', 'index.html')):
return STATUS_AVAILABLE
else:
if os.path.exists(os.path.join(module_folder, 'docs', 'index.rst')):
return STATUS_IN_WORK
else:
return STATUS_MISSING
def module_spec_status(module_folder):
if os.path.exists(os.path.join(module_folder, 'requirements', 'specification.reqif')):
try:
with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh:
ut = json.loads(fh.read())
if len(ut['lost_souls']['item_list']) > 0 or len(ut['lost_souls']['testcase_list']) > 0:
return STATUS_IN_WORK
else:
return STATUS_CLEAN
except IOError:
return STATUS_EXISTS
else:
return STATUS_MISSING