• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2018 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 <grpc/support/port_platform.h>
20 
21 #include <grpc/grpc.h>
22 #include <grpcpp/channel.h>
23 #include <grpcpp/client_context.h>
24 #include <grpcpp/create_channel.h>
25 #include <grpcpp/security/credentials.h>
26 #include <grpcpp/security/server_credentials.h>
27 #include <grpcpp/server.h>
28 #include <grpcpp/server_builder.h>
29 #include <grpcpp/server_context.h>
30 
31 #include <grpcpp/ext/channelz_service_plugin.h>
32 #include "src/core/lib/gpr/env.h"
33 #include "src/proto/grpc/channelz/channelz.grpc.pb.h"
34 #include "src/proto/grpc/testing/echo.grpc.pb.h"
35 #include "test/core/util/port.h"
36 #include "test/core/util/test_config.h"
37 #include "test/cpp/end2end/test_service_impl.h"
38 
39 #include <gtest/gtest.h>
40 
41 using grpc::channelz::v1::GetChannelRequest;
42 using grpc::channelz::v1::GetChannelResponse;
43 using grpc::channelz::v1::GetServerRequest;
44 using grpc::channelz::v1::GetServerResponse;
45 using grpc::channelz::v1::GetServerSocketsRequest;
46 using grpc::channelz::v1::GetServerSocketsResponse;
47 using grpc::channelz::v1::GetServersRequest;
48 using grpc::channelz::v1::GetServersResponse;
49 using grpc::channelz::v1::GetSocketRequest;
50 using grpc::channelz::v1::GetSocketResponse;
51 using grpc::channelz::v1::GetSubchannelRequest;
52 using grpc::channelz::v1::GetSubchannelResponse;
53 using grpc::channelz::v1::GetTopChannelsRequest;
54 using grpc::channelz::v1::GetTopChannelsResponse;
55 
56 namespace grpc {
57 namespace testing {
58 namespace {
59 
60 // Proxy service supports N backends. Sends RPC to backend dictated by
61 // request->backend_channel_idx().
62 class Proxy : public ::grpc::testing::EchoTestService::Service {
63  public:
Proxy()64   Proxy() {}
65 
AddChannelToBackend(const std::shared_ptr<Channel> & channel)66   void AddChannelToBackend(const std::shared_ptr<Channel>& channel) {
67     stubs_.push_back(grpc::testing::EchoTestService::NewStub(channel));
68   }
69 
Echo(ServerContext * server_context,const EchoRequest * request,EchoResponse * response)70   Status Echo(ServerContext* server_context, const EchoRequest* request,
71               EchoResponse* response) override {
72     std::unique_ptr<ClientContext> client_context =
73         ClientContext::FromServerContext(*server_context);
74     size_t idx = request->param().backend_channel_idx();
75     GPR_ASSERT(idx < stubs_.size());
76     return stubs_[idx]->Echo(client_context.get(), *request, response);
77   }
78 
BidiStream(ServerContext * server_context,ServerReaderWriter<EchoResponse,EchoRequest> * stream_from_client)79   Status BidiStream(ServerContext* server_context,
80                     ServerReaderWriter<EchoResponse, EchoRequest>*
81                         stream_from_client) override {
82     EchoRequest request;
83     EchoResponse response;
84     std::unique_ptr<ClientContext> client_context =
85         ClientContext::FromServerContext(*server_context);
86 
87     // always use the first proxy for streaming
88     auto stream_to_backend = stubs_[0]->BidiStream(client_context.get());
89     while (stream_from_client->Read(&request)) {
90       stream_to_backend->Write(request);
91       stream_to_backend->Read(&response);
92       stream_from_client->Write(response);
93     }
94 
95     stream_to_backend->WritesDone();
96     return stream_to_backend->Finish();
97   }
98 
99  private:
100   std::vector<std::unique_ptr<::grpc::testing::EchoTestService::Stub>> stubs_;
101 };
102 
103 }  // namespace
104 
105 class ChannelzServerTest : public ::testing::Test {
106  public:
ChannelzServerTest()107   ChannelzServerTest() {}
SetUpTestCase()108   static void SetUpTestCase() {
109 #if TARGET_OS_IPHONE
110     // Workaround Apple CFStream bug
111     gpr_setenv("grpc_cfstream", "0");
112 #endif
113   }
SetUp()114   void SetUp() override {
115     // ensure channel server is brought up on all severs we build.
116     ::grpc::channelz::experimental::InitChannelzService();
117 
118     // We set up a proxy server with channelz enabled.
119     proxy_port_ = grpc_pick_unused_port_or_die();
120     ServerBuilder proxy_builder;
121     std::string proxy_server_address = "localhost:" + to_string(proxy_port_);
122     proxy_builder.AddListeningPort(proxy_server_address,
123                                    InsecureServerCredentials());
124     // forces channelz and channel tracing to be enabled.
125     proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1);
126     proxy_builder.AddChannelArgument(
127         GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024);
128     proxy_builder.RegisterService(&proxy_service_);
129     proxy_server_ = proxy_builder.BuildAndStart();
130   }
131 
132   // Sets the proxy up to have an arbitrary number of backends.
ConfigureProxy(size_t num_backends)133   void ConfigureProxy(size_t num_backends) {
134     backends_.resize(num_backends);
135     for (size_t i = 0; i < num_backends; ++i) {
136       // create a new backend.
137       backends_[i].port = grpc_pick_unused_port_or_die();
138       ServerBuilder backend_builder;
139       std::string backend_server_address =
140           "localhost:" + to_string(backends_[i].port);
141       backend_builder.AddListeningPort(backend_server_address,
142                                        InsecureServerCredentials());
143       backends_[i].service.reset(new TestServiceImpl);
144       // ensure that the backend itself has channelz disabled.
145       backend_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 0);
146       backend_builder.RegisterService(backends_[i].service.get());
147       backends_[i].server = backend_builder.BuildAndStart();
148       // set up a channel to the backend. We ensure that this channel has
149       // channelz enabled since these channels (proxy outbound to backends)
150       // are the ones that our test will actually be validating.
151       ChannelArguments args;
152       args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1);
153       args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024);
154       std::shared_ptr<Channel> channel_to_backend = ::grpc::CreateCustomChannel(
155           backend_server_address, InsecureChannelCredentials(), args);
156       proxy_service_.AddChannelToBackend(channel_to_backend);
157     }
158   }
159 
ResetStubs()160   void ResetStubs() {
161     string target = "dns:localhost:" + to_string(proxy_port_);
162     ChannelArguments args;
163     // disable channelz. We only want to focus on proxy to backend outbound.
164     args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0);
165     std::shared_ptr<Channel> channel =
166         ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args);
167     channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel);
168     echo_stub_ = grpc::testing::EchoTestService::NewStub(channel);
169   }
170 
NewEchoStub()171   std::unique_ptr<grpc::testing::EchoTestService::Stub> NewEchoStub() {
172     string target = "dns:localhost:" + to_string(proxy_port_);
173     ChannelArguments args;
174     // disable channelz. We only want to focus on proxy to backend outbound.
175     args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0);
176     // This ensures that gRPC will not do connection sharing.
177     args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, true);
178     std::shared_ptr<Channel> channel =
179         ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args);
180     return grpc::testing::EchoTestService::NewStub(channel);
181   }
182 
SendSuccessfulEcho(int channel_idx)183   void SendSuccessfulEcho(int channel_idx) {
184     EchoRequest request;
185     EchoResponse response;
186     request.set_message("Hello channelz");
187     request.mutable_param()->set_backend_channel_idx(channel_idx);
188     ClientContext context;
189     Status s = echo_stub_->Echo(&context, request, &response);
190     EXPECT_EQ(response.message(), request.message());
191     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
192   }
193 
SendSuccessfulStream(int num_messages)194   void SendSuccessfulStream(int num_messages) {
195     EchoRequest request;
196     EchoResponse response;
197     request.set_message("Hello channelz");
198     ClientContext context;
199     auto stream_to_proxy = echo_stub_->BidiStream(&context);
200     for (int i = 0; i < num_messages; ++i) {
201       EXPECT_TRUE(stream_to_proxy->Write(request));
202       EXPECT_TRUE(stream_to_proxy->Read(&response));
203     }
204     stream_to_proxy->WritesDone();
205     Status s = stream_to_proxy->Finish();
206     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
207   }
208 
SendFailedEcho(int channel_idx)209   void SendFailedEcho(int channel_idx) {
210     EchoRequest request;
211     EchoResponse response;
212     request.set_message("Hello channelz");
213     request.mutable_param()->set_backend_channel_idx(channel_idx);
214     auto* error = request.mutable_param()->mutable_expected_error();
215     error->set_code(13);  // INTERNAL
216     error->set_error_message("error");
217     ClientContext context;
218     Status s = echo_stub_->Echo(&context, request, &response);
219     EXPECT_FALSE(s.ok());
220   }
221 
222   // Uses GetTopChannels to return the channel_id of a particular channel,
223   // so that the unit tests may test GetChannel call.
GetChannelId(int channel_idx)224   intptr_t GetChannelId(int channel_idx) {
225     GetTopChannelsRequest request;
226     GetTopChannelsResponse response;
227     request.set_start_channel_id(0);
228     ClientContext context;
229     Status s = channelz_stub_->GetTopChannels(&context, request, &response);
230     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
231     EXPECT_GT(response.channel_size(), channel_idx);
232     return response.channel(channel_idx).ref().channel_id();
233   }
234 
to_string(const int number)235   static string to_string(const int number) {
236     std::stringstream strs;
237     strs << number;
238     return strs.str();
239   }
240 
241  protected:
242   // package of data needed for each backend server.
243   struct BackendData {
244     std::unique_ptr<Server> server;
245     int port;
246     std::unique_ptr<TestServiceImpl> service;
247   };
248 
249   std::unique_ptr<grpc::channelz::v1::Channelz::Stub> channelz_stub_;
250   std::unique_ptr<grpc::testing::EchoTestService::Stub> echo_stub_;
251 
252   // proxy server to ping with channelz requests.
253   std::unique_ptr<Server> proxy_server_;
254   int proxy_port_;
255   Proxy proxy_service_;
256 
257   // backends. All implement the echo service.
258   std::vector<BackendData> backends_;
259 };
260 
TEST_F(ChannelzServerTest,BasicTest)261 TEST_F(ChannelzServerTest, BasicTest) {
262   ResetStubs();
263   ConfigureProxy(1);
264   GetTopChannelsRequest request;
265   GetTopChannelsResponse response;
266   request.set_start_channel_id(0);
267   ClientContext context;
268   Status s = channelz_stub_->GetTopChannels(&context, request, &response);
269   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
270   EXPECT_EQ(response.channel_size(), 1);
271 }
272 
TEST_F(ChannelzServerTest,HighStartId)273 TEST_F(ChannelzServerTest, HighStartId) {
274   ResetStubs();
275   ConfigureProxy(1);
276   GetTopChannelsRequest request;
277   GetTopChannelsResponse response;
278   request.set_start_channel_id(10000);
279   ClientContext context;
280   Status s = channelz_stub_->GetTopChannels(&context, request, &response);
281   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
282   EXPECT_EQ(response.channel_size(), 0);
283 }
284 
TEST_F(ChannelzServerTest,SuccessfulRequestTest)285 TEST_F(ChannelzServerTest, SuccessfulRequestTest) {
286   ResetStubs();
287   ConfigureProxy(1);
288   SendSuccessfulEcho(0);
289   GetChannelRequest request;
290   GetChannelResponse response;
291   request.set_channel_id(GetChannelId(0));
292   ClientContext context;
293   Status s = channelz_stub_->GetChannel(&context, request, &response);
294   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
295   EXPECT_EQ(response.channel().data().calls_started(), 1);
296   EXPECT_EQ(response.channel().data().calls_succeeded(), 1);
297   EXPECT_EQ(response.channel().data().calls_failed(), 0);
298 }
299 
TEST_F(ChannelzServerTest,FailedRequestTest)300 TEST_F(ChannelzServerTest, FailedRequestTest) {
301   ResetStubs();
302   ConfigureProxy(1);
303   SendFailedEcho(0);
304   GetChannelRequest request;
305   GetChannelResponse response;
306   request.set_channel_id(GetChannelId(0));
307   ClientContext context;
308   Status s = channelz_stub_->GetChannel(&context, request, &response);
309   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
310   EXPECT_EQ(response.channel().data().calls_started(), 1);
311   EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
312   EXPECT_EQ(response.channel().data().calls_failed(), 1);
313 }
314 
TEST_F(ChannelzServerTest,ManyRequestsTest)315 TEST_F(ChannelzServerTest, ManyRequestsTest) {
316   ResetStubs();
317   ConfigureProxy(1);
318   // send some RPCs
319   const int kNumSuccess = 10;
320   const int kNumFailed = 11;
321   for (int i = 0; i < kNumSuccess; ++i) {
322     SendSuccessfulEcho(0);
323   }
324   for (int i = 0; i < kNumFailed; ++i) {
325     SendFailedEcho(0);
326   }
327   GetChannelRequest request;
328   GetChannelResponse response;
329   request.set_channel_id(GetChannelId(0));
330   ClientContext context;
331   Status s = channelz_stub_->GetChannel(&context, request, &response);
332   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
333   EXPECT_EQ(response.channel().data().calls_started(),
334             kNumSuccess + kNumFailed);
335   EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
336   EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
337 }
338 
TEST_F(ChannelzServerTest,ManyChannels)339 TEST_F(ChannelzServerTest, ManyChannels) {
340   ResetStubs();
341   const int kNumChannels = 4;
342   ConfigureProxy(kNumChannels);
343   GetTopChannelsRequest request;
344   GetTopChannelsResponse response;
345   request.set_start_channel_id(0);
346   ClientContext context;
347   Status s = channelz_stub_->GetTopChannels(&context, request, &response);
348   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
349   EXPECT_EQ(response.channel_size(), kNumChannels);
350 }
351 
TEST_F(ChannelzServerTest,ManyRequestsManyChannels)352 TEST_F(ChannelzServerTest, ManyRequestsManyChannels) {
353   ResetStubs();
354   const int kNumChannels = 4;
355   ConfigureProxy(kNumChannels);
356   const int kNumSuccess = 10;
357   const int kNumFailed = 11;
358   for (int i = 0; i < kNumSuccess; ++i) {
359     SendSuccessfulEcho(0);
360     SendSuccessfulEcho(2);
361   }
362   for (int i = 0; i < kNumFailed; ++i) {
363     SendFailedEcho(1);
364     SendFailedEcho(2);
365   }
366 
367   // the first channel saw only successes
368   {
369     GetChannelRequest request;
370     GetChannelResponse response;
371     request.set_channel_id(GetChannelId(0));
372     ClientContext context;
373     Status s = channelz_stub_->GetChannel(&context, request, &response);
374     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
375     EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess);
376     EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
377     EXPECT_EQ(response.channel().data().calls_failed(), 0);
378   }
379 
380   // the second channel saw only failures
381   {
382     GetChannelRequest request;
383     GetChannelResponse response;
384     request.set_channel_id(GetChannelId(1));
385     ClientContext context;
386     Status s = channelz_stub_->GetChannel(&context, request, &response);
387     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
388     EXPECT_EQ(response.channel().data().calls_started(), kNumFailed);
389     EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
390     EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
391   }
392 
393   // the third channel saw both
394   {
395     GetChannelRequest request;
396     GetChannelResponse response;
397     request.set_channel_id(GetChannelId(2));
398     ClientContext context;
399     Status s = channelz_stub_->GetChannel(&context, request, &response);
400     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
401     EXPECT_EQ(response.channel().data().calls_started(),
402               kNumSuccess + kNumFailed);
403     EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
404     EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
405   }
406 
407   // the fourth channel saw nothing
408   {
409     GetChannelRequest request;
410     GetChannelResponse response;
411     request.set_channel_id(GetChannelId(3));
412     ClientContext context;
413     Status s = channelz_stub_->GetChannel(&context, request, &response);
414     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
415     EXPECT_EQ(response.channel().data().calls_started(), 0);
416     EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
417     EXPECT_EQ(response.channel().data().calls_failed(), 0);
418   }
419 }
420 
TEST_F(ChannelzServerTest,ManySubchannels)421 TEST_F(ChannelzServerTest, ManySubchannels) {
422   ResetStubs();
423   const int kNumChannels = 4;
424   ConfigureProxy(kNumChannels);
425   const int kNumSuccess = 10;
426   const int kNumFailed = 11;
427   for (int i = 0; i < kNumSuccess; ++i) {
428     SendSuccessfulEcho(0);
429     SendSuccessfulEcho(2);
430   }
431   for (int i = 0; i < kNumFailed; ++i) {
432     SendFailedEcho(1);
433     SendFailedEcho(2);
434   }
435   GetTopChannelsRequest gtc_request;
436   GetTopChannelsResponse gtc_response;
437   gtc_request.set_start_channel_id(0);
438   ClientContext context;
439   Status s =
440       channelz_stub_->GetTopChannels(&context, gtc_request, &gtc_response);
441   EXPECT_TRUE(s.ok()) << s.error_message();
442   EXPECT_EQ(gtc_response.channel_size(), kNumChannels);
443   for (int i = 0; i < gtc_response.channel_size(); ++i) {
444     // if the channel sent no RPCs, then expect no subchannels to have been
445     // created.
446     if (gtc_response.channel(i).data().calls_started() == 0) {
447       EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0);
448       continue;
449     }
450     // The resolver must return at least one address.
451     ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0);
452     GetSubchannelRequest gsc_request;
453     GetSubchannelResponse gsc_response;
454     gsc_request.set_subchannel_id(
455         gtc_response.channel(i).subchannel_ref(0).subchannel_id());
456     ClientContext context;
457     Status s =
458         channelz_stub_->GetSubchannel(&context, gsc_request, &gsc_response);
459     EXPECT_TRUE(s.ok()) << s.error_message();
460     EXPECT_EQ(gtc_response.channel(i).data().calls_started(),
461               gsc_response.subchannel().data().calls_started());
462     EXPECT_EQ(gtc_response.channel(i).data().calls_succeeded(),
463               gsc_response.subchannel().data().calls_succeeded());
464     EXPECT_EQ(gtc_response.channel(i).data().calls_failed(),
465               gsc_response.subchannel().data().calls_failed());
466   }
467 }
468 
TEST_F(ChannelzServerTest,BasicServerTest)469 TEST_F(ChannelzServerTest, BasicServerTest) {
470   ResetStubs();
471   ConfigureProxy(1);
472   GetServersRequest request;
473   GetServersResponse response;
474   request.set_start_server_id(0);
475   ClientContext context;
476   Status s = channelz_stub_->GetServers(&context, request, &response);
477   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
478   EXPECT_EQ(response.server_size(), 1);
479 }
480 
TEST_F(ChannelzServerTest,BasicGetServerTest)481 TEST_F(ChannelzServerTest, BasicGetServerTest) {
482   ResetStubs();
483   ConfigureProxy(1);
484   GetServersRequest get_servers_request;
485   GetServersResponse get_servers_response;
486   get_servers_request.set_start_server_id(0);
487   ClientContext get_servers_context;
488   Status s = channelz_stub_->GetServers(
489       &get_servers_context, get_servers_request, &get_servers_response);
490   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
491   EXPECT_EQ(get_servers_response.server_size(), 1);
492   GetServerRequest get_server_request;
493   GetServerResponse get_server_response;
494   get_server_request.set_server_id(
495       get_servers_response.server(0).ref().server_id());
496   ClientContext get_server_context;
497   s = channelz_stub_->GetServer(&get_server_context, get_server_request,
498                                 &get_server_response);
499   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
500   EXPECT_EQ(get_servers_response.server(0).ref().server_id(),
501             get_server_response.server().ref().server_id());
502 }
503 
TEST_F(ChannelzServerTest,ServerCallTest)504 TEST_F(ChannelzServerTest, ServerCallTest) {
505   ResetStubs();
506   ConfigureProxy(1);
507   const int kNumSuccess = 10;
508   const int kNumFailed = 11;
509   for (int i = 0; i < kNumSuccess; ++i) {
510     SendSuccessfulEcho(0);
511   }
512   for (int i = 0; i < kNumFailed; ++i) {
513     SendFailedEcho(0);
514   }
515   GetServersRequest request;
516   GetServersResponse response;
517   request.set_start_server_id(0);
518   ClientContext context;
519   Status s = channelz_stub_->GetServers(&context, request, &response);
520   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
521   EXPECT_EQ(response.server_size(), 1);
522   EXPECT_EQ(response.server(0).data().calls_succeeded(), kNumSuccess);
523   EXPECT_EQ(response.server(0).data().calls_failed(), kNumFailed);
524   // This is success+failure+1 because the call that retrieved this information
525   // will be counted as started. It will not track success/failure until after
526   // it has returned, so that is not included in the response.
527   EXPECT_EQ(response.server(0).data().calls_started(),
528             kNumSuccess + kNumFailed + 1);
529 }
530 
TEST_F(ChannelzServerTest,ManySubchannelsAndSockets)531 TEST_F(ChannelzServerTest, ManySubchannelsAndSockets) {
532   ResetStubs();
533   const int kNumChannels = 4;
534   ConfigureProxy(kNumChannels);
535   const int kNumSuccess = 10;
536   const int kNumFailed = 11;
537   for (int i = 0; i < kNumSuccess; ++i) {
538     SendSuccessfulEcho(0);
539     SendSuccessfulEcho(2);
540   }
541   for (int i = 0; i < kNumFailed; ++i) {
542     SendFailedEcho(1);
543     SendFailedEcho(2);
544   }
545   GetTopChannelsRequest gtc_request;
546   GetTopChannelsResponse gtc_response;
547   gtc_request.set_start_channel_id(0);
548   ClientContext context;
549   Status s =
550       channelz_stub_->GetTopChannels(&context, gtc_request, &gtc_response);
551   EXPECT_TRUE(s.ok()) << s.error_message();
552   EXPECT_EQ(gtc_response.channel_size(), kNumChannels);
553   for (int i = 0; i < gtc_response.channel_size(); ++i) {
554     // if the channel sent no RPCs, then expect no subchannels to have been
555     // created.
556     if (gtc_response.channel(i).data().calls_started() == 0) {
557       EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0);
558       continue;
559     }
560     // The resolver must return at least one address.
561     ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0);
562     // First grab the subchannel
563     GetSubchannelRequest get_subchannel_req;
564     GetSubchannelResponse get_subchannel_resp;
565     get_subchannel_req.set_subchannel_id(
566         gtc_response.channel(i).subchannel_ref(0).subchannel_id());
567     ClientContext get_subchannel_ctx;
568     Status s = channelz_stub_->GetSubchannel(
569         &get_subchannel_ctx, get_subchannel_req, &get_subchannel_resp);
570     EXPECT_TRUE(s.ok()) << s.error_message();
571     EXPECT_EQ(get_subchannel_resp.subchannel().socket_ref_size(), 1);
572     // Now grab the socket.
573     GetSocketRequest get_socket_req;
574     GetSocketResponse get_socket_resp;
575     ClientContext get_socket_ctx;
576     get_socket_req.set_socket_id(
577         get_subchannel_resp.subchannel().socket_ref(0).socket_id());
578     s = channelz_stub_->GetSocket(&get_socket_ctx, get_socket_req,
579                                   &get_socket_resp);
580     EXPECT_TRUE(
581         get_subchannel_resp.subchannel().socket_ref(0).name().find("http"));
582     EXPECT_TRUE(s.ok()) << s.error_message();
583     // calls started == streams started AND stream succeeded. Since none of
584     // these RPCs were canceled, all of the streams will succeeded even though
585     // the RPCs they represent might have failed.
586     EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(),
587               get_socket_resp.socket().data().streams_started());
588     EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(),
589               get_socket_resp.socket().data().streams_succeeded());
590     // All of the calls were unary, so calls started == messages sent.
591     EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(),
592               get_socket_resp.socket().data().messages_sent());
593     // We only get responses when the RPC was successful, so
594     // calls succeeded == messages received.
595     EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_succeeded(),
596               get_socket_resp.socket().data().messages_received());
597   }
598 }
599 
TEST_F(ChannelzServerTest,StreamingRPC)600 TEST_F(ChannelzServerTest, StreamingRPC) {
601   ResetStubs();
602   ConfigureProxy(1);
603   const int kNumMessages = 5;
604   SendSuccessfulStream(kNumMessages);
605   // Get the channel
606   GetChannelRequest get_channel_request;
607   GetChannelResponse get_channel_response;
608   get_channel_request.set_channel_id(GetChannelId(0));
609   ClientContext get_channel_context;
610   Status s = channelz_stub_->GetChannel(
611       &get_channel_context, get_channel_request, &get_channel_response);
612   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
613   EXPECT_EQ(get_channel_response.channel().data().calls_started(), 1);
614   EXPECT_EQ(get_channel_response.channel().data().calls_succeeded(), 1);
615   EXPECT_EQ(get_channel_response.channel().data().calls_failed(), 0);
616   // Get the subchannel
617   ASSERT_GT(get_channel_response.channel().subchannel_ref_size(), 0);
618   GetSubchannelRequest get_subchannel_request;
619   GetSubchannelResponse get_subchannel_response;
620   ClientContext get_subchannel_context;
621   get_subchannel_request.set_subchannel_id(
622       get_channel_response.channel().subchannel_ref(0).subchannel_id());
623   s = channelz_stub_->GetSubchannel(&get_subchannel_context,
624                                     get_subchannel_request,
625                                     &get_subchannel_response);
626   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
627   EXPECT_EQ(get_subchannel_response.subchannel().data().calls_started(), 1);
628   EXPECT_EQ(get_subchannel_response.subchannel().data().calls_succeeded(), 1);
629   EXPECT_EQ(get_subchannel_response.subchannel().data().calls_failed(), 0);
630   // Get the socket
631   ASSERT_GT(get_subchannel_response.subchannel().socket_ref_size(), 0);
632   GetSocketRequest get_socket_request;
633   GetSocketResponse get_socket_response;
634   ClientContext get_socket_context;
635   get_socket_request.set_socket_id(
636       get_subchannel_response.subchannel().socket_ref(0).socket_id());
637   EXPECT_TRUE(
638       get_subchannel_response.subchannel().socket_ref(0).name().find("http"));
639   s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request,
640                                 &get_socket_response);
641   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
642   EXPECT_EQ(get_socket_response.socket().data().streams_started(), 1);
643   EXPECT_EQ(get_socket_response.socket().data().streams_succeeded(), 1);
644   EXPECT_EQ(get_socket_response.socket().data().streams_failed(), 0);
645   EXPECT_EQ(get_socket_response.socket().data().messages_sent(), kNumMessages);
646   EXPECT_EQ(get_socket_response.socket().data().messages_received(),
647             kNumMessages);
648 }
649 
TEST_F(ChannelzServerTest,GetServerSocketsTest)650 TEST_F(ChannelzServerTest, GetServerSocketsTest) {
651   ResetStubs();
652   ConfigureProxy(1);
653   GetServersRequest get_server_request;
654   GetServersResponse get_server_response;
655   get_server_request.set_start_server_id(0);
656   ClientContext get_server_context;
657   Status s = channelz_stub_->GetServers(&get_server_context, get_server_request,
658                                         &get_server_response);
659   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
660   EXPECT_EQ(get_server_response.server_size(), 1);
661   GetServerSocketsRequest get_server_sockets_request;
662   GetServerSocketsResponse get_server_sockets_response;
663   get_server_sockets_request.set_server_id(
664       get_server_response.server(0).ref().server_id());
665   get_server_sockets_request.set_start_socket_id(0);
666   ClientContext get_server_sockets_context;
667   s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
668                                        get_server_sockets_request,
669                                        &get_server_sockets_response);
670   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
671   EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1);
672   EXPECT_TRUE(get_server_sockets_response.socket_ref(0).name().find("http"));
673 }
674 
TEST_F(ChannelzServerTest,GetServerSocketsPaginationTest)675 TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) {
676   ResetStubs();
677   ConfigureProxy(1);
678   std::vector<std::unique_ptr<grpc::testing::EchoTestService::Stub>> stubs;
679   const int kNumServerSocketsCreated = 20;
680   for (int i = 0; i < kNumServerSocketsCreated; ++i) {
681     stubs.push_back(NewEchoStub());
682     EchoRequest request;
683     EchoResponse response;
684     request.set_message("Hello channelz");
685     request.mutable_param()->set_backend_channel_idx(0);
686     ClientContext context;
687     Status s = stubs.back()->Echo(&context, request, &response);
688     EXPECT_EQ(response.message(), request.message());
689     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
690   }
691   GetServersRequest get_server_request;
692   GetServersResponse get_server_response;
693   get_server_request.set_start_server_id(0);
694   ClientContext get_server_context;
695   Status s = channelz_stub_->GetServers(&get_server_context, get_server_request,
696                                         &get_server_response);
697   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
698   EXPECT_EQ(get_server_response.server_size(), 1);
699   // Make a request that gets all of the serversockets
700   {
701     GetServerSocketsRequest get_server_sockets_request;
702     GetServerSocketsResponse get_server_sockets_response;
703     get_server_sockets_request.set_server_id(
704         get_server_response.server(0).ref().server_id());
705     get_server_sockets_request.set_start_socket_id(0);
706     ClientContext get_server_sockets_context;
707     s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
708                                          get_server_sockets_request,
709                                          &get_server_sockets_response);
710     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
711     // We add one to account the channelz stub that will end up creating
712     // a serversocket.
713     EXPECT_EQ(get_server_sockets_response.socket_ref_size(),
714               kNumServerSocketsCreated + 1);
715     EXPECT_TRUE(get_server_sockets_response.end());
716   }
717   // Now we make a request that exercises pagination.
718   {
719     GetServerSocketsRequest get_server_sockets_request;
720     GetServerSocketsResponse get_server_sockets_response;
721     get_server_sockets_request.set_server_id(
722         get_server_response.server(0).ref().server_id());
723     get_server_sockets_request.set_start_socket_id(0);
724     const int kMaxResults = 10;
725     get_server_sockets_request.set_max_results(kMaxResults);
726     ClientContext get_server_sockets_context;
727     s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
728                                          get_server_sockets_request,
729                                          &get_server_sockets_response);
730     EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
731     EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults);
732     EXPECT_FALSE(get_server_sockets_response.end());
733   }
734 }
735 
TEST_F(ChannelzServerTest,GetServerListenSocketsTest)736 TEST_F(ChannelzServerTest, GetServerListenSocketsTest) {
737   ResetStubs();
738   ConfigureProxy(1);
739   GetServersRequest get_server_request;
740   GetServersResponse get_server_response;
741   get_server_request.set_start_server_id(0);
742   ClientContext get_server_context;
743   Status s = channelz_stub_->GetServers(&get_server_context, get_server_request,
744                                         &get_server_response);
745   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
746   EXPECT_EQ(get_server_response.server_size(), 1);
747   EXPECT_EQ(get_server_response.server(0).listen_socket_size(), 1);
748   GetSocketRequest get_socket_request;
749   GetSocketResponse get_socket_response;
750   get_socket_request.set_socket_id(
751       get_server_response.server(0).listen_socket(0).socket_id());
752   EXPECT_TRUE(
753       get_server_response.server(0).listen_socket(0).name().find("http"));
754   ClientContext get_socket_context;
755   s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request,
756                                 &get_socket_response);
757   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
758 }
759 
760 }  // namespace testing
761 }  // namespace grpc
762 
main(int argc,char ** argv)763 int main(int argc, char** argv) {
764   grpc::testing::TestEnvironment env(argc, argv);
765   ::testing::InitGoogleTest(&argc, argv);
766   return RUN_ALL_TESTS();
767 }
768