Skip to content

Commit 67fd6c7

Browse files
committed
ingest_mdir: print test results as we go
Major improvement to the printing of results. Scan the tree for results and output as tester spits them out. Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 856197e commit 67fd6c7

File tree

1 file changed

+157
-7
lines changed

1 file changed

+157
-7
lines changed

ingest_mdir.py

Lines changed: 157 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import os
1515
import re
1616
import queue
17+
import shutil
1718
import tempfile
19+
import time
1820

1921
from core import cmd
2022
from core import log_open_sec, log_end_sec, log_init
@@ -23,6 +25,13 @@
2325
from core import Tree
2426
from core import Tester
2527

28+
CONSOLE_WIDTH = None
29+
BOLD = '\033[1m'
30+
RED = '\033[31m'
31+
GREEN = '\033[32m'
32+
YELLOW = '\033[33m'
33+
RESET = '\033[0m'
34+
2635
config = configparser.ConfigParser()
2736

2837
config.add_section('dirs')
@@ -40,6 +49,20 @@
4049
help='the directory where results will be generated')
4150

4251

52+
def get_console_width():
53+
""" Get console width to avoid line wraps where we can. """
54+
55+
global CONSOLE_WIDTH
56+
57+
if CONSOLE_WIDTH is None:
58+
try:
59+
terminal_size = shutil.get_terminal_size()
60+
CONSOLE_WIDTH = terminal_size.columns
61+
except OSError:
62+
CONSOLE_WIDTH = 80
63+
return CONSOLE_WIDTH
64+
65+
4366
def get_series_id(result_dir):
4467
""" Find an unused series ID. """
4568

@@ -49,9 +72,134 @@ def get_series_id(result_dir):
4972
return i
5073

5174

75+
def print_summary_singleton(print_state, files, full_path, patch_id):
76+
"""
77+
Print summaries, single patch mode.
78+
Output differs if we have one patch vs many because tester will
79+
run the same test on all the patches in sequence.
80+
"""
81+
82+
if len(print_state['seen']) == 1:
83+
print()
84+
print(BOLD + "Series level tests:")
85+
86+
if patch_id != print_state['last_patch']:
87+
print_state['last_patch'] = patch_id
88+
print(BOLD + "Patch level tests:")
89+
90+
test_name = os.path.basename(full_path)
91+
with open(os.path.join(full_path, "retcode"), "r", encoding="utf-8") as fp:
92+
retcode = int(fp.read())
93+
desc = None
94+
if "desc" in files:
95+
with open(os.path.join(full_path, "desc"), "r", encoding="utf-8") as fp:
96+
desc = fp.read().strip().replace('\n', ' ')
97+
98+
print(BOLD + f" {test_name:32}", end='')
99+
if retcode == 0:
100+
print(GREEN + "OKAY " + RESET, end='')
101+
elif retcode == 250:
102+
print(YELLOW + "WARNING" + RESET, end='')
103+
else:
104+
print(RED + "FAIL " + RESET + f"({retcode})", end='')
105+
106+
if desc:
107+
if len(desc) > get_console_width() - 41:
108+
print()
109+
print("", desc, end='')
110+
print('', flush=True)
111+
112+
113+
def print_summary_series(print_state, files, full_path, patch_id):
114+
""" Print summaries, series mode (more than one patch). """
115+
116+
test_name = os.path.basename(full_path)
117+
if test_name != print_state.get('last_test'):
118+
print_state['last_test'] = test_name
119+
print()
120+
print(BOLD + test_name)
121+
122+
with open(os.path.join(full_path, "retcode"), "r", encoding="utf-8") as fp:
123+
retcode = int(fp.read())
124+
desc = None
125+
if "desc" in files:
126+
with open(os.path.join(full_path, "desc"), "r", encoding="utf-8") as fp:
127+
desc = fp.read().strip().replace('\n', ' ')
128+
129+
if patch_id >= 0:
130+
patch_str = f"Patch {patch_id + 1:<6}"
131+
else:
132+
patch_str = "Full series "
133+
134+
failed = False
135+
print(BOLD + " " + patch_str, end='')
136+
if retcode == 0:
137+
print(GREEN + "OKAY " + RESET, end='')
138+
elif retcode == 250:
139+
print(YELLOW + "WARNING" + RESET, end='')
140+
else:
141+
print(RED + "FAIL " + RESET + f"({retcode})", end='')
142+
failed = True
143+
144+
if failed or (desc and len(desc) > get_console_width() - 21):
145+
print("\n", end=" ")
146+
if desc:
147+
print("", desc, end='')
148+
if failed:
149+
print("\n", end=" ")
150+
if failed:
151+
print(" Outputs:", full_path, end='')
152+
print('', flush=True)
153+
154+
155+
def print_test_summary(args, series, print_state):
156+
"""
157+
Report results based on files created by the tester in the filesystem.
158+
Track which files we have already as this function should be called
159+
periodically to check for new results, as the tester runs.
160+
"""
161+
162+
seen = print_state.get('seen', set())
163+
print_state['seen'] = seen
164+
print_state['last_patch'] = print_state.get('last_patch', -1)
165+
166+
for full_path, _, files in os.walk(os.path.join(args.result_dir,
167+
str(series.id))):
168+
if full_path in seen:
169+
continue
170+
if "summary" not in files:
171+
continue
172+
seen.add(full_path)
173+
174+
rel_path = full_path[len(args.result_dir) + 1:].split('/')
175+
176+
patch_id = -1
177+
if len(rel_path) == 3:
178+
patch_id = int(rel_path[-2]) - 1
179+
180+
if len(series.patches) == 1:
181+
print_summary_singleton(print_state, files, full_path, patch_id)
182+
else:
183+
print_summary_series(print_state, files, full_path, patch_id)
184+
185+
186+
def print_series_info(series):
187+
""" Print list of patches """
188+
189+
if len(series.patches) > 2 and series.cover_letter is None:
190+
print(BOLD + "No cover letter" + RESET)
191+
elif series.cover_letter:
192+
print(BOLD + series.title + RESET)
193+
194+
for p in series.patches:
195+
print(" " + f"[{p.id}] " + p.title)
196+
197+
52198
def run_tester(args, tree, series):
53199
""" Run the tester, report results as they appear """
54200

201+
summary_seen = {}
202+
55203
try:
56204
done = queue.Queue()
57205
pending = queue.Queue()
@@ -61,8 +209,15 @@ def run_tester(args, tree, series):
61209

62210
pending.put(series)
63211
pending.put(None)
212+
213+
while done.empty():
214+
print_test_summary(args, series, summary_seen)
215+
time.sleep(0.2)
64216
except:
217+
print("Error / Interrupt detected, asking runner to stop")
65218
tester.should_die = True
219+
tester.join()
220+
raise
66221
finally:
67222
tester.join()
68223

@@ -134,6 +289,8 @@ def main():
134289
tree_name = "unknown"
135290
print("Tree name unknown")
136291

292+
print_series_info(series)
293+
137294
try:
138295
tree = Tree(tree_name, tree_name, args.tree, current_branch=True)
139296
except cmd.CmdError:
@@ -152,13 +309,6 @@ def main():
152309
tree.git_checkout(tree.branch)
153310
tree.git_reset(head, hard=True)
154311

155-
# Summary hack
156-
os.system(f'for i in $(find {args.result_dir}/{series.id} -type f -name summary); do ' +
157-
'dir=$(dirname "$i"); ' +
158-
'head -n2 "$dir"/summary; ' +
159-
'cat "$dir"/desc 2>/dev/null; done'
160-
)
161-
162312

163313
if __name__ == "__main__":
164314
main()

0 commit comments

Comments
 (0)