From 2479a8443d67fc20928da16a89b682c8977f1feb Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 5 May 2025 10:33:57 +0200 Subject: [PATCH 01/13] Add test name to constructor --- src/sio3pack/packages/sinolpack/model.py | 2 +- src/sio3pack/test/test.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 1f89749..d419fe4 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -424,7 +424,7 @@ def _process_existing_tests(self): out_file = LocalFile(os.path.join(self.rootdir, "out", self.short_name + test_id + ".out")) else: out_file = None - self.tests.append(Test(test_id, in_file, out_file, group)) + self.tests.append(Test(self.short_name + test_id, test_id, in_file, out_file, group)) def get_tests(self) -> list[Test]: """ diff --git a/src/sio3pack/test/test.py b/src/sio3pack/test/test.py index 8c155c1..d071502 100644 --- a/src/sio3pack/test/test.py +++ b/src/sio3pack/test/test.py @@ -6,7 +6,8 @@ class Test: Represents an input and output test. """ - def __init__(self, test_id: str, in_file: File, out_file: File, group: str): + def __init__(self, test_name: str, test_id: str, in_file: File, out_file: File, group: str): + self.test_name = self.test_name self.test_id = test_id self.in_file = in_file self.out_file = out_file From 85b46932f7d73a69954334618afe5ec6de415160 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 5 May 2025 10:34:17 +0200 Subject: [PATCH 02/13] Not needed --- src/sio3pack/test/simple_test.py | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/sio3pack/test/simple_test.py diff --git a/src/sio3pack/test/simple_test.py b/src/sio3pack/test/simple_test.py deleted file mode 100644 index 3532aa0..0000000 --- a/src/sio3pack/test/simple_test.py +++ /dev/null @@ -1,23 +0,0 @@ -from sio3pack.files import File -from sio3pack.test import Test - - -class SimpleTest(Test): - def __init__( - self, - file_in: File, - file_out: File, - group: str, - default_mem_limit: int, - default_time_limit: int, - mem_limits: dict[str, int], - time_limits: dict[str, int], - ): - super().__init__() - self.file_in = file_in - self.file_out = file_out - self.group = group - self.default_mem_limit = default_mem_limit - self.default_time_limit = default_time_limit - self.mem_limits = mem_limits - self.time_limits = time_limits From 33ce082c08961ad2345d10789f75961fa3359625 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 5 May 2025 10:34:50 +0200 Subject: [PATCH 03/13] Formatter --- src/sio3pack/packages/sinolpack/model.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index d419fe4..7317c3f 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -276,16 +276,14 @@ def _get_model_solutions(self) -> list[dict[str, Any]]: self.main_model_solution = main_solution return model_solutions - def sort_model_solutions( - self, model_solutions: list[dict[str, Any]] - ) -> list[dict[str, Any]]: + def sort_model_solutions(self, model_solutions: list[dict[str, Any]]) -> list[dict[str, Any]]: """ Sorts model solutions by kind. """ def sort_key(model_solution): - kind: ModelSolutionKind = model_solution['kind'] - file: LocalFile = model_solution['file'] + kind: ModelSolutionKind = model_solution["kind"] + file: LocalFile = model_solution["file"] return kind.value, naturalsort_key(file.filename[: file.filename.index(".")]) return list(sorted(model_solutions, key=sort_key)) From 2d656279270cfd83b875477c0f6d86e19f413aa4 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 5 May 2025 10:36:01 +0200 Subject: [PATCH 04/13] Fix constructor --- src/sio3pack/test/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio3pack/test/test.py b/src/sio3pack/test/test.py index d071502..6341f44 100644 --- a/src/sio3pack/test/test.py +++ b/src/sio3pack/test/test.py @@ -7,7 +7,7 @@ class Test: """ def __init__(self, test_name: str, test_id: str, in_file: File, out_file: File, group: str): - self.test_name = self.test_name + self.test_name = test_name self.test_id = test_id self.in_file = in_file self.out_file = out_file From 5286254310e3c4427113dc1d2cf26cde18806b78 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Wed, 7 May 2025 21:46:28 +0200 Subject: [PATCH 05/13] Fixes --- src/sio3pack/files/local_file.py | 3 +++ src/sio3pack/packages/package/model.py | 3 +++ src/sio3pack/packages/sinolpack/model.py | 23 ++++++++++++++++++----- src/sio3pack/workflow/workflow.py | 3 ++- src/sio3pack/workflow/workflow_manager.py | 2 +- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/sio3pack/files/local_file.py b/src/sio3pack/files/local_file.py index 572476d..3ce564f 100644 --- a/src/sio3pack/files/local_file.py +++ b/src/sio3pack/files/local_file.py @@ -38,6 +38,9 @@ def __init__(self, path: str, exists=True): super().__init__(path) self.filename = os.path.basename(path) + def __repr__(self): + return f"" + def read(self) -> str: with open(self.path, "r") as f: return f.read() diff --git a/src/sio3pack/packages/package/model.py b/src/sio3pack/packages/package/model.py index 7ce41b0..51b3684 100644 --- a/src/sio3pack/packages/package/model.py +++ b/src/sio3pack/packages/package/model.py @@ -147,6 +147,9 @@ def get_title(self, lang: str | None = None) -> str: def get_statement(self, lang: str | None = None) -> File | None: pass + def reload_tests(self): + pass + @wrap_exceptions def get_tests(self) -> list[Test]: pass diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 7317c3f..37b03b2 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -153,7 +153,7 @@ def get_prog_dir(self) -> str: """ return os.path.join(self.rootdir, "prog") - def get_in_prog_dir(self, filename: str) -> File: + def get_in_prog_dir(self, filename: str) -> LocalFile: """ Returns the path to the input file in the program directory. """ @@ -288,6 +288,12 @@ def sort_key(model_solution): return list(sorted(model_solutions, key=sort_key)) + def _get_all_files_from_list(self, filenames: list[str]) -> list[LocalFile]: + files = [] + for filename in filenames: + files.append(self.get_in_prog_dir(filename)) + return files + def _process_prog_files(self): """ Process all files in the problem's program directory that are used. @@ -303,10 +309,11 @@ def _process_prog_files(self): if self.has_custom_graph: self.additional_files = self.workflow_manager.get_prog_files() else: + extensions = self.get_submittable_extensions() + ["sh"] self.additional_files = [] - self.additional_files.extend(self.config.get("extra_compilation_files", [])) - self.additional_files.extend(self.config.get("extra_execution_files", [])) - extensions = self.get_submittable_extensions() + self.additional_files.extend(self._get_all_files_from_list(self.config.get("extra_compilation_files", []))) + for extra_files in self.config.get("extra_execution_files", {}).values(): + self.additional_files.extend(self._get_all_files_from_list(extra_files)) self.special_files: dict[str, bool] = {} for file in ("ingen", "inwer", "soc", "chk"): try: @@ -386,7 +393,7 @@ def get_test_id_from_filename(self, filename: str) -> str: """ Returns the test ID from the filename. """ - match = re.match(rf"^{self.short_name}([a-zA-Z0-9]+)\.in$", filename) + match = re.match(rf"^{self.short_name}([a-zA-Z0-9]+)\.(in|out)$", filename) if match: return match.group(1) raise ValueError(f"Invalid filename format: {filename}") @@ -424,6 +431,12 @@ def _process_existing_tests(self): out_file = None self.tests.append(Test(self.short_name + test_id, test_id, in_file, out_file, group)) + def reload_tests(self): + """ + Updates `self.tests` variable with existing tests. + """ + self._process_existing_tests() + def get_tests(self) -> list[Test]: """ Returns the list of tests. diff --git a/src/sio3pack/workflow/workflow.py b/src/sio3pack/workflow/workflow.py index 4d221c1..c23d14b 100644 --- a/src/sio3pack/workflow/workflow.py +++ b/src/sio3pack/workflow/workflow.py @@ -1,3 +1,4 @@ +from sio3pack.files.file import File from sio3pack.workflow import ExecutionTask, Object, ScriptTask from sio3pack.workflow.object import ObjectList, ObjectsManager from sio3pack.workflow.tasks import Task @@ -161,7 +162,7 @@ def add_task(self, task: Task): """ self.tasks.append(task) - def get_prog_files(self) -> list[str]: + def get_prog_files(self) -> list[File]: """ Get all program files in the workflow. diff --git a/src/sio3pack/workflow/workflow_manager.py b/src/sio3pack/workflow/workflow_manager.py index 30e3704..59ba0a5 100644 --- a/src/sio3pack/workflow/workflow_manager.py +++ b/src/sio3pack/workflow/workflow_manager.py @@ -67,7 +67,7 @@ def get_default(self, name: str) -> Workflow: return self._get_compile_python_workflow() return None - def get_prog_files(self) -> list[str]: + def get_prog_files(self) -> list[File]: """ Get all program files used in all graphs. """ From 29778d6bc4916bbeae4f16e215fc7f085d2c3368 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 12 May 2025 16:39:53 +0200 Subject: [PATCH 06/13] short_name for sinol-make --- src/sio3pack/packages/sinolpack/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 37b03b2..424078c 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -103,7 +103,6 @@ def _from_file(self, file: LocalFile, configuration=None): archive.extract(to_path=self.tmpdir.name) self.rootdir = os.path.join(self.tmpdir.name, self.short_name) else: - # FIXME: Won't work in sinol-make. self.short_name = os.path.basename(os.path.abspath(file.path)) self.rootdir = os.path.abspath(file.path) @@ -187,6 +186,7 @@ def _process_config_yml(self): try: config = self.get_in_root("config.yml") self.config = yaml.safe_load(config.read()) + self.short_name = self.config.get("sinol_task_id", self.short_name) except FileNotFoundError: self.config = {} From 0e3744508cf6fa3818ea7c3c40696ee2bcf16c10 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Tue, 13 May 2025 00:06:06 +0200 Subject: [PATCH 07/13] Add reload_config function --- src/sio3pack/packages/package/model.py | 3 +++ src/sio3pack/packages/sinolpack/model.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/sio3pack/packages/package/model.py b/src/sio3pack/packages/package/model.py index 51b3684..97cadb0 100644 --- a/src/sio3pack/packages/package/model.py +++ b/src/sio3pack/packages/package/model.py @@ -139,6 +139,9 @@ def __getattr__(self, name: str) -> Any: except AttributeError: raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") + def reload_config(self): + pass + @wrap_exceptions def get_title(self, lang: str | None = None) -> str: pass diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 424078c..e138039 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -190,6 +190,12 @@ def _process_config_yml(self): except FileNotFoundError: self.config = {} + def reload_config(self): + """ + Process the config.yml file again in case it was modified. + """ + self._process_config_yml() + def _detect_full_name(self): """ Sets the problem's full name from the ``config.yml`` (key ``title``) From 8aeb68a0e349b7175d701e058f40fee84e05077a Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 26 May 2025 11:48:32 +0200 Subject: [PATCH 08/13] Fix --- src/sio3pack/packages/sinolpack/model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index e138039..bbc9742 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -464,11 +464,11 @@ def get_test(self, test_id: str) -> Test: return test raise ValueError(f"Test with ID {test_id} not found.") - def get_tests_with_inputs(self) -> list[Test]: + def get_tests_with_inputs(self, tests: list[Test]=None) -> list[Test]: """ Returns the list of input tests. """ - return [test for test in self.tests if test.in_file is not None] + return [test for test in tests or self.tests if test.in_file is not None] def get_corresponding_out_filename(self, in_test: str) -> str: """ @@ -592,8 +592,8 @@ def get(conf) -> int: if f"{type}_limits" in conf: if test.test_id in conf[f"{type}_limits"]: return conf[f"{type}_limits"][test.test_id] - if test.group in conf[f"{type}_limits"]: - return conf[f"{type}_limits"][test.group] + if int(test.group) in conf[f"{type}_limits"]: + return conf[f"{type}_limits"][int(test.group)] if f"{type}_limit" in conf: return conf[f"{type}_limit"] return None From 9ee7158c07225e4652a9e211c7275a6aafea640d Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 26 May 2025 11:48:47 +0200 Subject: [PATCH 09/13] Add repr --- src/sio3pack/test/test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sio3pack/test/test.py b/src/sio3pack/test/test.py index 6341f44..53a1e3e 100644 --- a/src/sio3pack/test/test.py +++ b/src/sio3pack/test/test.py @@ -12,3 +12,6 @@ def __init__(self, test_name: str, test_id: str, in_file: File, out_file: File, self.in_file = in_file self.out_file = out_file self.group = group + + def __repr__(self): + return f"" From c583697d412de741b565ba1189810b795c748ee7 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Mon, 26 May 2025 12:26:19 +0200 Subject: [PATCH 10/13] Fix --- src/sio3pack/packages/sinolpack/model.py | 2 +- tests/packages/sinolpack/test_utils.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 742a583..d7e1dbb 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -488,7 +488,7 @@ def _process_existing_tests(self): out_file = LocalFile(os.path.join(self.rootdir, "out", self.short_name + test_id + ".out")) else: out_file = None - self.tests.append(Test(self.short_name + test_id, test_name, test_id, in_file, out_file, group)) + self.tests.append(Test(test_name, test_id, in_file, out_file, group)) def reload_tests(self): """ diff --git a/tests/packages/sinolpack/test_utils.py b/tests/packages/sinolpack/test_utils.py index 34e503b..a5d033a 100644 --- a/tests/packages/sinolpack/test_utils.py +++ b/tests/packages/sinolpack/test_utils.py @@ -63,11 +63,11 @@ def test_get_limits(get_package): "time_limit": 1000, "memory_limit": 1024, "time_limits": { - "1": 2000, + 1: 2000, "1a": 3000, }, "memory_limits": { - "1": 2048, + 1: 2048, "1a": 3072, }, "override_limits": { @@ -75,11 +75,11 @@ def test_get_limits(get_package): "time_limit": 5000, "memory_limit": 4096, "time_limits": { - "2": 6000, + 2: 6000, "2a": 7000, }, "memory_limits": { - "2": 4096, + 2: 4096, "2a": 5120, }, } From 8ea178071f00a7eab13cc81f435d95293da0663a Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Wed, 28 May 2025 22:19:23 +0200 Subject: [PATCH 11/13] Fix --- src/sio3pack/packages/sinolpack/model.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index d7e1dbb..71503fb 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -325,13 +325,17 @@ def _process_prog_files(self): self.model_solutions = self.sort_model_solutions(self._get_model_solutions()) self.additional_files = [] - for file in self.config.get("extra_compilation_files", []) + self.config.get("extra_execution_files", []): + extra_files = [] + extra_files.extend(self.config.get("extra_compilation_files", [])) + for lang_extra_files in self.config.get("extra_execution_files", {}).values(): + extra_files.extend(lang_extra_files) + for file in extra_files: try: lf = LocalFile(os.path.join(self.get_prog_dir(), file)) self.additional_files.append(lf) except FileNotFoundError: pass - extensions = self.get_submittable_extensions() + extensions = self.get_submittable_extensions() + ["sh"] self.special_files: dict[str, File | None] = {} for file in self.special_file_types(): try: From 52e5aa4b55b1740843239f96adfb377ecd17ec22 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Thu, 5 Jun 2025 10:17:08 +0200 Subject: [PATCH 12/13] Fix tests --- tests/packages/sinolpack/test_workflows.py | 11 ++++------- tests/test_packages/extra_files/config.yml | 4 +++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/packages/sinolpack/test_workflows.py b/tests/packages/sinolpack/test_workflows.py index 0594002..f06481c 100644 --- a/tests/packages/sinolpack/test_workflows.py +++ b/tests/packages/sinolpack/test_workflows.py @@ -306,7 +306,7 @@ def test_extra_files(get_package): workflow = workflows[0] print(workflow.external_objects) - assert len(workflow.external_objects) == 5 + assert len(workflow.external_objects) == 4 extlib_h = None extlib_py = None for obj in workflow.external_objects: @@ -315,7 +315,7 @@ def test_extra_files(get_package): elif obj.handle.endswith("extlib.py"): extlib_py = obj assert extlib_h is not None, "Should have extlib.h as external object" - assert extlib_py is not None, "Should have extlib.py as external object" + assert extlib_py is None, "Should not have extlib.py as external object" for task in workflow.tasks: if isinstance(task, ExecutionTask): @@ -333,14 +333,11 @@ def test_extra_files(get_package): proc = task.processes[0] assert "extlib.h" in proc.arguments, "Should have extlib.h in arguments" elif task.name.startswith("Run solution for test"): - assert task.filesystem_manager.len() == 2 - ext_fs = task.filesystem_manager.get_by_id(1) - assert isinstance(ext_fs, ObjectFilesystem), "Should have object filesystem with external file" - assert ext_fs.object.handle == extlib_py.handle, "Should have extlib.py as external file" + assert task.filesystem_manager.len() == 1 assert task.mountnamespace_manager.len() == 1, "Should have one mount namespace" assert ( - len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 2 + len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 1 ), "Should have two mount points" # Check that python compilation doesnt have extlib.h in compilation args. diff --git a/tests/test_packages/extra_files/config.yml b/tests/test_packages/extra_files/config.yml index 305355f..91c7f21 100644 --- a/tests/test_packages/extra_files/config.yml +++ b/tests/test_packages/extra_files/config.yml @@ -3,5 +3,7 @@ extra_compilation_files: ['extlib.h'] extra_compilation_args: cpp: - 'extlib.h' -extra_execution_files: ['extlib.py'] +extra_execution_files: + py: + - 'extlib.py' extra_files: ['dir/some_file.txt'] From 0f4a3829c313ed79457073282b11e911c464aaf6 Mon Sep 17 00:00:00 2001 From: Tomasz Kwiatkowski Date: Thu, 5 Jun 2025 10:18:49 +0200 Subject: [PATCH 13/13] Run black --- src/sio3pack/packages/sinolpack/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 71503fb..f486329 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -515,7 +515,7 @@ def get_test(self, test_id: str) -> Test: return test raise ValueError(f"Test with ID {test_id} not found.") - def get_tests_with_inputs(self, tests: list[Test]=None) -> list[Test]: + def get_tests_with_inputs(self, tests: list[Test] = None) -> list[Test]: """ Returns the list of input tests. """