|  | @@ -43,56 +43,151 @@ namespace grpc_core {
 | 
	
		
			
				|  |  |  namespace channelz {
 | 
	
		
			
				|  |  |  namespace testing {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -TEST(ChannelzRegistryTest, UuidStartsAboveZeroTest) {
 | 
	
		
			
				|  |  | -  BaseNode* channelz_channel = nullptr;
 | 
	
		
			
				|  |  | -  intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
 | 
	
		
			
				|  |  | +class ChannelzRegistryPeer {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  const InlinedVector<BaseNode*, 20>* entities() {
 | 
	
		
			
				|  |  | +    return &ChannelzRegistry::Default()->entities_;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  int num_empty_slots() {
 | 
	
		
			
				|  |  | +    return ChannelzRegistry::Default()->num_empty_slots_;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class ChannelzRegistryTest : public ::testing::Test {
 | 
	
		
			
				|  |  | + protected:
 | 
	
		
			
				|  |  | +  // ensure we always have a fresh registry for tests.
 | 
	
		
			
				|  |  | +  void SetUp() override { ChannelzRegistry::Init(); }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void TearDown() override { ChannelzRegistry::Shutdown(); }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, UuidStartsAboveZeroTest) {
 | 
	
		
			
				|  |  | +  UniquePtr<BaseNode> channelz_channel =
 | 
	
		
			
				|  |  | +      MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel);
 | 
	
		
			
				|  |  | +  intptr_t uuid = channelz_channel->uuid();
 | 
	
		
			
				|  |  |    EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if "
 | 
	
		
			
				|  |  |                          "reserved according to "
 | 
	
		
			
				|  |  |                          "https://github.com/grpc/proposal/blob/master/"
 | 
	
		
			
				|  |  |                          "A14-channelz.md";
 | 
	
		
			
				|  |  | -  ChannelzRegistry::Unregister(uuid);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -TEST(ChannelzRegistryTest, UuidsAreIncreasing) {
 | 
	
		
			
				|  |  | -  BaseNode* channelz_channel = nullptr;
 | 
	
		
			
				|  |  | -  std::vector<intptr_t> uuids;
 | 
	
		
			
				|  |  | -  uuids.reserve(10);
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, UuidsAreIncreasing) {
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> channelz_channels;
 | 
	
		
			
				|  |  | +  channelz_channels.reserve(10);
 | 
	
		
			
				|  |  |    for (int i = 0; i < 10; ++i) {
 | 
	
		
			
				|  |  | -    // reregister the same object. It's ok since we are just testing uuids
 | 
	
		
			
				|  |  | -    uuids.push_back(ChannelzRegistry::Register(channelz_channel));
 | 
	
		
			
				|  |  | +    channelz_channels.push_back(
 | 
	
		
			
				|  |  | +        MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  for (size_t i = 1; i < uuids.size(); ++i) {
 | 
	
		
			
				|  |  | -    EXPECT_LT(uuids[i - 1], uuids[i]) << "Uuids must always be increasing";
 | 
	
		
			
				|  |  | +  for (size_t i = 1; i < channelz_channels.size(); ++i) {
 | 
	
		
			
				|  |  | +    EXPECT_LT(channelz_channels[i - 1]->uuid(), channelz_channels[i]->uuid())
 | 
	
		
			
				|  |  | +        << "Uuids must always be increasing";
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -TEST(ChannelzRegistryTest, RegisterGetTest) {
 | 
	
		
			
				|  |  | -  // we hackily jam an intptr_t into this pointer to check for equality later
 | 
	
		
			
				|  |  | -  BaseNode* channelz_channel = (BaseNode*)42;
 | 
	
		
			
				|  |  | -  intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
 | 
	
		
			
				|  |  | -  BaseNode* retrieved = ChannelzRegistry::Get(uuid);
 | 
	
		
			
				|  |  | -  EXPECT_EQ(channelz_channel, retrieved);
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, RegisterGetTest) {
 | 
	
		
			
				|  |  | +  UniquePtr<BaseNode> channelz_channel =
 | 
	
		
			
				|  |  | +      MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel);
 | 
	
		
			
				|  |  | +  BaseNode* retrieved = ChannelzRegistry::Get(channelz_channel->uuid());
 | 
	
		
			
				|  |  | +  EXPECT_EQ(channelz_channel.get(), retrieved);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -TEST(ChannelzRegistryTest, RegisterManyItems) {
 | 
	
		
			
				|  |  | -  // we hackily jam an intptr_t into this pointer to check for equality later
 | 
	
		
			
				|  |  | -  BaseNode* channelz_channel = (BaseNode*)42;
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, RegisterManyItems) {
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> channelz_channels;
 | 
	
		
			
				|  |  |    for (int i = 0; i < 100; i++) {
 | 
	
		
			
				|  |  | -    intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
 | 
	
		
			
				|  |  | -    BaseNode* retrieved = ChannelzRegistry::Get(uuid);
 | 
	
		
			
				|  |  | -    EXPECT_EQ(channelz_channel, retrieved);
 | 
	
		
			
				|  |  | +    channelz_channels.push_back(
 | 
	
		
			
				|  |  | +        MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +    BaseNode* retrieved = ChannelzRegistry::Get(channelz_channels[i]->uuid());
 | 
	
		
			
				|  |  | +    EXPECT_EQ(channelz_channels[i].get(), retrieved);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -TEST(ChannelzRegistryTest, NullIfNotPresentTest) {
 | 
	
		
			
				|  |  | -  // we hackily jam an intptr_t into this pointer to check for equality later
 | 
	
		
			
				|  |  | -  BaseNode* channelz_channel = (BaseNode*)42;
 | 
	
		
			
				|  |  | -  intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) {
 | 
	
		
			
				|  |  | +  UniquePtr<BaseNode> channelz_channel =
 | 
	
		
			
				|  |  | +      MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel);
 | 
	
		
			
				|  |  |    // try to pull out a uuid that does not exist.
 | 
	
		
			
				|  |  | -  BaseNode* nonexistant = ChannelzRegistry::Get(uuid + 1);
 | 
	
		
			
				|  |  | +  BaseNode* nonexistant = ChannelzRegistry::Get(channelz_channel->uuid() + 1);
 | 
	
		
			
				|  |  |    EXPECT_EQ(nonexistant, nullptr);
 | 
	
		
			
				|  |  | -  BaseNode* retrieved = ChannelzRegistry::Get(uuid);
 | 
	
		
			
				|  |  | -  EXPECT_EQ(channelz_channel, retrieved);
 | 
	
		
			
				|  |  | +  BaseNode* retrieved = ChannelzRegistry::Get(channelz_channel->uuid());
 | 
	
		
			
				|  |  | +  EXPECT_EQ(channelz_channel.get(), retrieved);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, TestCompaction) {
 | 
	
		
			
				|  |  | +  const int kLoopIterations = 100;
 | 
	
		
			
				|  |  | +  // These channels that will stay in the registry for the duration of the test.
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> even_channels;
 | 
	
		
			
				|  |  | +  even_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    // The channels will unregister themselves at the end of the for block.
 | 
	
		
			
				|  |  | +    std::vector<UniquePtr<BaseNode>> odd_channels;
 | 
	
		
			
				|  |  | +    odd_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +    for (int i = 0; i < kLoopIterations; i++) {
 | 
	
		
			
				|  |  | +      even_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +      odd_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // without compaction, there would be exactly kLoopIterations empty slots at
 | 
	
		
			
				|  |  | +  // this point. However, one of the unregisters should have triggered
 | 
	
		
			
				|  |  | +  // compaction.
 | 
	
		
			
				|  |  | +  ChannelzRegistryPeer peer;
 | 
	
		
			
				|  |  | +  EXPECT_LT(peer.num_empty_slots(), kLoopIterations);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) {
 | 
	
		
			
				|  |  | +  const int kLoopIterations = 100;
 | 
	
		
			
				|  |  | +  // These channels that will stay in the registry for the duration of the test.
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> even_channels;
 | 
	
		
			
				|  |  | +  even_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  std::vector<intptr_t> odd_uuids;
 | 
	
		
			
				|  |  | +  odd_uuids.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    // The channels will unregister themselves at the end of the for block.
 | 
	
		
			
				|  |  | +    std::vector<UniquePtr<BaseNode>> odd_channels;
 | 
	
		
			
				|  |  | +    odd_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +    for (int i = 0; i < kLoopIterations; i++) {
 | 
	
		
			
				|  |  | +      even_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +      odd_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +      odd_uuids.push_back(odd_channels[i]->uuid());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  for (int i = 0; i < kLoopIterations; i++) {
 | 
	
		
			
				|  |  | +    BaseNode* retrieved = ChannelzRegistry::Get(even_channels[i]->uuid());
 | 
	
		
			
				|  |  | +    EXPECT_EQ(even_channels[i].get(), retrieved);
 | 
	
		
			
				|  |  | +    retrieved = ChannelzRegistry::Get(odd_uuids[i]);
 | 
	
		
			
				|  |  | +    EXPECT_EQ(retrieved, nullptr);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) {
 | 
	
		
			
				|  |  | +  const int kLoopIterations = 100;
 | 
	
		
			
				|  |  | +  // These channels that will stay in the registry for the duration of the test.
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> even_channels;
 | 
	
		
			
				|  |  | +  even_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  std::vector<intptr_t> odd_uuids;
 | 
	
		
			
				|  |  | +  odd_uuids.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    // The channels will unregister themselves at the end of the for block.
 | 
	
		
			
				|  |  | +    std::vector<UniquePtr<BaseNode>> odd_channels;
 | 
	
		
			
				|  |  | +    odd_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +    for (int i = 0; i < kLoopIterations; i++) {
 | 
	
		
			
				|  |  | +      even_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +      odd_channels.push_back(
 | 
	
		
			
				|  |  | +          MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +      odd_uuids.push_back(odd_channels[i]->uuid());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  std::vector<UniquePtr<BaseNode>> more_channels;
 | 
	
		
			
				|  |  | +  more_channels.reserve(kLoopIterations);
 | 
	
		
			
				|  |  | +  for (int i = 0; i < kLoopIterations; i++) {
 | 
	
		
			
				|  |  | +    more_channels.push_back(
 | 
	
		
			
				|  |  | +        MakeUnique<BaseNode>(BaseNode::EntityType::kTopLevelChannel));
 | 
	
		
			
				|  |  | +    BaseNode* retrieved = ChannelzRegistry::Get(more_channels[i]->uuid());
 | 
	
		
			
				|  |  | +    EXPECT_EQ(more_channels[i].get(), retrieved);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  }  // namespace testing
 | 
	
	
		
			
				|  | @@ -101,9 +196,7 @@ TEST(ChannelzRegistryTest, NullIfNotPresentTest) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  int main(int argc, char** argv) {
 | 
	
		
			
				|  |  |    grpc_test_init(argc, argv);
 | 
	
		
			
				|  |  | -  grpc_init();
 | 
	
		
			
				|  |  |    ::testing::InitGoogleTest(&argc, argv);
 | 
	
		
			
				|  |  |    int ret = RUN_ALL_TESTS();
 | 
	
		
			
				|  |  | -  grpc_shutdown();
 | 
	
		
			
				|  |  |    return ret;
 | 
	
		
			
				|  |  |  }
 |