@@ -185,6 +185,7 @@ async def controlled_recv():
185185 async def test_download_ranges (
186186 self , mock_cls_async_read_object_stream , mock_random_int
187187 ):
188+ # Arrange
188189 data = b"these_are_18_chars"
189190 crc32c = Checksum (data ).digest ()
190191 crc32c_int = int .from_bytes (crc32c , "big" )
@@ -193,27 +194,36 @@ async def test_download_ranges(
193194 mock_random_int .side_effect = [456 ]
194195
195196 mock_mrd .read_obj_str .send = AsyncMock ()
196- mock_mrd .read_obj_str .recv = AsyncMock (
197- side_effect = [
198- _storage_v2 .BidiReadObjectResponse (
199- object_data_ranges = [
200- _storage_v2 .ObjectRangeData (
201- checksummed_data = _storage_v2 .ChecksummedData (
202- content = data , crc32c = crc32c_int
203- ),
204- range_end = True ,
205- read_range = _storage_v2 .ReadRange (
206- read_offset = 0 , read_length = 18 , read_id = 456
207- ),
208- )
209- ],
210- ),
211- None ,
212- ]
213- )
214-
197+ mock_mrd .read_obj_str .recv = AsyncMock ()
198+ mock_mrd .read_obj_str .recv .side_effect = [
199+ _storage_v2 .BidiReadObjectResponse (
200+ object_data_ranges = [
201+ _storage_v2 .ObjectRangeData (
202+ checksummed_data = _storage_v2 .ChecksummedData (
203+ content = data , crc32c = crc32c_int
204+ ),
205+ range_end = True ,
206+ read_range = _storage_v2 .ReadRange (
207+ read_offset = 0 , read_length = 18 , read_id = 456
208+ ),
209+ )
210+ ],
211+ ),
212+ None ,
213+ ]
214+ # Act
215215 buffer = BytesIO ()
216+
216217 await mock_mrd .download_ranges ([(0 , 18 , buffer )])
218+
219+ # Assert
220+ mock_mrd .read_obj_str .send .assert_called_once_with (
221+ _storage_v2 .BidiReadObjectRequest (
222+ read_ranges = [
223+ _storage_v2 .ReadRange (read_offset = 0 , read_length = 18 , read_id = 456 )
224+ ]
225+ )
226+ )
217227 assert buffer .getvalue () == data
218228
219229 @pytest .mark .asyncio
@@ -523,6 +533,7 @@ async def test_on_open_error_logs_warning(self, mock_logger):
523533 async def test_download_ranges_resumption_logging (
524534 self , mock_cls_async_read_object_stream , mock_random_int , mock_logger
525535 ):
536+ # Arrange
526537 mock_mrd , _ = await self ._make_mock_mrd (mock_cls_async_read_object_stream )
527538
528539 from google .api_core import exceptions as core_exceptions
@@ -561,11 +572,22 @@ async def staged_recv():
561572
562573 mock_random_int .return_value = 123
563574
575+ # Act
564576 buffer = BytesIO ()
577+
578+ # Patch Checksum where it is likely used (reads_resumption_strategy or similar),
579+ # but actually if we use google_crc32c directly, we should patch that or provide valid CRC.
580+ # Since we can't reliably predict where Checksum is imported/used without more digging,
581+ # let's provide a valid CRC for b"data".
582+ # Checksum(b"data").digest() -> needs to match crc32c=123.
583+ # But we can't force b"data" to have crc=123.
584+ # So we MUST patch Checksum.
585+ # It is used in google.cloud.storage.asyncio.retry.reads_resumption_strategy
565586 with mock .patch (
566587 "google.cloud.storage.asyncio.retry.reads_resumption_strategy.Checksum"
567588 ) as mock_chk :
568589 mock_chk .return_value .digest .return_value = (123 ).to_bytes (4 , "big" )
569590 await mock_mrd .download_ranges ([(0 , 4 , buffer )])
570591
592+ # Assert
571593 mock_logger .info .assert_any_call ("Resuming download (attempt 2) for 1 ranges." )
0 commit comments