Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/sio3pack/files/local_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ def __init__(self, path: str, exists=True):
super().__init__(path)
self.filename = os.path.basename(path)

def __repr__(self):
return f"<LocalFile {self.path}>"

def read(self) -> str:
with open(self.path, "r") as f:
return f.read()
Expand Down
7 changes: 7 additions & 0 deletions src/sio3pack/packages/package/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,20 @@ 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:
raise NotImplementedError("This method should be implemented in subclasses.")

@wrap_exceptions
def get_statement(self, lang: str | None = None) -> File | None:
raise NotImplementedError("This method should be implemented in subclasses.")
pass

def reload_tests(self):
pass

@wrap_exceptions
def get_test(self, test_id: str) -> Test:
Expand Down
38 changes: 30 additions & 8 deletions src/sio3pack/packages/sinolpack/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def _from_file(self, file: LocalFile, configuration: SIO3PackConfig = 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)

Expand Down Expand Up @@ -164,7 +163,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.
"""
Expand Down Expand Up @@ -193,9 +192,16 @@ 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 = {}

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``)
Expand Down Expand Up @@ -300,6 +306,12 @@ def special_file_types(self) -> list[str]:
"""
return ["ingen", "inwer", "soc", "chk"]

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.
Expand All @@ -313,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:
Expand Down Expand Up @@ -478,6 +494,12 @@ def _process_existing_tests(self):
out_file = None
self.tests.append(Test(test_name, test_id, in_file, out_file, group))

def reload_tests(self):
"""
Updates `self.tests` variable with existing tests.
"""
self._process_existing_tests()

def get_input_tests(self) -> list[Test]:
"""
Returns the list of tests with input files.
Expand All @@ -493,11 +515,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:
"""
Expand Down Expand Up @@ -617,8 +639,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
Expand Down
3 changes: 3 additions & 0 deletions src/sio3pack/test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,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"<Test {self.test_name}>"
3 changes: 2 additions & 1 deletion src/sio3pack/workflow/workflow.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from sio3pack.files.file import File
from sio3pack.workflow.object import Object, ObjectList, ObjectsManager
from sio3pack.workflow.tasks import ExecutionTask, ScriptTask, Task

Expand Down Expand Up @@ -160,7 +161,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.

Expand Down
2 changes: 1 addition & 1 deletion src/sio3pack/workflow/workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,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.
"""
Expand Down
8 changes: 4 additions & 4 deletions tests/packages/sinolpack/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,23 @@ 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": {
"py": {
"time_limit": 5000,
"memory_limit": 4096,
"time_limits": {
"2": 6000,
2: 6000,
"2a": 7000,
},
"memory_limits": {
"2": 4096,
2: 4096,
"2a": 5120,
},
}
Expand Down
11 changes: 4 additions & 7 deletions tests/packages/sinolpack/test_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand All @@ -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.
Expand Down
4 changes: 3 additions & 1 deletion tests/test_packages/extra_files/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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']