@@ -33,7 +33,6 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
3333namespace {
3434
3535using ::google::cloud::internal::CurrentOptions;
36- using ::google::cloud::internal::OptionsSpan;
3736using ::google::cloud::storage::testing::MockAsyncInsertStream;
3837using ::google::cloud::storage::testing::MockStorageStub;
3938using ::google::cloud::storage::testing::canonical_errors::PermanentError;
@@ -238,10 +237,15 @@ TEST_F(AsyncConnectionImplTest, AsyncInsertObjectTooManyTransients) {
238237}
239238
240239TEST_F (AsyncConnectionImplTest, AsyncDeleteObject) {
240+ AsyncSequencer<bool > sequencer;
241241 auto mock = std::make_shared<storage::testing::MockStorageStub>();
242242 EXPECT_CALL (*mock, AsyncDeleteObject)
243- .WillOnce ([this ](
244- CompletionQueue&, auto context,
243+ .WillOnce ([&] {
244+ return sequencer.PushBack (" DeleteObject(1)" ).then ([](auto ) {
245+ return TransientError ();
246+ });
247+ })
248+ .WillOnce ([&](CompletionQueue&, auto context,
245249 google::storage::v2::DeleteObjectRequest const & request) {
246250 // Verify at least one option is initialized with the correct
247251 // values.
@@ -252,24 +256,77 @@ TEST_F(AsyncConnectionImplTest, AsyncDeleteObject) {
252256 Pair (" x-goog-fieldmask" , " field1,field2" )));
253257 EXPECT_THAT (request.bucket (), " projects/_/buckets/test-bucket" );
254258 EXPECT_THAT (request.object (), " test-object" );
255- return make_ready_future (PermanentError ());
259+ return sequencer.PushBack (" DeleteObject(2)" ).then ([](auto ) {
260+ return Status{};
261+ });
256262 });
257- CompletionQueue cq;
258- auto connection = MakeTestConnection (cq, mock);
259- // Simulate the option span created by the `*Client` class. The
260- // `AuthorityOption` value is used by the `*Stub` classes. We want to verify
261- // it is initialized properly by the time it makes it to the mocked call.
262- OptionsSpan span (connection->options ());
263- auto response =
264- connection
265- ->AsyncDeleteObject (
266- storage::internal::DeleteObjectRequest (" test-bucket" ,
267- " test-object" )
268- .set_multiple_options (storage::Fields (" field1,field2" ),
269- storage::QuotaUser (" test-quota-user" )))
270- .get ();
271- EXPECT_THAT (response, StatusIs (PermanentError ().code (),
272- HasSubstr (PermanentError ().message ())));
263+
264+ internal::AutomaticallyCreatedBackgroundThreads pool (1 );
265+ auto connection = MakeTestConnection (pool.cq (), mock);
266+ auto pending = connection->AsyncDeleteObject (
267+ {storage_experimental::DeleteObjectRequest (" test-bucket" , " test-object" )
268+ .set_multiple_options (storage::Fields (" field1,field2" ),
269+ storage::QuotaUser (" test-quota-user" )),
270+ connection->options ()});
271+
272+ auto next = sequencer.PopFrontWithName ();
273+ EXPECT_EQ (next.second , " DeleteObject(1)" );
274+ next.first .set_value (false );
275+
276+ next = sequencer.PopFrontWithName ();
277+ EXPECT_EQ (next.second , " DeleteObject(2)" );
278+ next.first .set_value (true );
279+
280+ auto response = pending.get ();
281+ ASSERT_STATUS_OK (response);
282+ }
283+
284+ TEST_F (AsyncConnectionImplTest, AsyncDeleteObjectPermanentError) {
285+ AsyncSequencer<bool > sequencer;
286+ auto mock = std::make_shared<storage::testing::MockStorageStub>();
287+ EXPECT_CALL (*mock, AsyncDeleteObject).WillOnce ([&] {
288+ return sequencer.PushBack (" DeleteObject" ).then ([](auto ) {
289+ return PermanentError ();
290+ });
291+ });
292+
293+ internal::AutomaticallyCreatedBackgroundThreads pool (1 );
294+ auto connection = MakeTestConnection (pool.cq (), mock);
295+ auto pending = connection->AsyncDeleteObject (
296+ {storage_experimental::DeleteObjectRequest (" test-bucket" , " test-object" ),
297+ connection->options ()});
298+
299+ auto next = sequencer.PopFrontWithName ();
300+ EXPECT_EQ (next.second , " DeleteObject" );
301+ next.first .set_value (false );
302+
303+ auto response = pending.get ();
304+ EXPECT_THAT (response, StatusIs (PermanentError ().code ()));
305+ }
306+
307+ TEST_F (AsyncConnectionImplTest, AsyncDeleteObjectTooManyTransients) {
308+ AsyncSequencer<bool > sequencer;
309+ auto mock = std::make_shared<storage::testing::MockStorageStub>();
310+ EXPECT_CALL (*mock, AsyncDeleteObject).Times (3 ).WillRepeatedly ([&] {
311+ return sequencer.PushBack (" DeleteObject" ).then ([](auto ) {
312+ return TransientError ();
313+ });
314+ });
315+
316+ internal::AutomaticallyCreatedBackgroundThreads pool (1 );
317+ auto connection = MakeTestConnection (pool.cq (), mock);
318+ auto pending = connection->AsyncDeleteObject (
319+ {storage_experimental::DeleteObjectRequest (" test-bucket" , " test-object" ),
320+ connection->options ()});
321+
322+ for (int i = 0 ; i != 3 ; ++i) {
323+ auto next = sequencer.PopFrontWithName ();
324+ EXPECT_EQ (next.second , " DeleteObject" );
325+ next.first .set_value (false );
326+ }
327+
328+ auto response = pending.get ();
329+ EXPECT_THAT (response, StatusIs (TransientError ().code ()));
273330}
274331
275332} // namespace
0 commit comments