The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) https://grpc.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
6.2 KiB

//
//
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// 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 "test/cpp/ext/otel/otel_test_library.h"
#include "absl/functional/any_invocable.h"
#include "api/include/opentelemetry/metrics/provider.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "opentelemetry/sdk/metrics/export/metric_producer.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
#include <grpcpp/grpcpp.h>
#include "src/core/lib/channel/call_tracer.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/notification.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/byte_buffer_proto_helper.h"
namespace grpc {
namespace testing {
void OpenTelemetryPluginEnd2EndTest::Init(
const absl::flat_hash_set<absl::string_view>& metric_names,
opentelemetry::sdk::resource::Resource resource,
std::unique_ptr<grpc::internal::LabelsInjector> labels_injector,
bool test_no_meter_provider,
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
target_selector,
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
target_attribute_filter,
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
generic_method_attribute_filter) {
// We are resetting the MeterProvider and OpenTelemetry plugin at the start
// of each test to avoid test results from one test carrying over to another
// test. (Some measurements can get arbitrarily delayed.)
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>(
std::make_unique<opentelemetry::sdk::metrics::ViewRegistry>(),
std::move(resource));
reader_.reset(new grpc::testing::MockMetricReader);
meter_provider->AddMetricReader(reader_);
grpc_core::CoreConfiguration::Reset();
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
ot_builder.DisableAllMetrics();
for (const auto& metric_name : metric_names) {
ot_builder.EnableMetric(metric_name);
}
if (!test_no_meter_provider) {
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
reader_.reset(new grpc::testing::MockMetricReader);
meter_provider->AddMetricReader(reader_);
ot_builder.SetMeterProvider(std::move(meter_provider));
}
ot_builder.SetLabelsInjector(std::move(labels_injector));
ot_builder.SetTargetSelector(std::move(target_selector));
ot_builder.SetTargetAttributeFilter(std::move(target_attribute_filter));
ot_builder.SetGenericMethodAttributeFilter(
std::move(generic_method_attribute_filter));
ot_builder.BuildAndRegisterGlobal();
grpc_init();
grpc::ServerBuilder builder;
int port;
// Use IPv4 here because it's less flaky than IPv6 ("[::]:0") on Travis.
builder.AddListeningPort("0.0.0.0:0", grpc::InsecureServerCredentials(),
&port);
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
ASSERT_NE(nullptr, server_);
ASSERT_NE(0, port);
server_address_ = absl::StrCat("localhost:", port);
canonical_server_address_ = absl::StrCat("dns:///", server_address_);
auto channel =
grpc::CreateChannel(server_address_, grpc::InsecureChannelCredentials());
stub_ = EchoTestService::NewStub(channel);
generic_stub_ = std::make_unique<GenericStub>(std::move(channel));
}
void OpenTelemetryPluginEnd2EndTest::TearDown() {
server_->Shutdown();
grpc_shutdown_blocking();
delete grpc_core::ServerCallTracerFactory::Get(grpc_core::ChannelArgs());
grpc_core::ServerCallTracerFactory::RegisterGlobal(nullptr);
}
void OpenTelemetryPluginEnd2EndTest::ResetStub(
std::shared_ptr<Channel> channel) {
stub_ = EchoTestService::NewStub(channel);
generic_stub_ = std::make_unique<GenericStub>(std::move(channel));
}
void OpenTelemetryPluginEnd2EndTest::SendRPC() {
EchoRequest request;
request.set_message("foo");
EchoResponse response;
grpc::ClientContext context;
grpc::Status status = stub_->Echo(&context, request, &response);
}
void OpenTelemetryPluginEnd2EndTest::SendGenericRPC() {
grpc::ClientContext context;
EchoRequest request;
std::unique_ptr<ByteBuffer> send_buf = SerializeToByteBuffer(&request);
ByteBuffer recv_buf;
grpc_core::Notification notify;
generic_stub_->UnaryCall(&context, absl::StrCat("/", kGenericMethodName),
StubOptions(), send_buf.get(), &recv_buf,
[&](grpc::Status /*s*/) { notify.Notify(); });
notify.WaitForNotificationWithTimeout(absl::Seconds(5));
}
absl::flat_hash_map<
std::string, std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
OpenTelemetryPluginEnd2EndTest::ReadCurrentMetricsData(
absl::AnyInvocable<
bool(const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&)>
continue_predicate) {
absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
data;
auto deadline = absl::Now() + absl::Seconds(5);
do {
reader_->Collect([&](opentelemetry::sdk::metrics::ResourceMetrics& rm) {
for (const opentelemetry::sdk::metrics::ScopeMetrics& smd :
rm.scope_metric_data_) {
for (const opentelemetry::sdk::metrics::MetricData& md :
smd.metric_data_) {
for (const opentelemetry::sdk::metrics::PointDataAttributes& dp :
md.point_data_attr_) {
data[md.instrument_descriptor.name_].push_back(dp);
}
}
}
return true;
});
} while (continue_predicate(data) && deadline > absl::Now());
return data;
}
} // namespace testing
} // namespace grpc