forked from mattsm/boardfarm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
library.py
131 lines (112 loc) · 4.74 KB
/
library.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Copyright (c) 2015
#
# All rights reserved.
#
# This file is distributed under the Clear BSD license.
# The full text can be found in LICENSE in the root directory.
import datetime
import ipaddress
import json
import os
from termcolor import cprint
_version = (1, 0, 0)
version = '.'.join(str(x) for x in _version)
class HelperEncoder(json.JSONEncoder):
'''Turn some objects into a form that can be stored in JSON.'''
def default(self, obj):
if isinstance(obj, ipaddress.IPv4Network) or \
isinstance(obj, ipaddress.IPv4Address):
return str(obj)
elif isinstance(obj, datetime.datetime):
return str(obj)
elif hasattr(obj, 'shortname'):
return obj.shortname()
else:
try:
return json.JSONEncoder.default(self, obj)
except:
print("WARNING: HelperEncoder doesn't know how to convert %s to a string or number" % type(obj))
return ""
def clean_for_json(data):
'''
Given a python dictionary, walk the structure and convert values to
types that are valid for JSON. Return a python dictionary.
'''
return json.loads(json.dumps(data, cls=HelperEncoder))
def printd(data):
'''Pretty-print as a JSON data object.'''
print(json.dumps(data, sort_keys=True, indent=4, cls=HelperEncoder))
def print_bold(msg):
cprint(msg, None, attrs=['bold'])
def process_test_results(raw_test_results, golden={}):
full_results = {'test_results': [],
'tests_pass': 0,
'tests_fail': 0,
'tests_skip': 0,
'tests_total': 0,
'unexpected_fail': 0,
'unexpected_pass': 0,
}
for i, x in enumerate(raw_test_results):
def parse_and_add_results(cls, prefix=""):
name = prefix + getattr(cls, 'name', cls.__class__.__name__)
grade = getattr(cls, 'result_grade', None)
try:
if hasattr(cls, 'elapsed_time'):
elapsed_time = getattr(cls, 'elapsed_time')
else:
start_time = getattr(cls, 'start_time')
stop_time = getattr(cls, 'stop_time')
elapsed_time = stop_time - start_time
except:
elapsed_time = 0
unexpected = False
if '_source' in golden:
if name + "-result" in golden['_source']:
if golden['_source'][name + "-result"] != grade:
unexpected = True
if grade == "Unexp OK" or (grade == "OK" and unexpected):
grade = "Unexp OK"
full_results['unexpected_pass'] += 1
elif grade == "Exp FAIL" or (grade == "FAIL" and unexpected):
grade = "Exp FAIL"
full_results['unexpected_fail'] += 1
elif grade == "OK":
full_results['tests_pass'] += 1
elif grade == "FAIL":
full_results['tests_fail'] += 1
elif grade == "SKIP" or grade is None:
full_results['tests_skip'] += 1
message = getattr(cls, 'result_message', None)
if message is None:
try:
message = cls.__doc__.split('\n')[0]
except:
message = "Missing description of class (no docstring)"
print_bold("WARN: Please add docstring to %s." % cls)
pass
long_message = getattr(cls, 'long_result_message', "")
full_results['test_results'].append({"name": name, "message": message, "long_message": long_message, "grade": grade, "elapsed_time": elapsed_time})
try:
parse_and_add_results(x)
for subtest in x.subtests:
parse_and_add_results(subtest, prefix=x.__class__.__name__ + "-")
except Exception as e:
print("Failed to parse test result: %s" % e)
pass
full_results['tests_total'] = len(raw_test_results)
return full_results
def send_results_to_myqsl(testsuite, output_dir):
'''
Send url of results to a MySQL database. Only do this if we are on
a build server (use the build environment variables).
'''
dir = output_dir.replace(os.getcwd(), '').strip(os.sep)
build_id = os.environ.get('image_build_id', '')
build_url = os.environ.get('BUILD_URL', '')
if '' not in (build_id, testsuite, build_url):
from devices import mysql
build_url = build_url.replace("https://", "") + "artifact/openwrt/%s/results.html" % dir
title = 'Board Farm Results (suite: %s)' % testsuite
reporter = mysql.MySqlReporter()
reporter.insert_data(build_id, build_url, title)