5
5
from datetime import timedelta
6
6
from pathlib import Path
7
7
from urllib .request import urlopen
8
+ from traceback import print_exception
8
9
9
10
10
11
use_ansi = os .name != 'nt' and sys .stdout .isatty ()
@@ -159,16 +160,26 @@ def __str__(self):
159
160
return f'{ self .name } : time={ self .time_str ()} result={ self .result } '
160
161
161
162
163
+ def print_error (exc , context ):
164
+ exc .add_note (context )
165
+ print_exception (exc )
166
+
167
+
162
168
class Build :
163
169
def __init__ (self , name , builds_dir , misc = None ):
164
- if misc is None :
165
- misc = {}
166
170
self .name = name
167
171
self .dir = builds_dir / name
168
- self .misc = misc
172
+ self .misc = misc or {}
173
+ self .basename = self .misc .get ('basename' )
174
+ self .props = self .misc .get ('props' , {})
175
+ self .tests = {}
169
176
self .stats = TestStats ()
170
- self .basename = misc ['basename' ]
171
- self .props = misc .get ('props' , {})
177
+
178
+ if misc is None :
179
+ return
180
+
181
+ if self .basename is None :
182
+ raise ValueError (f'Build { name !r} is missing a basename, probably a missing latest.txt' )
172
183
173
184
# Get build.json. It should either exist locally or can be downloaded.
174
185
build_json_name = self .basename + '.build.json'
@@ -182,15 +193,20 @@ def __init__(self, name, builds_dir, misc=None):
182
193
with urlopen (url ) as f :
183
194
data = json .load (f )
184
195
else :
185
- raise ValueError (f'Can not get { build_json_name } for { name } ' )
196
+ raise ValueError (f'Can not get { build_json_name !r } for { name !r } ' )
186
197
187
- self .tests = {}
188
198
for t in data ['tests' ]:
189
- test_run = TestRun (t ['name' ], int (t ['result' ]), timedelta (seconds = int (t ['time' ])), t )
190
- self .stats .add (test_run .status , test_run .time )
191
- if test_run .name in self .tests :
192
- raise ValueError (f'Multiple { repr (test_run .name )} in { self .name } !' )
193
- self .tests [test_run .name ] = test_run
199
+ try :
200
+ self .add_test_run (t )
201
+ except BaseException as e :
202
+ print_error (e , f'Test { name !r} in build { name !r} caused this error' )
203
+
204
+ def add_test_run (self , t ):
205
+ test_run = TestRun (t ['name' ], int (t ['result' ]), timedelta (seconds = int (t ['time' ])), t )
206
+ self .stats .add (test_run .status , test_run .time )
207
+ if test_run .name in self .tests :
208
+ raise ValueError (f'Multiple { repr (test_run .name )} in { self .name } !' )
209
+ self .tests [test_run .name ] = test_run
194
210
195
211
def __iter__ (self ):
196
212
return iter (self .tests .values ())
@@ -245,8 +261,8 @@ def __init__(self, builds_dir: Path):
245
261
try :
246
262
build = Build (name , builds_dir , b )
247
263
except BaseException as e :
248
- e . add_note ( f'The build that caused an error was { name } ' )
249
- raise
264
+ print_error ( e , f'The build that caused this error was { name !r } ' )
265
+ build = Build ( name , builds_dir )
250
266
self .builds [name ] = build
251
267
252
268
# Collect all the tests
0 commit comments