1 //
2 //
3 // Copyright 2015 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
19 #include "src/core/lib/channel/channelz.h"
20
21 #include <string>
22
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25
26 #include <grpc/impl/channel_arg_names.h>
27 #include <grpc/status.h>
28
29 #include "src/core/lib/channel/channel_args.h"
30 #include "src/core/lib/gprpp/time.h"
31 #include "src/core/lib/surface/channel.h"
32 #include "src/core/lib/surface/server.h"
33 #include "test/core/end2end/end2end_tests.h"
34
35 using testing::HasSubstr;
36 using testing::Not;
37
38 namespace grpc_core {
39 namespace {
40
RunOneRequest(CoreEnd2endTest & test,bool request_is_success)41 void RunOneRequest(CoreEnd2endTest& test, bool request_is_success) {
42 auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
43 CoreEnd2endTest::IncomingMetadata server_initial_metadata;
44 CoreEnd2endTest::IncomingStatusOnClient server_status;
45 c.NewBatch(1)
46 .SendInitialMetadata({})
47 .SendCloseFromClient()
48 .RecvInitialMetadata(server_initial_metadata)
49 .RecvStatusOnClient(server_status);
50 auto s = test.RequestCall(101);
51 test.Expect(101, true);
52 test.Step();
53 CoreEnd2endTest::IncomingCloseOnServer client_close;
54 s.NewBatch(102)
55 .SendInitialMetadata({})
56 .SendStatusFromServer(
57 request_is_success ? GRPC_STATUS_OK : GRPC_STATUS_UNIMPLEMENTED,
58 "xyz", {})
59 .RecvCloseOnServer(client_close);
60 test.Expect(102, true);
61 test.Expect(1, true);
62 test.Step();
63 EXPECT_EQ(server_status.message(), "xyz");
64 EXPECT_EQ(s.method(), "/foo");
65 }
66
CORE_END2END_TEST(CoreEnd2endTest,Channelz)67 CORE_END2END_TEST(CoreEnd2endTest, Channelz) {
68 SKIP_IF_CHAOTIC_GOOD();
69 auto args = ChannelArgs()
70 .Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 0)
71 .Set(GRPC_ARG_ENABLE_CHANNELZ, true);
72 InitServer(args);
73 InitClient(args);
74
75 channelz::ChannelNode* channelz_channel =
76 grpc_channel_get_channelz_node(client());
77 ASSERT_NE(channelz_channel, nullptr);
78
79 channelz::ServerNode* channelz_server =
80 Server::FromC(server())->channelz_node();
81 ASSERT_NE(channelz_server, nullptr);
82
83 std::string json = channelz_channel->RenderJsonString();
84 // nothing is present yet
85 EXPECT_THAT(json, Not(HasSubstr("\"callsStarted\"")));
86 EXPECT_THAT(json, Not(HasSubstr("\"callsFailed\"")));
87 EXPECT_THAT(json, Not(HasSubstr("\"callsSucceeded\"")));
88
89 // one successful request
90 RunOneRequest(*this, true);
91
92 json = channelz_channel->RenderJsonString();
93 EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"1\""));
94 EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
95
96 // one failed request
97 RunOneRequest(*this, false);
98
99 json = channelz_channel->RenderJsonString();
100 EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"2\""));
101 EXPECT_THAT(json, HasSubstr("\"callsFailed\":\"1\""));
102 EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
103 // channel tracing is not enabled, so these should not be preset.
104 EXPECT_THAT(json, Not(HasSubstr("\"trace\"")));
105 EXPECT_THAT(json, Not(HasSubstr("\"description\":\"Channel created\"")));
106 EXPECT_THAT(json, Not(HasSubstr("\"severity\":\"CT_INFO\"")));
107
108 json = channelz_server->RenderJsonString();
109 EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"2\""));
110 EXPECT_THAT(json, HasSubstr("\"callsFailed\":\"1\""));
111 EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
112 // channel tracing is not enabled, so these should not be preset.
113 EXPECT_THAT(json, Not(HasSubstr("\"trace\"")));
114 EXPECT_THAT(json, Not(HasSubstr("\"description\":\"Channel created\"")));
115 EXPECT_THAT(json, Not(HasSubstr("\"severity\":\"CT_INFO\"")));
116
117 json = channelz_server->RenderServerSockets(0, 100);
118 EXPECT_THAT(json, HasSubstr("\"end\":true"));
119 }
120
CORE_END2END_TEST(CoreEnd2endTest,ChannelzWithChannelTrace)121 CORE_END2END_TEST(CoreEnd2endTest, ChannelzWithChannelTrace) {
122 SKIP_IF_CHAOTIC_GOOD();
123 auto args =
124 ChannelArgs()
125 .Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024 * 1024)
126 .Set(GRPC_ARG_ENABLE_CHANNELZ, true);
127 InitServer(args);
128 InitClient(args);
129
130 channelz::ChannelNode* channelz_channel =
131 grpc_channel_get_channelz_node(client());
132 ASSERT_NE(channelz_channel, nullptr);
133
134 channelz::ServerNode* channelz_server =
135 Server::FromC(server())->channelz_node();
136 ASSERT_NE(channelz_server, nullptr);
137
138 RunOneRequest(*this, true);
139
140 std::string json = channelz_channel->RenderJsonString();
141 EXPECT_THAT(json, HasSubstr("\"trace\""));
142 EXPECT_THAT(json, HasSubstr("\"description\":\"Channel created\""));
143 EXPECT_THAT(json, HasSubstr("\"severity\":\"CT_INFO\""));
144
145 json = channelz_server->RenderJsonString();
146 EXPECT_THAT(json, HasSubstr("\"trace\""));
147 EXPECT_THAT(json, HasSubstr("\"description\":\"Server created\""));
148 EXPECT_THAT(json, HasSubstr("\"severity\":\"CT_INFO\""));
149 }
150
CORE_END2END_TEST(CoreEnd2endTest,ChannelzDisabled)151 CORE_END2END_TEST(CoreEnd2endTest, ChannelzDisabled) {
152 SKIP_IF_CHAOTIC_GOOD();
153 auto args = ChannelArgs()
154 .Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 0)
155 .Set(GRPC_ARG_ENABLE_CHANNELZ, false);
156 InitServer(args);
157 InitClient(args);
158 channelz::ChannelNode* channelz_channel =
159 grpc_channel_get_channelz_node(client());
160 EXPECT_EQ(channelz_channel, nullptr);
161 RunOneRequest(*this, true);
162 }
163
164 } // namespace
165 } // namespace grpc_core
166