xref: /aosp_15_r20/external/grpc-grpc/test/core/util/fake_stats_plugin.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 The gRPC Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "test/core/util/fake_stats_plugin.h"
16 
17 #include "src/core/lib/config/core_configuration.h"
18 
19 namespace grpc_core {
20 
21 class FakeStatsClientFilter : public ChannelFilter {
22  public:
23   static const grpc_channel_filter kFilter;
24 
25   static absl::StatusOr<FakeStatsClientFilter> Create(
26       const ChannelArgs& /*args*/, ChannelFilter::Args /*filter_args*/);
27 
28   ArenaPromise<ServerMetadataHandle> MakeCallPromise(
29       CallArgs call_args, NextPromiseFactory next_promise_factory) override;
30 
31  private:
32   explicit FakeStatsClientFilter(
33       FakeClientCallTracerFactory* fake_client_call_tracer_factory);
34   FakeClientCallTracerFactory* const fake_client_call_tracer_factory_;
35 };
36 
37 const grpc_channel_filter FakeStatsClientFilter::kFilter =
38     MakePromiseBasedFilter<FakeStatsClientFilter, FilterEndpoint::kClient>(
39         "fake_stats_client");
40 
Create(const ChannelArgs & args,ChannelFilter::Args)41 absl::StatusOr<FakeStatsClientFilter> FakeStatsClientFilter::Create(
42     const ChannelArgs& args, ChannelFilter::Args /*filter_args*/) {
43   auto* fake_client_call_tracer_factory =
44       args.GetPointer<FakeClientCallTracerFactory>(
45           GRPC_ARG_INJECT_FAKE_CLIENT_CALL_TRACER_FACTORY);
46   GPR_ASSERT(fake_client_call_tracer_factory != nullptr);
47   return FakeStatsClientFilter(fake_client_call_tracer_factory);
48 }
49 
MakeCallPromise(CallArgs call_args,NextPromiseFactory next_promise_factory)50 ArenaPromise<ServerMetadataHandle> FakeStatsClientFilter::MakeCallPromise(
51     CallArgs call_args, NextPromiseFactory next_promise_factory) {
52   FakeClientCallTracer* client_call_tracer =
53       fake_client_call_tracer_factory_->CreateFakeClientCallTracer();
54   if (client_call_tracer != nullptr) {
55     auto* call_context = GetContext<grpc_call_context_element>();
56     call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value =
57         client_call_tracer;
58     call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].destroy =
59         nullptr;
60   }
61   return next_promise_factory(std::move(call_args));
62 }
63 
FakeStatsClientFilter(FakeClientCallTracerFactory * fake_client_call_tracer_factory)64 FakeStatsClientFilter::FakeStatsClientFilter(
65     FakeClientCallTracerFactory* fake_client_call_tracer_factory)
66     : fake_client_call_tracer_factory_(fake_client_call_tracer_factory) {}
67 
RegisterFakeStatsPlugin()68 void RegisterFakeStatsPlugin() {
69   CoreConfiguration::RegisterBuilder(
70       [](CoreConfiguration::Builder* builder) mutable {
71         builder->channel_init()
72             ->RegisterFilter(GRPC_CLIENT_CHANNEL,
73                              &FakeStatsClientFilter::kFilter)
74             .If([](const ChannelArgs& args) {
75               return args.GetPointer<FakeClientCallTracerFactory>(
76                          GRPC_ARG_INJECT_FAKE_CLIENT_CALL_TRACER_FACTORY) !=
77                      nullptr;
78             });
79       });
80 }
81 
82 namespace {
83 
AddKeyValuePairs(absl::Span<const absl::string_view> keys,absl::Span<const absl::string_view> values,std::vector<std::string> * key_value_pairs)84 void AddKeyValuePairs(absl::Span<const absl::string_view> keys,
85                       absl::Span<const absl::string_view> values,
86                       std::vector<std::string>* key_value_pairs) {
87   GPR_ASSERT(keys.size() == values.size());
88   for (size_t i = 0; i < keys.size(); ++i) {
89     key_value_pairs->push_back(absl::StrCat(keys[i], "=", values[i]));
90   }
91 }
92 
93 }  // namespace
94 
MakeLabelString(absl::Span<const absl::string_view> label_keys,absl::Span<const absl::string_view> label_values,absl::Span<const absl::string_view> optional_label_keys,absl::Span<const absl::string_view> optional_values)95 std::string MakeLabelString(
96     absl::Span<const absl::string_view> label_keys,
97     absl::Span<const absl::string_view> label_values,
98     absl::Span<const absl::string_view> optional_label_keys,
99     absl::Span<const absl::string_view> optional_values) {
100   std::vector<std::string> key_value_pairs;
101   AddKeyValuePairs(label_keys, label_values, &key_value_pairs);
102   AddKeyValuePairs(optional_label_keys, optional_values, &key_value_pairs);
103   return absl::StrJoin(key_value_pairs, ",");
104 }
105 
MakeStatsPluginForTarget(absl::string_view target_suffix)106 std::shared_ptr<FakeStatsPlugin> MakeStatsPluginForTarget(
107     absl::string_view target_suffix) {
108   return FakeStatsPluginBuilder()
109       .SetChannelFilter(
110           [target_suffix](const experimental::StatsPluginChannelScope& scope) {
111             return absl::EndsWith(scope.target(), target_suffix);
112           })
113       .BuildAndRegister();
114 }
115 
ResetGlobalInstrumentsRegistry()116 void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() {
117   auto& instruments = GlobalInstrumentsRegistry::GetInstrumentList();
118   instruments.clear();
119 }
120 
121 namespace {
122 
123 template <typename HandleType>
FindInstrument(const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor> & instruments,absl::string_view name,GlobalInstrumentsRegistry::ValueType value_type,GlobalInstrumentsRegistry::InstrumentType instrument_type)124 absl::optional<HandleType> FindInstrument(
125     const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
126         instruments,
127     absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type,
128     GlobalInstrumentsRegistry::InstrumentType instrument_type) {
129   for (const auto& descriptor : instruments) {
130     if (descriptor.name == name && descriptor.value_type == value_type &&
131         descriptor.instrument_type == instrument_type) {
132       HandleType handle;
133       handle.index = descriptor.index;
134       return handle;
135     }
136   }
137   return absl::nullopt;
138 }
139 
140 }  // namespace
141 
142 absl::optional<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>
FindUInt64CounterHandleByName(absl::string_view name)143 GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName(
144     absl::string_view name) {
145   return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>(
146       GlobalInstrumentsRegistry::GetInstrumentList(), name,
147       GlobalInstrumentsRegistry::ValueType::kUInt64,
148       GlobalInstrumentsRegistry::InstrumentType::kCounter);
149 }
150 
151 absl::optional<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>
FindDoubleCounterHandleByName(absl::string_view name)152 GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName(
153     absl::string_view name) {
154   return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>(
155       GlobalInstrumentsRegistry::GetInstrumentList(), name,
156       GlobalInstrumentsRegistry::ValueType::kDouble,
157       GlobalInstrumentsRegistry::InstrumentType::kCounter);
158 }
159 
160 absl::optional<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>
FindUInt64HistogramHandleByName(absl::string_view name)161 GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName(
162     absl::string_view name) {
163   return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>(
164       GlobalInstrumentsRegistry::GetInstrumentList(), name,
165       GlobalInstrumentsRegistry::ValueType::kUInt64,
166       GlobalInstrumentsRegistry::InstrumentType::kHistogram);
167 }
168 
169 absl::optional<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>
FindDoubleHistogramHandleByName(absl::string_view name)170 GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName(
171     absl::string_view name) {
172   return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>(
173       GlobalInstrumentsRegistry::GetInstrumentList(), name,
174       GlobalInstrumentsRegistry::ValueType::kDouble,
175       GlobalInstrumentsRegistry::InstrumentType::kHistogram);
176 }
177 
178 absl::optional<GlobalInstrumentsRegistry::GlobalInt64GaugeHandle>
FindInt64GaugeHandleByName(absl::string_view name)179 GlobalInstrumentsRegistryTestPeer::FindInt64GaugeHandleByName(
180     absl::string_view name) {
181   return FindInstrument<GlobalInstrumentsRegistry::GlobalInt64GaugeHandle>(
182       GlobalInstrumentsRegistry::GetInstrumentList(), name,
183       GlobalInstrumentsRegistry::ValueType::kInt64,
184       GlobalInstrumentsRegistry::InstrumentType::kGauge);
185 }
186 
187 absl::optional<GlobalInstrumentsRegistry::GlobalDoubleGaugeHandle>
FindDoubleGaugeHandleByName(absl::string_view name)188 GlobalInstrumentsRegistryTestPeer::FindDoubleGaugeHandleByName(
189     absl::string_view name) {
190   return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleGaugeHandle>(
191       GlobalInstrumentsRegistry::GetInstrumentList(), name,
192       GlobalInstrumentsRegistry::ValueType::kDouble,
193       GlobalInstrumentsRegistry::InstrumentType::kGauge);
194 }
195 
196 absl::optional<GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>
FindCallbackInt64GaugeHandleByName(absl::string_view name)197 GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName(
198     absl::string_view name) {
199   return FindInstrument<
200       GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>(
201       GlobalInstrumentsRegistry::GetInstrumentList(), name,
202       GlobalInstrumentsRegistry::ValueType::kInt64,
203       GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
204 }
205 
206 absl::optional<GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>
FindCallbackDoubleGaugeHandleByName(absl::string_view name)207 GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName(
208     absl::string_view name) {
209   return FindInstrument<
210       GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>(
211       GlobalInstrumentsRegistry::GetInstrumentList(), name,
212       GlobalInstrumentsRegistry::ValueType::kDouble,
213       GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
214 }
215 
216 GlobalInstrumentsRegistry::GlobalInstrumentDescriptor*
FindMetricDescriptorByName(absl::string_view name)217 GlobalInstrumentsRegistryTestPeer::FindMetricDescriptorByName(
218     absl::string_view name) {
219   for (auto& descriptor : GlobalInstrumentsRegistry::GetInstrumentList()) {
220     if (descriptor.name == name) {
221       return &descriptor;
222     }
223   }
224   return nullptr;
225 }
226 
227 }  // namespace grpc_core
228