channel_trace_test.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <gtest/gtest.h>
25 
26 #include <grpc/grpc_security.h>
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
30 
35 #include "src/core/lib/json/json.h"
39 
40 namespace grpc_core {
41 namespace channelz {
42 namespace testing {
43 
44 // testing peer to access channel internals
46  public:
47  explicit ChannelNodePeer(ChannelNode* node) : node_(node) {}
48  ChannelTrace* trace() const { return &node_->trace_; }
49 
50  private:
52 };
53 
54 size_t GetSizeofTraceEvent() { return sizeof(ChannelTrace::TraceEvent); }
55 
56 namespace {
57 
58 void ValidateJsonArraySize(const Json& array, size_t expected) {
59  if (expected == 0) {
61  } else {
63  EXPECT_EQ(array.array_value().size(), expected);
64  }
65 }
66 
67 void ValidateChannelTraceData(const Json& json,
68  size_t num_events_logged_expected,
69  size_t actual_num_events_expected) {
70  ASSERT_EQ(json.type(), Json::Type::OBJECT);
71  Json::Object object = json.object_value();
72  Json& num_events_logged_json = object["numEventsLogged"];
73  ASSERT_EQ(num_events_logged_json.type(), Json::Type::STRING);
74  size_t num_events_logged = static_cast<size_t>(
75  strtol(num_events_logged_json.string_value().c_str(), nullptr, 0));
76  ASSERT_EQ(num_events_logged, num_events_logged_expected);
77  Json& start_time_json = object["creationTimestamp"];
78  ASSERT_EQ(start_time_json.type(), Json::Type::STRING);
79  ValidateJsonArraySize(object["events"], actual_num_events_expected);
80 }
81 
82 void AddSimpleTrace(ChannelTrace* tracer) {
83  tracer->AddTraceEvent(ChannelTrace::Severity::Info,
84  grpc_slice_from_static_string("simple trace"));
85 }
86 
87 // checks for the existence of all the required members of the tracer.
88 void ValidateChannelTraceCustom(ChannelTrace* tracer, size_t num_events_logged,
89  size_t num_events_expected) {
90  Json json = tracer->RenderJson();
91  ASSERT_EQ(json.type(), Json::Type::OBJECT);
92  std::string json_str = json.Dump();
94  ValidateChannelTraceData(json, num_events_logged, num_events_expected);
95 }
96 
97 void ValidateChannelTrace(ChannelTrace* tracer, size_t num_events_logged) {
98  ValidateChannelTraceCustom(tracer, num_events_logged, num_events_logged);
99 }
100 
101 class ChannelFixture {
102  public:
103  explicit ChannelFixture(int max_tracer_event_memory) {
106  max_tracer_event_memory);
107  grpc_channel_args client_args = {1, &client_a};
109  channel_ = grpc_channel_create("fake_target", creds, &client_args);
111  }
112 
113  ~ChannelFixture() { grpc_channel_destroy(channel_); }
114 
115  grpc_channel* channel() { return channel_; }
116 
117  private:
119 };
120 
121 } // anonymous namespace
122 
123 const int kEventListMemoryLimit = 1024 * 1024;
124 
125 // Tests basic ChannelTrace functionality like construction, adding trace, and
126 // lookups by uuid.
127 TEST(ChannelTracerTest, BasicTest) {
130  AddSimpleTrace(&tracer);
131  AddSimpleTrace(&tracer);
132  tracer.AddTraceEvent(ChannelTrace::Severity::Info,
133  grpc_slice_from_static_string("trace three"));
134  tracer.AddTraceEvent(ChannelTrace::Severity::Error,
135  grpc_slice_from_static_string("trace four error"));
136  ValidateChannelTrace(&tracer, 4);
137  AddSimpleTrace(&tracer);
138  AddSimpleTrace(&tracer);
139  ValidateChannelTrace(&tracer, 6);
140  AddSimpleTrace(&tracer);
141  AddSimpleTrace(&tracer);
142  AddSimpleTrace(&tracer);
143  AddSimpleTrace(&tracer);
144  ValidateChannelTrace(&tracer, 10);
145 }
146 
147 // Tests more complex functionality, like a parent channel tracking
148 // subchannles. This exercises the ref/unref patterns since the parent tracer
149 // and this function will both hold refs to the subchannel.
150 TEST(ChannelTracerTest, ComplexTest) {
153  AddSimpleTrace(&tracer);
154  AddSimpleTrace(&tracer);
155  ChannelFixture channel1(kEventListMemoryLimit);
157  MakeRefCounted<ChannelNode>("fake_target", kEventListMemoryLimit, 0);
158  ChannelNodePeer sc1_peer(sc1.get());
160  ChannelTrace::Severity::Info,
161  grpc_slice_from_static_string("subchannel one created"), sc1);
162  ValidateChannelTrace(&tracer, 3);
163  AddSimpleTrace(sc1_peer.trace());
164  AddSimpleTrace(sc1_peer.trace());
165  AddSimpleTrace(sc1_peer.trace());
166  ValidateChannelTrace(sc1_peer.trace(), 3);
167  AddSimpleTrace(sc1_peer.trace());
168  AddSimpleTrace(sc1_peer.trace());
169  AddSimpleTrace(sc1_peer.trace());
170  ValidateChannelTrace(sc1_peer.trace(), 6);
171  AddSimpleTrace(&tracer);
172  AddSimpleTrace(&tracer);
173  ValidateChannelTrace(&tracer, 5);
174  ChannelFixture channel2(kEventListMemoryLimit);
176  MakeRefCounted<ChannelNode>("fake_target", kEventListMemoryLimit, 0);
178  ChannelTrace::Severity::Info,
179  grpc_slice_from_static_string("LB channel two created"), sc2);
181  ChannelTrace::Severity::Warning,
182  grpc_slice_from_static_string("subchannel one inactive"), sc1);
183  ValidateChannelTrace(&tracer, 7);
184  AddSimpleTrace(&tracer);
185  AddSimpleTrace(&tracer);
186  AddSimpleTrace(&tracer);
187  AddSimpleTrace(&tracer);
188  AddSimpleTrace(&tracer);
189  AddSimpleTrace(&tracer);
190  sc1.reset();
191  sc2.reset();
192 }
193 
194 // Test a case in which the parent channel has subchannels and the subchannels
195 // have connections. Ensures that everything lives as long as it should then
196 // gets deleted.
197 TEST(ChannelTracerTest, TestNesting) {
200  AddSimpleTrace(&tracer);
201  AddSimpleTrace(&tracer);
202  ValidateChannelTrace(&tracer, 2);
203  ChannelFixture channel1(kEventListMemoryLimit);
205  MakeRefCounted<ChannelNode>("fake_target", kEventListMemoryLimit, 0);
206  ChannelNodePeer sc1_peer(sc1.get());
208  ChannelTrace::Severity::Info,
209  grpc_slice_from_static_string("subchannel one created"), sc1);
210  ValidateChannelTrace(&tracer, 3);
211  AddSimpleTrace(sc1_peer.trace());
212  ChannelFixture channel2(kEventListMemoryLimit);
214  MakeRefCounted<ChannelNode>("fake_target", kEventListMemoryLimit, 0);
215  ChannelNodePeer conn1_peer(conn1.get());
216  // nesting one level deeper.
217  sc1_peer.trace()->AddTraceEventWithReference(
218  ChannelTrace::Severity::Info,
219  grpc_slice_from_static_string("connection one created"), conn1);
220  ValidateChannelTrace(&tracer, 3);
221  AddSimpleTrace(conn1_peer.trace());
222  AddSimpleTrace(&tracer);
223  AddSimpleTrace(&tracer);
224  ValidateChannelTrace(&tracer, 5);
225  ValidateChannelTrace(conn1_peer.trace(), 1);
226  ChannelFixture channel3(kEventListMemoryLimit);
228  MakeRefCounted<ChannelNode>("fake_target", kEventListMemoryLimit, 0);
230  ChannelTrace::Severity::Info,
231  grpc_slice_from_static_string("subchannel two created"), sc2);
232  // this trace should not get added to the parents children since it is already
233  // present in the tracer.
235  ChannelTrace::Severity::Warning,
236  grpc_slice_from_static_string("subchannel one inactive"), sc1);
237  AddSimpleTrace(&tracer);
238  ValidateChannelTrace(&tracer, 8);
239  sc1.reset();
240  sc2.reset();
241  conn1.reset();
242 }
243 
244 TEST(ChannelTracerTest, TestSmallMemoryLimit) {
246  // doesn't make sense, but serves a testing purpose for the channel tracing
247  // bookkeeping. All tracing events added should will get immediately garbage
248  // collected.
249  const int kSmallMemoryLimit = 1;
250  ChannelTrace tracer(kSmallMemoryLimit);
251  AddSimpleTrace(&tracer);
252  AddSimpleTrace(&tracer);
253  tracer.AddTraceEvent(ChannelTrace::Severity::Info,
254  grpc_slice_from_static_string("trace three"));
255  tracer.AddTraceEvent(ChannelTrace::Severity::Error,
256  grpc_slice_from_static_string("trace four error"));
257  ValidateChannelTraceCustom(&tracer, 4, 0);
258  AddSimpleTrace(&tracer);
259  AddSimpleTrace(&tracer);
260  ValidateChannelTraceCustom(&tracer, 6, 0);
261  AddSimpleTrace(&tracer);
262  AddSimpleTrace(&tracer);
263  AddSimpleTrace(&tracer);
264  AddSimpleTrace(&tracer);
265  ValidateChannelTraceCustom(&tracer, 10, 0);
266 }
267 
268 TEST(ChannelTracerTest, TestEviction) {
270  const int kTraceEventSize = GetSizeofTraceEvent();
271  const int kNumEvents = 5;
272  ChannelTrace tracer(kTraceEventSize * kNumEvents);
273  for (int i = 1; i <= kNumEvents; ++i) {
274  AddSimpleTrace(&tracer);
275  ValidateChannelTrace(&tracer, i);
276  }
277  // at this point the list is full, and each subsequent enntry will cause an
278  // eviction.
279  for (int i = 1; i <= kNumEvents; ++i) {
280  AddSimpleTrace(&tracer);
281  ValidateChannelTraceCustom(&tracer, kNumEvents + i, kNumEvents);
282  }
283 }
284 
285 TEST(ChannelTracerTest, TestMultipleEviction) {
287  const int kTraceEventSize = GetSizeofTraceEvent();
288  const int kNumEvents = 5;
289  ChannelTrace tracer(kTraceEventSize * kNumEvents);
290  for (int i = 1; i <= kNumEvents; ++i) {
291  AddSimpleTrace(&tracer);
292  ValidateChannelTrace(&tracer, i);
293  }
294  // at this point the list is full, and each subsequent enntry will cause an
295  // eviction. We will now add in a trace event that has a copied string. This
296  // uses more memory, so it will cause a double eviciction
297  tracer.AddTraceEvent(
298  ChannelTrace::Severity::Info,
300  "long enough string to trigger a multiple eviction"));
301  ValidateChannelTraceCustom(&tracer, kNumEvents + 1, kNumEvents - 1);
302 }
303 
304 TEST(ChannelTracerTest, TestTotalEviction) {
306  const int kTraceEventSize = GetSizeofTraceEvent();
307  const int kNumEvents = 5;
308  ChannelTrace tracer(kTraceEventSize * kNumEvents);
309  for (int i = 1; i <= kNumEvents; ++i) {
310  AddSimpleTrace(&tracer);
311  ValidateChannelTrace(&tracer, i);
312  }
313  // at this point the list is full. Now we add such a big slice that
314  // everything gets evicted.
315  grpc_slice huge_slice = grpc_slice_malloc(kTraceEventSize * (kNumEvents + 1));
316  tracer.AddTraceEvent(ChannelTrace::Severity::Info, huge_slice);
317  ValidateChannelTraceCustom(&tracer, kNumEvents + 1, 0);
318 }
319 
320 } // namespace testing
321 } // namespace channelz
322 } // namespace grpc_core
323 
324 int main(int argc, char** argv) {
325  grpc::testing::TestEnvironment env(&argc, argv);
326  grpc_init();
327  ::testing::InitGoogleTest(&argc, argv);
328  int ret = RUN_ALL_TESTS();
329  grpc_shutdown();
330  return ret;
331 }
grpc_arg
Definition: grpc_types.h:103
testing
Definition: aws_request_signer_test.cc:25
log.h
grpc_core::channelz::ChannelTrace::AddTraceEventWithReference
void AddTraceEventWithReference(Severity severity, const grpc_slice &data, RefCountedPtr< BaseNode > referenced_entity)
Definition: channel_trace.cc:113
generate.env
env
Definition: generate.py:37
grpc_core::RefCountedPtr::get
T * get() const
Definition: ref_counted_ptr.h:146
grpc_slice_from_copied_string
GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source)
Definition: slice/slice.cc:177
grpc_core::Json::Type::OBJECT
@ OBJECT
grpc_core
Definition: call_metric_recorder.h:31
string.h
grpc_core::RefCountedPtr::reset
void reset(T *value=nullptr)
Definition: ref_counted_ptr.h:111
grpc_core::channelz::testing::ChannelNodePeer
Definition: channel_trace_test.cc:45
useful.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc::testing::ValidateChannelTraceProtoJsonTranslation
void ValidateChannelTraceProtoJsonTranslation(const char *json_c_str)
Definition: channel_trace_proto_helper.cc:78
channel_trace_proto_helper.h
grpc_security.h
channelz.h
grpc_slice_malloc
GPRAPI grpc_slice grpc_slice_malloc(size_t length)
Definition: slice/slice.cc:227
grpc_channel_args
Definition: grpc_types.h:132
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
grpc_core::channelz::testing::TEST
TEST(ChannelTracerTest, BasicTest)
Definition: channel_trace_test.cc:127
string_util.h
channelz_registry.h
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
array
Definition: undname.c:101
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
channel_
grpc_channel * channel_
Definition: channel_trace_test.cc:118
grpc_insecure_credentials_create
GRPCAPI grpc_channel_credentials * grpc_insecure_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:64
grpc_core::channelz::testing::kEventListMemoryLimit
const int kEventListMemoryLimit
Definition: channel_trace_test.cc:123
grpc_slice_from_static_string
GPRAPI grpc_slice grpc_slice_from_static_string(const char *source)
Definition: slice/slice.cc:89
grpc_core::channelz::testing::ChannelNodePeer::ChannelNodePeer
ChannelNodePeer(ChannelNode *node)
Definition: channel_trace_test.cc:47
grpc_core::channelz::testing::GetSizeofTraceEvent
size_t GetSizeofTraceEvent(void)
Definition: channel_trace_test.cc:54
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
grpc_core::Json::Type::ARRAY
@ ARRAY
json.h
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_core::ExecCtx
Definition: exec_ctx.h:97
grpc_core::channelz::ChannelNode
Definition: channelz.h:178
test_config.h
main
int main(int argc, char **argv)
Definition: channel_trace_test.cc:324
grpc_channel_credentials_release
GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds)
Definition: credentials.cc:36
grpc_core::channelz::testing::ChannelNodePeer::node_
ChannelNode * node_
Definition: channel_trace_test.cc:51
grpc_core::Json::Object
std::map< std::string, Json > Object
Definition: src/core/lib/json/json.h:54
grpc_core::channelz::testing::ChannelNodePeer::trace
ChannelTrace * trace() const
Definition: channel_trace_test.cc:48
grpc_channel_create
GRPCAPI grpc_channel * grpc_channel_create(const char *target, grpc_channel_credentials *creds, const grpc_channel_args *args)
Definition: chttp2_connector.cc:366
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
grpc_channel_arg_integer_create
grpc_arg grpc_channel_arg_integer_create(char *name, int value)
Definition: channel_args.cc:484
GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE
#define GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE
Definition: grpc_types.h:318
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
grpc_core::Json::Type::JSON_NULL
@ JSON_NULL
alloc.h
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc_channel_destroy
GRPCAPI void grpc_channel_destroy(grpc_channel *channel)
Definition: channel.cc:437
exec_ctx.h
channelz
void channelz(grpc_end2end_test_config config)
Definition: test/core/end2end/tests/channelz.cc:318
grpc_core::channelz::ChannelTrace::TraceEvent
Definition: channel_trace.h:91
grpc_channel
struct grpc_channel grpc_channel
Definition: grpc_types.h:62
grpc_core::channelz::ChannelNode::trace_
ChannelTrace trace_
Definition: channelz.h:227
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
channel_trace.h
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
grpc_channel_credentials
Definition: src/core/lib/security/credentials/credentials.h:96
grpc_core::Json::Type::STRING
@ STRING
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
grpc_core::channelz::ChannelTrace
Definition: channel_trace.h:46
channel.h
grpc_core::channelz::ChannelTrace::AddTraceEvent
void AddTraceEvent(Severity severity, const grpc_slice &data)
Definition: channel_trace.cc:105


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:52