@ -260,12 +260,10 @@ class FakeResolverResponseGeneratorWrapper {
response_generator_ ;
} ;
constexpr absl : : string_view kDefaultAuthority = " default.example.com " ;
class ClientLbEnd2endTest : public : : testing : : Test {
protected :
ClientLbEnd2endTest ( )
: server_host_ ( " localhost " ) ,
creds_ ( std : : make_shared < FakeTransportSecurityChannelCredentials > ( ) ) { }
void SetUp ( ) override { grpc_init ( ) ; }
void TearDown ( ) override {
@ -273,25 +271,25 @@ class ClientLbEnd2endTest : public ::testing::Test {
servers_ [ i ] - > Shutdown ( ) ;
}
servers_ . clear ( ) ;
creds_ . reset ( ) ;
grpc_shutdown ( ) ;
}
void CreateServers ( size_t num_servers ,
std : : vector < int > ports = std : : vector < int > ( ) ) {
void CreateServers (
size_t num_servers , std : : vector < int > ports = { } ,
std : : shared_ptr < ServerCredentials > server_creds = nullptr ) {
servers_ . clear ( ) ;
for ( size_t i = 0 ; i < num_servers ; + + i ) {
int port = 0 ;
if ( ports . size ( ) = = num_servers ) port = ports [ i ] ;
servers_ . emplace_back ( new ServerData ( port ) ) ;
servers_ . emplace_back ( new ServerData ( port , server_creds ) ) ;
}
}
void StartServer ( size_t index ) { servers_ [ index ] - > Start ( server_host_ ) ; }
void StartServer ( size_t index ) { servers_ [ index ] - > Start ( ) ; }
void StartServers ( size_t num_servers ,
std : : vector < int > ports = std : : vector < int > ( ) ) {
CreateServers ( num_servers , std : : move ( ports ) ) ;
void StartServers ( size_t num_servers , std : : vector < int > ports = { } ,
std : : shared_ptr < ServerCredentials > server_creds = nullptr ) {
CreateServers ( num_servers , std : : move ( ports ) , std : : move ( server_creds ) ) ;
for ( size_t i = 0 ; i < num_servers ; + + i ) {
StartServer ( i ) ;
}
@ -315,19 +313,26 @@ class ClientLbEnd2endTest : public ::testing::Test {
std : : shared_ptr < Channel > BuildChannel (
const std : : string & lb_policy_name ,
const FakeResolverResponseGeneratorWrapper & response_generator ,
ChannelArguments args = ChannelArguments ( ) ) {
ChannelArguments args = ChannelArguments ( ) ,
std : : shared_ptr < ChannelCredentials > channel_creds = nullptr ) {
if ( ! lb_policy_name . empty ( ) ) {
args . SetLoadBalancingPolicyName ( lb_policy_name ) ;
} // else, default to pick first
args . SetPointer ( GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR ,
response_generator . Get ( ) ) ;
return grpc : : CreateCustomChannel ( " fake:default.example.com " , creds_ , args ) ;
if ( channel_creds = = nullptr ) {
channel_creds =
std : : make_shared < FakeTransportSecurityChannelCredentials > ( ) ;
}
return grpc : : CreateCustomChannel ( absl : : StrCat ( " fake: " , kDefaultAuthority ) ,
channel_creds , args ) ;
}
Status SendRpc (
const std : : unique_ptr < grpc : : testing : : EchoTestService : : Stub > & stub ,
EchoResponse * response = nullptr , int timeout_ms = 1000 ,
bool wait_for_ready = false , EchoRequest * request = nullptr ) {
bool wait_for_ready = false , EchoRequest * request = nullptr ,
std : : string authority_override = " " ) {
EchoResponse local_response ;
if ( response = = nullptr ) response = & local_response ;
EchoRequest local_request ;
@ -336,6 +341,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
request - > mutable_param ( ) - > set_echo_metadata ( true ) ;
ClientContext context ;
context . set_deadline ( grpc_timeout_milliseconds_to_deadline ( timeout_ms ) ) ;
if ( ! authority_override . empty ( ) ) context . set_authority ( authority_override ) ;
if ( wait_for_ready ) context . set_wait_for_ready ( true ) ;
context . AddMetadata ( " foo " , " 1 " ) ;
context . AddMetadata ( " bar " , " 2 " ) ;
@ -403,6 +409,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
struct ServerData {
const int port_ ;
const std : : shared_ptr < ServerCredentials > server_creds_ ;
std : : unique_ptr < Server > server_ ;
MyTestServiceImpl service_ ;
std : : unique_ptr < experimental : : ServerMetricRecorder > server_metric_recorder_ ;
@ -416,20 +423,27 @@ class ClientLbEnd2endTest : public ::testing::Test {
bool server_ready_ ABSL_GUARDED_BY ( mu_ ) = false ;
bool started_ ABSL_GUARDED_BY ( mu_ ) = false ;
explicit ServerData ( int port = 0 )
explicit ServerData (
int port = 0 , std : : shared_ptr < ServerCredentials > server_creds = nullptr )
: port_ ( port > 0 ? port : grpc_pick_unused_port_or_die ( ) ) ,
server_creds_ (
server_creds = = nullptr
? std : : shared_ptr <
ServerCredentials > ( new SecureServerCredentials (
grpc_fake_transport_security_server_credentials_create ( ) ) )
: std : : move ( server_creds ) ) ,
server_metric_recorder_ ( experimental : : ServerMetricRecorder : : Create ( ) ) ,
orca_service_ (
server_metric_recorder_ . get ( ) ,
experimental : : OrcaService : : Options ( ) . set_min_report_duration (
absl : : Seconds ( 0.1 ) ) ) { }
void Start ( const std : : string & server_host ) {
void Start ( ) {
LOG ( INFO ) < < " starting server on port " < < port_ ;
grpc_core : : MutexLock lock ( & mu_ ) ;
started_ = true ;
thread_ = std : : make_unique < std : : thread > (
std : : bind ( & ServerData : : Serve , this , server_host ) ) ;
thread_ =
std : : make_unique < std : : thread > ( std : : bind ( & ServerData : : Serve , this ) ) ;
while ( ! server_ready_ ) {
cond_ . Wait ( & mu_ ) ;
}
@ -437,13 +451,10 @@ class ClientLbEnd2endTest : public ::testing::Test {
LOG ( INFO ) < < " server startup complete " ;
}
void Serve ( const std : : string & server_host ) {
std : : ostringstream server_address ;
server_address < < server_host < < " : " < < port_ ;
void Serve ( ) {
ServerBuilder builder ;
std : : shared_ptr < ServerCredentials > creds ( new SecureServerCredentials (
grpc_fake_transport_security_server_credentials_create ( ) ) ) ;
builder . AddListeningPort ( server_address . str ( ) , std : : move ( creds ) ) ;
builder . AddListeningPort ( absl : : StrCat ( " localhost: " , port_ ) ,
server_creds_ ) ;
builder . RegisterService ( & service_ ) ;
builder . RegisterService ( & orca_service_ ) ;
if ( enable_noop_health_check_service_ ) {
@ -599,9 +610,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
" ( \\ ([0-9]+ \\ ))? " ) ;
}
const std : : string server_host_ ;
std : : vector < std : : unique_ptr < ServerData > > servers_ ;
std : : shared_ptr < ChannelCredentials > creds_ ;
} ;
TEST_F ( ClientLbEnd2endTest , ChannelStateConnectingWhenResolving ) {
@ -660,13 +669,31 @@ TEST_F(ClientLbEnd2endTest, ChannelIdleness) {
EXPECT_EQ ( channel - > GetState ( false ) , GRPC_CHANNEL_READY ) ;
}
TEST_F ( ClientLbEnd2endTest , AuthorityOverrideOnChannel ) {
//
// authority override tests
//
class AuthorityOverrideTest : public ClientLbEnd2endTest {
protected :
static void SetUpTestSuite ( ) {
grpc_core : : CoreConfiguration : : Reset ( ) ;
grpc_core : : CoreConfiguration : : RegisterBuilder (
[ ] ( grpc_core : : CoreConfiguration : : Builder * builder ) {
grpc_core : : RegisterAuthorityOverrideLoadBalancingPolicy ( builder ) ;
} ) ;
grpc_init ( ) ;
}
static void TearDownTestSuite ( ) {
grpc_shutdown ( ) ;
grpc_core : : CoreConfiguration : : Reset ( ) ;
}
} ;
TEST_F ( AuthorityOverrideTest , NoOverride ) {
StartServers ( 1 ) ;
// Set authority via channel arg.
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_DEFAULT_AUTHORITY , " foo.example.com " ) ;
auto channel = BuildChannel ( " " , response_generator , args ) ;
auto channel = BuildChannel ( " " , response_generator ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
@ -678,10 +705,10 @@ TEST_F(ClientLbEnd2endTest, AuthorityOverrideOnChannel) {
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " foo.example.com " , response . param ( ) . host ( ) ) ;
EXPECT_EQ ( kDefaultAuthority , response . param ( ) . host ( ) ) ;
}
TEST_F ( ClientLbEnd2end Test, Authority OverrideFromResolver) {
TEST_F ( AuthorityOverride Test, OverrideFromResolver ) {
StartServers ( 1 ) ;
FakeResolverResponseGeneratorWrapper response_generator ;
auto channel = BuildChannel ( " " , response_generator ) ;
@ -691,7 +718,51 @@ TEST_F(ClientLbEnd2endTest, AuthorityOverrideFromResolver) {
response_generator . SetNextResolution (
GetServersPorts ( ) , /*service_config_json=*/ nullptr ,
grpc_core : : ChannelArgs ( ) . Set ( GRPC_ARG_DEFAULT_AUTHORITY ,
" foo.example.com " ) ) ;
" from-resolver.example.com " ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
EchoResponse response ;
Status status = SendRpc ( stub , & response , /*timeout_ms=*/ 1000 ,
/*wait_for_ready=*/ false , & request ) ;
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " from-resolver.example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( AuthorityOverrideTest , OverrideOnChannel ) {
StartServers ( 1 ) ;
// Set authority via channel arg.
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_DEFAULT_AUTHORITY , " from-channel.example.com " ) ;
auto channel = BuildChannel ( " " , response_generator , args ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
EchoResponse response ;
Status status = SendRpc ( stub , & response , /*timeout_ms=*/ 1000 ,
/*wait_for_ready=*/ false , & request ) ;
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " from-channel.example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( AuthorityOverrideTest , OverrideFromLbPolicy ) {
// We use InsecureCreds here to avoid the authority check in the fake
// security connector.
StartServers ( 1 , { } , InsecureServerCredentials ( ) ) ;
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_TEST_LB_AUTHORITY_OVERRIDE , " from-lb.example.com " ) ;
auto channel = BuildChannel ( " authority_override_lb " , response_generator , args ,
InsecureChannelCredentials ( ) ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
@ -701,15 +772,38 @@ TEST_F(ClientLbEnd2endTest, AuthorityOverrideFromResolver) {
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " foo .example.com " , response . param ( ) . host ( ) ) ;
EXPECT_EQ ( " from-lb .example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( ClientLbEnd2endTest , AuthorityOverridePrecedence ) {
TEST_F ( AuthorityOverrideTest , PerRpcOverride ) {
// We use InsecureCreds here to avoid the authority check in the fake
// security connector.
StartServers ( 1 , { } , InsecureServerCredentials ( ) ) ;
FakeResolverResponseGeneratorWrapper response_generator ;
auto channel = BuildChannel ( " " , response_generator , ChannelArguments ( ) ,
InsecureChannelCredentials ( ) ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
EchoResponse response ;
Status status = SendRpc ( stub , & response , /*timeout_ms=*/ 1000 ,
/*wait_for_ready=*/ false , & request ,
/*authority_override=*/ " per-rpc.example.com " ) ;
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " per-rpc.example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( AuthorityOverrideTest ,
ChannelOverrideTakesPrecedenceOverResolverOverride ) {
StartServers ( 1 ) ;
// Set authority via channel arg.
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_DEFAULT_AUTHORITY , " foo.example.com " ) ;
args . SetString ( GRPC_ARG_DEFAULT_AUTHORITY , " from-channel .example.com " ) ;
auto channel = BuildChannel ( " " , response_generator , args ) ;
auto stub = BuildStub ( channel ) ;
// Inject resolver result that sets the per-address authority to a
@ -717,7 +811,32 @@ TEST_F(ClientLbEnd2endTest, AuthorityOverridePrecedence) {
response_generator . SetNextResolution (
GetServersPorts ( ) , /*service_config_json=*/ nullptr ,
grpc_core : : ChannelArgs ( ) . Set ( GRPC_ARG_DEFAULT_AUTHORITY ,
" bar.example.com " ) ) ;
" from-resolver.example.com " ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
EchoResponse response ;
Status status = SendRpc ( stub , & response , /*timeout_ms=*/ 1000 ,
/*wait_for_ready=*/ false , & request ) ;
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " from-channel.example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( AuthorityOverrideTest ,
LbPolicyOverrideTakesPrecedenceOverChannelOverride ) {
// We use InsecureCreds here to avoid the authority check in the fake
// security connector.
StartServers ( 1 , { } , InsecureServerCredentials ( ) ) ;
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_DEFAULT_AUTHORITY , " from-channel.example.com " ) ;
args . SetString ( GRPC_ARG_TEST_LB_AUTHORITY_OVERRIDE , " from-lb.example.com " ) ;
auto channel = BuildChannel ( " authority_override_lb " , response_generator , args ,
InsecureChannelCredentials ( ) ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
@ -727,7 +846,32 @@ TEST_F(ClientLbEnd2endTest, AuthorityOverridePrecedence) {
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " foo.example.com " , response . param ( ) . host ( ) ) ;
EXPECT_EQ ( " from-lb.example.com " , response . param ( ) . host ( ) ) ;
}
TEST_F ( AuthorityOverrideTest ,
PerRpcOverrideTakesPrecedenceOverLbPolicyOverride ) {
// We use InsecureCreds here to avoid the authority check in the fake
// security connector.
StartServers ( 1 , { } , InsecureServerCredentials ( ) ) ;
FakeResolverResponseGeneratorWrapper response_generator ;
ChannelArguments args ;
args . SetString ( GRPC_ARG_TEST_LB_AUTHORITY_OVERRIDE , " from-lb.example.com " ) ;
auto channel = BuildChannel ( " authority_override_lb " , response_generator , args ,
InsecureChannelCredentials ( ) ) ;
auto stub = BuildStub ( channel ) ;
response_generator . SetNextResolution ( GetServersPorts ( ) ) ;
// Send an RPC.
EchoRequest request ;
request . mutable_param ( ) - > set_echo_host_from_authority_header ( true ) ;
EchoResponse response ;
Status status = SendRpc ( stub , & response , /*timeout_ms=*/ 1000 ,
/*wait_for_ready=*/ false , & request ,
/*authority_override=*/ " per-rpc.example.com " ) ;
EXPECT_TRUE ( status . ok ( ) ) < < " code= " < < status . error_code ( )
< < " message= " < < status . error_message ( ) ;
// Check that the right authority was seen by the server.
EXPECT_EQ ( " per-rpc.example.com " , response . param ( ) . host ( ) ) ;
}
//
@ -1058,12 +1202,18 @@ TEST_F(PickFirstTest, GlobalSubchannelPool) {
StartServers ( kNumServers ) ;
std : : vector < int > ports = GetServersPorts ( ) ;
// Create two channels that (by default) use the global subchannel pool.
// Use the same channel creds for both, so that they have the same
// subchannel keys.
auto channel_creds =
std : : make_shared < FakeTransportSecurityChannelCredentials > ( ) ;
FakeResolverResponseGeneratorWrapper response_generator1 ;
auto channel1 = BuildChannel ( " pick_first " , response_generator1 ) ;
auto channel1 = BuildChannel ( " pick_first " , response_generator1 ,
ChannelArguments ( ) , channel_creds ) ;
auto stub1 = BuildStub ( channel1 ) ;
response_generator1 . SetNextResolution ( ports ) ;
FakeResolverResponseGeneratorWrapper response_generator2 ;
auto channel2 = BuildChannel ( " pick_first " , response_generator2 ) ;
auto channel2 = BuildChannel ( " pick_first " , response_generator2 ,
ChannelArguments ( ) , channel_creds ) ;
auto stub2 = BuildStub ( channel2 ) ;
response_generator2 . SetNextResolution ( ports ) ;
WaitForServer ( DEBUG_LOCATION , stub1 , 0 ) ;
@ -1984,20 +2134,26 @@ TEST_F(RoundRobinTest, WithHealthCheckingInhibitPerChannel) {
// Start server.
const int kNumServers = 1 ;
StartServers ( kNumServers ) ;
// Use the same channel creds for both channels, so that they have the same
// subchannel keys.
auto channel_creds =
std : : make_shared < FakeTransportSecurityChannelCredentials > ( ) ;
// Create a channel with health-checking enabled.
ChannelArguments args ;
args . SetServiceConfigJSON (
" { \" healthCheckConfig \" : "
" { \" serviceName \" : \" health_check_service_name \" }} " ) ;
FakeResolverResponseGeneratorWrapper response_generator1 ;
auto channel1 = BuildChannel ( " round_robin " , response_generator1 , args ) ;
auto channel1 =
BuildChannel ( " round_robin " , response_generator1 , args , channel_creds ) ;
auto stub1 = BuildStub ( channel1 ) ;
std : : vector < int > ports = GetServersPorts ( ) ;
response_generator1 . SetNextResolution ( ports ) ;
// Create a channel with health checking enabled but inhibited.
args . SetInt ( GRPC_ARG_INHIBIT_HEALTH_CHECKING , 1 ) ;
FakeResolverResponseGeneratorWrapper response_generator2 ;
auto channel2 = BuildChannel ( " round_robin " , response_generator2 , args ) ;
auto channel2 =
BuildChannel ( " round_robin " , response_generator2 , args , channel_creds ) ;
auto stub2 = BuildStub ( channel2 ) ;
response_generator2 . SetNextResolution ( ports ) ;
// First channel should not become READY, because health checks should be
@ -2024,13 +2180,18 @@ TEST_F(RoundRobinTest, HealthCheckingServiceNamePerChannel) {
// Start server.
const int kNumServers = 1 ;
StartServers ( kNumServers ) ;
// Use the same channel creds for both channels, so that they have the same
// subchannel keys.
auto channel_creds =
std : : make_shared < FakeTransportSecurityChannelCredentials > ( ) ;
// Create a channel with health-checking enabled.
ChannelArguments args ;
args . SetServiceConfigJSON (
" { \" healthCheckConfig \" : "
" { \" serviceName \" : \" health_check_service_name \" }} " ) ;
FakeResolverResponseGeneratorWrapper response_generator1 ;
auto channel1 = BuildChannel ( " round_robin " , response_generator1 , args ) ;
auto channel1 =
BuildChannel ( " round_robin " , response_generator1 , args , channel_creds ) ;
auto stub1 = BuildStub ( channel1 ) ;
std : : vector < int > ports = GetServersPorts ( ) ;
response_generator1 . SetNextResolution ( ports ) ;
@ -2041,7 +2202,8 @@ TEST_F(RoundRobinTest, HealthCheckingServiceNamePerChannel) {
" { \" healthCheckConfig \" : "
" { \" serviceName \" : \" health_check_service_name2 \" }} " ) ;
FakeResolverResponseGeneratorWrapper response_generator2 ;
auto channel2 = BuildChannel ( " round_robin " , response_generator2 , args2 ) ;
auto channel2 =
BuildChannel ( " round_robin " , response_generator2 , args2 , channel_creds ) ;
auto stub2 = BuildStub ( channel2 ) ;
response_generator2 . SetNextResolution ( ports ) ;
// Allow health checks from channel 2 to succeed.
@ -2202,6 +2364,10 @@ TEST_F(ClientLbPickArgsTest, Basic) {
< < ArgsSeenListString ( pick_args_seen_list ) ;
}
//
// tests that LB policies can get the call's trailing metadata
//
class OrcaLoadReportBuilder {
public :
OrcaLoadReportBuilder ( ) = default ;
@ -2245,10 +2411,6 @@ class OrcaLoadReportBuilder {
OrcaLoadReport report_ ;
} ;
//
// tests that LB policies can get the call's trailing metadata
//
OrcaLoadReport BackendMetricDataToOrcaLoadReport (
const grpc_core : : BackendMetricData & backend_metric_data ) {
auto builder = OrcaLoadReportBuilder ( )
@ -2700,7 +2862,7 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
}
//
// tests that address args from the resolver are visible to the LB policy
// tests that per- address args from the resolver are visible to the LB policy
//
class ClientLbAddressTest : public ClientLbEnd2endTest {
@ -2739,7 +2901,7 @@ class ClientLbAddressTest : public ClientLbEnd2endTest {
static ClientLbAddressTest * current_test_instance_ ;
grpc_core : : Mutex mu_ ;
std : : vector < std : : string > addresses_seen_ ;
std : : vector < std : : string > addresses_seen_ ABSL_GUARDED_BY ( & mu_ ) ;
} ;
ClientLbAddressTest * ClientLbAddressTest : : current_test_instance_ = nullptr ;