Procházet zdrojové kódy

Add integration tests for partial clone filtering

Jelmer Vernooij před 3 týdny
rodič
revize
43e02d18a8
1 změnil soubory, kde provedl 139 přidání a 0 odebrání
  1. 139 0
      tests/test_partial_clone.py

+ 139 - 0
tests/test_partial_clone.py

@@ -21,6 +21,9 @@
 
 """Tests for partial clone filter specifications."""
 
+import os
+import tempfile
+
 from dulwich.object_store import MemoryObjectStore
 from dulwich.objects import Blob, Tree
 from dulwich.partial_clone import (
@@ -32,6 +35,7 @@ from dulwich.partial_clone import (
     filter_pack_objects,
     parse_filter_spec,
 )
+from dulwich.repo import Repo
 from dulwich.tests.utils import make_commit
 
 from . import TestCase
@@ -419,3 +423,138 @@ class FilterPackObjectsTests(TestCase):
         self.assertNotIn(self.small_blob.id, filtered)
         self.assertNotIn(self.large_blob.id, filtered)
         self.assertIn(self.tree.id, filtered)
+
+
+class PartialCloneIntegrationTests(TestCase):
+    """Integration tests for partial clone with real repositories."""
+
+    def setUp(self):
+        super().setUp()
+        self.repo_dir = tempfile.mkdtemp()
+        self.addCleanup(self._cleanup)
+        self.repo = Repo.init(self.repo_dir)
+
+    def _cleanup(self):
+        """Clean up test repository."""
+        import shutil
+        if os.path.exists(self.repo_dir):
+            shutil.rmtree(self.repo_dir)
+
+    def test_blob_none_filter_with_real_repo(self):
+        """Test blob:none filter excludes blobs in real repository."""
+        # Create a tree with files
+        tree = Tree()
+
+        # Add some blobs to the tree
+        blob1 = Blob.from_string(b"file1 content")
+        blob2 = Blob.from_string(b"file2 content")
+        tree.add(b"file1.txt", 0o100644, blob1.id)
+        tree.add(b"file2.txt", 0o100644, blob2.id)
+
+        # Add objects to repo
+        self.repo.object_store.add_object(blob1)
+        self.repo.object_store.add_object(blob2)
+        self.repo.object_store.add_object(tree)
+
+        # Create commit
+        commit = make_commit(tree=tree.id, message=b"Test commit")
+        self.repo.object_store.add_object(commit)
+
+        # Get all objects
+        object_ids = [blob1.id, blob2.id, tree.id, commit.id]
+
+        # Apply blob:none filter
+        filter_spec = BlobNoneFilter()
+        filtered = filter_pack_objects(
+            self.repo.object_store, object_ids, filter_spec
+        )
+
+        # Verify blobs are excluded
+        self.assertNotIn(blob1.id, filtered)
+        self.assertNotIn(blob2.id, filtered)
+        # But tree and commit are included
+        self.assertIn(tree.id, filtered)
+        self.assertIn(commit.id, filtered)
+
+        # Verify we have only 2 objects (tree + commit)
+        self.assertEqual(2, len(filtered))
+
+    def test_blob_limit_filter_with_mixed_sizes(self):
+        """Test blob:limit filter with mixed blob sizes."""
+        tree = Tree()
+
+        # Create blobs of different sizes
+        small_blob = Blob.from_string(b"small")  # 5 bytes
+        medium_blob = Blob.from_string(b"x" * 50)  # 50 bytes
+        large_blob = Blob.from_string(b"y" * 500)  # 500 bytes
+
+        tree.add(b"small.txt", 0o100644, small_blob.id)
+        tree.add(b"medium.txt", 0o100644, medium_blob.id)
+        tree.add(b"large.txt", 0o100644, large_blob.id)
+
+        # Add to repo
+        self.repo.object_store.add_object(small_blob)
+        self.repo.object_store.add_object(medium_blob)
+        self.repo.object_store.add_object(large_blob)
+        self.repo.object_store.add_object(tree)
+
+        commit = make_commit(tree=tree.id)
+        self.repo.object_store.add_object(commit)
+
+        # Test with 100 byte limit
+        object_ids = [
+            small_blob.id,
+            medium_blob.id,
+            large_blob.id,
+            tree.id,
+            commit.id,
+        ]
+
+        filter_spec = BlobLimitFilter(100)
+        filtered = filter_pack_objects(
+            self.repo.object_store, object_ids, filter_spec
+        )
+
+        # Small and medium should be included
+        self.assertIn(small_blob.id, filtered)
+        self.assertIn(medium_blob.id, filtered)
+        # Large should be excluded
+        self.assertNotIn(large_blob.id, filtered)
+        # Tree and commit included
+        self.assertIn(tree.id, filtered)
+        self.assertIn(commit.id, filtered)
+
+    def test_combined_filter_integration(self):
+        """Test combined filters in real scenario."""
+        tree = Tree()
+
+        blob1 = Blob.from_string(b"content1")
+        blob2 = Blob.from_string(b"x" * 1000)
+
+        tree.add(b"file1.txt", 0o100644, blob1.id)
+        tree.add(b"file2.txt", 0o100644, blob2.id)
+
+        self.repo.object_store.add_object(blob1)
+        self.repo.object_store.add_object(blob2)
+        self.repo.object_store.add_object(tree)
+
+        commit = make_commit(tree=tree.id)
+        self.repo.object_store.add_object(commit)
+
+        # Combine: limit to 500 bytes, but also apply blob:none
+        # This should exclude ALL blobs (blob:none overrides limit)
+        filter_spec = CombineFilter([
+            BlobLimitFilter(500),
+            BlobNoneFilter(),
+        ])
+
+        object_ids = [blob1.id, blob2.id, tree.id, commit.id]
+        filtered = filter_pack_objects(
+            self.repo.object_store, object_ids, filter_spec
+        )
+
+        # All blobs excluded
+        self.assertNotIn(blob1.id, filtered)
+        self.assertNotIn(blob2.id, filtered)
+        # Only tree and commit
+        self.assertEqual(2, len(filtered))