fix(experimental): no state lookup while opening bidi-write stream (#… · googleapis/python-storage@2d5a7b1 · GitHub
Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit 2d5a7b1

Browse files
authored
fix(experimental): no state lookup while opening bidi-write stream (#1636)
fix(experimental): no state lookup while opening bidi-write stream
1 parent 4a609a4 commit 2d5a7b1

5 files changed

Lines changed: 57 additions & 20 deletions

File tree

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

Lines changed: 11 additions & 7 deletions

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ async def download_ranges(
216216
217217
:type read_ranges: List[Tuple[int, int, "BytesIO"]]
218218
:param read_ranges: A list of tuples, where each tuple represents a
219-
byte range (start_byte, bytes_to_read, writeable_buffer). Buffer has
219+
combintaion of byte_range and writeable buffer in format -
220+
(`start_byte`, `bytes_to_read`, `writeable_buffer`). Buffer has
220221
to be provided by the user, and user has to make sure appropriate
221222
memory is available in the application to avoid out-of-memory crash.
222223

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ async def open(self) -> None:
117117
object=self.object_name,
118118
generation=self.generation_number,
119119
),
120-
state_lookup=True,
121120
)
122121

123122
self.socket_like_rpc = AsyncBidiRpc(
@@ -136,11 +135,17 @@ async def open(self) -> None:
136135
raise ValueError(
137136
"Failed to obtain object generation after opening the stream"
138137
)
139-
self.generation_number = response.resource.generation
140138

141139
if not response.write_handle:
142140
raise ValueError("Failed to obtain write_handle after opening the stream")
143141

142+
if not response.resource.size:
143+
# Appending to a 0 byte appendable object.
144+
self.persisted_size = 0
145+
else:
146+
self.persisted_size = response.resource.size
147+
148+
self.generation_number = response.resource.generation
144149
self.write_handle = response.write_handle
145150

146151
async def close(self) -> None:

tests/unit/asyncio/test_async_appendable_object_writer.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,10 @@ async def test_open_appendable_object_writer(mock_write_object_stream, mock_clie
133133
writer = AsyncAppendableObjectWriter(mock_client, BUCKET, OBJECT)
134134
mock_stream = mock_write_object_stream.return_value
135135
mock_stream.open = mock.AsyncMock()
136-
mock_stream.send = mock.AsyncMock()
137-
mock_stream.recv = mock.AsyncMock()
138-
139-
mock_state_response = mock.MagicMock()
140-
mock_state_response.persisted_size = 1024
141-
mock_stream.recv.return_value = mock_state_response
142136

143137
mock_stream.generation_number = GENERATION
144138
mock_stream.write_handle = WRITE_HANDLE
139+
mock_stream.persisted_size = 0
145140

146141
# Act
147142
await writer.open()
@@ -151,11 +146,37 @@ async def test_open_appendable_object_writer(mock_write_object_stream, mock_clie
151146
assert writer._is_stream_open
152147
assert writer.generation == GENERATION
153148
assert writer.write_handle == WRITE_HANDLE
149+
assert writer.persisted_size == 0
154150

155-
expected_request = _storage_v2.BidiWriteObjectRequest(state_lookup=True)
156-
mock_stream.send.assert_awaited_once_with(expected_request)
157-
mock_stream.recv.assert_awaited_once()
158-
assert writer.persisted_size == 1024
151+
152+
@pytest.mark.asyncio
153+
@mock.patch(
154+
"google.cloud.storage._experimental.asyncio.async_appendable_object_writer._AsyncWriteObjectStream"
155+
)
156+
async def test_open_appendable_object_writer_existing_object(
157+
mock_write_object_stream, mock_client
158+
):
159+
"""Test the open method."""
160+
# Arrange
161+
writer = AsyncAppendableObjectWriter(
162+
mock_client, BUCKET, OBJECT, generation=GENERATION
163+
)
164+
mock_stream = mock_write_object_stream.return_value
165+
mock_stream.open = mock.AsyncMock()
166+
167+
mock_stream.generation_number = GENERATION
168+
mock_stream.write_handle = WRITE_HANDLE
169+
mock_stream.persisted_size = PERSISTED_SIZE
170+
171+
# Act
172+
await writer.open()
173+
174+
# Assert
175+
mock_stream.open.assert_awaited_once()
176+
assert writer._is_stream_open
177+
assert writer.generation == GENERATION
178+
assert writer.write_handle == WRITE_HANDLE
179+
assert writer.persisted_size == PERSISTED_SIZE
159180

160181

161182
@pytest.mark.asyncio

tests/unit/asyncio/test_async_write_object_stream.py

Lines changed: 6 additions & 0 deletions

0 commit comments

Comments
 (0)