@@ -85,9 +85,11 @@ def __init__(
85
85
task_type_parameters : object = None ,
86
86
language : str | None = None ,
87
87
multithreaded_sandbox : bool = False ,
88
+ archive_sandbox : bool = False ,
88
89
shard : int | None = None ,
89
90
keep_sandbox : bool = False ,
90
91
sandboxes : list [str ] | None = None ,
92
+ sandbox_digests : dict [str , str ] | None = None ,
91
93
info : str | None = None ,
92
94
success : bool | None = None ,
93
95
text : list [str ] | None = None ,
@@ -104,12 +106,15 @@ def __init__(
104
106
language: the language of the submission / user test.
105
107
multithreaded_sandbox: whether the sandbox should
106
108
allow multithreading.
109
+ archive_sandbox: whether the sandbox is to be archived.
107
110
shard: the shard of the Worker completing this job.
108
111
keep_sandbox: whether to forcefully keep the sandbox,
109
112
even if other conditions (the config, the sandbox status)
110
113
don't warrant it.
111
114
sandboxes: the paths of the sandboxes used in
112
115
the Worker during the execution of the job.
116
+ sandbox_digests: the digests of the sandbox archives used to
117
+ debug solutions. (map of sandbox path -> archive digest)
113
118
info: a human readable description of the job.
114
119
success: whether the job succeeded.
115
120
text: description of the outcome of the job,
@@ -125,6 +130,8 @@ def __init__(
125
130
task_type = ""
126
131
if sandboxes is None :
127
132
sandboxes = []
133
+ if sandbox_digests is None :
134
+ sandbox_digests = {}
128
135
if info is None :
129
136
info = ""
130
137
if files is None :
@@ -139,9 +146,11 @@ def __init__(
139
146
self .task_type_parameters = task_type_parameters
140
147
self .language = language
141
148
self .multithreaded_sandbox = multithreaded_sandbox
149
+ self .archive_sandbox = archive_sandbox
142
150
self .shard = shard
143
151
self .keep_sandbox = keep_sandbox
144
152
self .sandboxes = sandboxes
153
+ self .sandbox_digests = sandbox_digests
145
154
self .info = info
146
155
147
156
self .success = success
@@ -161,9 +170,11 @@ def export_to_dict(self) -> dict:
161
170
'task_type_parameters' : self .task_type_parameters ,
162
171
'language' : self .language ,
163
172
'multithreaded_sandbox' : self .multithreaded_sandbox ,
173
+ 'archive_sandbox' : self .archive_sandbox ,
164
174
'shard' : self .shard ,
165
175
'keep_sandbox' : self .keep_sandbox ,
166
176
'sandboxes' : self .sandboxes ,
177
+ 'sandbox_digests' : self .sandbox_digests ,
167
178
'info' : self .info ,
168
179
'success' : self .success ,
169
180
'text' : self .text ,
@@ -253,6 +264,26 @@ def from_operation(
253
264
job = EvaluationJob .from_user_test (operation , object_ , dataset )
254
265
return job
255
266
267
+ def get_sandbox_digest_list (self ) -> list [str ] | None :
268
+ """
269
+ Convert self.sandbox_digests into a list, where each index matches the
270
+ corresponding index in self.sandboxes.
271
+ """
272
+ if not self .sandbox_digests :
273
+ return None
274
+ res : list [str | None ] = [None ] * len (self .sandboxes )
275
+ for k ,v in self .sandbox_digests .items ():
276
+ if k in self .sandboxes :
277
+ index = self .sandboxes .index (k )
278
+ res [index ] = v
279
+ else :
280
+ logger .warning ("Have digest for unknown sandbox %s" , k )
281
+ if None in res :
282
+ ind = res .index (None )
283
+ logger .warning ("Sandbox %s was not archived" , self .sandboxes [ind ])
284
+ return None
285
+ return res
286
+
256
287
257
288
class CompilationJob (Job ):
258
289
"""Job representing a compilation.
@@ -274,9 +305,11 @@ def __init__(
274
305
shard : int | None = None ,
275
306
keep_sandbox : bool = False ,
276
307
sandboxes : list [str ] | None = None ,
308
+ sandbox_digests : dict [str , str ] | None = None ,
277
309
info : str | None = None ,
278
310
language : str | None = None ,
279
311
multithreaded_sandbox : bool = False ,
312
+ archive_sandbox : bool = False ,
280
313
files : dict [str , File ] | None = None ,
281
314
managers : dict [str , Manager ] | None = None ,
282
315
success : bool | None = None ,
@@ -296,9 +329,9 @@ def __init__(
296
329
"""
297
330
298
331
Job .__init__ (self , operation , task_type , task_type_parameters ,
299
- language , multithreaded_sandbox ,
300
- shard , keep_sandbox , sandboxes , info , success , text ,
301
- files , managers , executables )
332
+ language , multithreaded_sandbox , archive_sandbox ,
333
+ shard , keep_sandbox , sandboxes , sandbox_digests , info , success ,
334
+ text , files , managers , executables )
302
335
self .compilation_success = compilation_success
303
336
self .plus = plus
304
337
@@ -341,6 +374,7 @@ def from_submission(
341
374
task_type_parameters = dataset .task_type_parameters ,
342
375
language = submission .language ,
343
376
multithreaded_sandbox = multithreaded ,
377
+ archive_sandbox = operation .archive_sandbox ,
344
378
files = dict (submission .files ),
345
379
managers = dict (dataset .managers ),
346
380
info = "compile submission %d" % (submission .id )
@@ -367,7 +401,8 @@ def to_submission(self, sr: SubmissionResult):
367
401
self .plus .get ('execution_wall_clock_time' )
368
402
sr .compilation_memory = self .plus .get ('execution_memory' )
369
403
sr .compilation_shard = self .shard
370
- sr .compilation_sandbox = ":" .join (self .sandboxes )
404
+ sr .compilation_sandbox_paths = self .sandboxes
405
+ sr .compilation_sandbox_digests = self .get_sandbox_digest_list ()
371
406
for executable in self .executables .values ():
372
407
sr .executables .set (executable )
373
408
@@ -431,6 +466,7 @@ def from_user_test(
431
466
task_type_parameters = dataset .task_type_parameters ,
432
467
language = user_test .language ,
433
468
multithreaded_sandbox = multithreaded ,
469
+ archive_sandbox = operation .archive_sandbox ,
434
470
files = dict (user_test .files ),
435
471
managers = managers ,
436
472
info = "compile user test %d" % (user_test .id )
@@ -457,7 +493,8 @@ def to_user_test(self, ur: UserTestResult):
457
493
self .plus .get ('execution_wall_clock_time' )
458
494
ur .compilation_memory = self .plus .get ('execution_memory' )
459
495
ur .compilation_shard = self .shard
460
- ur .compilation_sandbox = ":" .join (self .sandboxes )
496
+ ur .compilation_sandbox_paths = self .sandboxes
497
+ ur .compilation_sandbox_digests = self .get_sandbox_digest_list ()
461
498
for executable in self .executables .values ():
462
499
u_executable = UserTestExecutable (
463
500
executable .filename , executable .digest )
@@ -485,9 +522,11 @@ def __init__(
485
522
shard : int | None = None ,
486
523
keep_sandbox : bool = False ,
487
524
sandboxes : list [str ] | None = None ,
525
+ sandbox_digests : dict [str , str ] | None = None ,
488
526
info : str | None = None ,
489
527
language : str | None = None ,
490
528
multithreaded_sandbox : bool = False ,
529
+ archive_sandbox : bool = False ,
491
530
files : dict [str , File ] | None = None ,
492
531
managers : dict [str , Manager ] | None = None ,
493
532
executables : dict [str , Executable ] | None = None ,
@@ -526,9 +565,9 @@ def __init__(
526
565
527
566
"""
528
567
Job .__init__ (self , operation , task_type , task_type_parameters ,
529
- language , multithreaded_sandbox ,
530
- shard , keep_sandbox , sandboxes , info , success , text ,
531
- files , managers , executables )
568
+ language , multithreaded_sandbox , archive_sandbox ,
569
+ shard , keep_sandbox , sandboxes , sandbox_digests , info , success ,
570
+ text , files , managers , executables )
532
571
self .input = input
533
572
self .output = output
534
573
self .time_limit = time_limit
@@ -592,6 +631,7 @@ def from_submission(
592
631
task_type_parameters = dataset .task_type_parameters ,
593
632
language = submission .language ,
594
633
multithreaded_sandbox = multithreaded ,
634
+ archive_sandbox = operation .archive_sandbox ,
595
635
files = dict (submission .files ),
596
636
managers = dict (dataset .managers ),
597
637
executables = dict (submission_result .executables ),
@@ -619,7 +659,8 @@ def to_submission(self, sr: SubmissionResult):
619
659
'execution_wall_clock_time' ),
620
660
execution_memory = self .plus .get ('execution_memory' ),
621
661
evaluation_shard = self .shard ,
622
- evaluation_sandbox = ":" .join (self .sandboxes ),
662
+ evaluation_sandbox_paths = self .sandboxes ,
663
+ evaluation_sandbox_digests = self .get_sandbox_digest_list (),
623
664
testcase = sr .dataset .testcases [self .operation .testcase_codename ])]
624
665
625
666
@staticmethod
@@ -674,6 +715,7 @@ def from_user_test(
674
715
task_type_parameters = dataset .task_type_parameters ,
675
716
language = user_test .language ,
676
717
multithreaded_sandbox = multithreaded ,
718
+ archive_sandbox = operation .archive_sandbox ,
677
719
files = dict (user_test .files ),
678
720
managers = managers ,
679
721
executables = dict (user_test_result .executables ),
@@ -704,7 +746,8 @@ def to_user_test(self, ur: UserTestResult):
704
746
self .plus .get ('execution_wall_clock_time' )
705
747
ur .execution_memory = self .plus .get ('execution_memory' )
706
748
ur .evaluation_shard = self .shard
707
- ur .evaluation_sandbox = ":" .join (self .sandboxes )
749
+ ur .evaluation_sandbox_paths = self .sandboxes
750
+ ur .evaluation_sandbox_digests = self .get_sandbox_digest_list ()
708
751
ur .output = self .user_output
709
752
710
753
0 commit comments