Skip to content

Commit

Permalink
Fail gracefully when testifle is not UTF-8
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinMeimar committed Oct 24, 2024
1 parent 3c38595 commit c8e04b9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 23 deletions.
4 changes: 2 additions & 2 deletions dragon_runner/harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from dragon_runner.cli import CLIArgs
from dragon_runner.config import Config, Executable, Package
from dragon_runner.log import log
from dragon_runner.testfile import TestFile
from dragon_runner.runner import TestResult, ToolChainRunner
from dragon_runner.utils import file_to_str

Expand Down Expand Up @@ -72,6 +71,7 @@ def run(self) -> bool:
"""
if self.cli_args.grade_file:
assert self.cli_args.failure_log is not None, "Need to supply failure log!"
print("Running Dragon Runner in grade mode")
return self.run_grader_json()
else:
return self.run_regular()
Expand Down Expand Up @@ -137,6 +137,7 @@ def run_grader_json(self) -> bool:
print(f"\nToolchain: {toolchain.name}")

for def_exe in defending_exes:
def_exe.source_env()
def_feedback_file = f"{def_exe.id}-{toolchain.name}feedback.txt"

for a_pkg in attacking_pkgs:
Expand All @@ -147,7 +148,6 @@ def run_grader_json(self) -> bool:
for a_spkg in a_pkg.subpackages:
for test in a_spkg.tests:
test_result: TestResult = tc_runner.run(test, def_exe)

if test_result.did_pass:
print(Fore.GREEN + '.' + Fore.RESET, end='')
pass_count += 1
Expand Down
46 changes: 25 additions & 21 deletions dragon_runner/testfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def _get_content(self, inline_directive: str, file_directive: str) -> Union[byte
return TestFileError(f"Failed to locate path supplied to {file_directive}: {full_path}")
return self._get_file_bytes(full_path)

return b'' # default to empty content
return file_path # default to empty content

def _get_file_bytes(self, file_path: str) -> Optional[bytes]:
"""
Expand All @@ -63,33 +63,37 @@ def _get_file_bytes(self, file_path: str) -> Optional[bytes]:
except FileNotFoundError:
return None

def _get_directive_contents(self, directive_prefix: str) -> Optional[bytes]:
def _get_directive_contents(self, directive_prefix: str) -> Union[bytes, TestFileError]:
"""
Look into the testfile itself for contents defined in directives.
Directives can appear anywhere in a line, as long as they're preceded by a comment syntax.
"""
contents = BytesIO()
first_match = True
with open(self.path, 'r') as test_file:
for line in test_file:
comment_index = line.find(self.comment_syntax)
directive_index = line.find(directive_prefix)
if comment_index == -1 or directive_index == -1 or comment_index > directive_index:
continue

rhs_line = line.split(directive_prefix, 1)[1]
rhs_bytes = str_to_bytes(rhs_line, chop_newline=True)
if rhs_bytes is None:
return None
if not first_match:
contents.write(b'\n')
try:
with open(self.path, 'r') as test_file:
for line in test_file:
comment_index = line.find(self.comment_syntax)
directive_index = line.find(directive_prefix)
if comment_index == -1 or directive_index == -1 or comment_index > directive_index:
continue

rhs_line = line.split(directive_prefix, 1)[1]
rhs_bytes = str_to_bytes(rhs_line, chop_newline=True)
if rhs_bytes is None:
return None
if not first_match:
contents.write(b'\n')

contents.write(rhs_bytes)
first_match = False
contents.seek(0)
return contents.getvalue() if contents else None
except UnicodeDecodeError as e:
return TestFileError(e.reason)
except Exception as e:
return TestFileError(f"Unkown error occured while parsing testfile: {self.path}")

contents.write(rhs_bytes)
first_match = False

contents.seek(0)
return contents.getvalue() if contents else None

def __repr__(self):
max_test_name_length = 30
test_name = os.path.basename(self.path)
Expand Down

0 comments on commit c8e04b9

Please sign in to comment.