• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test_util/fake_stats_plugin.h"
16 
17 #include "absl/log/check.h"
18 #include "src/core/config/core_configuration.h"
19 
20 namespace grpc_core {
21 
22 class FakeStatsClientFilter : public ChannelFilter {
23  public:
24   static const grpc_channel_filter kFilter;
25 
TypeName()26   static absl::string_view TypeName() { return "fake_stats_client"; }
27 
28   explicit FakeStatsClientFilter(
29       FakeClientCallTracerFactory* fake_client_call_tracer_factory);
30 
31   static absl::StatusOr<std::unique_ptr<FakeStatsClientFilter>> Create(
32       const ChannelArgs& /*args*/, ChannelFilter::Args /*filter_args*/);
33 
34   ArenaPromise<ServerMetadataHandle> MakeCallPromise(
35       CallArgs call_args, NextPromiseFactory next_promise_factory) override;
36 
37  private:
38   FakeClientCallTracerFactory* const fake_client_call_tracer_factory_;
39 };
40 
41 const grpc_channel_filter FakeStatsClientFilter::kFilter =
42     MakePromiseBasedFilter<FakeStatsClientFilter, FilterEndpoint::kClient>();
43 
44 absl::StatusOr<std::unique_ptr<FakeStatsClientFilter>>
Create(const ChannelArgs & args,ChannelFilter::Args)45 FakeStatsClientFilter::Create(const ChannelArgs& args,
46                               ChannelFilter::Args /*filter_args*/) {
47   auto* fake_client_call_tracer_factory =
48       args.GetPointer<FakeClientCallTracerFactory>(
49           GRPC_ARG_INJECT_FAKE_CLIENT_CALL_TRACER_FACTORY);
50   CHECK_NE(fake_client_call_tracer_factory, nullptr);
51   return std::make_unique<FakeStatsClientFilter>(
52       fake_client_call_tracer_factory);
53 }
54 
MakeCallPromise(CallArgs call_args,NextPromiseFactory next_promise_factory)55 ArenaPromise<ServerMetadataHandle> FakeStatsClientFilter::MakeCallPromise(
56     CallArgs call_args, NextPromiseFactory next_promise_factory) {
57   FakeClientCallTracer* client_call_tracer =
58       fake_client_call_tracer_factory_->CreateFakeClientCallTracer();
59   if (client_call_tracer != nullptr) {
60     SetContext<CallTracerAnnotationInterface>(client_call_tracer);
61   }
62   return next_promise_factory(std::move(call_args));
63 }
64 
FakeStatsClientFilter(FakeClientCallTracerFactory * fake_client_call_tracer_factory)65 FakeStatsClientFilter::FakeStatsClientFilter(
66     FakeClientCallTracerFactory* fake_client_call_tracer_factory)
67     : fake_client_call_tracer_factory_(fake_client_call_tracer_factory) {}
68 
RegisterFakeStatsPlugin()69 void RegisterFakeStatsPlugin() {
70   CoreConfiguration::RegisterBuilder(
71       [](CoreConfiguration::Builder* builder) mutable {
72         builder->channel_init()
73             ->RegisterFilter(GRPC_CLIENT_CHANNEL,
74                              &FakeStatsClientFilter::kFilter)
75             .If([](const ChannelArgs& args) {
76               return args.GetPointer<FakeClientCallTracerFactory>(
77                          GRPC_ARG_INJECT_FAKE_CLIENT_CALL_TRACER_FACTORY) !=
78                      nullptr;
79             });
80       });
81 }
82 
83 namespace {
84 
AddKeyValuePairs(absl::Span<const absl::string_view> keys,absl::Span<const absl::string_view> values,std::vector<std::string> * key_value_pairs)85 void AddKeyValuePairs(absl::Span<const absl::string_view> keys,
86                       absl::Span<const absl::string_view> values,
87                       std::vector<std::string>* key_value_pairs) {
88   CHECK(keys.size() == values.size());
89   for (size_t i = 0; i < keys.size(); ++i) {
90     key_value_pairs->push_back(absl::StrCat(keys[i], "=", values[i]));
91   }
92 }
93 
94 }  // namespace
95 
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)96 std::string MakeLabelString(
97     absl::Span<const absl::string_view> label_keys,
98     absl::Span<const absl::string_view> label_values,
99     absl::Span<const absl::string_view> optional_label_keys,
100     absl::Span<const absl::string_view> optional_values) {
101   std::vector<std::string> key_value_pairs;
102   AddKeyValuePairs(label_keys, label_values, &key_value_pairs);
103   AddKeyValuePairs(optional_label_keys, optional_values, &key_value_pairs);
104   return absl::StrJoin(key_value_pairs, ",");
105 }
106 
MakeStatsPluginForTarget(absl::string_view target_suffix)107 std::shared_ptr<FakeStatsPlugin> MakeStatsPluginForTarget(
108     absl::string_view target_suffix) {
109   return FakeStatsPluginBuilder()
110       .SetChannelFilter(
111           [target_suffix](const experimental::StatsPluginChannelScope& scope) {
112             return absl::EndsWith(scope.target(), target_suffix);
113           })
114       .BuildAndRegister();
115 }
116 
ResetGlobalInstrumentsRegistry()117 void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() {
118   auto& instruments = GlobalInstrumentsRegistry::GetInstrumentList();
119   instruments.clear();
120 }
121 
122 namespace {
123 
124 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindInstrument(const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor> & instruments,absl::string_view name,GlobalInstrumentsRegistry::ValueType value_type,GlobalInstrumentsRegistry::InstrumentType instrument_type)125 FindInstrument(
126     const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
127         instruments,
128     absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type,
129     GlobalInstrumentsRegistry::InstrumentType instrument_type) {
130   for (const auto& descriptor : instruments) {
131     if (descriptor.name == name && descriptor.value_type == value_type &&
132         descriptor.instrument_type == instrument_type) {
133       GlobalInstrumentsRegistry::GlobalInstrumentHandle handle;
134       handle.index = descriptor.index;
135       return handle;
136     }
137   }
138   return absl::nullopt;
139 }
140 
141 }  // namespace
142 
143 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64CounterHandleByName(absl::string_view name)144 GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName(
145     absl::string_view name) {
146   return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
147                         GlobalInstrumentsRegistry::ValueType::kUInt64,
148                         GlobalInstrumentsRegistry::InstrumentType::kCounter);
149 }
150 
151 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleCounterHandleByName(absl::string_view name)152 GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName(
153     absl::string_view name) {
154   return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
155                         GlobalInstrumentsRegistry::ValueType::kDouble,
156                         GlobalInstrumentsRegistry::InstrumentType::kCounter);
157 }
158 
159 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64HistogramHandleByName(absl::string_view name)160 GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName(
161     absl::string_view name) {
162   return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
163                         GlobalInstrumentsRegistry::ValueType::kUInt64,
164                         GlobalInstrumentsRegistry::InstrumentType::kHistogram);
165 }
166 
167 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleHistogramHandleByName(absl::string_view name)168 GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName(
169     absl::string_view name) {
170   return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
171                         GlobalInstrumentsRegistry::ValueType::kDouble,
172                         GlobalInstrumentsRegistry::InstrumentType::kHistogram);
173 }
174 
175 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackInt64GaugeHandleByName(absl::string_view name)176 GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName(
177     absl::string_view name) {
178   return FindInstrument(
179       GlobalInstrumentsRegistry::GetInstrumentList(), name,
180       GlobalInstrumentsRegistry::ValueType::kInt64,
181       GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
182 }
183 
184 absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackDoubleGaugeHandleByName(absl::string_view name)185 GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName(
186     absl::string_view name) {
187   return FindInstrument(
188       GlobalInstrumentsRegistry::GetInstrumentList(), name,
189       GlobalInstrumentsRegistry::ValueType::kDouble,
190       GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
191 }
192 
193 GlobalInstrumentsRegistry::GlobalInstrumentDescriptor*
FindMetricDescriptorByName(absl::string_view name)194 GlobalInstrumentsRegistryTestPeer::FindMetricDescriptorByName(
195     absl::string_view name) {
196   for (auto& descriptor : GlobalInstrumentsRegistry::GetInstrumentList()) {
197     if (descriptor.name == name) {
198       return &descriptor;
199     }
200   }
201   return nullptr;
202 }
203 
204 }  // namespace grpc_core
205