diff --git a/src/sinol_make/__init__.py b/src/sinol_make/__init__.py index 70502443..501e8b06 100644 --- a/src/sinol_make/__init__.py +++ b/src/sinol_make/__init__.py @@ -6,7 +6,7 @@ from sinol_make import util, oiejq -__version__ = "1.5.27" +__version__ = "1.5.28" def configure_parsers(): diff --git a/src/sinol_make/commands/run/__init__.py b/src/sinol_make/commands/run/__init__.py index c4d71ccd..719995c1 100644 --- a/src/sinol_make/commands/run/__init__.py +++ b/src/sinol_make/commands/run/__init__.py @@ -1157,6 +1157,25 @@ def compile_checker(self): if not checker_compilation[0]: util.exit_with_error('Checker compilation failed.') + def check_had_checker(self, has_checker): + """ + Checks if there was a checker and if it is now removed (or the other way around) and if so, removes tests cache. + In theory, removing cache after adding a checker is redundant, because during its compilation, the cache is + removed. + """ + had_checker = os.path.exists(paths.get_cache_path("checker")) + if (had_checker and not has_checker) or (not had_checker and has_checker): + cache.remove_results_cache() + if has_checker: + with open(paths.get_cache_path("checker"), "w") as f: + f.write("") + else: + try: + os.remove(paths.get_cache_path("checker")) + except FileNotFoundError: + pass + + def run(self, args): args = util.init_package_command(args) @@ -1187,6 +1206,7 @@ def run(self, args): self.compile_checker() else: self.checker = None + self.check_had_checker(self.checker is not None) lib = package_util.get_files_matching_pattern(self.ID, f'{self.ID}lib.*') self.has_lib = len(lib) != 0 diff --git a/tests/commands/run/test_integration.py b/tests/commands/run/test_integration.py index c0c90d90..b7a83321 100644 --- a/tests/commands/run/test_integration.py +++ b/tests/commands/run/test_integration.py @@ -266,7 +266,7 @@ def test_weak_compilation_flags(create_package): command = Command() command.run(args) - + @pytest.mark.parametrize("create_package", [get_oioioi_compilation_flags_package_path()], indirect=True) def test_oioioi_compilation_flags(create_package): """ @@ -747,3 +747,38 @@ def test_cwd_in_prog(create_package, time_tool): args = parser.parse_args(["run", "--time-tool", time_tool]) command = Command() command.run(args) + + +@pytest.mark.parametrize("create_package", [get_checker_package_path()], indirect=True) +def test_ghost_checker(create_package): + """ + Test if after removing a checker, the cached test results are removed. + """ + package_path = create_package + create_ins_outs(package_path) + parser = configure_parsers() + args = parser.parse_args(["run"]) + command = Command() + + # First run to cache test results. + command.run(args) + + # Remove checker. + os.unlink(os.path.join(os.getcwd(), "prog", "chkchk.cpp")) + shutil.copytree(paths.get_cache_path(), os.path.join(os.getcwd(), ".cache-copy")) + + command = Command() + command.check_had_checker(False) + + for solution in os.listdir(paths.get_cache_path("md5sums")): + cache_file: CacheFile = cache.get_cache_file(solution) + assert cache_file.tests == {} + + shutil.rmtree(paths.get_cache_path()) + shutil.move(os.path.join(os.getcwd(), ".cache-copy"), paths.get_cache_path()) + + # Run should fail, because outputs won't be checked with checker, so expected scores will be incorrect. + command = Command() + with pytest.raises(SystemExit) as e: + command.run(args) + assert e.value.code == 1