Skip to content

Commit c805e4d

Browse files
mzuenniRagnarGrootKoerkamp
authored andcommitted
Warn if output validator ever crashes
1 parent 0f0eafa commit c805e4d

File tree

2 files changed

+52
-16
lines changed

2 files changed

+52
-16
lines changed

bin/problem.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -773,14 +773,20 @@ def testcases(
773773
and mode in [validate.Mode.INVALID, validate.Mode.VALID_OUTPUT]
774774
and t.root in ["invalid_output", "valid_output"]
775775
):
776-
warn(
777-
f"Found file {f} for {mode} validation in {p.settings.type_name()} problem. Skipping."
776+
p._warn_once(
777+
t.name,
778+
f"Found file {f} for {mode} validation in {p.settings.type_name()} problem. Skipping.",
778779
)
779780
continue
780781
if needans and not t.ans_path.is_file():
781782
if t.root != "invalid_input":
782783
p._warn_once(t.name, f"Found input file {f} without a .ans file. Skipping.")
783784
continue
785+
if t.root in ["valid_output", "invalid_output"]:
786+
assert t.out_path is not None
787+
if not t.out_path.is_file():
788+
p._warn_once(t.name, f"Found input file {f} without a .out file. Skipping.")
789+
continue
784790
if mode == validate.Mode.VALID_OUTPUT:
785791
if t.out_path is None:
786792
continue

bin/testcase.py

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def _run_validators(
282282
) -> bool:
283283
args = []
284284
results = []
285+
output_validator_crash = False
285286
for validator in validators:
286287
name = validator.name
287288
if isinstance(validator, validate.OutputValidator) and mode == validate.Mode.ANSWER:
@@ -336,11 +337,31 @@ def _run_validators(
336337
data = ret.err
337338

338339
if expect_rejection:
339-
bar.debug(
340-
message,
341-
data=data,
342-
color=Fore.GREEN if ret.status == ExecStatus.REJECTED else Fore.YELLOW,
343-
)
340+
warn = False
341+
if (
342+
isinstance(validator, validate.OutputValidator)
343+
and ret.status == ExecStatus.ERROR
344+
):
345+
output_validator_crash = True
346+
warn = True
347+
elif ret.status == ExecStatus.TIMEOUT:
348+
warn = True
349+
else:
350+
color = Fore.GREEN if ret.status == ExecStatus.REJECTED else Fore.YELLOW
351+
352+
if warn:
353+
bar.part_done(
354+
False,
355+
message,
356+
data=data,
357+
warn_instead_of_error=warn_instead_of_error,
358+
)
359+
else:
360+
bar.debug(
361+
message,
362+
data=data,
363+
color=color,
364+
)
344365
elif ret.status == ExecStatus.ERROR and ret.returncode == 0:
345366
bar.part_done(
346367
False,
@@ -356,7 +377,11 @@ def _run_validators(
356377
warn_instead_of_error=warn_instead_of_error,
357378
)
358379

359-
if ret.status or self.root in [*config.INVALID_CASE_DIRECTORIES, "valid_output"]:
380+
if (
381+
ret.status
382+
or expect_rejection
383+
or self.root in [*config.INVALID_CASE_DIRECTORIES, "valid_output"]
384+
):
360385
continue
361386

362387
# Move testcase to destination directory if specified.
@@ -384,15 +409,20 @@ def _run_validators(
384409
break
385410

386411
if expect_rejection:
387-
success = ExecStatus.REJECTED in results
388-
accepted = all(results)
412+
issues = []
413+
if all(results):
414+
issues.append("All validators accepted.")
415+
elif ExecStatus.REJECTED not in results:
416+
issues.append(f"At least one validator must exit with {config.RTV_WA}.")
417+
else:
418+
if ExecStatus.TIMEOUT in results:
419+
issues.append("Validator timed out.")
420+
if output_validator_crash:
421+
issues.append("Output Validator crashed.")
422+
423+
success = not issues
389424
if not success:
390-
reason = (
391-
"All validators accepted."
392-
if accepted
393-
else f"At least one validator must exit with {config.RTV_WA}."
394-
)
395-
msg = f"was not properly rejected by {mode} validation. {reason}"
425+
msg = f"was not properly rejected by {mode} validation. {' '.join(issues)}"
396426
if warn_instead_of_error:
397427
bar.warn(msg)
398428
else:

0 commit comments

Comments
 (0)