|
@@ -0,0 +1,177 @@
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+"""Tests for dulwich.cloud.gcs."""
|
|
|
+
|
|
|
+import unittest
|
|
|
+from unittest.mock import MagicMock, patch
|
|
|
+
|
|
|
+from dulwich.cloud.gcs import GcsObjectStore
|
|
|
+
|
|
|
+
|
|
|
+class GcsObjectStoreTests(unittest.TestCase):
|
|
|
+ """Tests for the GcsObjectStore class."""
|
|
|
+
|
|
|
+ def setUp(self):
|
|
|
+ self.mock_bucket = MagicMock()
|
|
|
+ self.store = GcsObjectStore(self.mock_bucket, subpath="git")
|
|
|
+
|
|
|
+ def test_init(self):
|
|
|
+ """Test initialization and repr."""
|
|
|
+ self.assertEqual(self.mock_bucket, self.store.bucket)
|
|
|
+ self.assertEqual("git", self.store.subpath)
|
|
|
+ self.assertIn("GcsObjectStore", repr(self.store))
|
|
|
+ self.assertIn("git", repr(self.store))
|
|
|
+
|
|
|
+ def test_remove_pack(self):
|
|
|
+ """Test _remove_pack method."""
|
|
|
+ self.store._remove_pack("pack-1234")
|
|
|
+ self.mock_bucket.delete_blobs.assert_called_once()
|
|
|
+ args = self.mock_bucket.delete_blobs.call_args[0][0]
|
|
|
+ self.assertEqual(
|
|
|
+ sorted(args), sorted(["git/pack-1234.pack", "git/pack-1234.idx"])
|
|
|
+ )
|
|
|
+
|
|
|
+ def test_iter_pack_names(self):
|
|
|
+ """Test _iter_pack_names method."""
|
|
|
+
|
|
|
+ mock_blob1 = MagicMock()
|
|
|
+ mock_blob1.name = "git/pack-1234.pack"
|
|
|
+ mock_blob2 = MagicMock()
|
|
|
+ mock_blob2.name = "git/pack-1234.idx"
|
|
|
+ mock_blob3 = MagicMock()
|
|
|
+ mock_blob3.name = "git/pack-5678.pack"
|
|
|
+
|
|
|
+
|
|
|
+ self.mock_bucket.list_blobs.return_value = [mock_blob1, mock_blob2, mock_blob3]
|
|
|
+
|
|
|
+ pack_names = list(self.store._iter_pack_names())
|
|
|
+ self.assertEqual(["pack-1234"], pack_names)
|
|
|
+
|
|
|
+
|
|
|
+ self.mock_bucket.list_blobs.assert_called_once_with(prefix="git")
|
|
|
+
|
|
|
+ def test_load_pack_data(self):
|
|
|
+ """Test _load_pack_data method."""
|
|
|
+
|
|
|
+ mock_blob = MagicMock()
|
|
|
+ self.mock_bucket.blob.return_value = mock_blob
|
|
|
+
|
|
|
+
|
|
|
+ with patch("dulwich.cloud.gcs.PackData") as mock_pack_data_cls:
|
|
|
+ mock_pack_data = MagicMock()
|
|
|
+ mock_pack_data_cls.return_value = mock_pack_data
|
|
|
+
|
|
|
+
|
|
|
+ def mock_download_to_file(file_obj):
|
|
|
+ file_obj.write(b"not-a-real-pack-file")
|
|
|
+
|
|
|
+ mock_blob.download_to_file.side_effect = mock_download_to_file
|
|
|
+
|
|
|
+
|
|
|
+ result = self.store._load_pack_data("pack-1234")
|
|
|
+
|
|
|
+
|
|
|
+ self.assertEqual(mock_pack_data, result)
|
|
|
+ self.mock_bucket.blob.assert_called_once_with("git/pack-1234.pack")
|
|
|
+ mock_blob.download_to_file.assert_called_once()
|
|
|
+
|
|
|
+
|
|
|
+ mock_pack_data_cls.assert_called_once()
|
|
|
+ args, _ = mock_pack_data_cls.call_args
|
|
|
+ self.assertEqual("pack-1234.pack", args[0])
|
|
|
+
|
|
|
+ def test_load_pack_index(self):
|
|
|
+ """Test _load_pack_index method."""
|
|
|
+
|
|
|
+ with patch("dulwich.cloud.gcs.load_pack_index_file") as mock_load:
|
|
|
+
|
|
|
+ mock_blob = MagicMock()
|
|
|
+ self.mock_bucket.blob.return_value = mock_blob
|
|
|
+
|
|
|
+
|
|
|
+ def mock_download_to_file(file_obj):
|
|
|
+ file_obj.write(b"index-file-content")
|
|
|
+
|
|
|
+ mock_blob.download_to_file.side_effect = mock_download_to_file
|
|
|
+
|
|
|
+
|
|
|
+ mock_index = MagicMock()
|
|
|
+ mock_load.return_value = mock_index
|
|
|
+
|
|
|
+
|
|
|
+ result = self.store._load_pack_index("pack-1234")
|
|
|
+
|
|
|
+
|
|
|
+ self.assertEqual(mock_index, result)
|
|
|
+ self.mock_bucket.blob.assert_called_once_with("git/pack-1234.idx")
|
|
|
+ mock_blob.download_to_file.assert_called_once()
|
|
|
+ mock_load.assert_called_once()
|
|
|
+
|
|
|
+ self.assertEqual("pack-1234.idx", mock_load.call_args[0][0])
|
|
|
+
|
|
|
+ def test_get_pack(self):
|
|
|
+ """Test _get_pack method."""
|
|
|
+ with patch("dulwich.cloud.gcs.Pack") as mock_pack_cls:
|
|
|
+ mock_pack = MagicMock()
|
|
|
+ mock_pack_cls.from_lazy_objects.return_value = mock_pack
|
|
|
+
|
|
|
+ result = self.store._get_pack("pack-1234")
|
|
|
+
|
|
|
+ self.assertEqual(mock_pack, result)
|
|
|
+ mock_pack_cls.from_lazy_objects.assert_called_once()
|
|
|
+
|
|
|
+
|
|
|
+ args = mock_pack_cls.from_lazy_objects.call_args[0]
|
|
|
+ self.assertEqual(2, len(args))
|
|
|
+
|
|
|
+
|
|
|
+ self.assertTrue(callable(args[0]))
|
|
|
+ self.assertTrue(callable(args[1]))
|
|
|
+
|
|
|
+ def test_upload_pack(self):
|
|
|
+ """Test _upload_pack method."""
|
|
|
+
|
|
|
+ mock_idx_blob = MagicMock()
|
|
|
+ mock_data_blob = MagicMock()
|
|
|
+
|
|
|
+
|
|
|
+ def mock_blob(path):
|
|
|
+ if path.endswith(".idx"):
|
|
|
+ return mock_idx_blob
|
|
|
+ elif path.endswith(".pack"):
|
|
|
+ return mock_data_blob
|
|
|
+ else:
|
|
|
+ self.fail(f"Unexpected blob path: {path}")
|
|
|
+
|
|
|
+ self.mock_bucket.blob.side_effect = mock_blob
|
|
|
+
|
|
|
+
|
|
|
+ mock_index_file = MagicMock()
|
|
|
+ mock_pack_file = MagicMock()
|
|
|
+
|
|
|
+
|
|
|
+ self.store._upload_pack("pack-1234", mock_pack_file, mock_index_file)
|
|
|
+
|
|
|
+
|
|
|
+ self.mock_bucket.blob.assert_any_call("git/pack-1234.idx")
|
|
|
+ self.mock_bucket.blob.assert_any_call("git/pack-1234.pack")
|
|
|
+
|
|
|
+
|
|
|
+ mock_idx_blob.upload_from_file.assert_called_once_with(mock_index_file)
|
|
|
+ mock_data_blob.upload_from_file.assert_called_once_with(mock_pack_file)
|