fix: Update integration tests for new metadata format and caching behavior

- Fix sync tests: Add list_objects.side_effect = NotImplementedError() to mock
- Fix sync tests: Add side_effect for put() to avoid hanging
- Fix MockStorage: Add continuation_token parameter to list_objects()
- Fix stats tests: Update assertions to include use_cache and refresh_cache params
- Fix bucket management test: Update caching expectations for S3-based cache

All 97 integration tests now pass.
This commit is contained in:
Simone Scarduzio
2025-10-15 11:34:43 +02:00
parent 3753212f96
commit 3f689fc601
4 changed files with 34 additions and 30 deletions

View File

@@ -130,17 +130,23 @@ class TestSyncCommand:
# Mock service methods
mock_service.storage.list.return_value = [] # No existing files
mock_service.put.return_value = PutSummary(
operation="create_reference",
bucket="test-bucket",
key="backup/file.zip.delta",
original_name="file.zip",
file_size=8,
file_sha256="ghi789",
delta_size=None,
delta_ratio=None,
ref_key=None,
)
# Mock list_objects to raise NotImplementedError so it falls back to list()
mock_service.storage.list_objects.side_effect = NotImplementedError()
# Mock service.put to avoid actual execution
def mock_put(local_path, delta_space, max_ratio=None):
return PutSummary(
operation="create_reference",
bucket="test-bucket",
key=f"{delta_space.prefix}/{local_path.name}.delta" if delta_space.prefix else f"{local_path.name}.delta",
original_name=local_path.name,
file_size=local_path.stat().st_size,
file_sha256="ghi789",
delta_size=None,
delta_ratio=None,
ref_key=None,
)
mock_service.put.side_effect = mock_put
with patch("deltaglider.app.cli.main.create_service", return_value=mock_service):
result = runner.invoke(cli, ["sync", str(test_dir), "s3://test-bucket/backup/"])
@@ -175,6 +181,8 @@ class TestSyncCommand:
metadata={},
),
]
# Mock list_objects to raise NotImplementedError so it falls back to list()
mock_service.storage.list_objects.side_effect = NotImplementedError()
mock_service.storage.head.side_effect = [
None, # file1.zip doesn't exist
Mock(), # file1.zip.delta exists

View File

@@ -255,7 +255,7 @@ class TestBucketManagement:
call_count = {"value": 0}
def fake_get_bucket_stats(_: Any, bucket: str, mode: str) -> BucketStats:
def fake_get_bucket_stats(_: Any, bucket: str, mode: str, use_cache: bool = True, refresh_cache: bool = False) -> BucketStats:
call_count["value"] += 1
assert bucket == "bucket1"
if mode == "detailed":
@@ -271,24 +271,20 @@ class TestBucketManagement:
assert result_quick is quick_stats
assert call_count["value"] == 1
# Second quick call should hit cache
# Second quick call - caching is now done in _get_bucket_stats (S3-based)
# So each call goes through _get_bucket_stats (which handles caching internally)
assert client.get_bucket_stats("bucket1") is quick_stats
assert call_count["value"] == 1
assert call_count["value"] == 2
# Detailed call triggers new computation
result_detailed = client.get_bucket_stats("bucket1", mode="detailed")
assert result_detailed is detailed_stats
assert call_count["value"] == 2
# Quick call after detailed uses detailed cached value (more accurate)
assert client.get_bucket_stats("bucket1") is detailed_stats
assert call_count["value"] == 2
# Clearing the cache should force recomputation
client.clear_cache()
assert client.get_bucket_stats("bucket1") is quick_stats
assert call_count["value"] == 3
# Quick call - each mode has its own cache in _get_bucket_stats
assert client.get_bucket_stats("bucket1") is quick_stats
assert call_count["value"] == 4
def test_bucket_methods_without_boto3_client(self):
"""Test that bucket methods raise NotImplementedError when storage doesn't support it."""
service = create_service()

View File

@@ -43,7 +43,7 @@ class MockStorage:
if obj_head is not None:
yield obj_head
def list_objects(self, bucket, prefix="", delimiter="", max_keys=1000, start_after=None):
def list_objects(self, bucket, prefix="", delimiter="", max_keys=1000, start_after=None, continuation_token=None):
"""Mock list_objects operation for S3 features."""
objects = []
common_prefixes = set()

View File

@@ -49,7 +49,7 @@ class TestStatsCommand:
assert output["direct_objects"] == 3
# Verify client was called correctly
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick", use_cache=True, refresh_cache=False)
def test_stats_json_output_detailed(self):
"""Test stats command with detailed JSON output."""
@@ -77,7 +77,7 @@ class TestStatsCommand:
assert output["average_compression_ratio"] == 0.95
# Verify detailed flag was passed
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="detailed")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="detailed", use_cache=True, refresh_cache=False)
def test_stats_json_output_sampled(self):
"""Test stats command with sampled JSON output."""
@@ -101,7 +101,7 @@ class TestStatsCommand:
result = runner.invoke(cli, ["stats", "test-bucket", "--sampled", "--json"])
assert result.exit_code == 0
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="sampled")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="sampled", use_cache=True, refresh_cache=False)
def test_stats_sampled_and_detailed_conflict(self):
"""--sampled and --detailed flags must be mutually exclusive."""
@@ -190,7 +190,7 @@ class TestStatsCommand:
assert result.exit_code == 0
# Verify bucket name was parsed correctly from S3 URL
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick", use_cache=True, refresh_cache=False)
def test_stats_with_s3_url_trailing_slash(self):
"""Test stats command with s3:// URL format with trailing slash."""
@@ -215,7 +215,7 @@ class TestStatsCommand:
assert result.exit_code == 0
# Verify bucket name was parsed correctly from S3 URL with trailing slash
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick", use_cache=True, refresh_cache=False)
def test_stats_with_s3_url_with_prefix(self):
"""Test stats command with s3:// URL format with prefix (should ignore prefix)."""
@@ -240,4 +240,4 @@ class TestStatsCommand:
assert result.exit_code == 0
# Verify only bucket name was extracted, prefix ignored
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick")
mock_client.get_bucket_stats.assert_called_once_with("test-bucket", mode="quick", use_cache=True, refresh_cache=False)