|
15 | 15 | #include "google/cloud/bigtable/internal/async_row_reader.h" |
16 | 16 | #include "google/cloud/bigtable/row_reader.h" |
17 | 17 | #include "google/cloud/bigtable/testing/mock_bigtable_stub.h" |
| 18 | +#include "google/cloud/internal/async_streaming_read_rpc_impl.h" |
| 19 | +#include "google/cloud/internal/background_threads_impl.h" |
| 20 | +#include "google/cloud/internal/opentelemetry.h" |
18 | 21 | #include "google/cloud/testing_util/mock_backoff_policy.h" |
19 | 22 | #include "google/cloud/testing_util/mock_completion_queue_impl.h" |
| 23 | +#include "google/cloud/testing_util/opentelemetry_matchers.h" |
20 | 24 | #include "google/cloud/testing_util/status_matchers.h" |
21 | 25 | #include "absl/strings/str_format.h" |
22 | 26 | #include <gmock/gmock.h> |
@@ -1115,6 +1119,80 @@ TEST(AsyncRowReaderTest, CurrentOptionsContinuedOnRetries) { |
1115 | 1119 | timer_promise.set_value(make_status_or(std::chrono::system_clock::now())); |
1116 | 1120 | } |
1117 | 1121 |
|
| 1122 | +#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY |
| 1123 | +using ::google::cloud::testing_util::EnableTracing; |
| 1124 | +using ::google::cloud::testing_util::IsActive; |
| 1125 | +using ::google::cloud::testing_util::SpanNamed; |
| 1126 | +using ::testing::AllOf; |
| 1127 | +using ::testing::Each; |
| 1128 | +using ::testing::SizeIs; |
| 1129 | +using ErrorStream = internal::AsyncStreamingReadRpcError<v2::ReadRowsResponse>; |
| 1130 | + |
| 1131 | +TEST(AsyncRowReaderTest, TracedBackoff) { |
| 1132 | + auto span_catcher = testing_util::InstallSpanCatcher(); |
| 1133 | + |
| 1134 | + auto mock = std::make_shared<MockBigtableStub>(); |
| 1135 | + EXPECT_CALL(*mock, AsyncReadRows).Times(kNumRetries + 1).WillRepeatedly([] { |
| 1136 | + return std::make_unique<ErrorStream>(TransientError()); |
| 1137 | + }); |
| 1138 | + |
| 1139 | + promise<void> p; |
| 1140 | + internal::AutomaticallyCreatedBackgroundThreads background; |
| 1141 | + auto on_row = [](bigtable::Row const&) { return make_ready_future(true); }; |
| 1142 | + auto on_finish = [&p](Status const&) { p.set_value(); }; |
| 1143 | + |
| 1144 | + auto retry = DataLimitedErrorCountRetryPolicy(kNumRetries).clone(); |
| 1145 | + auto mock_b = std::make_unique<MockBackoffPolicy>(); |
| 1146 | + EXPECT_CALL(*mock_b, OnCompletion).Times(kNumRetries); |
| 1147 | + |
| 1148 | + internal::OptionsSpan o(EnableTracing(Options{})); |
| 1149 | + AsyncRowReader::Create(background.cq(), mock, kAppProfile, kTableName, |
| 1150 | + std::move(on_row), std::move(on_finish), |
| 1151 | + bigtable::RowSet(), bigtable::RowReader::NO_ROWS_LIMIT, |
| 1152 | + bigtable::Filter::PassAllFilter(), std::move(retry), |
| 1153 | + std::move(mock_b)); |
| 1154 | + |
| 1155 | + // Block until the async call has completed. |
| 1156 | + p.get_future().get(); |
| 1157 | + |
| 1158 | + EXPECT_THAT(span_catcher->GetSpans(), |
| 1159 | + AllOf(SizeIs(kNumRetries), Each(SpanNamed("Async Backoff")))); |
| 1160 | +} |
| 1161 | + |
| 1162 | +TEST(AsyncRowReaderTest, CallSpanActiveThroughout) { |
| 1163 | + auto span_catcher = testing_util::InstallSpanCatcher(); |
| 1164 | + |
| 1165 | + auto span = internal::MakeSpan("span"); |
| 1166 | + |
| 1167 | + auto mock = std::make_shared<MockBigtableStub>(); |
| 1168 | + EXPECT_CALL(*mock, AsyncReadRows) |
| 1169 | + .Times(kNumRetries + 1) |
| 1170 | + .WillRepeatedly([span] { |
| 1171 | + EXPECT_THAT(span, IsActive()); |
| 1172 | + return std::make_unique<ErrorStream>(TransientError()); |
| 1173 | + }); |
| 1174 | + |
| 1175 | + promise<void> p; |
| 1176 | + internal::AutomaticallyCreatedBackgroundThreads background; |
| 1177 | + auto on_row = [](bigtable::Row const&) { return make_ready_future(true); }; |
| 1178 | + auto on_finish = [&p](Status const&) { p.set_value(); }; |
| 1179 | + auto retry = DataLimitedErrorCountRetryPolicy(kNumRetries).clone(); |
| 1180 | + auto mock_b = std::make_unique<MockBackoffPolicy>(); |
| 1181 | + EXPECT_CALL(*mock_b, OnCompletion).Times(kNumRetries); |
| 1182 | + |
| 1183 | + auto scope = opentelemetry::trace::Scope(span); |
| 1184 | + internal::OptionsSpan o(EnableTracing(Options{})); |
| 1185 | + AsyncRowReader::Create(background.cq(), mock, kAppProfile, kTableName, |
| 1186 | + std::move(on_row), std::move(on_finish), |
| 1187 | + bigtable::RowSet(), bigtable::RowReader::NO_ROWS_LIMIT, |
| 1188 | + bigtable::Filter::PassAllFilter(), std::move(retry), |
| 1189 | + std::move(mock_b)); |
| 1190 | + |
| 1191 | + // Block until the async call has completed. |
| 1192 | + p.get_future().get(); |
| 1193 | +} |
| 1194 | +#endif // GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY |
| 1195 | + |
1118 | 1196 | } // namespace |
1119 | 1197 | GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END |
1120 | 1198 | } // namespace bigtable_internal |
|
0 commit comments