Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
#include "google/cloud/storage/async/reader_connection.h"
#include "google/cloud/storage/internal/async/reader_connection_tracing.h"
#include "google/cloud/internal/opentelemetry.h"
#include "google/cloud/version.h"
#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
Expand Down Expand Up @@ -58,7 +59,7 @@ class AsyncObjectDescriptorConnectionTracing
{{sc::kThreadId, internal::CurrentThreadId()},
{"read-start", p.start},
{"read-length", p.length}});
return result;
return MakeTracingReaderConnection(span_, std::move(result));
}

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,41 @@ namespace {
using ReadResponse =
::google::cloud::storage_experimental::AsyncReaderConnection::ReadResponse;
using ::google::cloud::storage_experimental::ObjectDescriptorConnection;
using ::google::cloud::storage_experimental::ReadPayload;
using ::google::cloud::storage_mocks::MockAsyncObjectDescriptorConnection;
using ::google::cloud::storage_mocks::MockAsyncReaderConnection;
using ::google::cloud::testing_util::EventNamed;
using ::google::cloud::testing_util::InstallSpanCatcher;
using ::google::cloud::testing_util::OTelAttribute;
using ::google::cloud::testing_util::OTelContextCaptured;
using ::google::cloud::testing_util::PromiseWithOTelContext;
using ::google::cloud::testing_util::SpanEventAttributesAre;
using ::google::cloud::testing_util::SpanHasInstrumentationScope;
using ::google::cloud::testing_util::SpanKindIsClient;
using ::google::cloud::testing_util::SpanNamed;
using ::google::cloud::testing_util::SpanWithStatus;
using ::google::cloud::testing_util::ThereIsAnActiveSpan;
using ::testing::_;

// A helper to set expectations on a mock async reader. It captures the OTel
// context and returns a future that can be controlled by the test.
auto expect_context = [](auto& p) {
return [&p] {
EXPECT_TRUE(ThereIsAnActiveSpan());
EXPECT_TRUE(OTelContextCaptured());
return p.get_future();
};
};

// A helper to be used in a `.then()` clause. It verifies the OTel context
// has been detached before the user receives the result.
auto expect_no_context = [](auto f) {
auto t = f.get();
EXPECT_FALSE(ThereIsAnActiveSpan());
EXPECT_FALSE(OTelContextCaptured());
return t;
};

TEST(ObjectDescriptorConnectionTracing, Read) {
namespace sc = ::opentelemetry::trace::SemanticConventions;
auto span_catcher = InstallSpanCatcher();
Expand Down Expand Up @@ -76,6 +99,55 @@ TEST(ObjectDescriptorConnectionTracing, Read) {
OTelAttribute<std::string>(sc::kThreadId, _)))))));
}

TEST(ObjectDescriptorConnectionTracing, ReadThenRead) {
namespace sc = ::opentelemetry::trace::SemanticConventions;
auto span_catcher = InstallSpanCatcher();

auto mock_connection =
std::make_shared<MockAsyncObjectDescriptorConnection>();
auto* mock_reader_ptr = new MockAsyncReaderConnection;
PromiseWithOTelContext<ReadResponse> p;
EXPECT_CALL(*mock_reader_ptr, Read).WillOnce(expect_context(p));

EXPECT_CALL(*mock_connection, Read)
.WillOnce([&](ObjectDescriptorConnection::ReadParams) {
return std::unique_ptr<storage_experimental::AsyncReaderConnection>(
mock_reader_ptr);
});

auto connection = MakeTracingObjectDescriptorConnection(
internal::MakeSpan("test-span"), std::move(mock_connection));

auto reader = connection->Read({});
auto f = reader->Read().then(expect_no_context);
p.set_value(ReadPayload("test-payload").set_offset(123));
(void)f.get();

connection.reset(); // End the span

auto spans = span_catcher->GetSpans();
EXPECT_THAT(
spans, ElementsAre(AllOf(
SpanNamed("test-span"),
SpanWithStatus(opentelemetry::trace::StatusCode::kOk),
SpanHasInstrumentationScope(), SpanKindIsClient(),
SpanEventsAre(
AllOf(EventNamed("gl-cpp.open.read"),
SpanEventAttributesAre(
OTelAttribute<std::int64_t>("read-length", 0),
OTelAttribute<std::int64_t>("read-start", 0),
OTelAttribute<std::string>(sc::kThreadId, _))),
AllOf(EventNamed("gl-cpp.read"),
SpanEventAttributesAre(
OTelAttribute<std::int64_t>(
"message.starting_offset", 123),
OTelAttribute<std::string>(sc::kThreadId, _),
OTelAttribute<std::int64_t>("rpc.message.id", 1),
// THIS WAS THE MISSING ATTRIBUTE:
OTelAttribute<std::string>("rpc.message.type",
"RECEIVED")))))));
}

} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace storage_internal
Expand Down
Loading