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
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <grpc/grpc.h>
23 #include <gtest/gtest.h>
24
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/string_util.h>
28
29 #include "src/core/lib/channel/channel_trace.h"
30 #include "src/core/lib/channel/channelz.h"
31 #include "src/core/lib/channel/channelz_registry.h"
32 #include "src/core/lib/gpr/useful.h"
33 #include "src/core/lib/gprpp/memory.h"
34 #include "src/core/lib/iomgr/exec_ctx.h"
35 #include "src/core/lib/json/json.h"
36 #include "src/core/lib/surface/channel.h"
37 #include "test/core/util/test_config.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 namespace grpc_core {
43 namespace channelz {
44 namespace testing {
45
46 class ChannelzRegistryTest : public ::testing::Test {
47 protected:
48 // ensure we always have a fresh registry for tests.
SetUp()49 void SetUp() override { ChannelzRegistry::Init(); }
50
TearDown()51 void TearDown() override { ChannelzRegistry::Shutdown(); }
52 };
53
CreateTestNode()54 static RefCountedPtr<BaseNode> CreateTestNode() {
55 return MakeRefCounted<ListenSocketNode>("test", "test");
56 }
57
TEST_F(ChannelzRegistryTest,UuidStartsAboveZeroTest)58 TEST_F(ChannelzRegistryTest, UuidStartsAboveZeroTest) {
59 RefCountedPtr<BaseNode> channelz_channel = CreateTestNode();
60 intptr_t uuid = channelz_channel->uuid();
61 EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if "
62 "reserved according to "
63 "https://github.com/grpc/proposal/blob/master/"
64 "A14-channelz.md";
65 }
66
TEST_F(ChannelzRegistryTest,UuidsAreIncreasing)67 TEST_F(ChannelzRegistryTest, UuidsAreIncreasing) {
68 std::vector<RefCountedPtr<BaseNode>> channelz_channels;
69 channelz_channels.reserve(10);
70 for (int i = 0; i < 10; ++i) {
71 channelz_channels.push_back(CreateTestNode());
72 }
73 for (size_t i = 1; i < channelz_channels.size(); ++i) {
74 EXPECT_LT(channelz_channels[i - 1]->uuid(), channelz_channels[i]->uuid())
75 << "Uuids must always be increasing";
76 }
77 }
78
TEST_F(ChannelzRegistryTest,RegisterGetTest)79 TEST_F(ChannelzRegistryTest, RegisterGetTest) {
80 RefCountedPtr<BaseNode> channelz_channel = CreateTestNode();
81 RefCountedPtr<BaseNode> retrieved =
82 ChannelzRegistry::Get(channelz_channel->uuid());
83 EXPECT_EQ(channelz_channel, retrieved);
84 }
85
TEST_F(ChannelzRegistryTest,RegisterManyItems)86 TEST_F(ChannelzRegistryTest, RegisterManyItems) {
87 std::vector<RefCountedPtr<BaseNode>> channelz_channels;
88 for (int i = 0; i < 100; i++) {
89 channelz_channels.push_back(CreateTestNode());
90 RefCountedPtr<BaseNode> retrieved =
91 ChannelzRegistry::Get(channelz_channels[i]->uuid());
92 EXPECT_EQ(channelz_channels[i], retrieved);
93 }
94 }
95
TEST_F(ChannelzRegistryTest,NullIfNotPresentTest)96 TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) {
97 RefCountedPtr<BaseNode> channelz_channel = CreateTestNode();
98 // try to pull out a uuid that does not exist.
99 RefCountedPtr<BaseNode> nonexistant =
100 ChannelzRegistry::Get(channelz_channel->uuid() + 1);
101 EXPECT_EQ(nonexistant, nullptr);
102 RefCountedPtr<BaseNode> retrieved =
103 ChannelzRegistry::Get(channelz_channel->uuid());
104 EXPECT_EQ(channelz_channel, retrieved);
105 }
106
TEST_F(ChannelzRegistryTest,TestUnregistration)107 TEST_F(ChannelzRegistryTest, TestUnregistration) {
108 const int kLoopIterations = 100;
109 // These channels will stay in the registry for the duration of the test.
110 std::vector<RefCountedPtr<BaseNode>> even_channels;
111 even_channels.reserve(kLoopIterations);
112 std::vector<intptr_t> odd_uuids;
113 odd_uuids.reserve(kLoopIterations);
114 {
115 // These channels will unregister themselves at the end of this block.
116 std::vector<RefCountedPtr<BaseNode>> odd_channels;
117 odd_channels.reserve(kLoopIterations);
118 for (int i = 0; i < kLoopIterations; i++) {
119 even_channels.push_back(CreateTestNode());
120 odd_channels.push_back(CreateTestNode());
121 odd_uuids.push_back(odd_channels[i]->uuid());
122 }
123 }
124 // Check that the even channels are present and the odd channels are not.
125 for (int i = 0; i < kLoopIterations; i++) {
126 RefCountedPtr<BaseNode> retrieved =
127 ChannelzRegistry::Get(even_channels[i]->uuid());
128 EXPECT_EQ(even_channels[i], retrieved);
129 retrieved = ChannelzRegistry::Get(odd_uuids[i]);
130 EXPECT_EQ(retrieved, nullptr);
131 }
132 // Add more channels and verify that they get added correctly, to make
133 // sure that the unregistration didn't leave the registry in a weird state.
134 std::vector<RefCountedPtr<BaseNode>> more_channels;
135 more_channels.reserve(kLoopIterations);
136 for (int i = 0; i < kLoopIterations; i++) {
137 more_channels.push_back(CreateTestNode());
138 RefCountedPtr<BaseNode> retrieved =
139 ChannelzRegistry::Get(more_channels[i]->uuid());
140 EXPECT_EQ(more_channels[i], retrieved);
141 }
142 }
143
144 } // namespace testing
145 } // namespace channelz
146 } // namespace grpc_core
147
main(int argc,char ** argv)148 int main(int argc, char** argv) {
149 grpc::testing::TestEnvironment env(argc, argv);
150 ::testing::InitGoogleTest(&argc, argv);
151 int ret = RUN_ALL_TESTS();
152 return ret;
153 }
154