summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/lib/oeqa/core/case.py49
-rw-r--r--scripts/lib/resulttool/log.py43
-rw-r--r--scripts/lib/resulttool/resultutils.py45
3 files changed, 109 insertions, 28 deletions
diff --git a/meta/lib/oeqa/core/case.py b/meta/lib/oeqa/core/case.py
index aca144e9dc..180635ac6c 100644
--- a/meta/lib/oeqa/core/case.py
+++ b/meta/lib/oeqa/core/case.py
@@ -4,6 +4,8 @@
4# SPDX-License-Identifier: MIT 4# SPDX-License-Identifier: MIT
5# 5#
6 6
7import base64
8import zlib
7import unittest 9import unittest
8 10
9from oeqa.core.exception import OEQAMissingVariable 11from oeqa.core.exception import OEQAMissingVariable
@@ -49,3 +51,50 @@ class OETestCase(unittest.TestCase):
49 for d in self.decorators: 51 for d in self.decorators:
50 d.tearDownDecorator() 52 d.tearDownDecorator()
51 self.tearDownMethod() 53 self.tearDownMethod()
54
55class OEPTestResultTestCase:
56 """
57 Mix-in class to provide functions to make interacting with extraresults for
58 the purposes of storing ptestresult data.
59 """
60 @staticmethod
61 def _compress_log(log):
62 logdata = log.encode("utf-8")
63 logdata = zlib.compress(logdata)
64 logdata = base64.b64encode(logdata).decode("utf-8")
65 return {"compressed" : logdata}
66
67 def ptest_rawlog(self, log):
68 if not hasattr(self, "extraresults"):
69 self.extraresults = {"ptestresult.sections" : {}}
70 self.extraresults["ptestresult.rawlogs"] = {"log" : self._compress_log(log)}
71
72 def ptest_section(self, section, duration = None, log = None, logfile = None, exitcode = None):
73 if not hasattr(self, "extraresults"):
74 self.extraresults = {"ptestresult.sections" : {}}
75
76 sections = self.extraresults.get("ptestresult.sections")
77 if section not in sections:
78 sections[section] = {}
79
80 if log is not None:
81 sections[section]["log"] = self._compress_log(log)
82 elif logfile is not None:
83 with open(logfile, "r") as f:
84 sections[section]["log"] = self._compress_log(f.read())
85
86 if duration is not None:
87 sections[section]["duration"] = duration
88 if exitcode is not None:
89 sections[section]["exitcode"] = exitcode
90
91 def ptest_result(self, section, test, result):
92 if not hasattr(self, "extraresults"):
93 self.extraresults = {"ptestresult.sections" : {}}
94
95 sections = self.extraresults.get("ptestresult.sections")
96 if section not in sections:
97 sections[section] = {}
98 resultname = "ptestresult.{}.{}".format(section, test)
99 self.extraresults[resultname] = {"status" : result}
100
diff --git a/scripts/lib/resulttool/log.py b/scripts/lib/resulttool/log.py
index 2352c767d9..f1bfd99500 100644
--- a/scripts/lib/resulttool/log.py
+++ b/scripts/lib/resulttool/log.py
@@ -8,12 +8,12 @@ import os
8import resulttool.resultutils as resultutils 8import resulttool.resultutils as resultutils
9 9
10def show_ptest(result, ptest, logger): 10def show_ptest(result, ptest, logger):
11 if 'ptestresult.sections' in result: 11 logdata = resultutils.ptestresult_get_log(result, ptest)
12 if ptest in result['ptestresult.sections'] and 'log' in result['ptestresult.sections'][ptest]: 12 if logdata is not None:
13 print(result['ptestresult.sections'][ptest]['log']) 13 print(logdata)
14 return 0 14 return 0
15 15
16 print("ptest '%s' not found" % ptest) 16 print("ptest '%s' log not found" % ptest)
17 return 1 17 return 1
18 18
19def show_reproducible(result, reproducible, logger): 19def show_reproducible(result, reproducible, logger):
@@ -25,7 +25,6 @@ def show_reproducible(result, reproducible, logger):
25 print("reproducible '%s' not found" % reproducible) 25 print("reproducible '%s' not found" % reproducible)
26 return 1 26 return 1
27 27
28
29def log(args, logger): 28def log(args, logger):
30 results = resultutils.load_resultsdata(args.source) 29 results = resultutils.load_resultsdata(args.source)
31 30
@@ -35,24 +34,24 @@ def log(args, logger):
35 return 1 34 return 1
36 35
37 for _, run_name, _, r in resultutils.test_run_results(results): 36 for _, run_name, _, r in resultutils.test_run_results(results):
38 if args.dump_ptest: 37 if args.dump_ptest and 'ptestresult.sections' in r:
39 if 'ptestresult.sections' in r: 38 for name, ptest in r['ptestresult.sections'].items():
40 for name, ptest in r['ptestresult.sections'].items(): 39 logdata = resultutils.ptestresult_get_log(r, name)
41 if 'log' in ptest: 40 if logdata is not None:
42 dest_dir = args.dump_ptest 41 dest_dir = args.dump_ptest
43 if args.prepend_run: 42 if args.prepend_run:
44 dest_dir = os.path.join(dest_dir, run_name) 43 dest_dir = os.path.join(dest_dir, run_name)
45 44
46 os.makedirs(dest_dir, exist_ok=True) 45 os.makedirs(dest_dir, exist_ok=True)
47 46 dest = os.path.join(dest_dir, '%s.log' % name)
48 dest = os.path.join(dest_dir, '%s.log' % name) 47 print(dest)
49 print(dest) 48 with open(dest, 'w') as f:
50 with open(dest, 'w') as f: 49 f.write(logdata)
51 f.write(ptest['log'])
52 50
53 if args.raw_ptest: 51 if args.raw_ptest:
54 if 'ptestresult.rawlogs' in r: 52 rawlog = resultutils.ptestresult_get_rawlogs(r)
55 print(r['ptestresult.rawlogs']['log']) 53 if rawlog is not None:
54 print(rawlog)
56 else: 55 else:
57 print('Raw ptest logs not found') 56 print('Raw ptest logs not found')
58 return 1 57 return 1
diff --git a/scripts/lib/resulttool/resultutils.py b/scripts/lib/resulttool/resultutils.py
index e595c185df..177fb25f93 100644
--- a/scripts/lib/resulttool/resultutils.py
+++ b/scripts/lib/resulttool/resultutils.py
@@ -7,6 +7,8 @@
7# 7#
8 8
9import os 9import os
10import base64
11import zlib
10import json 12import json
11import scriptpath 13import scriptpath
12import copy 14import copy
@@ -117,6 +119,34 @@ def strip_ptestresults(results):
117 del newresults[res]['result']['ptestresult.sections'][i]['log'] 119 del newresults[res]['result']['ptestresult.sections'][i]['log']
118 return newresults 120 return newresults
119 121
122def decode_log(logdata):
123 if isinstance(logdata, str):
124 return logdata
125 elif isinstance(logdata, dict):
126 if "compressed" in logdata:
127 data = logdata.get("compressed")
128 data = base64.b64decode(data.encode("utf-8"))
129 return zlib.decompress(data).decode("utf-8")
130 return None
131
132def ptestresult_get_log(results, section):
133 if 'ptestresult.sections' not in results:
134 return None
135 if section not in results['ptestresult.sections']:
136 return None
137
138 ptest = results['ptestresult.sections'][section]
139 if 'log' not in ptest:
140 return None
141 return decode_log(ptest['log'])
142
143def ptestresult_get_rawlogs(results):
144 if 'ptestresult.rawlogs' not in results:
145 return None
146 if 'log' not in results['ptestresult.rawlogs']:
147 return None
148 return decode_log(results['ptestresult.rawlogs']['log'])
149
120def save_resultsdata(results, destdir, fn="testresults.json", ptestjson=False, ptestlogs=False): 150def save_resultsdata(results, destdir, fn="testresults.json", ptestjson=False, ptestlogs=False):
121 for res in results: 151 for res in results:
122 if res: 152 if res:
@@ -131,14 +161,17 @@ def save_resultsdata(results, destdir, fn="testresults.json", ptestjson=False, p
131 f.write(json.dumps(resultsout, sort_keys=True, indent=4)) 161 f.write(json.dumps(resultsout, sort_keys=True, indent=4))
132 for res2 in results[res]: 162 for res2 in results[res]:
133 if ptestlogs and 'result' in results[res][res2]: 163 if ptestlogs and 'result' in results[res][res2]:
134 if 'ptestresult.rawlogs' in results[res][res2]['result']: 164 seriesresults = results[res][res2]['result']
165 rawlogs = ptestresult_get_rawlogs(seriesresults)
166 if rawlogs is not None:
135 with open(dst.replace(fn, "ptest-raw.log"), "w+") as f: 167 with open(dst.replace(fn, "ptest-raw.log"), "w+") as f:
136 f.write(results[res][res2]['result']['ptestresult.rawlogs']['log']) 168 f.write(rawlogs)
137 if 'ptestresult.sections' in results[res][res2]['result']: 169 if 'ptestresult.sections' in seriesresults:
138 for i in results[res][res2]['result']['ptestresult.sections']: 170 for i in seriesresults['ptestresult.sections']:
139 if 'log' in results[res][res2]['result']['ptestresult.sections'][i]: 171 sectionlog = ptestresult_get_log(seriesresults, i)
172 if sectionlog is not None:
140 with open(dst.replace(fn, "ptest-%s.log" % i), "w+") as f: 173 with open(dst.replace(fn, "ptest-%s.log" % i), "w+") as f:
141 f.write(results[res][res2]['result']['ptestresult.sections'][i]['log']) 174 f.write(sectionlog)
142 175
143def git_get_result(repo, tags): 176def git_get_result(repo, tags):
144 git_objs = [] 177 git_objs = []