channelz_test.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  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. #include "src/core/lib/channel/channelz.h"
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <gtest/gtest.h>
  22. #include <grpc/grpc_security.h>
  23. #include <grpc/support/alloc.h>
  24. #include <grpc/support/log.h>
  25. #include <grpc/support/string_util.h>
  26. #include "src/core/lib/channel/channel_trace.h"
  27. #include "src/core/lib/channel/channelz_registry.h"
  28. #include "src/core/lib/gpr/useful.h"
  29. #include "src/core/lib/iomgr/exec_ctx.h"
  30. #include "src/core/lib/json/json.h"
  31. #include "src/core/lib/surface/channel.h"
  32. #include "src/core/lib/surface/server.h"
  33. #include "test/core/util/test_config.h"
  34. #include "test/cpp/util/channel_trace_proto_helper.h"
  35. namespace grpc_core {
  36. namespace channelz {
  37. namespace testing {
  38. // testing peer to access channel internals
  39. class CallCountingHelperPeer {
  40. public:
  41. explicit CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {}
  42. gpr_timespec last_call_started_time() const {
  43. CallCountingHelper::CounterData data;
  44. node_->CollectData(&data);
  45. return gpr_cycle_counter_to_time(data.last_call_started_cycle);
  46. }
  47. private:
  48. CallCountingHelper* node_;
  49. };
  50. namespace {
  51. std::vector<intptr_t> GetUuidListFromArray(const Json::Array& arr) {
  52. std::vector<intptr_t> uuids;
  53. for (const Json& value : arr) {
  54. EXPECT_EQ(value.type(), Json::Type::OBJECT);
  55. if (value.type() != Json::Type::OBJECT) continue;
  56. const Json::Object& object = value.object_value();
  57. auto it = object.find("ref");
  58. EXPECT_NE(it, object.end());
  59. if (it == object.end()) continue;
  60. EXPECT_EQ(it->second.type(), Json::Type::OBJECT);
  61. if (it->second.type() != Json::Type::OBJECT) continue;
  62. const Json::Object& ref_object = it->second.object_value();
  63. it = ref_object.find("channelId");
  64. EXPECT_NE(it, ref_object.end());
  65. if (it != ref_object.end()) {
  66. uuids.push_back(atoi(it->second.string_value().c_str()));
  67. }
  68. }
  69. return uuids;
  70. }
  71. void ValidateJsonArraySize(const Json& array, size_t expected) {
  72. if (expected == 0) {
  73. ASSERT_EQ(array.type(), Json::Type::JSON_NULL);
  74. } else {
  75. ASSERT_EQ(array.type(), Json::Type::ARRAY);
  76. EXPECT_EQ(array.array_value().size(), expected);
  77. }
  78. }
  79. void ValidateJsonEnd(const Json& json, bool end) {
  80. auto it = json.object_value().find("end");
  81. if (end) {
  82. ASSERT_NE(it, json.object_value().end());
  83. EXPECT_EQ(it->second.type(), Json::Type::JSON_TRUE);
  84. } else {
  85. ASSERT_EQ(it, json.object_value().end());
  86. }
  87. }
  88. void ValidateGetTopChannels(size_t expected_channels) {
  89. std::string json_str = ChannelzRegistry::GetTopChannels(0);
  90. grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(
  91. json_str.c_str());
  92. grpc_error_handle error = GRPC_ERROR_NONE;
  93. Json parsed_json = Json::Parse(json_str, &error);
  94. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  95. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  96. // This check will naturally have to change when we support pagination.
  97. // tracked: https://github.com/grpc/grpc/issues/16019.
  98. ValidateJsonArraySize((*parsed_json.mutable_object())["channel"],
  99. expected_channels);
  100. ValidateJsonEnd(parsed_json, true);
  101. // Also check that the core API formats this correctly.
  102. char* core_api_json_str = grpc_channelz_get_top_channels(0);
  103. grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(
  104. core_api_json_str);
  105. gpr_free(core_api_json_str);
  106. }
  107. void ValidateGetServers(size_t expected_servers) {
  108. std::string json_str = ChannelzRegistry::GetServers(0);
  109. grpc::testing::ValidateGetServersResponseProtoJsonTranslation(
  110. json_str.c_str());
  111. grpc_error_handle error = GRPC_ERROR_NONE;
  112. Json parsed_json = Json::Parse(json_str, &error);
  113. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  114. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  115. // This check will naturally have to change when we support pagination.
  116. // tracked: https://github.com/grpc/grpc/issues/16019.
  117. ValidateJsonArraySize((*parsed_json.mutable_object())["server"],
  118. expected_servers);
  119. ValidateJsonEnd(parsed_json, true);
  120. // Also check that the core API formats this correctly.
  121. char* core_api_json_str = grpc_channelz_get_servers(0);
  122. grpc::testing::ValidateGetServersResponseProtoJsonTranslation(
  123. core_api_json_str);
  124. gpr_free(core_api_json_str);
  125. }
  126. class ChannelFixture {
  127. public:
  128. explicit ChannelFixture(int max_tracer_event_memory = 0) {
  129. grpc_arg client_a[] = {
  130. grpc_channel_arg_integer_create(
  131. const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
  132. max_tracer_event_memory),
  133. grpc_channel_arg_integer_create(
  134. const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
  135. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  136. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  137. channel_ = grpc_channel_create("fake_target", creds, &client_args);
  138. grpc_channel_credentials_release(creds);
  139. }
  140. ~ChannelFixture() { grpc_channel_destroy(channel_); }
  141. grpc_channel* channel() { return channel_; }
  142. private:
  143. grpc_channel* channel_;
  144. };
  145. class ServerFixture {
  146. public:
  147. explicit ServerFixture(int max_tracer_event_memory = 0) {
  148. grpc_arg server_a[] = {
  149. grpc_channel_arg_integer_create(
  150. const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
  151. max_tracer_event_memory),
  152. grpc_channel_arg_integer_create(
  153. const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true),
  154. };
  155. grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a};
  156. server_ = grpc_server_create(&server_args, nullptr);
  157. }
  158. ~ServerFixture() { grpc_server_destroy(server_); }
  159. grpc_server* server() const { return server_; }
  160. private:
  161. grpc_server* server_;
  162. };
  163. struct ValidateChannelDataArgs {
  164. int64_t calls_started;
  165. int64_t calls_failed;
  166. int64_t calls_succeeded;
  167. };
  168. void ValidateChildInteger(const Json::Object& object, const std::string& key,
  169. int64_t expected) {
  170. auto it = object.find(key);
  171. if (expected == 0) {
  172. ASSERT_EQ(it, object.end());
  173. return;
  174. }
  175. ASSERT_NE(it, object.end());
  176. ASSERT_EQ(it->second.type(), Json::Type::STRING);
  177. int64_t gotten_number = static_cast<int64_t>(
  178. strtol(it->second.string_value().c_str(), nullptr, 0));
  179. EXPECT_EQ(gotten_number, expected);
  180. }
  181. void ValidateCounters(const std::string& json_str,
  182. const ValidateChannelDataArgs& args) {
  183. grpc_error_handle error = GRPC_ERROR_NONE;
  184. Json json = Json::Parse(json_str, &error);
  185. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  186. ASSERT_EQ(json.type(), Json::Type::OBJECT);
  187. Json::Object* object = json.mutable_object();
  188. Json& data = (*object)["data"];
  189. ASSERT_EQ(data.type(), Json::Type::OBJECT);
  190. ValidateChildInteger(data.object_value(), "callsStarted", args.calls_started);
  191. ValidateChildInteger(data.object_value(), "callsFailed", args.calls_failed);
  192. ValidateChildInteger(data.object_value(), "callsSucceeded",
  193. args.calls_succeeded);
  194. }
  195. void ValidateChannel(ChannelNode* channel,
  196. const ValidateChannelDataArgs& args) {
  197. std::string json_str = channel->RenderJsonString();
  198. grpc::testing::ValidateChannelProtoJsonTranslation(json_str.c_str());
  199. ValidateCounters(json_str, args);
  200. // also check that the core API formats this the correct way
  201. char* core_api_json_str = grpc_channelz_get_channel(channel->uuid());
  202. grpc::testing::ValidateGetChannelResponseProtoJsonTranslation(
  203. core_api_json_str);
  204. gpr_free(core_api_json_str);
  205. }
  206. void ValidateServer(ServerNode* server, const ValidateChannelDataArgs& args) {
  207. std::string json_str = server->RenderJsonString();
  208. grpc::testing::ValidateServerProtoJsonTranslation(json_str.c_str());
  209. ValidateCounters(json_str, args);
  210. // also check that the core API formats this the correct way
  211. char* core_api_json_str = grpc_channelz_get_server(server->uuid());
  212. grpc::testing::ValidateGetServerResponseProtoJsonTranslation(
  213. core_api_json_str);
  214. gpr_free(core_api_json_str);
  215. }
  216. gpr_timespec GetLastCallStartedTime(CallCountingHelper* channel) {
  217. CallCountingHelperPeer peer(channel);
  218. return peer.last_call_started_time();
  219. }
  220. void ChannelzSleep(int64_t sleep_us) {
  221. gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
  222. gpr_time_from_micros(sleep_us, GPR_TIMESPAN)));
  223. ExecCtx::Get()->InvalidateNow();
  224. }
  225. } // anonymous namespace
  226. class ChannelzChannelTest : public ::testing::TestWithParam<size_t> {};
  227. TEST_P(ChannelzChannelTest, BasicChannel) {
  228. ExecCtx exec_ctx;
  229. ChannelFixture channel(GetParam());
  230. ChannelNode* channelz_channel =
  231. grpc_channel_get_channelz_node(channel.channel());
  232. ValidateChannel(channelz_channel, {0, 0, 0});
  233. }
  234. TEST(ChannelzChannelTest, ChannelzDisabled) {
  235. ExecCtx exec_ctx;
  236. // explicitly disable channelz
  237. grpc_arg arg[] = {
  238. grpc_channel_arg_integer_create(
  239. const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
  240. 0),
  241. grpc_channel_arg_integer_create(
  242. const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), false)};
  243. grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
  244. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  245. grpc_channel* channel = grpc_channel_create("fake_target", creds, &args);
  246. grpc_channel_credentials_release(creds);
  247. ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel);
  248. ASSERT_EQ(channelz_channel, nullptr);
  249. grpc_channel_destroy(channel);
  250. }
  251. TEST_P(ChannelzChannelTest, BasicChannelAPIFunctionality) {
  252. ExecCtx exec_ctx;
  253. ChannelFixture channel(GetParam());
  254. ChannelNode* channelz_channel =
  255. grpc_channel_get_channelz_node(channel.channel());
  256. channelz_channel->RecordCallStarted();
  257. channelz_channel->RecordCallFailed();
  258. channelz_channel->RecordCallSucceeded();
  259. ValidateChannel(channelz_channel, {1, 1, 1});
  260. channelz_channel->RecordCallStarted();
  261. channelz_channel->RecordCallFailed();
  262. channelz_channel->RecordCallSucceeded();
  263. channelz_channel->RecordCallStarted();
  264. channelz_channel->RecordCallFailed();
  265. channelz_channel->RecordCallSucceeded();
  266. ValidateChannel(channelz_channel, {3, 3, 3});
  267. }
  268. TEST_P(ChannelzChannelTest, LastCallStartedTime) {
  269. ExecCtx exec_ctx;
  270. CallCountingHelper counter;
  271. // start a call to set the last call started timestamp
  272. counter.RecordCallStarted();
  273. gpr_timespec time1 = GetLastCallStartedTime(&counter);
  274. // time gone by should not affect the timestamp
  275. ChannelzSleep(100);
  276. gpr_timespec time2 = GetLastCallStartedTime(&counter);
  277. EXPECT_EQ(gpr_time_cmp(time1, time2), 0);
  278. // calls succeeded or failed should not affect the timestamp
  279. ChannelzSleep(100);
  280. counter.RecordCallFailed();
  281. counter.RecordCallSucceeded();
  282. gpr_timespec time3 = GetLastCallStartedTime(&counter);
  283. EXPECT_EQ(gpr_time_cmp(time1, time3), 0);
  284. // another call started should affect the timestamp
  285. // sleep for extra long to avoid flakes (since we cache Now())
  286. ChannelzSleep(5000);
  287. counter.RecordCallStarted();
  288. gpr_timespec time4 = GetLastCallStartedTime(&counter);
  289. EXPECT_NE(gpr_time_cmp(time1, time4), 0);
  290. }
  291. class ChannelzRegistryBasedTest : public ::testing::TestWithParam<size_t> {
  292. protected:
  293. // ensure we always have a fresh registry for tests.
  294. void SetUp() override {
  295. ChannelzRegistry::Shutdown();
  296. ChannelzRegistry::Init();
  297. }
  298. void TearDown() override {
  299. ChannelzRegistry::Shutdown();
  300. ChannelzRegistry::Init();
  301. }
  302. };
  303. TEST_F(ChannelzRegistryBasedTest, BasicGetTopChannelsTest) {
  304. ExecCtx exec_ctx;
  305. ChannelFixture channel;
  306. ValidateGetTopChannels(1);
  307. }
  308. TEST_F(ChannelzRegistryBasedTest, NoChannelsTest) {
  309. ExecCtx exec_ctx;
  310. ValidateGetTopChannels(0);
  311. }
  312. TEST_F(ChannelzRegistryBasedTest, ManyChannelsTest) {
  313. ExecCtx exec_ctx;
  314. ChannelFixture channels[10];
  315. (void)channels; // suppress unused variable error
  316. ValidateGetTopChannels(10);
  317. }
  318. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsPagination) {
  319. ExecCtx exec_ctx;
  320. // This is over the pagination limit.
  321. ChannelFixture channels[150];
  322. (void)channels; // suppress unused variable error
  323. std::string json_str = ChannelzRegistry::GetTopChannels(0);
  324. grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(
  325. json_str.c_str());
  326. grpc_error_handle error = GRPC_ERROR_NONE;
  327. Json parsed_json = Json::Parse(json_str, &error);
  328. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  329. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  330. // 100 is the pagination limit.
  331. ValidateJsonArraySize((*parsed_json.mutable_object())["channel"], 100);
  332. ValidateJsonEnd(parsed_json, false);
  333. // Now we get the rest.
  334. json_str = ChannelzRegistry::GetTopChannels(101);
  335. grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(
  336. json_str.c_str());
  337. error = GRPC_ERROR_NONE;
  338. parsed_json = Json::Parse(json_str, &error);
  339. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  340. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  341. ValidateJsonArraySize((*parsed_json.mutable_object())["channel"], 50);
  342. ValidateJsonEnd(parsed_json, true);
  343. }
  344. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidCheck) {
  345. const intptr_t kNumChannels = 50;
  346. ExecCtx exec_ctx;
  347. ChannelFixture channels[kNumChannels];
  348. (void)channels; // suppress unused variable error
  349. std::string json_str = ChannelzRegistry::GetTopChannels(0);
  350. grpc_error_handle error = GRPC_ERROR_NONE;
  351. Json parsed_json = Json::Parse(json_str, &error);
  352. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  353. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  354. Json& array = (*parsed_json.mutable_object())["channel"];
  355. ValidateJsonArraySize(array, kNumChannels);
  356. std::vector<intptr_t> uuids = GetUuidListFromArray(array.array_value());
  357. for (int i = 0; i < kNumChannels; ++i) {
  358. EXPECT_EQ(i + 1, uuids[i]);
  359. }
  360. }
  361. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMiddleUuidCheck) {
  362. const intptr_t kNumChannels = 50;
  363. const intptr_t kMidQuery = 40;
  364. ExecCtx exec_ctx;
  365. ChannelFixture channels[kNumChannels];
  366. (void)channels; // suppress unused variable error
  367. // Only query for the end of the channels.
  368. std::string json_str = ChannelzRegistry::GetTopChannels(kMidQuery);
  369. grpc_error_handle error = GRPC_ERROR_NONE;
  370. Json parsed_json = Json::Parse(json_str, &error);
  371. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  372. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  373. Json& array = (*parsed_json.mutable_object())["channel"];
  374. ValidateJsonArraySize(array, kNumChannels - kMidQuery + 1);
  375. std::vector<intptr_t> uuids = GetUuidListFromArray(array.array_value());
  376. for (size_t i = 0; i < uuids.size(); ++i) {
  377. EXPECT_EQ(static_cast<intptr_t>(kMidQuery + i), uuids[i]);
  378. }
  379. }
  380. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsNoHitUuid) {
  381. ExecCtx exec_ctx;
  382. ChannelFixture pre_channels[40]; // will take uuid[1, 40]
  383. (void)pre_channels; // suppress unused variable error
  384. ServerFixture servers[10]; // will take uuid[41, 50]
  385. (void)servers; // suppress unused variable error
  386. ChannelFixture channels[10]; // will take uuid[51, 60]
  387. (void)channels; // suppress unused variable error
  388. // Query in the middle of the server channels.
  389. std::string json_str = ChannelzRegistry::GetTopChannels(45);
  390. grpc_error_handle error = GRPC_ERROR_NONE;
  391. Json parsed_json = Json::Parse(json_str, &error);
  392. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  393. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  394. Json& array = (*parsed_json.mutable_object())["channel"];
  395. ValidateJsonArraySize(array, 10);
  396. std::vector<intptr_t> uuids = GetUuidListFromArray(array.array_value());
  397. for (size_t i = 0; i < uuids.size(); ++i) {
  398. EXPECT_EQ(static_cast<intptr_t>(51 + i), uuids[i]);
  399. }
  400. }
  401. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMoreGaps) {
  402. ExecCtx exec_ctx;
  403. ChannelFixture channel_with_uuid1;
  404. { ServerFixture channel_with_uuid2; }
  405. ChannelFixture channel_with_uuid3;
  406. { ServerFixture server_with_uuid4; }
  407. ChannelFixture channel_with_uuid5;
  408. // Current state of list: [1, NULL, 3, NULL, 5]
  409. std::string json_str = ChannelzRegistry::GetTopChannels(2);
  410. grpc_error_handle error = GRPC_ERROR_NONE;
  411. Json parsed_json = Json::Parse(json_str, &error);
  412. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  413. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  414. Json array = (*parsed_json.mutable_object())["channel"];
  415. ValidateJsonArraySize(array, 2);
  416. std::vector<intptr_t> uuids = GetUuidListFromArray(array.array_value());
  417. EXPECT_EQ(static_cast<intptr_t>(3), uuids[0]);
  418. EXPECT_EQ(static_cast<intptr_t>(5), uuids[1]);
  419. json_str = ChannelzRegistry::GetTopChannels(4);
  420. error = GRPC_ERROR_NONE;
  421. parsed_json = Json::Parse(json_str, &error);
  422. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  423. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  424. array = (*parsed_json.mutable_object())["channel"];
  425. ValidateJsonArraySize(array, 1);
  426. uuids = GetUuidListFromArray(array.array_value());
  427. EXPECT_EQ(static_cast<intptr_t>(5), uuids[0]);
  428. }
  429. TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidAfterCompaction) {
  430. const intptr_t kLoopIterations = 50;
  431. ExecCtx exec_ctx;
  432. std::vector<std::unique_ptr<ChannelFixture>> even_channels;
  433. {
  434. // these will delete and unregister themselves after this block.
  435. std::vector<std::unique_ptr<ChannelFixture>> odd_channels;
  436. for (int i = 0; i < kLoopIterations; i++) {
  437. odd_channels.push_back(absl::make_unique<ChannelFixture>());
  438. even_channels.push_back(absl::make_unique<ChannelFixture>());
  439. }
  440. }
  441. std::string json_str = ChannelzRegistry::GetTopChannels(0);
  442. grpc_error_handle error = GRPC_ERROR_NONE;
  443. Json parsed_json = Json::Parse(json_str, &error);
  444. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
  445. ASSERT_EQ(parsed_json.type(), Json::Type::OBJECT);
  446. Json& array = (*parsed_json.mutable_object())["channel"];
  447. ValidateJsonArraySize(array, kLoopIterations);
  448. std::vector<intptr_t> uuids = GetUuidListFromArray(array.array_value());
  449. for (int i = 0; i < kLoopIterations; ++i) {
  450. // only the even uuids will still be present.
  451. EXPECT_EQ((i + 1) * 2, uuids[i]);
  452. }
  453. }
  454. TEST_F(ChannelzRegistryBasedTest, InternalChannelTest) {
  455. ExecCtx exec_ctx;
  456. ChannelFixture channels[10];
  457. (void)channels; // suppress unused variable error
  458. // create an internal channel
  459. grpc_arg client_a[] = {
  460. grpc_channel_arg_integer_create(
  461. const_cast<char*>(GRPC_ARG_CHANNELZ_IS_INTERNAL_CHANNEL), 1),
  462. grpc_channel_arg_integer_create(
  463. const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true),
  464. };
  465. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  466. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  467. grpc_channel* internal_channel =
  468. grpc_channel_create("fake_target", creds, &client_args);
  469. grpc_channel_credentials_release(creds);
  470. // The internal channel should not be returned from the request
  471. ValidateGetTopChannels(10);
  472. grpc_channel_destroy(internal_channel);
  473. }
  474. TEST(ChannelzServerTest, BasicServerAPIFunctionality) {
  475. ExecCtx exec_ctx;
  476. ServerFixture server(10);
  477. ServerNode* channelz_server = Server::FromC(server.server())->channelz_node();
  478. channelz_server->RecordCallStarted();
  479. channelz_server->RecordCallFailed();
  480. channelz_server->RecordCallSucceeded();
  481. ValidateServer(channelz_server, {1, 1, 1});
  482. channelz_server->RecordCallStarted();
  483. channelz_server->RecordCallFailed();
  484. channelz_server->RecordCallSucceeded();
  485. channelz_server->RecordCallStarted();
  486. channelz_server->RecordCallFailed();
  487. channelz_server->RecordCallSucceeded();
  488. ValidateServer(channelz_server, {3, 3, 3});
  489. }
  490. TEST_F(ChannelzRegistryBasedTest, BasicGetServersTest) {
  491. ExecCtx exec_ctx;
  492. ServerFixture server;
  493. ValidateGetServers(1);
  494. }
  495. TEST_F(ChannelzRegistryBasedTest, NoServersTest) {
  496. ExecCtx exec_ctx;
  497. ValidateGetServers(0);
  498. }
  499. TEST_F(ChannelzRegistryBasedTest, ManyServersTest) {
  500. ExecCtx exec_ctx;
  501. ServerFixture servers[10];
  502. (void)servers; // suppress unused variable error
  503. ValidateGetServers(10);
  504. }
  505. INSTANTIATE_TEST_SUITE_P(ChannelzChannelTestSweep, ChannelzChannelTest,
  506. ::testing::Values(0, 8, 64, 1024, 1024 * 1024));
  507. } // namespace testing
  508. } // namespace channelz
  509. } // namespace grpc_core
  510. int main(int argc, char** argv) {
  511. grpc::testing::TestEnvironment env(argc, argv);
  512. grpc_init();
  513. ::testing::InitGoogleTest(&argc, argv);
  514. int ret = RUN_ALL_TESTS();
  515. grpc_shutdown();
  516. return ret;
  517. }