-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
256 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from __future__ import annotations | ||
|
||
import abc | ||
import io | ||
import tarfile | ||
from typing import TYPE_CHECKING, Literal | ||
|
||
if TYPE_CHECKING: | ||
from daiv_sandbox.schemas import RunResult | ||
from daiv_sandbox.sessions import SandboxDockerSession | ||
|
||
|
||
class LanguageManager(abc.ABC): | ||
""" | ||
Abstract base class for language managers. | ||
""" | ||
|
||
@abc.abstractmethod | ||
def install_dependencies(self, session: SandboxDockerSession, dependencies: list[str]) -> RunResult: | ||
pass | ||
|
||
@abc.abstractmethod | ||
def run_code(self, session: SandboxDockerSession, workdir: str, code: str) -> RunResult: | ||
pass | ||
|
||
@staticmethod | ||
def factory(language: Literal["python"]) -> LanguageManager: | ||
if language == "python": | ||
return PythonLanguageManager() | ||
raise ValueError(f"Unsupported language: {language}") | ||
|
||
|
||
class PythonLanguageManager(LanguageManager): | ||
""" | ||
Language manager for Python. | ||
""" | ||
|
||
def install_dependencies(self, session: SandboxDockerSession, dependencies: list[str]) -> RunResult: | ||
""" | ||
Install dependencies. | ||
""" | ||
return session.execute_command(f"pip install {' '.join(dependencies)}", workdir="/") | ||
|
||
def run_code(self, session: SandboxDockerSession, workdir: str, code: str) -> RunResult: | ||
""" | ||
Run code. | ||
""" | ||
with io.BytesIO() as tar_file: | ||
with tarfile.open(fileobj=tar_file, mode="w:gz") as tar: | ||
tarinfo = tarfile.TarInfo(name="main.py") | ||
tarinfo.size = len(code.encode()) | ||
tar.addfile(tarinfo, io.BytesIO(code.encode())) | ||
|
||
tar_file.seek(0) | ||
session.copy_to_runtime(workdir, tar_file) | ||
|
||
return session.execute_command("python main.py", workdir=workdir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from unittest.mock import MagicMock | ||
|
||
import pytest | ||
|
||
from daiv_sandbox.languages import LanguageManager, PythonLanguageManager | ||
from daiv_sandbox.schemas import RunResult | ||
from daiv_sandbox.sessions import SandboxDockerSession | ||
|
||
|
||
@pytest.fixture | ||
def setup_manager(): | ||
session = MagicMock(spec=SandboxDockerSession) | ||
manager = PythonLanguageManager() | ||
return session, manager | ||
|
||
|
||
def test_factory(): | ||
manager = LanguageManager.factory("python") | ||
assert isinstance(manager, PythonLanguageManager) | ||
|
||
|
||
def test_factory_unsupported_language(): | ||
with pytest.raises(ValueError, match="Unsupported language: unsupported"): | ||
LanguageManager.factory("unsupported") | ||
|
||
|
||
def test_install_dependencies(setup_manager): | ||
session, manager = setup_manager | ||
|
||
# Mock the expected result | ||
expected_result = RunResult(command="pip install numpy pandas", output="Dependencies installed", exit_code=0) | ||
session.execute_command.return_value = expected_result | ||
|
||
# Call the method | ||
result = manager.install_dependencies(session, ["numpy", "pandas"]) | ||
|
||
# Assertions | ||
session.execute_command.assert_called_once_with("pip install numpy pandas", workdir="/") | ||
assert result == expected_result | ||
|
||
|
||
def test_run_code(setup_manager): | ||
session, manager = setup_manager | ||
|
||
# Mock the expected result | ||
expected_result = RunResult(command="python main.py", output="Code executed", exit_code=0) | ||
session.execute_command.return_value = expected_result | ||
|
||
# Call the method | ||
code = "print('Hello, World!')" | ||
result = manager.run_code(session, "/workdir", code) | ||
|
||
# Assertions | ||
session.copy_to_runtime.assert_called_once() | ||
session.execute_command.assert_called_once_with("python main.py", workdir="/workdir") | ||
assert result == expected_result |
Oops, something went wrong.