blob: 153f2b8e1074ae35d5ceb812656a5842682407d2 [file] [log] [blame]
Brad Bishop40320b12019-03-26 16:08:25 -04001# resulttool - common library/utility functions
2#
3# Copyright (c) 2019, Intel Corporation.
4# Copyright (c) 2019, Linux Foundation
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms and conditions of the GNU General Public License,
8# version 2, as published by the Free Software Foundation.
9#
10# This program is distributed in the hope it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13# more details.
14#
15import os
16import json
17import scriptpath
18scriptpath.add_oe_lib_path()
19
20flatten_map = {
21 "oeselftest": [],
22 "runtime": [],
23 "sdk": [],
24 "sdkext": [],
25 "manual": []
26}
27regression_map = {
28 "oeselftest": ['TEST_TYPE', 'MACHINE'],
29 "runtime": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'IMAGE_PKGTYPE', 'DISTRO'],
30 "sdk": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'SDKMACHINE'],
31 "sdkext": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'SDKMACHINE'],
32 "manual": ['TEST_TYPE', 'TEST_MODULE', 'IMAGE_BASENAME', 'MACHINE']
33}
34store_map = {
35 "oeselftest": ['TEST_TYPE'],
36 "runtime": ['TEST_TYPE', 'DISTRO', 'MACHINE', 'IMAGE_BASENAME'],
37 "sdk": ['TEST_TYPE', 'MACHINE', 'SDKMACHINE', 'IMAGE_BASENAME'],
38 "sdkext": ['TEST_TYPE', 'MACHINE', 'SDKMACHINE', 'IMAGE_BASENAME'],
39 "manual": ['TEST_TYPE', 'TEST_MODULE', 'MACHINE', 'IMAGE_BASENAME']
40}
41
42#
43# Load the json file and append the results data into the provided results dict
44#
45def append_resultsdata(results, f, configmap=store_map):
46 if type(f) is str:
47 with open(f, "r") as filedata:
48 data = json.load(filedata)
49 else:
50 data = f
51 for res in data:
52 if "configuration" not in data[res] or "result" not in data[res]:
53 raise ValueError("Test results data without configuration or result section?")
54 if "TESTSERIES" not in data[res]["configuration"]:
55 data[res]["configuration"]["TESTSERIES"] = os.path.basename(os.path.dirname(f))
56 testtype = data[res]["configuration"].get("TEST_TYPE")
57 if testtype not in configmap:
58 raise ValueError("Unknown test type %s" % testtype)
59 configvars = configmap[testtype]
60 testpath = "/".join(data[res]["configuration"].get(i) for i in configmap[testtype])
61 if testpath not in results:
62 results[testpath] = {}
63 if 'ptestresult.rawlogs' in data[res]['result']:
64 del data[res]['result']['ptestresult.rawlogs']
65 if 'ptestresult.sections' in data[res]['result']:
66 for i in data[res]['result']['ptestresult.sections']:
67 if 'log' in data[res]['result']['ptestresult.sections'][i]:
68 del data[res]['result']['ptestresult.sections'][i]['log']
69 results[testpath][res] = data[res]
70
71#
72# Walk a directory and find/load results data
73# or load directly from a file
74#
75def load_resultsdata(source, configmap=store_map):
76 results = {}
77 if os.path.isfile(source):
78 append_resultsdata(results, source, configmap)
79 return results
80 for root, dirs, files in os.walk(source):
81 for name in files:
82 f = os.path.join(root, name)
83 if name == "testresults.json":
84 append_resultsdata(results, f, configmap)
85 return results
86
87def filter_resultsdata(results, resultid):
88 newresults = {}
89 for r in results:
90 for i in results[r]:
91 if i == resultsid:
92 newresults[r] = {}
93 newresults[r][i] = results[r][i]
94 return newresults
95
96def save_resultsdata(results, destdir, fn="testresults.json"):
97 for res in results:
98 if res:
99 dst = destdir + "/" + res + "/" + fn
100 else:
101 dst = destdir + "/" + fn
102 os.makedirs(os.path.dirname(dst), exist_ok=True)
103 with open(dst, 'w') as f:
104 f.write(json.dumps(results[res], sort_keys=True, indent=4))
105
106def git_get_result(repo, tags):
107 git_objs = []
108 for tag in tags:
109 files = repo.run_cmd(['ls-tree', "--name-only", "-r", tag]).splitlines()
110 git_objs.extend([tag + ':' + f for f in files if f.endswith("testresults.json")])
111
112 def parse_json_stream(data):
113 """Parse multiple concatenated JSON objects"""
114 objs = []
115 json_d = ""
116 for line in data.splitlines():
117 if line == '}{':
118 json_d += '}'
119 objs.append(json.loads(json_d))
120 json_d = '{'
121 else:
122 json_d += line
123 objs.append(json.loads(json_d))
124 return objs
125
126 # Optimize by reading all data with one git command
127 results = {}
128 for obj in parse_json_stream(repo.run_cmd(['show'] + git_objs + ['--'])):
129 append_resultsdata(results, obj)
130
131 return results