From c8e04b98e4d0460dd577cd8abc1f18ccf5211b49 Mon Sep 17 00:00:00 2001 From: Justin Date: Wed, 23 Oct 2024 20:29:44 -0600 Subject: [PATCH] Fail gracefully when testifle is not UTF-8 --- dragon_runner/harness.py | 4 ++-- dragon_runner/testfile.py | 46 +++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/dragon_runner/harness.py b/dragon_runner/harness.py index 2d9c1f5..96adbf7 100644 --- a/dragon_runner/harness.py +++ b/dragon_runner/harness.py @@ -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 @@ -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() @@ -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: @@ -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 diff --git a/dragon_runner/testfile.py b/dragon_runner/testfile.py index b1450d4..4a17296 100644 --- a/dragon_runner/testfile.py +++ b/dragon_runner/testfile.py @@ -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]: """ @@ -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)