3030#include " google/cloud/credentials.h"
3131#include " google/cloud/grpc_options.h"
3232#include " google/cloud/internal/async_streaming_read_rpc_impl.h"
33+ #include " google/cloud/internal/time_utils.h"
34+ #include " google/cloud/testing_util/fake_completion_queue_impl.h"
3335#include " google/cloud/testing_util/mock_backoff_policy.h"
3436#include " google/cloud/testing_util/status_matchers.h"
3537#include " google/cloud/testing_util/validate_metadata.h"
@@ -58,6 +60,7 @@ using ::google::cloud::bigtable::testing::MockMutateRowsLimiter;
5860using ::google::cloud::bigtable::testing::MockMutateRowsStream;
5961using ::google::cloud::bigtable::testing::MockReadRowsStream;
6062using ::google::cloud::bigtable::testing::MockSampleRowKeysStream;
63+ using ::google::cloud::testing_util::FakeCompletionQueueImpl;
6164using ::google::cloud::testing_util::MockBackoffPolicy;
6265using ::google::cloud::testing_util::StatusIs;
6366using ::testing::An;
@@ -217,6 +220,17 @@ std::shared_ptr<DataConnectionImpl> TestConnection(
217220 std::move (background), std::move (stub), std::move (limiter), Options{});
218221}
219222
223+ std::shared_ptr<DataConnectionImpl> TestConnection (
224+ std::unique_ptr<BackgroundThreads> background,
225+ std::shared_ptr<BigtableStub> stub,
226+ std::unique_ptr<OperationContextFactory> operation_context_factory,
227+ std::shared_ptr<MutateRowsLimiter> limiter =
228+ std::make_shared<NoopMutateRowsLimiter>()) {
229+ return std::make_shared<DataConnectionImpl>(
230+ std::move (background), std::move (stub),
231+ std::move (operation_context_factory), std::move (limiter), Options{});
232+ }
233+
220234std::shared_ptr<DataConnectionImpl> TestConnection (
221235 std::shared_ptr<BigtableStub> stub,
222236 std::unique_ptr<OperationContextFactory> operation_context_factory,
@@ -266,6 +280,11 @@ TEST(TransformReadModifyWriteRowResponse, Basic) {
266280 MatchCell (c3), MatchCell (c4)));
267281}
268282
283+ class MockBackgroundThreads : public BackgroundThreads {
284+ public:
285+ MOCK_METHOD (CompletionQueue, cq, (), (const , override ));
286+ };
287+
269288#ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
270289
271290class MockMetric : public Metric {
@@ -2736,17 +2755,40 @@ TEST_F(DataConnectionTest, AsyncReadRowFailure) {
27362755}
27372756
27382757TEST_F (DataConnectionTest, ExecuteQuery) {
2739- auto conn = TestConnection (std::make_shared<MockBigtableStub>());
2758+ auto fake_cq_impl = std::make_shared<FakeCompletionQueueImpl>();
2759+ auto mock_bg = std::make_unique<MockBackgroundThreads>();
2760+ EXPECT_CALL (*mock_bg, cq).WillRepeatedly ([&]() {
2761+ return CompletionQueue{fake_cq_impl};
2762+ });
2763+
2764+ auto refresh_fn = []() {
2765+ return make_ready_future (
2766+ StatusOr<google::bigtable::v2::PrepareQueryResponse>(
2767+ Status{StatusCode::kUnimplemented , " not implemented" }));
2768+ };
2769+
2770+ v2::PrepareQueryResponse response;
2771+ *response.mutable_valid_until () = internal::ToProtoTimestamp (
2772+ std::chrono::system_clock::now () + std::chrono::seconds (3600 ));
2773+
2774+ auto query_plan =
2775+ QueryPlan::Create (CompletionQueue (fake_cq_impl), std::move (response),
2776+ std::move (refresh_fn));
2777+
2778+ auto mock_stub = std::make_shared<MockBigtableStub>();
2779+ auto conn = TestConnection (std::move (mock_stub));
27402780 internal::OptionsSpan span (CallOptions ());
27412781 bigtable::InstanceResource instance (Project (" test-project" ), " test-instance" );
27422782 bigtable::SqlStatement sql (" SELECT * FROM `test-table`" );
27432783 auto prepared_query =
2744- bigtable::PreparedQuery (CompletionQueue{}, instance, sql,
2745- google::bigtable::v2::PrepareQueryResponse{});
2784+ bigtable::PreparedQuery (instance, sql, std::move (query_plan));
27462785 auto bound_query = prepared_query.BindParameters ({});
27472786 EXPECT_THAT (
27482787 conn->ExecuteQuery (bigtable::ExecuteQueryParams{std::move (bound_query)}),
27492788 StatusIs (StatusCode::kUnimplemented ));
2789+
2790+ // Cancel all pending operations, satisfying any remaining futures.
2791+ fake_cq_impl->SimulateCompletion (false );
27502792}
27512793
27522794TEST_F (DataConnectionTest, PrepareQuerySuccess) {
@@ -2773,10 +2815,19 @@ TEST_F(DataConnectionTest, PrepareQuerySuccess) {
27732815 request.instance_name ());
27742816 EXPECT_EQ (" SELECT * FROM the-table" , request.query ());
27752817 v2::PrepareQueryResponse response;
2818+ *response.mutable_valid_until () = internal::ToProtoTimestamp (
2819+ std::chrono::system_clock::now () + std::chrono::seconds (3600 ));
27762820 return response;
27772821 });
27782822
2779- auto conn = TestConnection (std::move (mock), std::move (factory));
2823+ auto fake_cq_impl = std::make_shared<FakeCompletionQueueImpl>();
2824+ auto mock_bg = std::make_unique<MockBackgroundThreads>();
2825+ EXPECT_CALL (*mock_bg, cq).WillRepeatedly ([&]() {
2826+ return CompletionQueue{fake_cq_impl};
2827+ });
2828+
2829+ auto conn =
2830+ TestConnection (std::move (mock_bg), std::move (mock), std::move (factory));
27802831 internal::OptionsSpan span (CallOptions ());
27812832 auto params = bigtable::PrepareQueryParams{
27822833 bigtable::InstanceResource (google::cloud::Project (" the-project" ),
@@ -2786,6 +2837,9 @@ TEST_F(DataConnectionTest, PrepareQuerySuccess) {
27862837 ASSERT_STATUS_OK (prepared_query);
27872838 EXPECT_EQ (prepared_query->instance (), params.instance );
27882839 EXPECT_EQ (prepared_query->sql_statement (), params.sql_statement );
2840+
2841+ // Cancel all pending operations, satisfying any remaining futures.
2842+ fake_cq_impl->SimulateCompletion (false );
27892843}
27902844
27912845TEST_F (DataConnectionTest, PrepareQueryPermanentError) {
@@ -2844,7 +2898,14 @@ TEST_F(DataConnectionTest, AsyncPrepareQuerySuccess) {
28442898 return make_ready_future (make_status_or (v2::PrepareQueryResponse{}));
28452899 });
28462900
2847- auto conn = TestConnection (std::move (mock), std::move (factory));
2901+ auto fake_cq_impl = std::make_shared<FakeCompletionQueueImpl>();
2902+ auto mock_bg = std::make_unique<MockBackgroundThreads>();
2903+ EXPECT_CALL (*mock_bg, cq).WillRepeatedly ([&]() {
2904+ return CompletionQueue{fake_cq_impl};
2905+ });
2906+
2907+ auto conn =
2908+ TestConnection (std::move (mock_bg), std::move (mock), std::move (factory));
28482909 internal::OptionsSpan span (CallOptions ());
28492910 auto params = bigtable::PrepareQueryParams{
28502911 bigtable::InstanceResource (google::cloud::Project (" the-project" ),
@@ -2853,6 +2914,9 @@ TEST_F(DataConnectionTest, AsyncPrepareQuerySuccess) {
28532914 auto future = conn->AsyncPrepareQuery (params);
28542915 auto result = future.get ();
28552916 ASSERT_STATUS_OK (result);
2917+
2918+ // Cancel all pending operations, satisfying any remaining futures.
2919+ fake_cq_impl->SimulateCompletion (false );
28562920}
28572921
28582922TEST_F (DataConnectionTest, AsyncPrepareQueryPermanentError) {
0 commit comments