channelz_service_test.cc 37 KB

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