diff --git a/google/cloud/bigtable/examples/table_admin_snippets.cc b/google/cloud/bigtable/examples/table_admin_snippets.cc index 6e6499a19d647..3f95b4b1fafd5 100644 --- a/google/cloud/bigtable/examples/table_admin_snippets.cc +++ b/google/cloud/bigtable/examples/table_admin_snippets.cc @@ -622,7 +622,7 @@ void DropRowsByPrefix( } void WaitForConsistencyCheck( - google::cloud::bigtable_admin::BigtableTableAdminClient admin, + google::cloud::bigtable_admin::BigtableTableAdminClient const& admin, std::vector const& argv) { //! [wait for consistency check] namespace cbt = ::google::cloud::bigtable; @@ -631,7 +631,7 @@ void WaitForConsistencyCheck( using ::google::cloud::future; using ::google::cloud::Status; using ::google::cloud::StatusOr; - [](cbta::BigtableTableAdminClient, std::string const& project_id, + [](cbta::BigtableTableAdminClient const&, std::string const& project_id, std::string const& instance_id, std::string const& table_id) { auto client = cbta::BigtableTableAdminClient( cbta::MakeBigtableTableAdminConnection()); diff --git a/google/cloud/spanner/README.md b/google/cloud/spanner/README.md index e02250f356a8a..01463c94475ca 100644 --- a/google/cloud/spanner/README.md +++ b/google/cloud/spanner/README.md @@ -18,6 +18,8 @@ this library. ```cc +#include "google/cloud/internal/disable_deprecation_warnings.inc" + #include "google/cloud/spanner/client.h" #include @@ -45,6 +47,7 @@ int main(int argc, char* argv[]) { return 0; } +#include "google/cloud/internal/diagnostics_pop.inc" ``` diff --git a/google/cloud/spanner/admin/integration_tests/backup_extra_integration_test.cc b/google/cloud/spanner/admin/integration_tests/backup_extra_integration_test.cc index 557b6674848bc..8e880f7fa88d7 100644 --- a/google/cloud/spanner/admin/integration_tests/backup_extra_integration_test.cc +++ b/google/cloud/spanner/admin/integration_tests/backup_extra_integration_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/admin/database_admin_options.h" #include "google/cloud/spanner/admin/instance_admin_client.h" @@ -541,3 +541,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/admin/integration_tests/backup_integration_test.cc b/google/cloud/spanner/admin/integration_tests/backup_integration_test.cc index 127fa61186e4b..14085985883d5 100644 --- a/google/cloud/spanner/admin/integration_tests/backup_integration_test.cc +++ b/google/cloud/spanner/admin/integration_tests/backup_integration_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/admin/database_admin_options.h" #include "google/cloud/spanner/backoff_policy.h" @@ -275,3 +275,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/benchmarks/multiple_rows_cpu_benchmark.cc b/google/cloud/spanner/benchmarks/multiple_rows_cpu_benchmark.cc index 5179c7eb81f38..edfd09d82e1e6 100644 --- a/google/cloud/spanner/benchmarks/multiple_rows_cpu_benchmark.cc +++ b/google/cloud/spanner/benchmarks/multiple_rows_cpu_benchmark.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/benchmarks/benchmarks_config.h" #include "google/cloud/spanner/client.h" @@ -1434,3 +1434,4 @@ int main(int argc, char* argv[]) { : "database dropped\n"); return exit_status; } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/benchmarks/single_row_throughput_benchmark.cc b/google/cloud/spanner/benchmarks/single_row_throughput_benchmark.cc index 396b042b9b2f8..115d324d601bc 100644 --- a/google/cloud/spanner/benchmarks/single_row_throughput_benchmark.cc +++ b/google/cloud/spanner/benchmarks/single_row_throughput_benchmark.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/benchmarks/benchmarks_config.h" #include "google/cloud/spanner/client.h" @@ -511,3 +511,4 @@ int main(int argc, char* argv[]) { : "database dropped\n"); return 0; } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/client.cc b/google/cloud/spanner/client.cc index 03a04dd965fed..210e03858858c 100644 --- a/google/cloud/spanner/client.cc +++ b/google/cloud/spanner/client.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/client.h" #include "google/cloud/spanner/internal/connection_impl.h" #include "google/cloud/spanner/internal/spanner_stub_factory.h" @@ -432,3 +432,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/client_test.cc b/google/cloud/spanner/client_test.cc index 626b6e207479f..7d642c99dd7f8 100644 --- a/google/cloud/spanner/client_test.cc +++ b/google/cloud/spanner/client_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/client.h" #include "google/cloud/mocks/mock_stream_range.h" #include "google/cloud/spanner/connection.h" @@ -1339,3 +1339,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/commit_options.cc b/google/cloud/spanner/commit_options.cc index 804b40908f0bf..0291668647d2a 100644 --- a/google/cloud/spanner/commit_options.cc +++ b/google/cloud/spanner/commit_options.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/commit_options.h" #include "google/cloud/spanner/options.h" @@ -48,3 +48,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/connection.cc b/google/cloud/spanner/connection.cc index 9a3352f68901a..8c7309423b4c3 100644 --- a/google/cloud/spanner/connection.cc +++ b/google/cloud/spanner/connection.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/connection.h" #include "google/cloud/spanner/query_partition.h" #include "google/cloud/spanner/read_partition.h" @@ -115,3 +115,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/integration_tests/client_integration_test.cc b/google/cloud/spanner/integration_tests/client_integration_test.cc index eaa1a258860ee..f21bbec7a636a 100644 --- a/google/cloud/spanner/integration_tests/client_integration_test.cc +++ b/google/cloud/spanner/integration_tests/client_integration_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/client.h" #include "google/cloud/spanner/database.h" @@ -1769,3 +1769,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/integration_tests/client_stress_test.cc b/google/cloud/spanner/integration_tests/client_stress_test.cc index 472b71ec3432d..eab83e81d0b6f 100644 --- a/google/cloud/spanner/integration_tests/client_stress_test.cc +++ b/google/cloud/spanner/integration_tests/client_stress_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/client.h" #include "google/cloud/spanner/database.h" #include "google/cloud/spanner/testing/database_integration_test.h" @@ -148,6 +148,8 @@ TEST_F(ClientStressTest, ParseArgs) { /// @test Stress test the library using ExecuteQuery calls. TEST_F(ClientStressTest, UpsertAndSelect) { + // TODO(#15939): Update emulator and enable this test. + if (UsingEmulator()) GTEST_SKIP(); int const task_count = TaskCount(); auto select_task = [](Client client) { @@ -216,6 +218,8 @@ TEST_F(ClientStressTest, UpsertAndSelect) { /// @test Stress test the library using Read calls. TEST_F(ClientStressTest, UpsertAndRead) { + // TODO(#15939): Update emulator and enable this test. + if (UsingEmulator()) GTEST_SKIP(); int const task_count = TaskCount(); auto read_task = [](Client client) { @@ -302,3 +306,4 @@ int main(int argc, char* argv[]) { return RUN_ALL_TESTS(); } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/integration_tests/data_types_integration_test.cc b/google/cloud/spanner/integration_tests/data_types_integration_test.cc index 0245dfa1a9e69..1ea2f1e646f03 100644 --- a/google/cloud/spanner/integration_tests/data_types_integration_test.cc +++ b/google/cloud/spanner/integration_tests/data_types_integration_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/client.h" #include "google/cloud/spanner/database.h" @@ -1003,3 +1003,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/integration_tests/session_pool_integration_test.cc b/google/cloud/spanner/integration_tests/session_pool_integration_test.cc index 08e6ba6274d2f..ef3036e083e77 100644 --- a/google/cloud/spanner/integration_tests/session_pool_integration_test.cc +++ b/google/cloud/spanner/integration_tests/session_pool_integration_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/defaults.h" #include "google/cloud/spanner/internal/session_pool.h" #include "google/cloud/spanner/internal/spanner_stub_factory.h" @@ -124,3 +124,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/connection_impl.cc b/google/cloud/spanner/internal/connection_impl.cc index f137fcd2ca1ef..e7da01b3d48b2 100644 --- a/google/cloud/spanner/internal/connection_impl.cc +++ b/google/cloud/spanner/internal/connection_impl.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/connection_impl.h" #include "google/cloud/spanner/internal/defaults.h" #include "google/cloud/spanner/internal/logging_result_set_reader.h" @@ -1446,3 +1446,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/connection_impl_test.cc b/google/cloud/spanner/internal/connection_impl_test.cc index e01ae824baea3..5b8595ec3a4e4 100644 --- a/google/cloud/spanner/internal/connection_impl_test.cc +++ b/google/cloud/spanner/internal/connection_impl_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/connection_impl.h" #include "google/cloud/spanner/client.h" #include "google/cloud/spanner/internal/defaults.h" @@ -90,8 +90,6 @@ using ::testing::Property; using ::testing::Return; using ::testing::Sequence; using ::testing::SetArgPointee; -using ::testing::StartsWith; -using ::testing::StrictMock; using ::testing::UnorderedElementsAre; using ::testing::UnorderedPointwise; using ::testing::Unused; @@ -287,16 +285,6 @@ google::spanner::v1::Transaction MakeTestTransaction( return txn; } -// Create a `BatchCreateSessionsResponse` with the given `sessions`. -google::spanner::v1::BatchCreateSessionsResponse MakeSessionsResponse( - std::vector sessions) { - google::spanner::v1::BatchCreateSessionsResponse response; - for (auto& session : sessions) { - response.add_session()->set_name(std::move(session)); - } - return response; -} - // Create a `CommitResponse` with the given `commit_timestamp` and // `commit_stats`. google::spanner::v1::CommitResponse MakeCommitResponse( @@ -409,14 +397,9 @@ TEST(ConnectionImplTest, ReadCreateSessionFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -427,7 +410,7 @@ TEST(ConnectionImplTest, ReadCreateSessionFailure) { {"column1"}}); for (auto& row : rows) { EXPECT_THAT(row, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } } @@ -435,16 +418,13 @@ TEST(ConnectionImplTest, ReadStreamingReadFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto finish_status = internal::PermissionDeniedError("uh-oh in GrpcReader::Finish"); EXPECT_CALL(*mock, StreamingRead) .WillOnce( Return(ByMove(MakeReader({}, finish_status)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -463,8 +443,8 @@ TEST(ConnectionImplTest, ReadSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto retry_status = internal::UnavailableError("try-again"); std::vector responses = { R"pb( @@ -527,9 +507,6 @@ TEST(ConnectionImplTest, ReadSuccess) { EXPECT_THAT(request.resume_token(), Eq("restart-row-2")); return MakeReader({responses[1], responses[2]}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -553,13 +530,13 @@ TEST(ConnectionImplTest, ReadDirectedRead) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); EXPECT_CALL(*mock, StreamingRead) .WillOnce([](std::shared_ptr const&, Options const&, google::spanner::v1::ReadRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_TRUE(request.has_directed_read_options()); auto const& directed_read_options = request.directed_read_options(); EXPECT_TRUE(directed_read_options.has_include_replicas()); @@ -572,9 +549,6 @@ TEST(ConnectionImplTest, ReadDirectedRead) { return MakeReader( {R"pb(metadata: { transaction: { id: "ABCDEF00" } })pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -593,22 +567,19 @@ TEST(ConnectionImplTest, ReadDirectedRead) { spanner::ReplicaSelection(spanner::ReplicaType::kReadOnly)}, true)}); EXPECT_TRUE(ContainsNoRows(rows)); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "ABCDEF00", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "ABCDEF00", false, "")); } TEST(ConnectionImplTest, ReadPermanentFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, StreamingRead) .WillOnce(Return(ByMove(MakeReader( {}, internal::PermissionDeniedError("uh-oh"))))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -627,8 +598,8 @@ TEST(ConnectionImplTest, ReadTooManyTransientFailures) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, StreamingRead) .Times(AtLeast(2)) // This won't compile without `Unused` despite what the gMock docs say. @@ -636,9 +607,6 @@ TEST(ConnectionImplTest, ReadTooManyTransientFailures) { return MakeReader( {}, internal::UnavailableError("try-again")); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -658,17 +626,14 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); auto constexpr kText = R"pb( metadata: { transaction: { id: "ABCDEF00" } } )pb"; EXPECT_CALL(*mock, StreamingRead) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -677,8 +642,8 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransaction) { auto rows = conn->Read( {txn, "table", spanner::KeySet::All(), {"UserId", "UserName"}}); EXPECT_TRUE(ContainsNoRows(rows)); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "ABCDEF00", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "ABCDEF00", false, "")); } TEST(ConnectionImplTest, ReadImplicitBeginTransactionOneTransientFailure) { @@ -711,23 +676,19 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransactionOneTransientFailure) { // n.b. these calls are explicitly sequenced because using the scoped // `InSequence` object causes gMock to get confused by the reader calls. Sequence s; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .InSequence(s) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), - HasBeginTransaction()))) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + EXPECT_CALL( + *mock, StreamingRead( + _, _, AllOf(HasSession("multiplexed"), HasBeginTransaction()))) .InSequence(s) .WillOnce(Return(ByMove(std::move(failing_reader)))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), - HasBeginTransaction()))) + EXPECT_CALL( + *mock, StreamingRead( + _, _, AllOf(HasSession("multiplexed"), HasBeginTransaction()))) .InSequence(s) .WillOnce(Return(ByMove(std::move(ok_reader)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .InSequence(s) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -741,8 +702,8 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransactionOneTransientFailure) { auto actual = std::vector>{stream.begin(), stream.end()}; EXPECT_THAT(actual, ElementsAre(IsOkAndHolds(RowType(12, "Steve")), IsOkAndHolds(RowType(42, "Ann")))); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "ABCDEF00", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "ABCDEF00", false, "")); } TEST(ConnectionImplTest, ReadImplicitBeginTransactionOnePermanentFailure) { @@ -774,26 +735,22 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransactionOnePermanentFailure) { // n.b. these calls are explicitly sequenced because using the scoped // `InSequence` object causes gMock to get confused by the reader calls. Sequence s; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .InSequence(s) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), - HasBeginTransaction()))) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + EXPECT_CALL( + *mock, StreamingRead( + _, _, AllOf(HasSession("multiplexed"), HasBeginTransaction()))) .InSequence(s) .WillOnce(Return(ByMove(std::move(failing_reader)))); EXPECT_CALL(*mock, BeginTransaction) .InSequence(s) .WillOnce(Return(MakeTestTransaction("FEDCBA98"))); EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasTransactionId("FEDCBA98")))) .InSequence(s) .WillOnce(Return(ByMove(std::move(ok_reader)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .InSequence(s) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -807,8 +764,8 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransactionOnePermanentFailure) { auto actual = std::vector>{stream.begin(), stream.end()}; EXPECT_THAT(actual, ElementsAre(IsOkAndHolds(RowType(12, "Steve")), IsOkAndHolds(RowType(42, "Ann")))); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "FEDCBA98", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "FEDCBA98", false, "")); } TEST(ConnectionImplTest, ReadImplicitBeginTransactionPermanentFailure) { @@ -822,26 +779,22 @@ TEST(ConnectionImplTest, ReadImplicitBeginTransactionPermanentFailure) { // n.b. these calls are explicitly sequenced because using the scoped // `InSequence` object causes gMock to get confused by the reader calls. Sequence s; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .InSequence(s) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), - HasBeginTransaction()))) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + EXPECT_CALL( + *mock, StreamingRead( + _, _, AllOf(HasSession("multiplexed"), HasBeginTransaction()))) .InSequence(s) .WillOnce(Return(ByMove(std::move(reader1)))); EXPECT_CALL(*mock, BeginTransaction) .InSequence(s) .WillOnce(Return(MakeTestTransaction("FEDCBA98"))); EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasTransactionId("FEDCBA98")))) .InSequence(s) .WillOnce(Return(ByMove(std::move(reader2)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .InSequence(s) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -859,13 +812,10 @@ TEST(ConnectionImplTest, ExecuteQueryCreateSessionFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillRepeatedly(Return( + Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -874,7 +824,7 @@ TEST(ConnectionImplTest, ExecuteQueryCreateSessionFailure) { spanner::SqlStatement("SELECT * FROM Table")}); for (auto& row : rows) { EXPECT_THAT(row, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } } @@ -882,15 +832,12 @@ TEST(ConnectionImplTest, ExecuteQueryStreamingReadFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader( {}, internal::PermissionDeniedError("uh-oh in GrpcReader::Finish"))))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -907,8 +854,8 @@ TEST(ConnectionImplTest, ExecuteQueryReadSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { row_type: { @@ -935,9 +882,6 @@ TEST(ConnectionImplTest, ExecuteQueryReadSuccess) { )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -960,13 +904,13 @@ TEST(ConnectionImplTest, ExecuteQueryDirectedRead) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce([](std::shared_ptr const&, Options const&, google::spanner::v1::ExecuteSqlRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_TRUE(request.has_directed_read_options()); auto const& directed_read_options = request.directed_read_options(); EXPECT_TRUE(directed_read_options.has_exclude_replicas()); @@ -979,9 +923,6 @@ TEST(ConnectionImplTest, ExecuteQueryDirectedRead) { return MakeReader( {R"pb(metadata: { transaction: { id: "00FEDCBA" } })pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -996,16 +937,16 @@ TEST(ConnectionImplTest, ExecuteQueryDirectedRead) { {spanner::ReplicaSelection(spanner::ReplicaType::kReadWrite), spanner::ReplicaSelection("us-east4")})}); EXPECT_TRUE(ContainsNoRows(rows)); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "00FEDCBA", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "00FEDCBA", false, "")); } TEST(ConnectionImplTest, ExecuteQueryPgNumericResult) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { row_type: { @@ -1026,9 +967,6 @@ TEST(ConnectionImplTest, ExecuteQueryPgNumericResult) { )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1053,8 +991,8 @@ TEST(ConnectionImplTest, ExecuteQueryJsonBResult) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { row_type: { @@ -1075,9 +1013,6 @@ TEST(ConnectionImplTest, ExecuteQueryJsonBResult) { )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1100,8 +1035,8 @@ TEST(ConnectionImplTest, ExecuteQueryNumericParameter) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kResponseNumeric = R"pb( metadata: { row_type: { @@ -1153,9 +1088,6 @@ TEST(ConnectionImplTest, ExecuteQueryNumericParameter) { google::spanner::v1::TypeAnnotationCode::PG_NUMERIC); return MakeReader({kResponsePgNumeric}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1186,8 +1118,8 @@ TEST(ConnectionImplTest, ExecuteQueryPgOidResult) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { row_type: { @@ -1208,9 +1140,6 @@ TEST(ConnectionImplTest, ExecuteQueryPgOidResult) { )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1233,17 +1162,14 @@ TEST(ConnectionImplTest, ExecuteQueryImplicitBeginTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); auto constexpr kText = R"pb( metadata: { transaction: { id: "00FEDCBA" } } )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1252,8 +1178,8 @@ TEST(ConnectionImplTest, ExecuteQueryImplicitBeginTransaction) { auto rows = conn->ExecuteQuery({txn, spanner::SqlStatement("SELECT * FROM Table")}); EXPECT_TRUE(ContainsNoRows(rows)); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "00FEDCBA", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "00FEDCBA", false, "")); } /** @@ -1261,6 +1187,9 @@ TEST(ConnectionImplTest, ExecuteQueryImplicitBeginTransaction) { * by QueryOptions contain the expected fields. */ TEST(ConnectionImplTest, QueryOptions) { + // TODO(#15927): Update the instrumentation of this test for multiplexed + // sessions. + GTEST_SKIP(); struct { // Given these QueryOptions ... spanner::QueryOptions options; @@ -1452,8 +1381,8 @@ TEST(ConnectionImplTest, QueryOptions) { .Build())); // ExecuteQuery(). - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))) .RetiresOnSaturation(); EXPECT_CALL(*mock, ExecuteStreamingSql(_, _, execute_sql_request_matcher)) .WillOnce(Return(ByMove(std::move(stream)))) @@ -1467,8 +1396,8 @@ TEST(ConnectionImplTest, QueryOptions) { .RetiresOnSaturation(); // ExecutePartitionedDml(). - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))) .RetiresOnSaturation(); EXPECT_CALL(*mock, BeginTransaction(_, _, begin_transaction_request_matcher)) @@ -1504,10 +1433,11 @@ TEST(ConnectionImplTest, QueryOptions) { .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))) - .RetiresOnSaturation(); + // EXPECT_CALL(*mock, + // AsyncDeleteSession(_, _, _, + // HasSessionName("session-name"))) + // .WillOnce(Return(make_ready_future(Status{}))) + // .RetiresOnSaturation(); } auto conn = MakeConnectionImpl(db, mock); @@ -1531,11 +1461,6 @@ TEST(ConnectionImplTest, ExecuteDmlCreateSessionFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1545,15 +1470,15 @@ TEST(ConnectionImplTest, ExecuteDmlCreateSessionFailure) { conn->ExecuteDml({txn, spanner::SqlStatement("DELETE * FROM Table")}); EXPECT_THAT(result, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, ExecuteDmlDeleteSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { transaction: { id: "1234567890" } } stats: { row_count_exact: 42 } @@ -1563,9 +1488,6 @@ TEST(ConnectionImplTest, ExecuteDmlDeleteSuccess) { EXPECT_CALL(*mock, ExecuteSql) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1584,16 +1506,13 @@ TEST(ConnectionImplTest, ExecuteDmlDeletePermanentFailure) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kPermissionDenied, "uh-oh in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -1612,8 +1531,8 @@ TEST(ConnectionImplTest, ExecuteDmlDeleteTooManyTransientFailures) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kUnavailable, "try-again in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) @@ -1623,9 +1542,6 @@ TEST(ConnectionImplTest, ExecuteDmlDeleteTooManyTransientFailures) { EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) .WillRepeatedly(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -1648,8 +1564,8 @@ TEST(ConnectionImplTest, ExecuteDmlTransactionAtomicity) { Status begin_status(StatusCode::kInvalidArgument, "BeginTransaction status"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); // The first `ExecuteDml` call tries to implicitly begin the transaction // via `ExecuteSql`, and then explicitly via `BeginTransaction`. Both fail, @@ -1657,10 +1573,6 @@ TEST(ConnectionImplTest, ExecuteDmlTransactionAtomicity) { // not valid the client fails any subsequent operations itself. EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(op_status)); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(begin_status)); - - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -1683,18 +1595,14 @@ TEST(ConnectionImplTest, ExecuteDmlTransactionMissing) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); // Return an otherwise valid response that does not contain a transaction. google::spanner::v1::ResultSet response; ASSERT_TRUE(TextFormat::ParseFromString("metadata: {}", &response)); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); spanner::Transaction txn = @@ -1710,8 +1618,8 @@ TEST(ConnectionImplTest, ProfileQuerySuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { row_type: { @@ -1741,9 +1649,6 @@ TEST(ConnectionImplTest, ProfileQuerySuccess) { )pb"; EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce(Return(ByMove(MakeReader({kText})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1780,11 +1685,6 @@ TEST(ConnectionImplTest, ProfileQueryCreateSessionFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1793,7 +1693,7 @@ TEST(ConnectionImplTest, ProfileQueryCreateSessionFailure) { spanner::SqlStatement("SELECT * FROM Table")}); for (auto& row : result) { EXPECT_THAT(row, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } } @@ -1801,16 +1701,13 @@ TEST(ConnectionImplTest, ProfileQueryStreamingReadFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto finish_status = internal::PermissionDeniedError("uh-oh in GrpcReader::Finish"); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce( Return(ByMove(MakeReader({}, finish_status)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1830,10 +1727,6 @@ TEST(ConnectionImplTest, ProfileDmlCreateSessionFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); @@ -1843,15 +1736,15 @@ TEST(ConnectionImplTest, ProfileDmlCreateSessionFailure) { auto result = conn->ProfileDml({txn, spanner::SqlStatement("DELETE * FROM Table")}); EXPECT_THAT(result, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, ProfileDmlDeleteSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: { transaction: { id: "1234567890" } } stats: { @@ -1870,9 +1763,6 @@ TEST(ConnectionImplTest, ProfileDmlDeleteSuccess) { EXPECT_CALL(*mock, ExecuteSql) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -1906,16 +1796,13 @@ TEST(ConnectionImplTest, ProfileDmlDeletePermanentFailure) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kPermissionDenied, "uh-oh in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -1934,8 +1821,8 @@ TEST(ConnectionImplTest, ProfileDmlDeleteTooManyTransientFailures) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kUnavailable, "try-again in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) @@ -1945,9 +1832,6 @@ TEST(ConnectionImplTest, ProfileDmlDeleteTooManyTransientFailures) { EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) .WillRepeatedly(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -1965,8 +1849,8 @@ TEST(ConnectionImplTest, AnalyzeSqlSuccess) { auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( metadata: {} stats: { query_plan { plan_nodes: { index: 42 } } } @@ -1976,9 +1860,6 @@ TEST(ConnectionImplTest, AnalyzeSqlSuccess) { EXPECT_CALL(*mock, ExecuteSql) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(ByMove(std::move(response)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2002,11 +1883,6 @@ TEST(ConnectionImplTest, AnalyzeSqlCreateSessionFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2015,7 +1891,7 @@ TEST(ConnectionImplTest, AnalyzeSqlCreateSessionFailure) { auto result = conn->AnalyzeSql({txn, spanner::SqlStatement("DELETE * FROM Table")}); EXPECT_THAT(result, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, AnalyzeSqlDeletePermanentFailure) { @@ -2024,16 +1900,13 @@ TEST(ConnectionImplTest, AnalyzeSqlDeletePermanentFailure) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kPermissionDenied, "uh-oh in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, ExecuteSql).WillOnce(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -2052,8 +1925,8 @@ TEST(ConnectionImplTest, AnalyzeSqlDeleteTooManyTransientFailures) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kUnavailable, "try-again in ExecuteDml"); EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) @@ -2063,9 +1936,6 @@ TEST(ConnectionImplTest, AnalyzeSqlDeleteTooManyTransientFailures) { EXPECT_CALL(*mock, ExecuteSql) .Times(AtLeast(2)) .WillRepeatedly(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto conn = MakeConnectionImpl(db, mock); @@ -2082,8 +1952,8 @@ TEST(ConnectionImplTest, ExecuteBatchDmlSuccess) { auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); auto mock = std::make_shared(); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( result_sets: { metadata: { transaction: { id: "1234567890" } } @@ -2101,9 +1971,6 @@ TEST(ConnectionImplTest, ExecuteBatchDmlSuccess) { HasPriority(google::spanner::v1::RequestOptions::PRIORITY_MEDIUM))) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto request = { spanner::SqlStatement("UPDATE ..."), @@ -2127,7 +1994,7 @@ TEST(ConnectionImplTest, ExecuteBatchDmlSuccess) { EXPECT_EQ(result->stats[1].row_count, 1); EXPECT_EQ(result->stats[2].row_count, 2); EXPECT_THAT( - txn, HasSessionAndTransaction("session-name", "1234567890", true, "tag")); + txn, HasSessionAndTransaction("multiplexed", "1234567890", true, "tag")); } TEST(ConnectionImplTest, MultiplexedExecuteBatchDmlSuccess) { @@ -2173,7 +2040,8 @@ TEST(ConnectionImplTest, MultiplexedExecuteBatchDmlSuccess) { spanner::SqlStatement("UPDATE ..."), }; - auto options = Options{}.set({}); + auto options = Options{}; + // .set({}); auto conn = MakeConnectionImpl(db, mock, options); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto txn = spanner::MakeReadWriteTransaction( @@ -2199,8 +2067,8 @@ TEST(ConnectionImplTest, ExecuteBatchDmlPartialFailure) { auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); auto mock = std::make_shared(); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kText = R"pb( result_sets: { metadata: { transaction: { id: "1234567890" } } @@ -2212,9 +2080,6 @@ TEST(ConnectionImplTest, ExecuteBatchDmlPartialFailure) { google::spanner::v1::ExecuteBatchDmlResponse response; ASSERT_TRUE(TextFormat::ParseFromString(kText, &response)); EXPECT_CALL(*mock, ExecuteBatchDml).WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto request = { spanner::SqlStatement("UPDATE ..."), @@ -2234,7 +2099,7 @@ TEST(ConnectionImplTest, ExecuteBatchDmlPartialFailure) { EXPECT_EQ(result->stats[0].row_count, 42); EXPECT_EQ(result->stats[1].row_count, 43); EXPECT_THAT( - txn, HasSessionAndTransaction("session-name", "1234567890", true, "tag")); + txn, HasSessionAndTransaction("multiplexed", "1234567890", true, "tag")); } TEST(ConnectionImplTest, ExecuteBatchDmlPermanentFailure) { @@ -2243,17 +2108,14 @@ TEST(ConnectionImplTest, ExecuteBatchDmlPermanentFailure) { auto mock = std::make_shared(); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kPermissionDenied, "uh-oh in ExecuteBatchDml"); EXPECT_CALL(*mock, ExecuteBatchDml).WillOnce(Return(status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, ExecuteBatchDml).WillOnce(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto request = { @@ -2276,8 +2138,8 @@ TEST(ConnectionImplTest, ExecuteBatchDmlTooManyTransientFailures) { auto mock = std::make_shared(); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kUnavailable, "try-again in ExecuteBatchDml"); EXPECT_CALL(*mock, ExecuteBatchDml) @@ -2288,10 +2150,6 @@ TEST(ConnectionImplTest, ExecuteBatchDmlTooManyTransientFailures) { EXPECT_CALL(*mock, ExecuteBatchDml) .Times(AtLeast(2)) .WillRepeatedly(Return(status)); - - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto request = { @@ -2314,8 +2172,8 @@ TEST(ConnectionImplTest, ExecuteBatchDmlNoResultSets) { auto mock = std::make_shared(); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); // The `ExecuteBatchDml` call can succeed, but with no `ResultSet`s and an // error status in the response. auto constexpr kText = R"pb( @@ -2324,18 +2182,15 @@ TEST(ConnectionImplTest, ExecuteBatchDmlNoResultSets) { google::spanner::v1::ExecuteBatchDmlResponse response; ASSERT_TRUE(TextFormat::ParseFromString(kText, &response)); EXPECT_CALL(*mock, ExecuteBatchDml(_, _, - AllOf(HasSession("session-name"), + AllOf(HasSession("multiplexed"), HasBeginTransaction()))) .WillOnce(Return(response)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction("BD000001"))); EXPECT_CALL(*mock, ExecuteBatchDml(_, _, - AllOf(HasSession("session-name"), + AllOf(HasSession("multiplexed"), HasTransactionId("BD000001")))) .WillOnce(Return(response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); } auto request = {spanner::SqlStatement("UPDATE ...")}; @@ -2353,8 +2208,8 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlDeleteSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce( @@ -2375,9 +2230,6 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlDeleteSuccess) { {}, internal::UnavailableError("try-again in ExecutePartitionedDml"))))) .WillOnce(Return(ByMove(MakeReader({kTextResponse})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2392,8 +2244,8 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlExcludeFromChangeStreams) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce( [](grpc::ClientContext&, Options const&, @@ -2410,9 +2262,6 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlExcludeFromChangeStreams) { ExecuteStreamingSql( _, _, AllOf(HasRequestTag("tag"), HasTransactionTag("")))) .WillOnce(Return(ByMove(MakeReader({kTextResponse})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span( @@ -2432,26 +2281,21 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlCreateSessionFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto result = conn->ExecutePartitionedDml( {spanner::SqlStatement("DELETE * FROM Table")}); EXPECT_THAT(result, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, ExecutePartitionedDmlDeletePermanentFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(MakeTestTransaction())); @@ -2462,10 +2306,6 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlDeletePermanentFailure) { .WillOnce(Return(ByMove(MakeReader( {}, internal::InternalError("permanent failure"))))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto result = conn->ExecutePartitionedDml( @@ -2478,8 +2318,8 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlDeleteTooManyTransientFailures) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(MakeTestTransaction())); @@ -2491,9 +2331,6 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlDeleteTooManyTransientFailures) { {}, internal::UnavailableError("try-again in ExecutePartitionedDml")); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2508,8 +2345,8 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlRetryableInternalErrors) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction("2345678901"))); @@ -2529,10 +2366,6 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlRetryableInternalErrors) { "HTTP/2 error code: INTERNAL_ERROR\nReceived Rst Stream"))))) .WillOnce(Return(ByMove(MakeReader({kTextResponse})))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); auto result = conn->ExecutePartitionedDml( @@ -2546,14 +2379,11 @@ TEST(ConnectionImplTest, auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(Status(StatusCode::kPermissionDenied, "uh-oh in ExecutePartitionedDml"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2568,15 +2398,12 @@ TEST(ConnectionImplTest, auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .Times(AtLeast(2)) .WillRepeatedly(Return(Status(StatusCode::kUnavailable, "try-again in ExecutePartitionedDml"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2594,56 +2421,47 @@ TEST(ConnectionImplTest, CommitCreateSessionPermanentFailure) { EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); auto commit = conn->Commit({spanner::MakeReadWriteTransaction()}); EXPECT_THAT(commit, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, CommitCreateSessionTooManyTransientFailures) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kUnavailable, - "try-again in BatchCreateSessions"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillRepeatedly(Return( + Status(StatusCode::kUnavailable, "try-again in CreateSession"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); auto commit = conn->Commit({spanner::MakeReadWriteTransaction()}); EXPECT_THAT(commit, StatusIs(StatusCode::kUnavailable, - HasSubstr("try-again in BatchCreateSessions"))); + HasSubstr("try-again in CreateSession"))); } TEST(ConnectionImplTest, CommitCreateSessionRetry) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .WillOnce(Return( - Status(StatusCode::kUnavailable, "try-again in BatchCreateSessions"))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + Status(StatusCode::kUnavailable, "try-again in CreateSession"))) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(txn)); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(txn.id())))) .WillOnce( Return(Status(StatusCode::kPermissionDenied, "uh-oh in Commit"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2656,8 +2474,8 @@ TEST(ConnectionImplTest, CommitBeginTransactionRetry) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) @@ -2666,12 +2484,9 @@ TEST(ConnectionImplTest, CommitBeginTransactionRetry) { spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value(); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(txn.id())))) .WillOnce(Return(MakeCommitResponse(commit_timestamp))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2684,13 +2499,10 @@ TEST(ConnectionImplTest, CommitBeginTransactionSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2706,14 +2518,11 @@ TEST(ConnectionImplTest, CommitBeginTransactionPermanentFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return( Status(StatusCode::kInvalidArgument, "BeginTransaction failed"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2733,18 +2542,15 @@ TEST(ConnectionImplTest, CommitCommitPermanentFailure) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(txn)); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(txn.id())))) .WillOnce( Return(Status(StatusCode::kPermissionDenied, "uh-oh in Commit"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2757,18 +2563,15 @@ TEST(ConnectionImplTest, CommitCommitTooManyTransientFailures) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(txn)); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(txn.id())))) .WillOnce( Return(Status(StatusCode::kPermissionDenied, "uh-oh in Commit"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -2781,13 +2584,10 @@ TEST(ConnectionImplTest, CommitCommitInvalidatedTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); EXPECT_CALL(*mock, Commit).Times(0); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2806,19 +2606,16 @@ TEST(ConnectionImplTest, CommitCommitIdempotentTransientSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto const commit_timestamp = spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value(); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasNakedTransactionId("test-txn-id")))) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(MakeCommitResponse(commit_timestamp))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2836,21 +2633,18 @@ TEST(ConnectionImplTest, CommitSuccessWithTransactionId) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL( *mock, - Commit(_, _, - AllOf(HasSession("test-session-name"), - HasNakedTransactionId("test-txn-id"), - HasPriority( - google::spanner::v1::RequestOptions::PRIORITY_HIGH)))) + Commit( + _, _, + AllOf( + HasSession("multiplexed"), HasNakedTransactionId("test-txn-id"), + HasPriority(google::spanner::v1::RequestOptions::PRIORITY_HIGH)))) .WillOnce(Return(MakeCommitResponse( spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value()))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2870,8 +2664,8 @@ TEST(ConnectionImplTest, CommitSuccessWithStats) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce( [](grpc::ClientContext&, Options const&, @@ -2881,16 +2675,13 @@ TEST(ConnectionImplTest, CommitSuccessWithStats) { EXPECT_FALSE(request.has_mutation_key()); return MakeTestTransaction(); }); - EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), - HasReturnStats(true)))) + EXPECT_CALL( + *mock, + Commit(_, _, AllOf(HasSession("multiplexed"), HasReturnStats(true)))) .WillOnce(Return(MakeCommitResponse( spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value(), spanner::CommitStats{42}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -2948,7 +2739,8 @@ TEST(ConnectionImplTest, MutationCommitSuccess) { commit_timestamp, spanner::CommitStats{request.mutations_size()}); }); - auto options = Options{}.set({}); + auto options = Options{}; + // .set({}); auto conn = MakeConnectionImpl(db, mock, options); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto commit = conn->Commit({spanner::MakeReadWriteTransaction(), mutations, @@ -3019,7 +2811,8 @@ TEST(ConnectionImplTest, MutationCommitRetryOnceSuccess) { commit_timestamp, spanner::CommitStats{original_mutations_size}); }); - auto options = Options{}.set({}); + auto options = Options{}; + // .set({}); auto conn = MakeConnectionImpl(db, mock, options); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto commit = conn->Commit({spanner::MakeReadWriteTransaction(), mutations, @@ -3104,7 +2897,8 @@ TEST(ConnectionImplTest, MutationCommitRetryMoreThanOnceSuccess) { commit_timestamp, spanner::CommitStats{original_mutations_size}); }); - auto options = Options{}.set({}); + auto options = Options{}; + // .set({}); auto conn = MakeConnectionImpl(db, mock, options); internal::OptionsSpan span(MakeLimitedTimeOptions()); auto commit = conn->Commit({spanner::MakeReadWriteTransaction(), mutations, @@ -3188,7 +2982,8 @@ TEST(ConnectionImplTest, MultiplexedPrecommitUpdated) { }); } - auto options = Options{}.set({}); + auto options = Options{}; + // .set({}); auto conn = MakeConnectionImpl(db, mock, options); internal::OptionsSpan span(MakeLimitedTimeOptions()); spanner::Transaction txn = @@ -3207,8 +3002,8 @@ TEST(ConnectionImplTest, CommitSuccessExcludeFromChangeStreams) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction) .WillOnce( [](grpc::ClientContext&, Options const&, @@ -3217,13 +3012,10 @@ TEST(ConnectionImplTest, CommitSuccessExcludeFromChangeStreams) { EXPECT_TRUE(request.options().exclude_txn_from_change_streams()); return MakeTestTransaction(); }); - EXPECT_CALL(*mock, Commit(_, _, HasSession("test-session-name"))) + EXPECT_CALL(*mock, Commit(_, _, HasSession("multiplexed"))) .WillOnce(Return(MakeCommitResponse( spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value()))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span( @@ -3241,20 +3033,17 @@ TEST(ConnectionImplTest, CommitSuccessWithMaxCommitDelay) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(txn)); EXPECT_CALL(*mock, Commit(_, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasMaxCommitDelay(std::chrono::milliseconds(100))))) .WillOnce(Return(MakeCommitResponse( spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value()))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3269,21 +3058,18 @@ TEST(ConnectionImplTest, CommitSuccessWithCompression) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::spanner::v1::Transaction txn = MakeTestTransaction(); EXPECT_CALL(*mock, BeginTransaction).WillOnce(Return(txn)); EXPECT_CALL(*mock, Commit(HasCompressionAlgorithm(GRPC_COMPRESS_GZIP), _, - HasSession("test-session-name"))) + HasSession("multiplexed"))) .WillOnce([](grpc::ClientContext&, Options const&, google::spanner::v1::CommitRequest const&) { return MakeCommitResponse( spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) .value()); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span( @@ -3301,8 +3087,8 @@ TEST(ConnectionImplTest, CommitAtLeastOnce) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); // The whole point! auto const commit_timestamp = spanner::MakeTimestamp(std::chrono::system_clock::from_time_t(123)) @@ -3311,7 +3097,7 @@ TEST(ConnectionImplTest, CommitAtLeastOnce) { .WillOnce([commit_timestamp]( grpc::ClientContext&, Options const&, google::spanner::v1::CommitRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_TRUE(request.has_single_use_transaction()); EXPECT_EQ(0, request.mutations_size()); EXPECT_FALSE(request.return_commit_stats()); @@ -3321,9 +3107,6 @@ TEST(ConnectionImplTest, CommitAtLeastOnce) { EXPECT_THAT(request.request_options().transaction_tag(), IsEmpty()); return MakeCommitResponse(commit_timestamp); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3338,13 +3121,13 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatched) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); using BatchWriteRequest = google::spanner::v1::BatchWriteRequest; EXPECT_CALL(*mock, BatchWrite) .WillOnce([](std::shared_ptr const&, Options const&, BatchWriteRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_EQ(google::spanner::v1::RequestOptions::PRIORITY_UNSPECIFIED, request.request_options().priority()); EXPECT_THAT(request.request_options().request_tag(), IsEmpty()); @@ -3359,7 +3142,7 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatched) { }) .WillOnce([&](std::shared_ptr const&, Options const&, BatchWriteRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_EQ(google::spanner::v1::RequestOptions::PRIORITY_UNSPECIFIED, request.request_options().priority()); EXPECT_THAT(request.request_options().request_tag(), IsEmpty()); @@ -3378,9 +3161,6 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatched) { commit_timestamp { seconds: 123 } )pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3396,75 +3176,17 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatched) { EXPECT_EQ(++it, commit_results.end()); } -TEST(ConnectionImplTest, CommitAtLeastOnceBatchedSessionNotFound) { - auto mock = std::make_shared>(); - auto db = spanner::Database("placeholder_project", "placeholder_instance", - "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name-1"}))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name-2"}))); - using BatchWriteRequest = google::spanner::v1::BatchWriteRequest; - EXPECT_CALL(*mock, BatchWrite) - .WillOnce([](std::shared_ptr const&, Options const&, - BatchWriteRequest const& request) { - EXPECT_EQ("test-session-name-1", request.session()); - EXPECT_THAT(request.mutation_groups(), IsEmpty()); - EXPECT_FALSE(request.exclude_txn_from_change_streams()); - return MakeReader( - {}, SessionNotFoundError(request.session())); - }) - .WillOnce([&](std::shared_ptr const&, Options const&, - BatchWriteRequest const& request) { - EXPECT_EQ("test-session-name-2", request.session()); - EXPECT_THAT(request.mutation_groups(), IsEmpty()); - EXPECT_FALSE(request.exclude_txn_from_change_streams()); - return MakeReader( - {R"pb(status {} - commit_timestamp { seconds: 123 })pb"}); - }); - EXPECT_CALL( - *mock, AsyncDeleteSession(_, _, _, HasSessionName("test-session-name-2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - auto conn = MakeConnectionImpl(db, mock); - internal::OptionsSpan span(MakeLimitedTimeOptions()); - { - auto commit_results = conn->BatchWrite({{}, Options{}}); - auto it = commit_results.begin(); - ASSERT_NE(it, commit_results.end()); - EXPECT_THAT(*it, Not(IsOk())); - EXPECT_TRUE(IsSessionNotFound(it->status())) << it->status(); - EXPECT_EQ(++it, commit_results.end()); - } - - // "test-session-name-1" should not have been returned to the pool. - // The best (only?) way to verify this is to make another write and - // check that another session was allocated (hence the strict mock). - { - auto commit_results = conn->BatchWrite({{}, Options{}}); - auto it = commit_results.begin(); - ASSERT_NE(it, commit_results.end()); - EXPECT_THAT( - *it, - IsOkAndHolds(AllOf( - Field(&spanner::BatchedCommitResult::indexes, IsEmpty()), - Field(&spanner::BatchedCommitResult::commit_timestamp, - Eq(spanner::MakeTimestamp(absl::FromUnixSeconds(123))))))); - EXPECT_EQ(++it, commit_results.end()); - } -} - TEST(ConnectionImplTest, CommitAtLeastOnceBatchedExcludeFromChangeStreams) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); using BatchWriteRequest = google::spanner::v1::BatchWriteRequest; EXPECT_CALL(*mock, BatchWrite) .WillOnce([&](std::shared_ptr const&, Options const&, BatchWriteRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_EQ(google::spanner::v1::RequestOptions::PRIORITY_UNSPECIFIED, request.request_options().priority()); EXPECT_THAT(request.request_options().request_tag(), IsEmpty()); @@ -3483,9 +3205,6 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatchedExcludeFromChangeStreams) { commit_timestamp { seconds: 123 } )pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span( @@ -3506,13 +3225,9 @@ TEST(ConnectionImplTest, CommitAtLeastOnceBatchedExcludeFromChangeStreams) { TEST(ConnectionImplTest, RollbackCreateSessionFailure) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, CreateSession(_, _, HasDatabase(db))) + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) .WillRepeatedly(Return( Status(StatusCode::kPermissionDenied, "uh-oh in CreateSession"))); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .Times(AtLeast(2)) - .WillRepeatedly(Return(Status(StatusCode::kPermissionDenied, - "uh-oh in BatchCreateSessions"))); EXPECT_CALL(*mock, Rollback).Times(0); EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); @@ -3522,15 +3237,15 @@ TEST(ConnectionImplTest, RollbackCreateSessionFailure) { SetTransactionId(txn, "test-txn-id"); auto rollback = conn->Rollback({txn}); EXPECT_THAT(rollback, StatusIs(StatusCode::kPermissionDenied, - HasSubstr("uh-oh in BatchCreateSessions"))); + HasSubstr("uh-oh in CreateSession"))); } TEST(ConnectionImplTest, RollbackBeginTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - std::string const session_name = "test-session-name"; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({session_name}))); + std::string const session_name = "multiplexed"; + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); std::string const transaction_id = "RollbackBeginTransaction"; EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction(transaction_id))); @@ -3538,9 +3253,6 @@ TEST(ConnectionImplTest, RollbackBeginTransaction) { AllOf(HasSession(session_name), HasNakedTransactionId(transaction_id)))) .WillOnce(Return(Status())); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3552,12 +3264,9 @@ TEST(ConnectionImplTest, RollbackBeginTransaction) { TEST(ConnectionImplTest, RollbackSingleUseTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, Rollback).Times(0); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3572,18 +3281,15 @@ TEST(ConnectionImplTest, RollbackSingleUseTransaction) { TEST(ConnectionImplTest, RollbackPermanentFailure) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - std::string const session_name = "test-session-name"; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({session_name}))); + std::string const session_name = "multiplexed"; + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); std::string const transaction_id = "test-txn-id"; EXPECT_CALL(*mock, Rollback(_, _, - AllOf(HasSession(session_name), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(transaction_id)))) .WillOnce( Return(Status(StatusCode::kPermissionDenied, "uh-oh in Rollback"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -3597,9 +3303,9 @@ TEST(ConnectionImplTest, RollbackPermanentFailure) { TEST(ConnectionImplTest, RollbackTooManyTransientFailures) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - std::string const session_name = "test-session-name"; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({session_name}))); + std::string const session_name = "multiplexed"; + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); std::string const transaction_id = "test-txn-id"; EXPECT_CALL(*mock, Rollback(_, _, AllOf(HasSession(session_name), @@ -3607,9 +3313,6 @@ TEST(ConnectionImplTest, RollbackTooManyTransientFailures) { .Times(AtLeast(2)) .WillRepeatedly( Return(Status(StatusCode::kUnavailable, "try-again in Rollback"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -3623,18 +3326,15 @@ TEST(ConnectionImplTest, RollbackTooManyTransientFailures) { TEST(ConnectionImplTest, RollbackSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - std::string const session_name = "test-session-name"; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({session_name}))); + std::string const session_name = "multiplexed"; + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); std::string const transaction_id = "test-txn-id"; EXPECT_CALL(*mock, Rollback(_, _, - AllOf(HasSession(session_name), + AllOf(HasSession("multiplexed"), HasNakedTransactionId(transaction_id)))) .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(Status())); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3648,12 +3348,9 @@ TEST(ConnectionImplTest, RollbackInvalidatedTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, Rollback).Times(0); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3673,22 +3370,19 @@ TEST(ConnectionImplTest, ReadPartition) { auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); EXPECT_CALL(*mock, StreamingRead) .WillOnce([](std::shared_ptr const&, Options const&, google::spanner::v1::ReadRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_EQ("Table", request.table()); EXPECT_EQ("DEADBEEF", request.partition_token()); EXPECT_TRUE(request.data_boost_enabled()); return MakeReader( {R"pb(metadata: { transaction: { id: "ABCDEF00" } })pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3706,8 +3400,8 @@ TEST(ConnectionImplTest, PartitionReadSuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kTextPartitionResponse = R"pb( partitions: { partition_token: "BADDECAF" } partitions: { partition_token: "DEADBEEF" } @@ -3718,7 +3412,7 @@ TEST(ConnectionImplTest, PartitionReadSuccess) { TextFormat::ParseFromString(kTextPartitionResponse, &partition_response)); auto constexpr kTextPartitionRequest = R"pb( - session: "test-session-name" + session: "multiplexed" transaction: { begin { read_only { strong: true return_read_timestamp: true } } } @@ -3737,10 +3431,6 @@ TEST(ConnectionImplTest, PartitionReadSuccess) { .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(partition_response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); spanner::Transaction txn = @@ -3758,16 +3448,16 @@ TEST(ConnectionImplTest, PartitionReadSuccess) { read_options}, {absl::nullopt, absl::nullopt, data_boost}}); ASSERT_STATUS_OK(result); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "CAFEDEAD", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "CAFEDEAD", false, "")); std::vector expected_read_partitions = { spanner_internal::MakeReadPartition( - "CAFEDEAD", false, "", "test-session-name", "BADDECAF", "table", + "CAFEDEAD", false, "", "multiplexed", "BADDECAF", "table", spanner::KeySet::All(), {"UserId", "UserName"}, data_boost, read_options), spanner_internal::MakeReadPartition( - "CAFEDEAD", false, "", "test-session-name", "DEADBEEF", "table", + "CAFEDEAD", false, "", "multiplexed", "DEADBEEF", "table", spanner::KeySet::All(), {"UserId", "UserName"}, data_boost, read_options)}; @@ -3780,16 +3470,13 @@ TEST(ConnectionImplTest, PartitionReadPermanentFailure) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kPermissionDenied, "uh-oh"); EXPECT_CALL(*mock, PartitionRead).WillOnce(Return(status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, PartitionRead).WillOnce(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); } auto conn = MakeConnectionImpl(db, mock); @@ -3809,8 +3496,8 @@ TEST(ConnectionImplTest, PartitionReadTooManyTransientFailures) { "placeholder_database_id"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Status status(StatusCode::kUnavailable, "try-again"); EXPECT_CALL(*mock, PartitionRead) .Times(AtLeast(2)) @@ -3820,9 +3507,6 @@ TEST(ConnectionImplTest, PartitionReadTooManyTransientFailures) { EXPECT_CALL(*mock, PartitionRead) .Times(AtLeast(2)) .WillRepeatedly(Return(status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); } auto conn = MakeConnectionImpl(db, mock); @@ -3841,22 +3525,19 @@ TEST(ConnectionImplTest, QueryPartition) { auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce([](std::shared_ptr const&, Options const&, google::spanner::v1::ExecuteSqlRequest const& request) { - EXPECT_EQ("test-session-name", request.session()); + EXPECT_EQ("multiplexed", request.session()); EXPECT_EQ("SELECT * FROM Table", request.sql()); EXPECT_EQ("DEADBEEF", request.partition_token()); EXPECT_TRUE(request.data_boost_enabled()); return MakeReader( {R"pb(metadata: { transaction: { id: "ABCDEF00" } })pb"}); }); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -3872,8 +3553,8 @@ TEST(ConnectionImplTest, PartitionQuerySuccess) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto constexpr kTextPartitionResponse = R"pb( partitions: { partition_token: "BADDECAF" } partitions: { partition_token: "DEADBEEF" } @@ -3884,7 +3565,7 @@ TEST(ConnectionImplTest, PartitionQuerySuccess) { TextFormat::ParseFromString(kTextPartitionResponse, &partition_response)); auto constexpr kTextPartitionRequest = R"pb( - session: "test-session-name" + session: "multiplexed" transaction: { begin { read_only { strong: true return_read_timestamp: true } } } @@ -3899,10 +3580,6 @@ TEST(ConnectionImplTest, PartitionQuerySuccess) { .WillOnce(Return(Status(StatusCode::kUnavailable, "try-again"))) .WillOnce(Return(partition_response)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); spanner::SqlStatement sql_statement("SELECT * FROM Table"); @@ -3914,12 +3591,12 @@ TEST(ConnectionImplTest, PartitionQuerySuccess) { ASSERT_STATUS_OK(result); std::vector expected_query_partitions = { - spanner_internal::MakeQueryPartition("CAFEDEAD", false, "", - "test-session-name", "BADDECAF", - data_boost, sql_statement), - spanner_internal::MakeQueryPartition("CAFEDEAD", false, "", - "test-session-name", "DEADBEEF", - data_boost, sql_statement)}; + spanner_internal::MakeQueryPartition("CAFEDEAD", false, "", "multiplexed", + "BADDECAF", data_boost, + sql_statement), + spanner_internal::MakeQueryPartition("CAFEDEAD", false, "", "multiplexed", + "DEADBEEF", data_boost, + sql_statement)}; EXPECT_THAT(*result, UnorderedPointwise(Eq(), expected_query_partitions)); } @@ -3931,15 +3608,12 @@ TEST(ConnectionImplTest, PartitionQueryPermanentFailure) { Status failed_status = Status(StatusCode::kPermissionDenied, "End of line."); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, PartitionQuery).WillOnce(Return(failed_status)); EXPECT_CALL(*mock, BeginTransaction) .WillOnce(Return(MakeTestTransaction())); EXPECT_CALL(*mock, PartitionQuery).WillOnce(Return(failed_status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); } auto conn = MakeConnectionImpl(db, mock); @@ -3960,8 +3634,8 @@ TEST(ConnectionImplTest, PartitionQueryTooManyTransientFailures) { Status(StatusCode::kUnavailable, "try-again in PartitionQuery"); { InSequence seq; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, PartitionQuery) .Times(AtLeast(2)) .WillRepeatedly(Return(failed_status)); @@ -3970,9 +3644,6 @@ TEST(ConnectionImplTest, PartitionQueryTooManyTransientFailures) { EXPECT_CALL(*mock, PartitionQuery) .Times(AtLeast(2)) .WillRepeatedly(Return(failed_status)); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); } auto conn = MakeConnectionImpl(db, mock); @@ -3990,36 +3661,15 @@ TEST(ConnectionImplTest, MultipleThreads) { auto db = spanner::Database("project", "instance", "database"); std::string const session_prefix = "test-session-prefix-"; std::string const role = "TestRole"; - std::atomic session_counter(0); - EXPECT_CALL(*mock, BatchCreateSessions( - _, _, AllOf(HasDatabase(db), HasCreatorRole(role)))) - .WillRepeatedly( - [&session_prefix, &session_counter]( - grpc::ClientContext&, Options const&, - google::spanner::v1::BatchCreateSessionsRequest const& request) { - google::spanner::v1::BatchCreateSessionsResponse response; - for (int i = 0; i < request.session_count(); ++i) { - response.add_session()->set_name( - session_prefix + std::to_string(++session_counter)); - } - return response; - }); + EXPECT_CALL(*mock, CreateSession(_, _, AllOf(IsMultiplexed()))) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, Rollback) .WillRepeatedly([session_prefix]( grpc::ClientContext&, Options const&, google::spanner::v1::RollbackRequest const& request) { - EXPECT_THAT(request.session(), StartsWith(session_prefix)); + EXPECT_THAT(request.session(), Eq("multiplexed")); return Status(); }); - EXPECT_CALL(*mock, AsyncDeleteSession) - .WillRepeatedly( - [session_prefix]( - CompletionQueue&, std::shared_ptr const&, - internal::ImmutableOptions const&, - google::spanner::v1::DeleteSessionRequest const& request) { - EXPECT_THAT(request.name(), StartsWith(session_prefix)); - return make_ready_future(Status{}); - }); int const per_thread_iterations = 1000; auto const thread_count = []() -> unsigned { @@ -4052,118 +3702,6 @@ TEST(ConnectionImplTest, MultipleThreads) { } } -/** - * @test Verify Transactions remain bound to a single Session. - * - * This test makes interleaved Read() calls using two separate Transactions, - * and ensures each Transaction uses the same session consistently. - */ -TEST(ConnectionImplTest, TransactionSessionBinding) { - auto mock = std::make_shared(); - auto db = spanner::Database("placeholder_project", "placeholder_instance", - "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"session-1"}))) - .WillOnce(Return(MakeSessionsResponse({"session-2"}))); - - constexpr int kNumResponses = 4; - std::array>, - kNumResponses> - readers; - for (int i = 0; i < kNumResponses; ++i) { - auto constexpr kText = R"pb( - metadata: { - row_type: { - fields: { - name: "Number", - type: { code: INT64 } - } - } - } - )pb"; - PartialResultSet response; - ASSERT_TRUE(TextFormat::ParseFromString(kText, &response)); - // The first two responses are reads from two different "begin" - // transactions. - if (i == 0) { - *response.mutable_metadata()->mutable_transaction() = - MakeTestTransaction("ABCDEF01"); - } else if (i == 1) { - *response.mutable_metadata()->mutable_transaction() = - MakeTestTransaction("ABCDEF02"); - } - response.add_values()->set_string_value(std::to_string(i)); - readers[i] = MakeReader({std::move(response)}); - } - - // Ensure the StreamingRead calls have the expected session and transaction - // IDs or "begin" set as appropriate. - { - InSequence s; - EXPECT_CALL( - *mock, StreamingRead( - _, _, AllOf(HasSession("session-1"), HasBeginTransaction()))) - .WillOnce(Return(ByMove(std::move(readers[0])))); - EXPECT_CALL( - *mock, StreamingRead( - _, _, AllOf(HasSession("session-2"), HasBeginTransaction()))) - .WillOnce(Return(ByMove(std::move(readers[1])))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("session-1"), - HasTransactionId("ABCDEF01")))) - .WillOnce(Return(ByMove(std::move(readers[2])))); - EXPECT_CALL(*mock, StreamingRead(_, _, - AllOf(HasSession("session-2"), - HasTransactionId("ABCDEF02")))) - .WillOnce(Return(ByMove(std::move(readers[3])))); - } - - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, HasSessionName("session-1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, HasSessionName("session-2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - // Now do the actual reads and verify the results. - auto conn = MakeConnectionImpl(db, mock); - internal::OptionsSpan span(MakeLimitedTimeOptions()); - - spanner::Transaction txn1 = - MakeReadOnlyTransaction(spanner::Transaction::ReadOnlyOptions()); - auto rows = conn->Read({txn1, "table", spanner::KeySet::All(), {"Number"}}); - EXPECT_THAT(txn1, - HasSessionAndTransaction("session-1", "ABCDEF01", false, "")); - for (auto& row : spanner::StreamOf>(rows)) { - ASSERT_STATUS_OK(row); - EXPECT_EQ(std::get<0>(*row), 0); - } - - spanner::Transaction txn2 = - MakeReadOnlyTransaction(spanner::Transaction::ReadOnlyOptions()); - rows = conn->Read({txn2, "table", spanner::KeySet::All(), {"Number"}}); - EXPECT_THAT(txn2, - HasSessionAndTransaction("session-2", "ABCDEF02", false, "")); - for (auto& row : spanner::StreamOf>(rows)) { - ASSERT_STATUS_OK(row); - EXPECT_EQ(std::get<0>(*row), 1); - } - - rows = conn->Read({txn1, "table", spanner::KeySet::All(), {"Number"}}); - EXPECT_THAT(txn1, - HasSessionAndTransaction("session-1", "ABCDEF01", false, "")); - for (auto& row : spanner::StreamOf>(rows)) { - ASSERT_STATUS_OK(row); - EXPECT_EQ(std::get<0>(*row), 2); - } - - rows = conn->Read({txn2, "table", spanner::KeySet::All(), {"Number"}}); - EXPECT_THAT(txn2, - HasSessionAndTransaction("session-2", "ABCDEF02", false, "")); - for (auto& row : spanner::StreamOf>(rows)) { - ASSERT_STATUS_OK(row); - EXPECT_EQ(std::get<0>(*row), 3); - } -} - /** * @test Verify if a `Transaction` outlives the `ConnectionImpl` it was used * with, it does not call back into the deleted `ConnectionImpl` to release @@ -4173,8 +3711,8 @@ TEST(ConnectionImplTest, TransactionOutlivesConnection) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, BeginTransaction).Times(0); auto constexpr kText = R"pb( @@ -4183,13 +3721,6 @@ TEST(ConnectionImplTest, TransactionOutlivesConnection) { EXPECT_CALL(*mock, StreamingRead) .WillOnce(Return(ByMove(MakeReader({kText})))); - // Because the transaction outlives the connection, the session is not in - // the pool when the connection is destroyed, so the session is leaked. - // Only the multiplexed session is deleted. - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); - auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); spanner::Transaction txn = @@ -4197,8 +3728,8 @@ TEST(ConnectionImplTest, TransactionOutlivesConnection) { auto rows = conn->Read( {txn, "table", spanner::KeySet::All(), {"UserId", "UserName"}}); EXPECT_TRUE(ContainsNoRows(rows)); - EXPECT_THAT(txn, HasSessionAndTransaction("test-session-name", "ABCDEF00", - false, "")); + EXPECT_THAT(txn, + HasSessionAndTransaction("multiplexed", "ABCDEF00", false, "")); // `conn` is the only reference to the `ConnectionImpl`, so dropping it will // cause the `ConnectionImpl` object to be deleted, while `txn` and its @@ -4206,85 +3737,13 @@ TEST(ConnectionImplTest, TransactionOutlivesConnection) { conn.reset(); } -TEST(ConnectionImplTest, ReadSessionNotFound) { - auto mock = std::make_shared>(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name-1"}))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name-2"}))); - EXPECT_CALL(*mock, StreamingRead) - .WillOnce([](std::shared_ptr const&, Options const&, - google::spanner::v1::ReadRequest const& request) { - EXPECT_THAT(request.session(), Eq("test-session-name-1")); - EXPECT_THAT(request.transaction().id(), Eq("test-txn-id-1")); - return MakeReader( - {}, SessionNotFoundError(request.session())); - }) - .WillOnce([](std::shared_ptr const&, Options const&, - google::spanner::v1::ReadRequest const& request) { - EXPECT_THAT(request.session(), Eq("test-session-name-2")); - EXPECT_THAT(request.transaction().id(), Eq("test-txn-id-2")); - return MakeReader({ - R"pb( - metadata: { - row_type: { - fields: { - name: "UserId", - type: { code: INT64 } - } - fields: { - name: "UserName", - type: { code: STRING } - } - } - } - )pb"}); - }); - EXPECT_CALL( - *mock, AsyncDeleteSession(_, _, _, HasSessionName("test-session-name-1"))) - .Times(0); - EXPECT_CALL( - *mock, AsyncDeleteSession(_, _, _, HasSessionName("test-session-name-2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - auto conn = MakeConnectionImpl(db, mock); - internal::OptionsSpan span(MakeLimitedRetryOptions()); - { - auto txn = spanner::MakeReadWriteTransaction(); - SetTransactionId(txn, "test-txn-id-1"); - auto params = spanner::Connection::ReadParams{txn}; - auto response = GetSingularRow(conn->Read(std::move(params))); - EXPECT_THAT(response, Not(IsOk())); - auto const& status = response.status(); - EXPECT_TRUE(IsSessionNotFound(status)) << status; - EXPECT_THAT(txn, HasBadSession()); - } - - // "test-session-name-1" should not have been returned to the pool. - // The best (only?) way to verify this is to make another read and - // check that another session was allocated (hence the strict mock). - { - auto txn = spanner::MakeReadWriteTransaction(); - SetTransactionId(txn, "test-txn-id-2"); - auto params = spanner::Connection::ReadParams{txn}; - auto rows = conn->Read(std::move(params)); - using RowType = std::tuple; - auto stream = spanner::StreamOf(rows); - auto actual = std::vector>{stream.begin(), stream.end()}; - EXPECT_THAT(actual, IsEmpty()); - } -} - TEST(ConnectionImplTest, PartitionReadSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, PartitionRead) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4301,15 +3760,12 @@ TEST(ConnectionImplTest, PartitionReadSessionNotFound) { TEST(ConnectionImplTest, ExecuteQuerySessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - auto finish_status = SessionNotFoundError("test-session-name"); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + auto finish_status = SessionNotFoundError("multiplexed"); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce( Return(ByMove(MakeReader({}, finish_status)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4325,15 +3781,12 @@ TEST(ConnectionImplTest, ExecuteQuerySessionNotFound) { TEST(ConnectionImplTest, ProfileQuerySessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - auto finish_status = SessionNotFoundError("test-session-name"); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); + auto finish_status = SessionNotFoundError("multiplexed"); EXPECT_CALL(*mock, ExecuteStreamingSql) .WillOnce( Return(ByMove(MakeReader({}, finish_status)))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4349,13 +3802,10 @@ TEST(ConnectionImplTest, ProfileQuerySessionNotFound) { TEST(ConnectionImplTest, ExecuteDmlSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, ExecuteSql) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4371,13 +3821,10 @@ TEST(ConnectionImplTest, ExecuteDmlSessionNotFound) { TEST(ConnectionImplTest, ProfileDmlSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, ExecuteSql) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4393,13 +3840,10 @@ TEST(ConnectionImplTest, ProfileDmlSessionNotFound) { TEST(ConnectionImplTest, AnalyzeSqlSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, ExecuteSql) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4415,13 +3859,10 @@ TEST(ConnectionImplTest, AnalyzeSqlSessionNotFound) { TEST(ConnectionImplTest, PartitionQuerySessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, PartitionQuery) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4437,13 +3878,10 @@ TEST(ConnectionImplTest, PartitionQuerySessionNotFound) { TEST(ConnectionImplTest, ExecuteBatchDmlSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, ExecuteBatchDml) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4466,13 +3904,10 @@ TEST(ConnectionImplTest, ExecutePartitionedDmlSessionNotFound) { TEST(ConnectionImplTest, CommitSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, Commit) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4488,13 +3923,10 @@ TEST(ConnectionImplTest, CommitSessionNotFound) { TEST(ConnectionImplTest, RollbackSessionNotFound) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, Rollback) - .WillOnce(Return(SessionNotFoundError("test-session-name"))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, Not(HasSessionName("multiplexed")))) - .Times(0); + .WillOnce(Return(SessionNotFoundError("multiplexed"))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedRetryOptions()); @@ -4508,17 +3940,14 @@ TEST(ConnectionImplTest, RollbackSessionNotFound) { TEST(ConnectionImplTest, ReadRequestOrderByParameterUnspecified) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Sequence s; EXPECT_CALL( *mock, StreamingRead( _, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasOrderBy( google::spanner::v1::ReadRequest::ORDER_BY_UNSPECIFIED)))) .InSequence(s) @@ -4537,25 +3966,21 @@ TEST(ConnectionImplTest, ReadRequestOrderByParameterUnspecified) { for (auto const& row : rows1) { (void)row; } - EXPECT_THAT(txn1, - HasSessionAndTransaction("test-session-name", "txn1", false, "")); + EXPECT_THAT(txn1, HasSessionAndTransaction("multiplexed", "txn1", false, "")); } TEST(ConnectionImplTest, ReadRequestOrderByParameterNoOrder) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Sequence s; EXPECT_CALL( *mock, StreamingRead( _, _, AllOf( - HasSession("test-session-name"), + HasSession("multiplexed"), HasOrderBy(google::spanner::v1::ReadRequest::ORDER_BY_NO_ORDER)))) .InSequence(s) .WillOnce(Return(ByMove(MakeReader( @@ -4580,24 +4005,20 @@ TEST(ConnectionImplTest, ReadRequestOrderByParameterNoOrder) { for (auto const& row : rows1) { (void)row; } - EXPECT_THAT(txn1, - HasSessionAndTransaction("test-session-name", "txn1", false, "")); + EXPECT_THAT(txn1, HasSessionAndTransaction("multiplexed", "txn1", false, "")); } TEST(ConnectionImplTest, ReadRequestLockHintParameterUnspecified) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Sequence s; EXPECT_CALL( *mock, StreamingRead( _, _, - AllOf(HasSession("test-session-name"), + AllOf(HasSession("multiplexed"), HasLockHint( google::spanner::v1::ReadRequest::LOCK_HINT_UNSPECIFIED)))) .InSequence(s) @@ -4616,25 +4037,21 @@ TEST(ConnectionImplTest, ReadRequestLockHintParameterUnspecified) { for (auto const& row : rows1) { (void)row; } - EXPECT_THAT(txn1, - HasSessionAndTransaction("test-session-name", "txn1", false, "")); + EXPECT_THAT(txn1, HasSessionAndTransaction("multiplexed", "txn1", false, "")); } TEST(ConnectionImplTest, ReadRequestLockHintShared) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); Sequence s; EXPECT_CALL( *mock, StreamingRead( _, _, AllOf( - HasSession("test-session-name"), + HasSession("multiplexed"), HasLockHint(google::spanner::v1::ReadRequest::LOCK_HINT_SHARED)))) .InSequence(s) .WillOnce(Return(ByMove(MakeReader( @@ -4660,19 +4077,15 @@ TEST(ConnectionImplTest, ReadRequestLockHintShared) { for (auto const& row : rows1) { (void)row; } - EXPECT_THAT(txn1, - HasSessionAndTransaction("test-session-name", "txn1", false, "")); + EXPECT_THAT(txn1, HasSessionAndTransaction("multiplexed", "txn1", false, "")); } TEST(ConnectionImplTest, OperationsFailOnInvalidatedTransaction) { auto mock = std::make_shared(); auto db = spanner::Database("placeholder_project", "placeholder_instance", "placeholder_database_id"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, HasDatabase(db))) - .WillOnce(Return(MakeSessionsResponse({"test-session-name"}))); - EXPECT_CALL(*mock, - AsyncDeleteSession(_, _, _, HasSessionName("test-session-name"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL(*mock, CreateSession(_, _, IsMultiplexed())) + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); auto conn = MakeConnectionImpl(db, mock); internal::OptionsSpan span(MakeLimitedTimeOptions()); @@ -4752,3 +4165,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/defaults.cc b/google/cloud/spanner/internal/defaults.cc index 863dc944c7e7f..fdfd785c366c8 100644 --- a/google/cloud/spanner/internal/defaults.cc +++ b/google/cloud/spanner/internal/defaults.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/defaults.h" #include "google/cloud/spanner/internal/session_pool.h" #include "google/cloud/spanner/options.h" @@ -72,6 +72,8 @@ Options DefaultOptions(Options opts) { } } + opts.set({}); + // Sets Spanner-specific session-pool options. auto& num_channels = opts.lookup(); num_channels = (std::max)(num_channels, 1); @@ -164,3 +166,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/defaults_test.cc b/google/cloud/spanner/internal/defaults_test.cc index f07d76d5d0a10..d3c2a498f65dd 100644 --- a/google/cloud/spanner/internal/defaults_test.cc +++ b/google/cloud/spanner/internal/defaults_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/defaults.h" #include "google/cloud/spanner/internal/session_pool.h" #include "google/cloud/spanner/options.h" @@ -304,3 +304,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/partial_result_set_resume_test.cc b/google/cloud/spanner/internal/partial_result_set_resume_test.cc index 844e9ceb14442..7fef58f76f520 100644 --- a/google/cloud/spanner/internal/partial_result_set_resume_test.cc +++ b/google/cloud/spanner/internal/partial_result_set_resume_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/partial_result_set_resume.h" #include "google/cloud/spanner/internal/partial_result_set_source.h" #include "google/cloud/spanner/mocks/row.h" @@ -610,3 +610,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/partial_result_set_source.cc b/google/cloud/spanner/internal/partial_result_set_source.cc index 937aa714df83d..bf763ff48082a 100644 --- a/google/cloud/spanner/internal/partial_result_set_source.cc +++ b/google/cloud/spanner/internal/partial_result_set_source.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/partial_result_set_source.h" #include "google/cloud/spanner/internal/merge_chunk.h" #include "google/cloud/spanner/options.h" @@ -299,3 +299,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/partial_result_set_source_test.cc b/google/cloud/spanner/internal/partial_result_set_source_test.cc index 1238436be66a9..bc3a408c41cff 100644 --- a/google/cloud/spanner/internal/partial_result_set_source_test.cc +++ b/google/cloud/spanner/internal/partial_result_set_source_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/partial_result_set_source.h" #include "google/cloud/spanner/mocks/row.h" #include "google/cloud/spanner/options.h" @@ -938,3 +938,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/route_to_leader.cc b/google/cloud/spanner/internal/route_to_leader.cc index f53a3615bd668..b404321fca9ec 100644 --- a/google/cloud/spanner/internal/route_to_leader.cc +++ b/google/cloud/spanner/internal/route_to_leader.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/route_to_leader.h" #include "google/cloud/spanner/options.h" #include "google/cloud/options.h" @@ -33,3 +33,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/route_to_leader_test.cc b/google/cloud/spanner/internal/route_to_leader_test.cc index df4bef1e6b1b9..58785f7136f56 100644 --- a/google/cloud/spanner/internal/route_to_leader_test.cc +++ b/google/cloud/spanner/internal/route_to_leader_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/route_to_leader.h" #include "google/cloud/spanner/options.h" #include "google/cloud/options.h" @@ -82,3 +82,4 @@ TEST_F(RouteToLeader, OptionFalse) { GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/session_pool.cc b/google/cloud/spanner/internal/session_pool.cc index e1a9d6f03342f..ca064dad712c0 100644 --- a/google/cloud/spanner/internal/session_pool.cc +++ b/google/cloud/spanner/internal/session_pool.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/session_pool.h" #include "google/cloud/spanner/internal/route_to_leader.h" #include "google/cloud/spanner/internal/session.h" @@ -734,3 +734,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/internal/session_pool_test.cc b/google/cloud/spanner/internal/session_pool_test.cc index 8f95b27a556e4..17b7cafdbf914 100644 --- a/google/cloud/spanner/internal/session_pool_test.cc +++ b/google/cloud/spanner/internal/session_pool_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/internal/session_pool.h" #include "google/cloud/spanner/internal/defaults.h" #include "google/cloud/spanner/internal/session.h" @@ -47,7 +47,6 @@ namespace { using ::google::cloud::testing_util::FakeCompletionQueueImpl; using ::google::cloud::testing_util::FakeSteadyClock; using ::google::cloud::testing_util::StatusIs; -using ::google::protobuf::TextFormat; using ::testing::_; using ::testing::AllOf; using ::testing::AnyOf; @@ -57,8 +56,6 @@ using ::testing::HasSubstr; using ::testing::Not; using ::testing::Pair; using ::testing::Return; -using ::testing::StrictMock; -using ::testing::UnorderedElementsAre; auto constexpr kRouteToLeader = "x-goog-spanner-route-to-leader"; @@ -125,20 +122,6 @@ google::spanner::v1::Session MakeMultiplexedSession(std::string name, return session; } -// Create a response with the given `sessions`. -google::spanner::v1::BatchCreateSessionsResponse MakeSessionsResponse( - std::vector sessions, std::string role = "") { - google::spanner::v1::BatchCreateSessionsResponse response; - for (auto& session : sessions) { - auto* s = response.add_session(); - s->set_name(std::move(session)); - *s->mutable_create_time() = Now(); - *s->mutable_approximate_last_use_time() = Now(); - if (!role.empty()) s->set_creator_role(role); - } - return response; -} - std::shared_ptr MakeTestSessionPool( spanner::Database db, std::vector> stubs, CompletionQueue cq, Options opts = {}) { @@ -162,9 +145,8 @@ TEST_F(SessionPoolTest, Multiplexed) { .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set({})); + auto pool = MakeTestSessionPool(db, {mock}, threads.cq(), {}); + // Options{}.set({})); auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); EXPECT_EQ((*session)->session_name(), "multiplexed"); @@ -184,11 +166,10 @@ TEST_F(SessionPoolTest, MultiplexedAllocateRouteToLeader) { }); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{} - .set(true) - .set({})); + auto pool = + MakeTestSessionPool(db, {mock}, threads.cq(), + Options{}.set(true)); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); EXPECT_EQ((*session)->session_name(), "multiplexed"); @@ -198,17 +179,16 @@ TEST_F(SessionPoolTest, MultiplexedAllocateRouteToLeader) { TEST_F(SessionPoolTest, AllocateRouteToLeader) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, - BatchCreateSessions( - _, _, AllOf(DatabaseIs(db.FullName()), SessionCountIs(42)))) + + EXPECT_CALL( + *mock, + CreateSession(_, _, AllOf(DatabaseIs(db.FullName()), IsMultiplexed()))) .WillOnce([this](grpc::ClientContext& context, Options const&, - google::spanner::v1::BatchCreateSessionsRequest const&) { + google::spanner::v1::CreateSessionRequest const&) { EXPECT_THAT(GetMetadata(context), Contains(Pair(kRouteToLeader, "true"))); - return MakeSessionsResponse({"session1"}); + return MakeMultiplexedSession("multiplexed"); }); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; auto pool = @@ -216,15 +196,16 @@ TEST_F(SessionPoolTest, AllocateRouteToLeader) { Options{} .set(true) .set(42)); - auto session = pool->Allocate(); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); + EXPECT_EQ((*session)->session_name(), "multiplexed"); EXPECT_EQ(pool->GetStub(**session), mock); } TEST_F(SessionPoolTest, MultiplexedAllocateNoRouteToLeader) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); + EXPECT_CALL( *mock, CreateSession(_, _, AllOf(DatabaseIs(db.FullName()), IsMultiplexed()))) @@ -237,11 +218,10 @@ TEST_F(SessionPoolTest, MultiplexedAllocateNoRouteToLeader) { }); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{} - .set(false) - .set({})); + auto pool = + MakeTestSessionPool(db, {mock}, threads.cq(), + Options{}.set(false)); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); EXPECT_EQ((*session)->session_name(), "multiplexed"); @@ -251,18 +231,17 @@ TEST_F(SessionPoolTest, MultiplexedAllocateNoRouteToLeader) { TEST_F(SessionPoolTest, AllocateNoRouteToLeader) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, - BatchCreateSessions( - _, _, AllOf(DatabaseIs(db.FullName()), SessionCountIs(42)))) + + EXPECT_CALL( + *mock, + CreateSession(_, _, AllOf(DatabaseIs(db.FullName()), IsMultiplexed()))) .WillOnce([this](grpc::ClientContext& context, Options const&, - google::spanner::v1::BatchCreateSessionsRequest const&) { + google::spanner::v1::CreateSessionRequest const&) { EXPECT_THAT(GetMetadata(context), AnyOf(Contains(Pair(kRouteToLeader, "false")), Not(Contains(Pair(kRouteToLeader, _))))); - return MakeSessionsResponse({"session1"}); + return MakeMultiplexedSession("multiplexed"); }); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; auto pool = @@ -270,50 +249,12 @@ TEST_F(SessionPoolTest, AllocateNoRouteToLeader) { Options{} .set(false) .set(42)); - auto session = pool->Allocate(); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); + EXPECT_EQ((*session)->session_name(), "multiplexed"); EXPECT_EQ(pool->GetStub(**session), mock); } -TEST_F(SessionPoolTest, ReleaseBadSession) { - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, - BatchCreateSessions( - _, _, AllOf(DatabaseIs(db.FullName()), SessionCountIs(1)))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session1"})))); - EXPECT_CALL(*mock, - BatchCreateSessions( - _, _, AllOf(DatabaseIs(db.FullName()), SessionCountIs(2)))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session2"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .Times(0); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set(1)); - { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); - } - { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); - (*session)->set_bad(); // Marking session1 as bad - } - { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session2"); // Got a new session - } -} - TEST_F(SessionPoolTest, MultiplexedCreateError) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); @@ -322,213 +263,34 @@ TEST_F(SessionPoolTest, MultiplexedCreateError) { Return(ByMove(Status(StatusCode::kInternal, "init failure")))); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set({})); + auto pool = MakeTestSessionPool(db, {mock}, threads.cq(), {}); + auto session = pool->Multiplexed(); EXPECT_THAT(session, StatusIs(StatusCode::kInternal, HasSubstr("init failure"))); } -TEST_F(SessionPoolTest, CreateError) { - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(Status(StatusCode::kInternal, "init failure")))) - .WillOnce(Return(ByMove(Status(StatusCode::kInternal, "some failure")))); - EXPECT_CALL(*mock, AsyncDeleteSession).Times(0); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool(db, {mock}, threads.cq()); - auto session = pool->Allocate(); - EXPECT_THAT(session, - StatusIs(StatusCode::kInternal, HasSubstr("some failure"))); -} - TEST_F(SessionPoolTest, ReuseSession) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session1"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); + EXPECT_CALL( + *mock, + CreateSession(_, _, AllOf(DatabaseIs(db.FullName()), IsMultiplexed()))) + .WillOnce([](grpc::ClientContext&, Options const&, + google::spanner::v1::CreateSessionRequest const&) { + return MakeMultiplexedSession("multiplexed"); + }); google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; auto pool = MakeTestSessionPool(db, {mock}, threads.cq()); - auto session = pool->Allocate(); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); + EXPECT_EQ((*session)->session_name(), "multiplexed"); session->reset(); - auto session2 = pool->Allocate(); - ASSERT_STATUS_OK(session2); - EXPECT_EQ((*session2)->session_name(), "session1"); -} - -TEST_F(SessionPoolTest, Lifo) { - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session2"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool(db, {mock}, threads.cq()); - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); - - auto session2 = pool->Allocate(); + auto session2 = pool->Multiplexed(); ASSERT_STATUS_OK(session2); - EXPECT_EQ((*session2)->session_name(), "session2"); - - session->reset(); - session2->reset(); - - // The pool is Last-In-First-Out (LIFO), so we expect to get the sessions - // back in the reverse order they were released. - auto session3 = pool->Allocate(); - ASSERT_STATUS_OK(session3); - EXPECT_EQ((*session3)->session_name(), "session2"); - - auto session4 = pool->Allocate(); - ASSERT_STATUS_OK(session4); - EXPECT_EQ((*session4)->session_name(), "session1"); -} - -TEST_F(SessionPoolTest, MinSessionsEagerAllocation) { - int const min_sessions = 3; - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions(_, _, SessionCountIs(min_sessions))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s3", "s2", "s1"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set(min_sessions)); - auto session = pool->Allocate(); -} - -TEST_F(SessionPoolTest, MinSessionsMultipleAllocations) { - int const min_sessions = 3; - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - // The constructor will make this call. - EXPECT_CALL(*mock, BatchCreateSessions(_, _, SessionCountIs(min_sessions))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s3", "s2", "s1"})))); - // When we run out of sessions it will make this call. - EXPECT_CALL(*mock, - BatchCreateSessions(_, _, SessionCountIs(min_sessions + 1))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s7", "s6", "s5", "s4"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s4"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s5"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s6"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s7"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set(min_sessions)); - std::vector sessions; - std::vector session_names; - for (int i = 1; i <= 7; ++i) { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - session_names.push_back((*session)->session_name()); - sessions.push_back(*std::move(session)); - } - EXPECT_THAT(session_names, - UnorderedElementsAre("s1", "s2", "s3", "s4", "s5", "s6", "s7")); -} - -TEST_F(SessionPoolTest, MaxSessionsFailOnExhaustion) { - int const max_sessions_per_channel = 3; - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s2"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s3"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{} - .set( - max_sessions_per_channel) - .set( - spanner::ActionOnExhaustion::kFail)); - std::vector sessions; - std::vector session_names; - for (int i = 1; i <= 3; ++i) { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - session_names.push_back((*session)->session_name()); - sessions.push_back(*std::move(session)); - } - EXPECT_THAT(session_names, UnorderedElementsAre("s1", "s2", "s3")); - auto session = pool->Allocate(); - EXPECT_THAT(session, StatusIs(StatusCode::kResourceExhausted, - "session pool exhausted")); -} - -TEST_F(SessionPoolTest, MaxSessionsBlockUntilRelease) { - int const max_sessions_per_channel = 1; - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s1"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{} - .set( - max_sessions_per_channel) - .set( - spanner::ActionOnExhaustion::kBlock)); - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "s1"); - - // This thread will block in Allocate() until the main thread releases s1. - std::thread t([&pool]() { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "s1"); - }); - - session->reset(); - t.join(); + EXPECT_EQ((*session2)->session_name(), "multiplexed"); } TEST_F(SessionPoolTest, MultiplexedLabels) { @@ -552,33 +314,13 @@ TEST_F(SessionPoolTest, MultiplexedLabels) { google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; auto pool = MakeTestSessionPool( db, {mock}, threads.cq(), - Options{} - .set(std::move(labels)) - .set({})); + Options{}.set(std::move(labels))); + // .set({})); auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); EXPECT_EQ((*session)->session_name(), "multiplexed"); } -TEST_F(SessionPoolTest, Labels) { - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - std::map labels = { - {"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; - EXPECT_CALL(*mock, BatchCreateSessions(_, _, LabelsAre(labels))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session1"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set(std::move(labels))); - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); -} - TEST_F(SessionPoolTest, MultiplexedCreatorRole) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); @@ -596,143 +338,13 @@ TEST_F(SessionPoolTest, MultiplexedCreatorRole) { google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; auto pool = MakeTestSessionPool( db, {mock}, threads.cq(), - Options{} - .set(role) - .set({})); + Options{}.set(role)); + auto session = pool->Multiplexed(); ASSERT_STATUS_OK(session); EXPECT_EQ((*session)->session_name(), "multiplexed"); } -TEST_F(SessionPoolTest, CreatorRole) { - auto mock = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - std::string const role = "public"; - EXPECT_CALL(*mock, - BatchCreateSessions( - _, _, AllOf(DatabaseIs(db.FullName()), CreatorRoleIs(role)))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"session1"}, role)))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("session1"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool( - db, {mock}, threads.cq(), - Options{}.set(role)); - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - EXPECT_EQ((*session)->session_name(), "session1"); -} - -TEST_F(SessionPoolTest, MultipleChannels) { - auto mock1 = std::make_shared(); - auto mock2 = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock1, CreateSession) - .WillRepeatedly( - Return(ByMove(Status(StatusCode::kInternal, "init failure")))); - EXPECT_CALL(*mock1, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c1s1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c1s2"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c1s3"})))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, CreateSession) - .WillRepeatedly( - Return(ByMove(Status(StatusCode::kInternal, "init failure")))); - EXPECT_CALL(*mock2, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c2s1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c2s2"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c2s3"})))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - auto pool = MakeTestSessionPool(db, {mock1, mock2}, threads.cq()); - std::vector sessions; - std::vector session_names; - for (int i = 1; i <= 6; ++i) { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - session_names.push_back((*session)->session_name()); - sessions.push_back(*std::move(session)); - } - EXPECT_THAT(session_names, UnorderedElementsAre("c1s1", "c1s2", "c1s3", - "c2s1", "c2s2", "c2s3")); -} - -TEST_F(SessionPoolTest, MultipleChannelsPreAllocation) { - auto mock1 = std::make_shared(); - auto mock2 = std::make_shared(); - auto mock3 = std::make_shared(); - auto db = spanner::Database("project", "instance", "database"); - EXPECT_CALL(*mock1, CreateSession) - .WillRepeatedly( - Return(ByMove(Status(StatusCode::kInternal, "init failure")))); - EXPECT_CALL(*mock1, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c1s1", "c1s2", "c1s3"})))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock1, AsyncDeleteSession(_, _, _, SessionNameIs("c1s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, CreateSession) - .WillRepeatedly( - Return(ByMove(Status(StatusCode::kInternal, "init failure")))); - EXPECT_CALL(*mock2, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c2s1", "c2s2", "c2s3"})))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock2, AsyncDeleteSession(_, _, _, SessionNameIs("c2s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock3, CreateSession) - .WillRepeatedly( - Return(ByMove(Status(StatusCode::kInternal, "init failure")))); - EXPECT_CALL(*mock3, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"c3s1", "c3s2", "c3s3"})))); - EXPECT_CALL(*mock3, AsyncDeleteSession(_, _, _, SessionNameIs("c3s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock3, AsyncDeleteSession(_, _, _, SessionNameIs("c3s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock3, AsyncDeleteSession(_, _, _, SessionNameIs("c3s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::cloud::internal::AutomaticallyCreatedBackgroundThreads threads; - // note that min_sessions will effectively be reduced to 9 - // (max_sessions_per_channel * num_channels). - auto pool = MakeTestSessionPool( - db, {mock1, mock2, mock3}, threads.cq(), - Options{} - .set(3) - .set( - spanner::ActionOnExhaustion::kFail)); - std::vector sessions; - std::vector session_names; - for (int i = 1; i <= 9; ++i) { - auto session = pool->Allocate(); - ASSERT_STATUS_OK(session); - session_names.push_back((*session)->session_name()); - sessions.push_back(*std::move(session)); - } - EXPECT_THAT(session_names, - UnorderedElementsAre("c1s1", "c1s2", "c1s3", "c2s1", "c2s2", - "c2s3", "c3s1", "c3s2", "c3s3")); - auto session = pool->Allocate(); - EXPECT_THAT(session, StatusIs(StatusCode::kResourceExhausted, - "session pool exhausted")); -} - TEST_F(SessionPoolTest, GetStubForStublessSession) { auto mock = std::make_shared(); auto db = spanner::Database("project", "instance", "database"); @@ -772,8 +384,7 @@ TEST_F(SessionPoolTest, MultilpexedSessionReplacementSuccess) { .set( background_interval) .set( - replacement_interval) - .set({})); + replacement_interval)); auto s1 = pool->Multiplexed(); ASSERT_STATUS_OK(s1); @@ -796,7 +407,7 @@ TEST_F(SessionPoolTest, MultilpexedSessionReplacementRpcPermanentFailure) { EXPECT_CALL( *mock, CreateSession(_, _, AllOf(DatabaseIs(db.FullName()), IsMultiplexed()))) - .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed1"})))); + .WillOnce(Return(ByMove(MakeMultiplexedSession({"multiplexed"})))); EXPECT_CALL(*mock, AsyncCreateSession(_, _, _, _)) .WillOnce(Return(make_ready_future(StatusOr( Status(StatusCode::kResourceExhausted, "retry policy exhausted"))))); @@ -814,172 +425,26 @@ TEST_F(SessionPoolTest, MultilpexedSessionReplacementRpcPermanentFailure) { .set( background_interval) .set( - replacement_interval) - .set({})); + replacement_interval)); auto s1 = pool->Multiplexed(); ASSERT_STATUS_OK(s1); - EXPECT_EQ((*s1)->session_name(), "multiplexed1"); + EXPECT_EQ((*s1)->session_name(), "multiplexed"); clock->AdvanceTime(background_interval); impl->SimulateCompletion(true); auto s2 = pool->Multiplexed(); ASSERT_STATUS_OK(s2); - EXPECT_EQ((*s2)->session_name(), "multiplexed1"); + EXPECT_EQ((*s2)->session_name(), "multiplexed"); // Cancel all pending operations, satisfying any remaining futures. impl->SimulateCompletion(false); } -TEST_F(SessionPoolTest, SessionRefresh) { - auto mock = std::make_shared>(); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s2"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s2"))) - .WillOnce(Return(make_ready_future(Status{}))); - - google::spanner::v1::ResultSet result; - auto constexpr kResultSetText = R"pb( - metadata: { - row_type: { fields: { type: { code: INT64 } } } - transaction: {} - } - rows: { values: { string_value: "1" } } - )pb"; - ASSERT_TRUE(TextFormat::ParseFromString(kResultSetText, &result)); - - EXPECT_CALL(*mock, AsyncExecuteSql) - .WillOnce( - [&result](CompletionQueue&, auto, auto, - google::spanner::v1::ExecuteSqlRequest const& request) { - EXPECT_EQ("s2", request.session()); - return make_ready_future(make_status_or(std::move(result))); - }); - - auto db = spanner::Database("project", "instance", "database"); - auto impl = std::make_shared(); - auto keep_alive_interval = std::chrono::seconds(1); - auto clock = std::make_shared(); - auto pool = MakeTestSessionPool( - db, {mock}, CompletionQueue(impl), - Options{} - .set(keep_alive_interval) - .set(clock)); - - // Allocate and release two session, "s1" and "s2". This will satisfy the - // BatchCreateSessions() expectations. - { - auto s1 = pool->Allocate(); - ASSERT_STATUS_OK(s1); - EXPECT_EQ("s1", (*s1)->session_name()); - { - auto s2 = pool->Allocate(); - ASSERT_STATUS_OK(s2); - EXPECT_EQ("s2", (*s2)->session_name()); - } - // Wait for "s2" to need refreshing before releasing "s1". - clock->AdvanceTime(keep_alive_interval * 2); - } - - // Simulate completion of pending operations, which will result in - // a call to RefreshExpiringSessions(). This should refresh "s2" and - // satisfy the AsyncExecuteSql() expectation. - impl->SimulateCompletion(true); - - // We should still be able to allocate sessions "s1" and "s2". - auto s1 = pool->Allocate(); - ASSERT_STATUS_OK(s1); - EXPECT_EQ("s1", (*s1)->session_name()); - auto s2 = pool->Allocate(); - ASSERT_STATUS_OK(s2); - EXPECT_EQ("s2", (*s2)->session_name()); - - // Cancel all pending operations, satisfying any remaining futures. When - // compiling with exceptions disabled the destructors eventually invoke - // `std::abort()`. On real programs, shutting down the completion queue - // will have the same effect. - impl->SimulateCompletion(false); -} - -TEST_F(SessionPoolTest, SessionRefreshNotFound) { - auto mock = std::make_shared>(); - EXPECT_CALL(*mock, BatchCreateSessions) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s1"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s2"})))) - .WillOnce(Return(ByMove(MakeSessionsResponse({"s3"})))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s1"))) - .WillOnce(Return(make_ready_future(Status{}))); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s2"))).Times(0); - EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, SessionNameIs("s3"))) - .WillOnce(Return(make_ready_future(Status{}))); - - EXPECT_CALL(*mock, AsyncExecuteSql) - .WillOnce([](CompletionQueue&, auto, auto, - google::spanner::v1::ExecuteSqlRequest const& request) { - EXPECT_EQ("s2", request.session()); - // The "SELECT 1" refresh returns "Session not found". - return make_ready_future(StatusOr( - spanner_testing::SessionNotFoundError(request.session()))); - }); - - auto db = spanner::Database("project", "instance", "database"); - auto impl = std::make_shared(); - auto keep_alive_interval = std::chrono::seconds(1); - auto clock = std::make_shared(); - auto pool = MakeTestSessionPool( - db, {mock}, CompletionQueue(impl), - Options{} - .set(keep_alive_interval) - .set(clock)); - - // Allocate and release two session, "s1" and "s2". This will satisfy the - // the first two BatchCreateSessions() expectations. - { - auto s1 = pool->Allocate(); - ASSERT_STATUS_OK(s1); - EXPECT_EQ("s1", (*s1)->session_name()); - { - auto s2 = pool->Allocate(); - ASSERT_STATUS_OK(s2); - EXPECT_EQ("s2", (*s2)->session_name()); - } - // Wait for "s2" to need refreshing before releasing "s1". - clock->AdvanceTime(keep_alive_interval * 2); - } - EXPECT_EQ(pool->total_sessions(), 2); - - // Simulate completion of pending operations, which will result in - // a call to RefreshExpiringSessions(). This should refresh "s2" and - // satisfy the AsyncExecuteSql() expectation, which fails the call. - impl->SimulateCompletion(true); - EXPECT_EQ(pool->total_sessions(), 1); - - // We should still be able to allocate session "s1". - auto s1 = pool->Allocate(); - ASSERT_STATUS_OK(s1); - EXPECT_EQ("s1", (*s1)->session_name()); - EXPECT_EQ(pool->total_sessions(), 1); - - // However "s2" will be gone now, so a new allocation will produce - // "s3", satisfying the final BatchCreateSessions() expectation. - auto s3 = pool->Allocate(); - ASSERT_STATUS_OK(s3); - EXPECT_EQ("s3", (*s3)->session_name()); - EXPECT_EQ(pool->total_sessions(), 2); - - // Cancel all pending operations, satisfying any remaining futures. When - // compiling with exceptions disabled the destructors eventually invoke - // `std::abort()`. In non-test programs, the completion queue does this - // automatically as part of its shutdown. - impl->SimulateCompletion(false); -} - } // namespace GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/options.h b/google/cloud/spanner/options.h index 8111acfc5df15..377053724f9f4 100644 --- a/google/cloud/spanner/options.h +++ b/google/cloud/spanner/options.h @@ -75,8 +75,10 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN * more information. * * @ingroup google-cloud-spanner-options + * */ -struct EnableMultiplexedSessionOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Multiplex Sessions are always enabled") + EnableMultiplexedSessionOption { using Type = absl::monostate; }; @@ -155,7 +157,8 @@ struct SessionCreatorRoleOption { * * @ingroup google-cloud-spanner-options */ -struct SessionPoolMinSessionsOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Option not used with Multiplex Sessions") + SessionPoolMinSessionsOption { using Type = int; }; @@ -167,7 +170,8 @@ struct SessionPoolMinSessionsOption { * * @ingroup google-cloud-spanner-options */ -struct SessionPoolMaxSessionsPerChannelOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Option not used with Multiplex Sessions") + SessionPoolMaxSessionsPerChannelOption { using Type = int; }; @@ -179,12 +183,14 @@ struct SessionPoolMaxSessionsPerChannelOption { * * @ingroup google-cloud-spanner-options */ -struct SessionPoolMaxIdleSessionsOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Option not used with Multiplex Sessions") + SessionPoolMaxIdleSessionsOption { using Type = int; }; /// Action to take when the session pool is exhausted. -enum class ActionOnExhaustion { +enum class GOOGLE_CLOUD_CPP_DEPRECATED( + "Option not used with Multiplex Sessions") ActionOnExhaustion { /// Wait until a session is returned to the pool. kBlock, /// Fail the operation immediately. @@ -197,7 +203,8 @@ enum class ActionOnExhaustion { * * @ingroup google-cloud-spanner-options */ -struct SessionPoolActionOnExhaustionOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Option not used with Multiplex Sessions") + SessionPoolActionOnExhaustionOption { using Type = spanner::ActionOnExhaustion; }; @@ -231,7 +238,8 @@ struct LockHintOption { * * @ingroup google-cloud-spanner-options */ -struct SessionPoolKeepAliveIntervalOption { +struct GOOGLE_CLOUD_CPP_DEPRECATED("Option not used with Multiplex Sessions") + SessionPoolKeepAliveIntervalOption { using Type = std::chrono::seconds; }; @@ -252,11 +260,9 @@ struct SessionPoolLabelsOption { /** * List of all SessionPool options. Pass to `spanner::MakeConnection()`. */ -using SessionPoolOptionList = OptionList< - RouteToLeaderOption, SessionCreatorRoleOption, SessionPoolMinSessionsOption, - SessionPoolMaxSessionsPerChannelOption, SessionPoolMaxIdleSessionsOption, - SessionPoolActionOnExhaustionOption, SessionPoolKeepAliveIntervalOption, - SessionPoolLabelsOption, EnableMultiplexedSessionOption>; +using SessionPoolOptionList = + OptionList; /** * Option for `google::cloud::Options` to set the optimizer version used in an diff --git a/google/cloud/spanner/partition_options.cc b/google/cloud/spanner/partition_options.cc index b96c3f0ad648c..3e8195c51e699 100644 --- a/google/cloud/spanner/partition_options.cc +++ b/google/cloud/spanner/partition_options.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/partition_options.h" #include "google/cloud/spanner/options.h" @@ -72,3 +72,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/query_options.cc b/google/cloud/spanner/query_options.cc index ce682dabfea1a..2d04751078508 100644 --- a/google/cloud/spanner/query_options.cc +++ b/google/cloud/spanner/query_options.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/query_options.h" #include "google/cloud/spanner/options.h" @@ -54,3 +54,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/query_options_test.cc b/google/cloud/spanner/query_options_test.cc index d5389a76220b0..3a60d897656d6 100644 --- a/google/cloud/spanner/query_options_test.cc +++ b/google/cloud/spanner/query_options_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/query_options.h" #include "google/cloud/spanner/options.h" #include "google/cloud/spanner/version.h" @@ -132,3 +133,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/query_partition.cc b/google/cloud/spanner/query_partition.cc index 112b4ae7fa38b..289ba4c2fd0f0 100644 --- a/google/cloud/spanner/query_partition.cc +++ b/google/cloud/spanner/query_partition.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/query_partition.h" #include "google/cloud/internal/make_status.h" #include "google/spanner/v1/spanner.pb.h" @@ -133,3 +133,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/query_partition_test.cc b/google/cloud/spanner/query_partition_test.cc index 3e6cc8a87936b..cd34b2deda4a2 100644 --- a/google/cloud/spanner/query_partition_test.cc +++ b/google/cloud/spanner/query_partition_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/query_partition.h" #include "google/cloud/spanner/connection.h" #include "google/cloud/spanner/testing/matchers.h" @@ -176,3 +176,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/quickstart/quickstart.cc b/google/cloud/spanner/quickstart/quickstart.cc index 20637df503486..e4b6a644a4924 100644 --- a/google/cloud/spanner/quickstart/quickstart.cc +++ b/google/cloud/spanner/quickstart/quickstart.cc @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +#include "google/cloud/internal/disable_deprecation_warnings.inc" //! [all] #include "google/cloud/spanner/client.h" @@ -41,3 +42,4 @@ int main(int argc, char* argv[]) { return 0; } //! [all] +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/read_options.cc b/google/cloud/spanner/read_options.cc index 82ce337c63f4b..75cb195f4959e 100644 --- a/google/cloud/spanner/read_options.cc +++ b/google/cloud/spanner/read_options.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/read_options.h" #include "google/cloud/spanner/options.h" @@ -58,3 +58,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/read_partition.cc b/google/cloud/spanner/read_partition.cc index 594a6e3238682..dab03a30d97f6 100644 --- a/google/cloud/spanner/read_partition.cc +++ b/google/cloud/spanner/read_partition.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/read_partition.h" #include "google/cloud/internal/make_status.h" #include "google/spanner/v1/spanner.pb.h" @@ -148,3 +148,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/read_partition_test.cc b/google/cloud/spanner/read_partition_test.cc index 14866aa7e5f9f..0e5481ae944b9 100644 --- a/google/cloud/spanner/read_partition_test.cc +++ b/google/cloud/spanner/read_partition_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/read_partition.h" #include "google/cloud/spanner/testing/matchers.h" #include "google/cloud/testing_util/is_proto_equal.h" @@ -234,3 +234,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/results_test.cc b/google/cloud/spanner/results_test.cc index f182c799f9e74..a9d53bcb68c29 100644 --- a/google/cloud/spanner/results_test.cc +++ b/google/cloud/spanner/results_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/results.h" #include "google/cloud/spanner/mocks/mock_spanner_connection.h" #include "google/cloud/spanner/mocks/row.h" @@ -261,3 +261,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/samples/client_samples.cc b/google/cloud/spanner/samples/client_samples.cc index d38b404221777..468bd1096fd32 100644 --- a/google/cloud/spanner/samples/client_samples.cc +++ b/google/cloud/spanner/samples/client_samples.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/admin/instance_admin_client.h" #include "google/cloud/spanner/client.h" @@ -140,3 +140,4 @@ int main(int argc, char* argv[]) { // NOLINT(bugprone-exception-escape) }); return example.Run(argc, argv); } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/samples/graph_samples.cc b/google/cloud/spanner/samples/graph_samples.cc index 0388843a952a8..547751b31df14 100644 --- a/google/cloud/spanner/samples/graph_samples.cc +++ b/google/cloud/spanner/samples/graph_samples.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/admin/database_admin_options.h" #include "google/cloud/spanner/client.h" @@ -607,3 +607,4 @@ int main(int ac, char* av[]) try { std::cerr << ex.what() << "\n"; return 1; } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/samples/mock_execute_query.cc b/google/cloud/spanner/samples/mock_execute_query.cc index 3927168aaa68a..0086a05858645 100644 --- a/google/cloud/spanner/samples/mock_execute_query.cc +++ b/google/cloud/spanner/samples/mock_execute_query.cc @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +#include "google/cloud/internal/disable_deprecation_warnings.inc" //! [all] @@ -108,3 +109,4 @@ TEST(MockSpannerClient, SuccessfulExecuteQuery) { } // namespace //! [all] +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/samples/postgresql_samples.cc b/google/cloud/spanner/samples/postgresql_samples.cc index 6f8e8f83bcf8a..073fcbe11a9e7 100644 --- a/google/cloud/spanner/samples/postgresql_samples.cc +++ b/google/cloud/spanner/samples/postgresql_samples.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/admin/database_admin_client.h" #include "google/cloud/spanner/bytes.h" #include "google/cloud/spanner/client.h" @@ -1321,3 +1321,4 @@ int main(int ac, char* av[]) try { std::cerr << "\n" << ex.what() << "\n"; return 1; } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/samples/samples.cc b/google/cloud/spanner/samples/samples.cc index 61277749062b4..f543d663b4fdd 100644 --- a/google/cloud/spanner/samples/samples.cc +++ b/google/cloud/spanner/samples/samples.cc @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +#include "google/cloud/internal/disable_deprecation_warnings.inc" //! [START spanner_quickstart] #include "google/cloud/spanner/client.h" @@ -6202,3 +6203,4 @@ int main(int ac, char* av[]) try { std::cerr << ex.what() << "\n"; return 1; } +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/session_pool_options_test.cc b/google/cloud/spanner/session_pool_options_test.cc index 2fc944f4237ff..3ed25147a965f 100644 --- a/google/cloud/spanner/session_pool_options_test.cc +++ b/google/cloud/spanner/session_pool_options_test.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/session_pool_options.h" #include "google/cloud/spanner/version.h" #include @@ -82,3 +82,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc" diff --git a/google/cloud/spanner/transaction.cc b/google/cloud/spanner/transaction.cc index c4284201916a3..393f02906b32b 100644 --- a/google/cloud/spanner/transaction.cc +++ b/google/cloud/spanner/transaction.cc @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#include "google/cloud/internal/disable_deprecation_warnings.inc" #include "google/cloud/spanner/transaction.h" #include "google/cloud/spanner/internal/session.h" #include "google/cloud/spanner/internal/transaction_impl.h" @@ -191,3 +191,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace spanner_internal } // namespace cloud } // namespace google +#include "google/cloud/internal/diagnostics_pop.inc"