@@ -560,7 +560,9 @@ async def test_close_with_checksum_and_finalize(self, mock_appendable_writer):
560560
561561 checksum = 12345678
562562 await writer .close (finalize_on_close = True , full_object_checksum = checksum )
563- writer .finalize .assert_awaited_once_with (full_object_checksum = checksum )
563+ writer .finalize .assert_awaited_once_with (
564+ full_object_checksum = checksum , retry_policy = None
565+ )
564566
565567 @pytest .mark .asyncio
566568 async def test_close_with_checksum_without_finalize_raises (
@@ -625,3 +627,76 @@ async def test_finalize_mismatch_closes_stream(self, mock_appendable_writer):
625627 # Assert stream was closed and local state reset despite exception
626628 mock_appendable_writer ["mock_stream" ].close .assert_awaited ()
627629 assert not writer ._is_stream_open
630+
631+ @pytest .mark .asyncio
632+ async def test_finalize_retry_on_transient_error (self , mock_appendable_writer ):
633+ writer = self ._make_one (mock_appendable_writer ["mock_client" ])
634+ writer ._is_stream_open = True
635+ writer .write_obj_stream = mock_appendable_writer ["mock_stream" ]
636+
637+ resource = storage_type .Object (size = 999 )
638+ mock_appendable_writer ["mock_stream" ].recv .side_effect = [
639+ exceptions .InternalServerError ("500 Transient Error" ),
640+ storage_type .BidiWriteObjectResponse (resource = resource ),
641+ ]
642+
643+ res = await writer .finalize ()
644+
645+ assert res == resource
646+ assert writer .persisted_size == 999
647+ assert mock_appendable_writer ["mock_stream" ].send .await_count == 2
648+ assert not writer ._is_stream_open
649+
650+ @pytest .mark .asyncio
651+ async def test_finalize_custom_retry_policy (self , mock_appendable_writer ):
652+ from google .api_core .retry_async import AsyncRetry
653+
654+ writer = self ._make_one (mock_appendable_writer ["mock_client" ])
655+ writer ._is_stream_open = True
656+ writer .write_obj_stream = mock_appendable_writer ["mock_stream" ]
657+
658+ custom_policy = AsyncRetry (predicate = lambda exc : isinstance (exc , exceptions .InternalServerError ))
659+ resource = storage_type .Object (size = 999 )
660+ mock_appendable_writer ["mock_stream" ].recv .return_value = (
661+ storage_type .BidiWriteObjectResponse (resource = resource )
662+ )
663+
664+ res = await writer .finalize (retry_policy = custom_policy )
665+ assert res == resource
666+
667+ @pytest .mark .asyncio
668+ async def test_close_with_finalize_and_custom_retry_policy (self , mock_appendable_writer ):
669+ from google .api_core .retry_async import AsyncRetry
670+
671+ writer = self ._make_one (mock_appendable_writer ["mock_client" ])
672+ writer ._is_stream_open = True
673+ writer .finalize = AsyncMock ()
674+
675+ custom_policy = AsyncRetry (predicate = lambda exc : False )
676+ await writer .close (finalize_on_close = True , retry_policy = custom_policy )
677+ writer .finalize .assert_awaited_once_with (
678+ full_object_checksum = None ,
679+ retry_policy = custom_policy ,
680+ )
681+
682+ @pytest .mark .asyncio
683+ async def test_close_retry_on_transient_error (self , mock_appendable_writer ):
684+ writer = self ._make_one (mock_appendable_writer ["mock_client" ])
685+ writer ._is_stream_open = True
686+ writer .write_obj_stream = mock_appendable_writer ["mock_stream" ]
687+
688+ resource = storage_type .Object (size = 999 )
689+ mock_appendable_writer ["mock_stream" ].recv .side_effect = [
690+ exceptions .InternalServerError ("500 Transient Error" ),
691+ storage_type .BidiWriteObjectResponse (resource = resource ),
692+ ]
693+
694+ res = await writer .close (finalize_on_close = True )
695+
696+ assert res == resource
697+ assert writer .persisted_size == 999
698+ assert mock_appendable_writer ["mock_stream" ].send .await_count == 2
699+ assert not writer ._is_stream_open
700+
701+
702+
0 commit comments