Harden external file connector boundaries
This commit is contained in:
64
tests/test_storage_backends.py
Normal file
64
tests/test_storage_backends.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import unittest
|
||||
from unittest.mock import MagicMock, PropertyMock, patch
|
||||
|
||||
from govoplan_files.backend.storage.backends import S3StorageBackend, StorageBackendError
|
||||
|
||||
|
||||
def _backend() -> S3StorageBackend:
|
||||
return S3StorageBackend(
|
||||
bucket="files",
|
||||
endpoint_url="https://objects.example.test",
|
||||
region_name="test",
|
||||
access_key_id="access",
|
||||
secret_access_key="secret",
|
||||
)
|
||||
|
||||
|
||||
class S3StorageBackendTests(unittest.TestCase):
|
||||
def test_get_bytes_rejects_declared_oversize_object_without_reading(self) -> None:
|
||||
body = MagicMock()
|
||||
client = MagicMock()
|
||||
client.get_object.return_value = {"ContentLength": 6, "Body": body}
|
||||
with patch.dict("os.environ", {"GOVOPLAN_CONNECTOR_MAX_FILE_TRANSFER_BYTES": "5"}), patch.object(
|
||||
S3StorageBackend,
|
||||
"client",
|
||||
new_callable=PropertyMock,
|
||||
return_value=client,
|
||||
), self.assertRaisesRegex(StorageBackendError, "deployment limit"):
|
||||
_backend().get_bytes("large.bin")
|
||||
body.read.assert_not_called()
|
||||
body.close.assert_called_once_with()
|
||||
|
||||
def test_iter_bytes_rejects_undeclared_oversize_object(self) -> None:
|
||||
client = MagicMock()
|
||||
client.get_object.return_value = {"Body": io.BytesIO(b"123456")}
|
||||
with patch.dict("os.environ", {"GOVOPLAN_CONNECTOR_MAX_FILE_TRANSFER_BYTES": "5"}), patch.object(
|
||||
S3StorageBackend,
|
||||
"client",
|
||||
new_callable=PropertyMock,
|
||||
return_value=client,
|
||||
), self.assertRaisesRegex(StorageBackendError, "deployment limit"):
|
||||
list(_backend().iter_bytes("large.bin", chunk_size=3))
|
||||
|
||||
def test_iter_bytes_closes_streaming_body_when_consumer_stops_early(self) -> None:
|
||||
body = MagicMock()
|
||||
body.read.side_effect = (b"123", b"456", b"")
|
||||
client = MagicMock()
|
||||
client.get_object.return_value = {"ContentLength": 6, "Body": body}
|
||||
with patch.dict("os.environ", {"GOVOPLAN_CONNECTOR_MAX_FILE_TRANSFER_BYTES": "10"}), patch.object(
|
||||
S3StorageBackend,
|
||||
"client",
|
||||
new_callable=PropertyMock,
|
||||
return_value=client,
|
||||
):
|
||||
chunks = _backend().iter_bytes("object.bin", chunk_size=3)
|
||||
self.assertEqual(b"123", next(chunks))
|
||||
chunks.close()
|
||||
body.close.assert_called_once_with()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user