diff options
| author | 2022-11-24 10:32:32 +0800 | |
|---|---|---|
| committer | 2022-11-24 10:32:32 +0800 | |
| commit | 78b4b6af18a40db3162aad56eb726a26c5a74e8c (patch) | |
| tree | 409018c39136b481249623663b8672f9ded3719d | |
| parent | Refactor subprocess mount to ctypes call (diff) | |
Refactor output files in `output` dir
| -rw-r--r-- | snekbox/memfs.py | 16 | ||||
| -rw-r--r-- | snekbox/nsjail.py | 18 | ||||
| -rw-r--r-- | snekbox/snekio.py | 13 | ||||
| -rw-r--r-- | tests/test_integration.py | 21 | ||||
| -rw-r--r-- | tests/test_nsjail.py | 6 | 
5 files changed, 54 insertions, 20 deletions
| diff --git a/snekbox/memfs.py b/snekbox/memfs.py index 16f5cfb..a39b690 100644 --- a/snekbox/memfs.py +++ b/snekbox/memfs.py @@ -62,7 +62,12 @@ class MemFS:      @property      def home(self) -> Path:          """Path to home directory.""" -        return Path(self.path, "home") +        return self.path / "home" + +    @property +    def output(self) -> Path: +        """Path to output directory.""" +        return self.home / "output"      def __enter__(self) -> MemFS:          """Mounts a new tempfs, returns self.""" @@ -79,7 +84,8 @@ class MemFS:          else:              raise RuntimeError("Failed to generate a unique tempdir name in 10 attempts") -        self.mkdir("home") +        self.mkdir(self.home) +        self.mkdir(self.output)          return self      def __exit__( @@ -98,17 +104,17 @@ class MemFS:          return folder      def attachments( -        self, max_count: int, pattern: str = "output*" +        self, max_count: int, pattern: str = "**/*"      ) -> Generator[FileAttachment, None, None]:          """Return a list of attachments in the tempdir."""          count = 0 -        for file in self.home.glob(pattern): +        for file in self.output.rglob(pattern):              if count > max_count:                  log.info(f"Max attachments {max_count} reached, skipping remaining files")                  break              if file.is_file():                  count += 1 -                yield FileAttachment.from_path(file) +                yield FileAttachment.from_path(file, relative_to=self.output)      def cleanup(self) -> None:          """Unmounts tmpfs.""" diff --git a/snekbox/nsjail.py b/snekbox/nsjail.py index 88af3cf..4538287 100644 --- a/snekbox/nsjail.py +++ b/snekbox/nsjail.py @@ -53,8 +53,21 @@ class NsJail:          memfs_instance_size: int = 48 * 1024 * 1024,          files_limit: int = 100,          files_timeout: float = 15, -        files_pattern: str = "output*", +        files_pattern: str = "**/*",      ): +        """ +        Initialize NsJail. + +        Args: +            nsjail_path: Path to the NsJail binary. +            config_path: Path to the NsJail configuration file. +            max_output_size: Maximum size of the output in bytes. +            read_chunk_size: Size of the read buffer in bytes. +            memfs_instance_size: Size of the tmpfs instance in bytes. +            files_limit: Maximum number of files to parse for attach. +            files_timeout: Maximum time in seconds to wait for files to be written / read. +            files_pattern: Pattern to match files to attach. +        """          self.nsjail_path = nsjail_path          self.config_path = config_path          self.max_output_size = max_output_size @@ -178,7 +191,6 @@ class NsJail:              )          with NamedTemporaryFile() as nsj_log, MemFS(self.memfs_instance_size) as fs: -            # Add the temp dir to be mounted as cwd              nsjail_args = (                  # Set fslimit to unlimited, cannot be set in cfg                  # due to upstream protobuf parsing issue @@ -204,7 +216,7 @@ class NsJail:                  *iter_lstrip(py_args),              ] -            # Write files if any +            # Write provided files if any              for file in files:                  file.save_to(fs.home)                  log.info(f"Created file at {(fs.home / file.path)!r}.") diff --git a/snekbox/snekio.py b/snekbox/snekio.py index bc71501..7852301 100644 --- a/snekbox/snekio.py +++ b/snekbox/snekio.py @@ -57,9 +57,16 @@ class FileAttachment(Generic[T]):          return cls(path, content)      @classmethod -    def from_path(cls, file: Path) -> FileAttachment[bytes]: -        """Create an attachment from a file path.""" -        return cls(file.name, file.read_bytes()) +    def from_path(cls, file: Path, relative_to: Path | None = None) -> FileAttachment[bytes]: +        """ +        Create an attachment from a file path. + +        Args: +            file: The file to attach. +            relative_to: The root for the path name. +        """ +        path = file.relative_to(relative_to) if relative_to else file +        return cls(str(path), file.read_bytes())      @property      def size(self) -> int: diff --git a/tests/test_integration.py b/tests/test_integration.py index 086abab..ba0d9b5 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -62,11 +62,15 @@ class IntegrationTests(unittest.TestCase):                          "path": "main.py",                          "content": b64encode_code(                              """ +                            from pathlib import Path                              from mod import lib                              print(lib.var) -                            with open('output.txt', 'w') as f: -                                f.write('file write test') +                            with open('output/test.txt', 'w') as f: +                                f.write('test 1') + +                            Path('output/dir').mkdir() +                            Path('output/dir/test2.txt').write_text('test 2')                              """                          ),                      }, @@ -80,10 +84,15 @@ class IntegrationTests(unittest.TestCase):                  "returncode": 0,                  "files": [                      { -                        "path": "output.txt", -                        "size": len("file write test"), -                        "content": b64encode_code("file write test"), -                    } +                        "path": "dir/test2.txt", +                        "size": len("test 2"), +                        "content": b64encode_code("test 2"), +                    }, +                    { +                        "path": "test.txt", +                        "size": len("test 1"), +                        "content": b64encode_code("test 1"), +                    },                  ],              } diff --git a/tests/test_nsjail.py b/tests/test_nsjail.py index da2afea..d63180d 100644 --- a/tests/test_nsjail.py +++ b/tests/test_nsjail.py @@ -190,16 +190,16 @@ class NsJailTests(unittest.TestCase):              data = "a" * 1024              size = 32 * 1024 * 1024 -            with open("src", "w") as f: +            with open("output/file", "w") as f:                  for _ in range((size // 1024) - 5):                      f.write(data)              for i in range(100): -                os.symlink("src", f"output{i}") +                os.symlink("file", f"output/file{i}")              """          ).strip() -        nsjail = NsJail(memfs_instance_size=48 * 1024 * 1024, files_timeout=1) +        nsjail = NsJail(memfs_instance_size=32 * 1024 * 1024, files_timeout=1)          result = nsjail.python3(["-c", code])          self.assertEqual(result.returncode, None)          self.assertEqual( | 
