1+ import dataclasses
2+ from typing import List
3+
14import consts
25import discord
36from run_eval import CompileResult , EvalResult , RunResult
@@ -43,31 +46,51 @@ async def _send_split_log(thread: discord.Thread, partial_message: str, header:
4346 return ""
4447
4548
46- async def _generate_compile_report (thread : discord .Thread , comp : CompileResult ):
49+ @dataclasses .dataclass
50+ class Text :
51+ text : str
52+
53+
54+ @dataclasses .dataclass
55+ class Log :
56+ header : str
57+ content : str
58+
59+
60+ class RunResultReport :
61+ def __init__ (self ):
62+ self .data : List [Text | Log ] = []
63+
64+ def add_text (self , section : str ):
65+ self .data .append (Text (section ))
66+
67+ def add_log (self , header : str , log : str ):
68+ self .data .append (Log (header , log ))
69+
70+
71+ def _generate_compile_report (reporter : "RunResultReport" , comp : CompileResult ):
4772 message = ""
4873 if not comp .nvcc_found :
4974 message += "# Compilation failed\n NVCC could not be found.\n "
5075 message += "This indicates a bug in the runner configuration, _not in your code_.\n "
5176 message += "Please notify the server admins of this problem"
52- await thread . send (message )
77+ reporter . add_text (message )
5378 return
5479
5580 # ok, we found nvcc
5681 message += "# Compilation failed\n "
5782 message += "Command "
5883 message += f"```bash\n >{ _limit_length (comp .command , 1000 )} ```\n "
5984 message += f"exited with code **{ comp .exit_code } **."
85+ reporter .add_text (message )
6086
61- message = await _send_split_log ( thread , message , "Compiler stderr" , comp .stderr .strip ())
87+ reporter . add_log ( "Compiler stderr" , comp .stderr .strip ())
6288
6389 if len (comp .stdout .strip ()) > 0 :
64- message = await _send_split_log ( thread , message , "Compiler stdout" , comp .stdout .strip ())
90+ reporter . add_log ( "Compiler stdout" , comp .stdout .strip ())
6591
66- if len (message ) != 0 :
67- await thread .send (message )
6892
69-
70- async def _generate_crash_report (thread : discord .Thread , run : RunResult ):
93+ def _generate_crash_report (reporter : "RunResultReport" , run : RunResult ):
7194 message = "# Running failed\n "
7295 message += "Command "
7396 message += f"```bash\n { _limit_length (run .command , 1000 )} ```\n "
@@ -77,40 +100,30 @@ async def _generate_crash_report(thread: discord.Thread, run: RunResult):
77100 message += (
78101 f"exited with error code **{ run .exit_code } ** after { float (run .duration ):.2f} seconds."
79102 )
103+ reporter .add_text (message )
80104
81105 if len (run .stderr .strip ()) > 0 :
82- message = await _send_split_log ( thread , message , "Program stderr" , run .stderr .strip ())
106+ reporter . add_log ( "Program stderr" , run .stderr .strip ())
83107
84108 if len (run .stdout .strip ()) > 0 :
85- message = await _send_split_log (thread , message , "Program stdout" , run .stdout .strip ())
86-
87- if len (message ) != 0 :
88- await thread .send (message )
109+ reporter .add_log ("Program stdout" , run .stdout .strip ())
89110
90111
91- async def _generate_test_report (thread : discord . Thread , run : RunResult ):
112+ def _generate_test_report (reporter : "RunResultReport" , run : RunResult ):
92113 message = "# Testing failed\n "
93114 message += "Command "
94115 message += f"```bash\n { _limit_length (run .command , 1000 )} ```\n "
95116 message += f"ran successfully in { run .duration :.2f} seconds, but did not pass all tests.\n "
117+ reporter .add_text (message )
96118
97119 # Generate a test
98- message = await _send_split_log (
99- thread ,
100- message ,
101- "Test log" ,
102- make_test_log (run ),
103- )
120+ reporter .add_log ("Test log" , make_test_log (run ))
104121
105122 if len (run .stderr .strip ()) > 0 :
106- message = await _send_split_log ( thread , message , "Program stderr" , run .stderr .strip ())
123+ reporter . add_log ( "Program stderr" , run .stderr .strip ())
107124
108125 if len (run .stdout .strip ()) > 0 :
109- message = await _send_split_log (thread , message , "Program stdout" , run .stdout .strip ())
110-
111- if len (message ) != 0 :
112- await thread .send (message )
113- return
126+ reporter .add_log ("Program stdout" , run .stdout .strip ())
114127
115128
116129def _short_fail_reason (run : RunResult ):
@@ -237,98 +250,80 @@ def log_one(base_name):
237250 return "❗ Could not find any benchmarks"
238251
239252
240- async def generate_report (thread : discord .Thread , runs : dict [str , EvalResult ]): # noqa: C901
241- message = ""
242-
253+ def generate_report (reporter : "RunResultReport" , runs : dict [str , EvalResult ]): # noqa: C901
243254 if "test" in runs :
244255 test_run = runs ["test" ]
245256
246257 if test_run .compilation is not None and not test_run .compilation .success :
247- await _generate_compile_report (thread , test_run .compilation )
258+ _generate_compile_report (reporter , test_run .compilation )
248259 return
249260
250261 test_run = test_run .run
251262
252263 if not test_run .success :
253- await _generate_crash_report (thread , test_run )
264+ _generate_crash_report (reporter , test_run )
254265 return
255266
256267 if not test_run .passed :
257- await _generate_test_report (thread , test_run )
268+ _generate_test_report (reporter , test_run )
258269 return
259270 else :
260271 num_tests = int (test_run .result .get ("test-count" , 0 ))
261-
262- message = await _send_split_log (
263- thread ,
264- message ,
265- f"✅ Passed { num_tests } /{ num_tests } tests" ,
266- make_test_log (test_run ),
267- )
272+ reporter .add_log (f"✅ Passed { num_tests } /{ num_tests } tests" , make_test_log (test_run ))
268273
269274 if "benchmark" in runs :
270275 bench_run = runs ["benchmark" ]
271276 if bench_run .compilation is not None and not bench_run .compilation .success :
272- await _generate_compile_report (thread , bench_run .compilation )
277+ _generate_compile_report (reporter , bench_run .compilation )
273278 return
274279
275280 bench_run = bench_run .run
276281 if not bench_run .success :
277- await _generate_crash_report (thread , bench_run )
282+ _generate_crash_report (reporter , bench_run )
278283 return
279284
280- message = await _send_split_log (
281- thread ,
282- message ,
285+ reporter .add_log (
283286 "Benchmarks" ,
284287 make_benchmark_log (bench_run ),
285288 )
286289
287290 if "leaderboard" in runs :
288291 bench_run = runs ["leaderboard" ]
289292 if bench_run .compilation is not None and not bench_run .compilation .success :
290- await _generate_compile_report (thread , bench_run .compilation )
293+ _generate_compile_report (reporter , bench_run .compilation )
291294 return
292295
293296 bench_run = bench_run .run
294297 if not bench_run .success :
295- await _generate_crash_report (thread , bench_run )
298+ _generate_crash_report (reporter , bench_run )
296299 return
297300
298- message = await _send_split_log (
299- thread ,
300- message ,
301+ reporter .add_log (
301302 "Ranked Benchmark" ,
302303 make_benchmark_log (bench_run ),
303304 )
304305
305306 if "script" in runs :
306307 run = runs ["script" ]
307308 if run .compilation is not None and not run .compilation .success :
308- await _generate_compile_report (thread , run .compilation )
309+ _generate_compile_report (reporter , run .compilation )
309310 return
310311
311312 run = run .run
312313 # OK, we were successful
313- message + = "# Success!\n "
314+ message = "# Success!\n "
314315 message += "Command "
315316 message += f"```bash\n { _limit_length (run .command , 1000 )} ```\n "
316317 message += f"ran successfully in { run .duration :.2} seconds.\n "
318+ reporter .add_text (message )
317319
318320 if len (runs ) == 1 :
319321 run = next (iter (runs .values ()))
320322 if len (run .run .stderr .strip ()) > 0 :
321- message = await _send_split_log (
322- thread , message , "Program stderr" , run .run .stderr .strip ()
323- )
323+ reporter .add_log ("Program stderr" , run .run .stderr .strip ())
324324
325325 if len (run .run .stdout .strip ()) > 0 :
326- message = await _send_split_log (
327- thread , message , "Program stdout" , run .run .stdout .strip ()
328- )
329-
330- if len (message ) != 0 :
331- await thread .send (message )
326+ reporter .add_log ("Program stdout" , run .run .stdout .strip ())
332327
333328
334329class MultiProgressReporter :
@@ -361,6 +356,7 @@ async def _update_message(self):
361356
362357class RunProgressReporter :
363358 def __init__ (self , title : str ):
359+ # short report
364360 self .title = title
365361 self .lines = []
366362
@@ -411,7 +407,21 @@ async def generate_report(self, title: str, runs: dict[str, EvalResult]):
411407 auto_archive_duration = 1440 ,
412408 )
413409 await thread .add_user (self .interaction .user )
414- await generate_report (thread , runs )
410+ report = RunResultReport ()
411+ generate_report (report , runs )
412+ message = ""
413+ for part in report .data :
414+ if isinstance (part , Text ):
415+ if len (message ) + len (part .text ) > 1900 :
416+ await thread .send (message )
417+ message = ""
418+ message += part .text
419+ elif isinstance (part , Log ):
420+ message = await _send_split_log (thread , message , part .header , part .content )
421+
422+ if len (message ) > 0 :
423+ await thread .send (message )
424+
415425 await self .push (f"See results at { thread .jump_url } " )
416426
417427
0 commit comments