@@ -757,8 +757,7 @@ TEST(AsyncWriterConnectionTest, FinalizeAppendableWithExpectedChecksum) {
757757 EXPECT_EQ (request.common_object_request_params ().encryption_algorithm (),
758758 " test-only-algo" );
759759 EXPECT_TRUE (request.has_object_checksums ());
760- EXPECT_EQ (request.object_checksums ().crc32c (),
761- 123456 );
760+ EXPECT_EQ (request.object_checksums ().crc32c (), 123456 );
762761 return sequencer.PushBack (" Write" );
763762 });
764763 EXPECT_CALL (*mock, Read).WillOnce ([&]() {
@@ -861,6 +860,124 @@ TEST(AsyncWriterConnectionTest,
861860 next.first .set_value (true );
862861}
863862
863+ TEST (AsyncWriterConnectionTest,
864+ FinalizeNonAppendableWithExpectedChecksumFromCurrentOptions) {
865+ AsyncSequencer<bool > sequencer;
866+ auto mock = std::make_unique<MockStream>();
867+ EXPECT_CALL (*mock, Cancel).Times (1 );
868+ EXPECT_CALL (*mock, Write)
869+ .WillOnce ([&](Request const & request, grpc::WriteOptions wopt) {
870+ EXPECT_TRUE (request.finish_write ());
871+ EXPECT_TRUE (wopt.is_last_message ());
872+ EXPECT_EQ (request.common_object_request_params ().encryption_algorithm (),
873+ " test-only-algo" );
874+ EXPECT_TRUE (request.has_object_checksums ());
875+ EXPECT_EQ (request.object_checksums ().crc32c (), 654321 );
876+ return sequencer.PushBack (" Write" );
877+ });
878+ EXPECT_CALL (*mock, Read).WillOnce ([&]() {
879+ return sequencer.PushBack (" Read" ).then ([](auto f) {
880+ if (!f.get ()) return absl::optional<Response>();
881+ return absl::make_optional (MakeTestResponse ());
882+ });
883+ });
884+ EXPECT_CALL (*mock, Finish).WillOnce ([&] {
885+ return sequencer.PushBack (" Finish" ).then ([](auto f) {
886+ if (f.get ()) return Status{};
887+ return PermanentError ();
888+ });
889+ });
890+ auto hash = std::make_shared<MockHashFunction>();
891+ EXPECT_CALL (*hash, Update (_, An<absl::Cord const &>(), _)).Times (1 );
892+ // It shouldn't call Finish() because we use kFinalize!
893+ EXPECT_CALL (*hash, Finish).Times (0 );
894+
895+ auto request = MakeRequest ();
896+ // Ensure it's explicitly not appendable.
897+ request.mutable_write_object_spec ()->set_appendable (false );
898+
899+ auto tested = std::make_unique<AsyncWriterConnectionImpl>(
900+ TestOptions (), std::move (request), std::move (mock), hash, 1024 );
901+
902+ internal::OptionsSpan span (
903+ Options{}.set <storage::UseCrc32cValueOption>(654321 ));
904+ auto response = tested->Finalize (WritePayload{});
905+
906+ auto next = sequencer.PopFrontWithName ();
907+ ASSERT_THAT (next.second , " Write" );
908+ next.first .set_value (true );
909+ next = sequencer.PopFrontWithName ();
910+ ASSERT_THAT (next.second , " Read" );
911+ next.first .set_value (true );
912+ auto object = response.get ();
913+ EXPECT_THAT (object, IsOkAndHolds (IsProtoEqual (MakeTestObject ())))
914+ << " =" << object->DebugString ();
915+
916+ tested = {};
917+ next = sequencer.PopFrontWithName ();
918+ ASSERT_THAT (next.second , " Finish" );
919+ next.first .set_value (true );
920+ }
921+
922+ TEST (AsyncWriterConnectionTest,
923+ FinalizeNonAppendableWithExpectedMD5FromCurrentOptions) {
924+ AsyncSequencer<bool > sequencer;
925+ auto mock = std::make_unique<MockStream>();
926+ EXPECT_CALL (*mock, Cancel).Times (1 );
927+ EXPECT_CALL (*mock, Write)
928+ .WillOnce ([&](Request const & request, grpc::WriteOptions wopt) {
929+ EXPECT_TRUE (request.finish_write ());
930+ EXPECT_TRUE (wopt.is_last_message ());
931+ EXPECT_EQ (request.common_object_request_params ().encryption_algorithm (),
932+ " test-only-algo" );
933+ EXPECT_TRUE (request.has_object_checksums ());
934+ EXPECT_EQ (request.object_checksums ().md5_hash (), " test-md5" );
935+ return sequencer.PushBack (" Write" );
936+ });
937+ EXPECT_CALL (*mock, Read).WillOnce ([&]() {
938+ return sequencer.PushBack (" Read" ).then ([](auto f) {
939+ if (!f.get ()) return absl::optional<Response>();
940+ return absl::make_optional (MakeTestResponse ());
941+ });
942+ });
943+ EXPECT_CALL (*mock, Finish).WillOnce ([&] {
944+ return sequencer.PushBack (" Finish" ).then ([](auto f) {
945+ if (f.get ()) return Status{};
946+ return PermanentError ();
947+ });
948+ });
949+ auto hash = std::make_shared<MockHashFunction>();
950+ EXPECT_CALL (*hash, Update (_, An<absl::Cord const &>(), _)).Times (1 );
951+ // It shouldn't call Finish() because we use kFinalize!
952+ EXPECT_CALL (*hash, Finish).Times (0 );
953+
954+ auto request = MakeRequest ();
955+ // Ensure it's explicitly not appendable.
956+ request.mutable_write_object_spec ()->set_appendable (false );
957+
958+ auto tested = std::make_unique<AsyncWriterConnectionImpl>(
959+ TestOptions (), std::move (request), std::move (mock), hash, 1024 );
960+
961+ internal::OptionsSpan span (
962+ Options{}.set <storage::UseMD5ValueOption>(" test-md5" ));
963+ auto response = tested->Finalize (WritePayload{});
964+
965+ auto next = sequencer.PopFrontWithName ();
966+ ASSERT_THAT (next.second , " Write" );
967+ next.first .set_value (true );
968+ next = sequencer.PopFrontWithName ();
969+ ASSERT_THAT (next.second , " Read" );
970+ next.first .set_value (true );
971+ auto object = response.get ();
972+ EXPECT_THAT (object, IsOkAndHolds (IsProtoEqual (MakeTestObject ())))
973+ << " =" << object->DebugString ();
974+
975+ tested = {};
976+ next = sequencer.PopFrontWithName ();
977+ ASSERT_THAT (next.second , " Finish" );
978+ next.first .set_value (true );
979+ }
980+
864981TEST (AsyncWriterConnectionTest, ResumeWithHandle) {
865982 AsyncSequencer<bool > sequencer;
866983 auto mock = std::make_unique<MockStream>();
0 commit comments