3ab9a10055
Depends-On: I12cf2dbc62a25c1a56f7f0f7d54b7df412c2b397 Change-Id: I4b8f7e30c3d78c662bfcd44a5a46cfffc4dd2227 Implements: blueprint dashboard-selenium-tests-migrate-to-infra-ci
165 lines
4.9 KiB
Python
165 lines
4.9 KiB
Python
#!/usr/bin/python
|
|
# Copyright (c) 2015 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
|
|
from __future__ import with_statement
|
|
import jinja2
|
|
import lxml.etree as et
|
|
import uuid
|
|
import sys
|
|
import os
|
|
import re
|
|
|
|
if not __name__ == "__main__":
|
|
sys.exit(1)
|
|
if not len(sys.argv) >= 3:
|
|
sys.exit(1)
|
|
if not os.path.exists(sys.argv[1]):
|
|
sys.exit(1)
|
|
|
|
LOG_LINE_PATTERN = "^(?P<date>20[0-9]{2}\-[0-9]{2}\-[0-9]{2}) (?P<time>[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+) (?P<pid>[0-9]+) (?P<level>[A-Z]+) (?P<package>.*?) \[\-\](?P<log>.*?)$"
|
|
|
|
|
|
def get_attr(element, attr):
|
|
return element.attrib[attr] if attr in element.attrib.keys() else None
|
|
|
|
|
|
def parse_log_file(log_file_path):
|
|
LOG_RECORDS = []
|
|
LAST_LOG_ENTRY = None
|
|
|
|
with open(log_file_path, 'r') as log_file:
|
|
for line in log_file.readlines():
|
|
match = re.match(LOG_LINE_PATTERN, line, re.S)
|
|
if match:
|
|
LAST_LOG_ENTRY = {
|
|
'date': match.group('date'),
|
|
'time': match.group('time'),
|
|
'pid': match.group('pid'),
|
|
'level': match.group('level'),
|
|
'package': match.group('package'),
|
|
'log': match.group('log')
|
|
}
|
|
|
|
LOG_RECORDS.append(LAST_LOG_ENTRY)
|
|
elif LAST_LOG_ENTRY is not None:
|
|
LAST_LOG_ENTRY['log'] += line
|
|
|
|
return [log_record for log_record in LOG_RECORDS if log_record['level'] == "ERROR"]
|
|
|
|
|
|
STATS = {
|
|
'total': 0,
|
|
'success': 0,
|
|
'skip': 0,
|
|
'error': 0,
|
|
'failure': 0,
|
|
}
|
|
|
|
REPORT = {}
|
|
|
|
et.set_default_parser(et.XMLParser(huge_tree=True))
|
|
|
|
tree = et.parse(sys.argv[1])
|
|
root = tree.getroot()
|
|
|
|
STATS['total'] = int(root.attrib['tests'])
|
|
STATS['failure'] = int(root.attrib['failures'])
|
|
STATS['error'] = int(root.attrib['errors'])
|
|
STATS['skip'] = int(root.attrib['skip'])
|
|
STATS['unsuccess'] = STATS['failure'] + STATS['error'] + STATS['skip']
|
|
STATS['success'] = STATS['total'] - STATS['unsuccess']
|
|
|
|
for case in root:
|
|
class_name = case.attrib['classname']
|
|
|
|
screenshot_file = 'logs/artifacts/screenshots/%s.png' % case.attrib['name']
|
|
screenshot_path = os.path.join(
|
|
os.environ.get('WORKSPACE'),
|
|
screenshot_file
|
|
)
|
|
|
|
test = {
|
|
'name': case.attrib['name'],
|
|
'time': case.attrib['time'],
|
|
'result': 'success',
|
|
'exc_type': None,
|
|
'exc_message': None,
|
|
'traceback': None,
|
|
'output': case.text,
|
|
'uuid': str(uuid.uuid1()),
|
|
'screenshot': None
|
|
}
|
|
|
|
for child in case:
|
|
test['exc_type'] = get_attr(child, 'type')
|
|
test['exc_message'] = get_attr(child, 'message')
|
|
test['traceback'] = child.text
|
|
if child.tag == 'error':
|
|
test['result'] = 'error'
|
|
if os.path.exists(screenshot_path):
|
|
test['screenshot'] = screenshot_file
|
|
elif child.tag == 'failure':
|
|
test['result'] = 'failure'
|
|
if os.path.exists(screenshot_path):
|
|
test['screenshot'] = screenshot_file
|
|
elif child.tag == 'skipped':
|
|
test['result'] = 'skip'
|
|
|
|
if class_name not in REPORT.keys():
|
|
REPORT[class_name] = {
|
|
'tests': [],
|
|
'stats': {
|
|
'total': 0,
|
|
'failure': 0,
|
|
'error': 0,
|
|
'skip': 0,
|
|
'success': 0,
|
|
},
|
|
'result': 'success',
|
|
'uuid': str(uuid.uuid1()),
|
|
}
|
|
|
|
REPORT[class_name]['tests'].append(test)
|
|
REPORT[class_name]['stats']['total'] += 1
|
|
REPORT[class_name]['stats'][test['result']] += 1
|
|
|
|
TOTAL = REPORT[class_name]['stats']['total']
|
|
|
|
for class_name in REPORT.keys():
|
|
if REPORT[class_name]['stats']['failure'] > 0:
|
|
REPORT[class_name]['result'] = 'failure'
|
|
elif REPORT[class_name]['stats']['error'] > 0:
|
|
REPORT[class_name]['result'] = 'failure'
|
|
elif REPORT[class_name]['stats']['skip'] == TOTAL:
|
|
REPORT[class_name]['result'] = 'skip'
|
|
else:
|
|
REPORT[class_name]['result'] = 'success'
|
|
|
|
jinja = jinja2.Environment(
|
|
loader=jinja2.FileSystemLoader(os.path.join(
|
|
os.path.dirname(__file__), 'templates')
|
|
)
|
|
)
|
|
|
|
with open(sys.argv[2], 'w') as report_file:
|
|
report_file.write(jinja.get_template(
|
|
os.path.basename('report.template')
|
|
).render(
|
|
report=REPORT,
|
|
stats=STATS,
|
|
coverage=False,
|
|
))
|