forked from p34709852/monkey
Island: Add FileRepositoryCachingDecorator
This commit is contained in:
parent
d4883c6e44
commit
9affe10f67
|
@ -1,6 +1,7 @@
|
|||
from .errors import RemovalError, RetrievalError, StorageError
|
||||
from .i_file_repository import FileNotFoundError, IFileRepository
|
||||
from .local_storage_file_repository import LocalStorageFileRepository
|
||||
from .file_repository_caching_decorator import FileRepositoryCachingDecorator
|
||||
from .file_repository_locking_decorator import FileRepositoryLockingDecorator
|
||||
from .file_repository_logging_decorator import FileRepositoryLoggingDecorator
|
||||
from .i_agent_binary_repository import IAgentBinaryRepository
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import io
|
||||
import shutil
|
||||
from functools import lru_cache
|
||||
from typing import BinaryIO
|
||||
|
||||
from . import IFileRepository
|
||||
|
||||
|
||||
class FileRepositoryCachingDecorator(IFileRepository):
|
||||
def __init__(self, file_repository: IFileRepository):
|
||||
self._file_repository = file_repository
|
||||
|
||||
def save_file(self, unsafe_file_name: str, file_contents: BinaryIO):
|
||||
self._open_file.cache_clear()
|
||||
return self._file_repository.save_file(unsafe_file_name, file_contents)
|
||||
|
||||
def open_file(self, unsafe_file_name: str) -> BinaryIO:
|
||||
original_file = self._open_file(unsafe_file_name)
|
||||
file_copy = io.BytesIO()
|
||||
|
||||
shutil.copyfileobj(original_file, file_copy)
|
||||
original_file.seek(0)
|
||||
file_copy.seek(0)
|
||||
|
||||
return file_copy
|
||||
|
||||
@lru_cache(maxsize=16)
|
||||
def _open_file(self, unsafe_file_name: str) -> BinaryIO:
|
||||
return self._file_repository.open_file(unsafe_file_name)
|
||||
|
||||
def delete_file(self, unsafe_file_name: str):
|
||||
self._open_file.cache_clear()
|
||||
return self._file_repository.delete_file(unsafe_file_name)
|
||||
|
||||
def delete_all_files(self):
|
||||
self._open_file.cache_clear()
|
||||
return self._file_repository.delete_all_files()
|
|
@ -0,0 +1,55 @@
|
|||
import io
|
||||
|
||||
import pytest
|
||||
from tests.monkey_island import SingleFileRepository
|
||||
|
||||
from monkey_island.cc import repository
|
||||
from monkey_island.cc.repository import FileRepositoryCachingDecorator
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def file_repository():
|
||||
return FileRepositoryCachingDecorator(SingleFileRepository())
|
||||
|
||||
|
||||
def test_open_cache_file(file_repository):
|
||||
file_name = "test.txt"
|
||||
file_contents = b"Hello World!"
|
||||
|
||||
file_repository.save_file(file_name, io.BytesIO(file_contents))
|
||||
assert file_repository.open_file(file_name).read() == file_contents
|
||||
assert file_repository.open_file(file_name).read() == file_contents
|
||||
|
||||
|
||||
def test_overwrite_file(file_repository):
|
||||
file_name = "test.txt"
|
||||
file_contents_1 = b"Hello World!"
|
||||
file_contents_2 = b"Goodbye World!"
|
||||
|
||||
file_repository.save_file(file_name, io.BytesIO(file_contents_1))
|
||||
assert file_repository.open_file(file_name).read() == file_contents_1
|
||||
|
||||
file_repository.save_file(file_name, io.BytesIO(file_contents_2))
|
||||
assert file_repository.open_file(file_name).read() == file_contents_2
|
||||
|
||||
|
||||
def test_delete_file(file_repository):
|
||||
file_name = "test.txt"
|
||||
file_contents = b"Hello World!"
|
||||
|
||||
file_repository.save_file(file_name, io.BytesIO(file_contents))
|
||||
file_repository.delete_file(file_name)
|
||||
|
||||
with pytest.raises(repository.FileNotFoundError):
|
||||
file_repository.open_file(file_name)
|
||||
|
||||
|
||||
def test_delete_all_files(file_repository):
|
||||
file_name = "test.txt"
|
||||
file_contents = b"Hello World!"
|
||||
|
||||
file_repository.save_file(file_name, io.BytesIO(file_contents))
|
||||
file_repository.delete_all_files()
|
||||
|
||||
with pytest.raises(repository.FileNotFoundError):
|
||||
file_repository.open_file(file_name)
|
Loading…
Reference in New Issue