Skip to content

Commit dfe4566

Browse files
feat(zb-experimental): implement open in writer (#1618)
feat(zb-experimental): implement open in writer --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent ec470a2 commit dfe4566

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

google/cloud/storage/_experimental/asyncio/async_appendable_object_writer.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,17 @@ async def state_lookup(self) -> int:
126126

127127
async def open(self) -> None:
128128
"""Opens the underlying bidi-gRPC stream."""
129-
raise NotImplementedError("open is not implemented yet.")
129+
if self._is_stream_open:
130+
raise ValueError("Underlying bidi-gRPC stream is already open")
131+
132+
await self.write_obj_stream.open()
133+
self._is_stream_open = True
134+
if self.generation is None:
135+
self.generation = self.write_obj_stream.generation_number
136+
self.write_handle = self.write_obj_stream.write_handle
137+
138+
# Update self.persisted_size
139+
_ = await self.state_lookup()
130140

131141
async def append(self, data: bytes):
132142
raise NotImplementedError("append is not implemented yet.")

tests/unit/asyncio/test_async_appendable_object_writer.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,62 @@ async def test_state_lookup(mock_write_object_stream, mock_client):
112112

113113

114114
@pytest.mark.asyncio
115-
async def test_unimplemented_methods_raise_error(mock_client):
116-
"""Test that all currently unimplemented methods raise NotImplementedError."""
115+
@mock.patch(
116+
"google.cloud.storage._experimental.asyncio.async_appendable_object_writer._AsyncWriteObjectStream"
117+
)
118+
async def test_open_appendable_object_writer(mock_write_object_stream, mock_client):
119+
"""Test the open method."""
120+
# Arrange
117121
writer = AsyncAppendableObjectWriter(mock_client, BUCKET, OBJECT)
122+
mock_stream = mock_write_object_stream.return_value
123+
mock_stream.open = mock.AsyncMock()
124+
mock_stream.send = mock.AsyncMock()
125+
mock_stream.recv = mock.AsyncMock()
118126

119-
with pytest.raises(NotImplementedError):
127+
mock_state_response = mock.MagicMock()
128+
mock_state_response.persisted_size = 1024
129+
mock_stream.recv.return_value = mock_state_response
130+
131+
mock_stream.generation_number = GENERATION
132+
mock_stream.write_handle = WRITE_HANDLE
133+
134+
# Act
135+
await writer.open()
136+
137+
# Assert
138+
mock_stream.open.assert_awaited_once()
139+
assert writer._is_stream_open
140+
assert writer.generation == GENERATION
141+
assert writer.write_handle == WRITE_HANDLE
142+
143+
expected_request = _storage_v2.BidiWriteObjectRequest(state_lookup=True)
144+
mock_stream.send.assert_awaited_once_with(expected_request)
145+
mock_stream.recv.assert_awaited_once()
146+
assert writer.persisted_size == 1024
147+
148+
149+
@pytest.mark.asyncio
150+
@mock.patch(
151+
"google.cloud.storage._experimental.asyncio.async_appendable_object_writer._AsyncWriteObjectStream"
152+
)
153+
async def test_open_when_already_open_raises_error(
154+
mock_write_object_stream, mock_client
155+
):
156+
"""Test that opening an already open writer raises a ValueError."""
157+
# Arrange
158+
writer = AsyncAppendableObjectWriter(mock_client, BUCKET, OBJECT)
159+
writer._is_stream_open = True # Manually set to open
160+
161+
# Act & Assert
162+
with pytest.raises(ValueError, match="Underlying bidi-gRPC stream is already open"):
120163
await writer.open()
121164

165+
166+
@pytest.mark.asyncio
167+
async def test_unimplemented_methods_raise_error(mock_client):
168+
"""Test that all currently unimplemented methods raise NotImplementedError."""
169+
writer = AsyncAppendableObjectWriter(mock_client, BUCKET, OBJECT)
170+
122171
with pytest.raises(NotImplementedError):
123172
await writer.append(b"data")
124173

tests/unit/test_bucket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,7 @@ def test_move_blob_needs_url_encoding(self):
23502350
timeout=30,
23512351
retry=None,
23522352
_target_object=new_blob,
2353-
)
2353+
)
23542354

23552355
def test_move_blob_w_user_project(self):
23562356
source_name = "source"

0 commit comments

Comments
 (0)