@ -43,6 +43,35 @@ namespace grpc {
namespace testing {
namespace {
using : : testing : : ElementsAre ;
using : : testing : : Pair ;
opentelemetry : : sdk : : resource : : Resource TestGkeResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " gcp_kubernetes_engine " ) ;
attributes . SetAttribute ( " k8s.pod.name " , " pod " ) ;
attributes . SetAttribute ( " k8s.container.name " , " container " ) ;
attributes . SetAttribute ( " k8s.namespace.name " , " namespace " ) ;
attributes . SetAttribute ( " k8s.cluster.name " , " cluster " ) ;
attributes . SetAttribute ( " cloud.region " , " region " ) ;
attributes . SetAttribute ( " cloud.account.id " , " id " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
opentelemetry : : sdk : : resource : : Resource TestGceResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " gcp_compute_engine " ) ;
attributes . SetAttribute ( " cloud.availability_zone " , " zone " ) ;
attributes . SetAttribute ( " cloud.account.id " , " id " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
opentelemetry : : sdk : : resource : : Resource TestUnknownResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " random " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
class TestScenario {
public :
enum class ResourceType : std : : uint8_t { kGke , kGce , kUnknown } ;
@ -91,32 +120,6 @@ class TestScenario {
XdsBootstrapSource bootstrap_source ( ) const { return bootstrap_source_ ; }
private :
static opentelemetry : : sdk : : resource : : Resource TestGkeResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " gcp_kubernetes_engine " ) ;
attributes . SetAttribute ( " k8s.pod.name " , " pod " ) ;
attributes . SetAttribute ( " k8s.container.name " , " container " ) ;
attributes . SetAttribute ( " k8s.namespace.name " , " namespace " ) ;
attributes . SetAttribute ( " k8s.cluster.name " , " cluster " ) ;
attributes . SetAttribute ( " cloud.region " , " region " ) ;
attributes . SetAttribute ( " cloud.account.id " , " id " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
static opentelemetry : : sdk : : resource : : Resource TestGceResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " gcp_compute_engine " ) ;
attributes . SetAttribute ( " cloud.availability_zone " , " zone " ) ;
attributes . SetAttribute ( " cloud.account.id " , " id " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
static opentelemetry : : sdk : : resource : : Resource TestUnknownResource ( ) {
opentelemetry : : sdk : : common : : AttributeMap attributes ;
attributes . SetAttribute ( " cloud.platform " , " random " ) ;
return opentelemetry : : sdk : : resource : : Resource : : Create ( attributes ) ;
}
ResourceType type_ ;
XdsBootstrapSource bootstrap_source_ ;
} ;
@ -163,7 +166,7 @@ class MetadataExchangeTest
case TestScenario : : XdsBootstrapSource : : kFromFile : {
ASSERT_EQ ( bootstrap_file_name_ , nullptr ) ;
FILE * bootstrap_file =
gpr_tmpfile ( " gcp_observability_config " , & bootstrap_file_name_ ) ;
gpr_tmpfile ( " xds_bootstrap " , & bootstrap_file_name_ ) ;
fputs ( kBootstrap , bootstrap_file ) ;
fclose ( bootstrap_file ) ;
grpc_core : : SetEnv ( " GRPC_XDS_BOOTSTRAP " , bootstrap_file_name_ ) ;
@ -186,7 +189,7 @@ class MetadataExchangeTest
}
~ MetadataExchangeTest ( ) override {
grpc_core : : UnsetEnv ( " GRPC_GCP_OBSERVABILITY _CONFIG " ) ;
grpc_core : : UnsetEnv ( " GRPC_XDS_BOOTSTRAP _CONFIG " ) ;
grpc_core : : UnsetEnv ( " GRPC_XDS_BOOTSTRAP " ) ;
if ( bootstrap_file_name_ ! = nullptr ) {
remove ( bootstrap_file_name_ ) ;
@ -418,6 +421,134 @@ TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) {
" mynamespace " ) ;
}
// Creates a serialized slice with labels for metadata exchange based on \a
// resource.
grpc_core : : Slice RemoteMetadataSliceFromResource (
const opentelemetry : : sdk : : resource : : Resource & resource ) {
return grpc : : internal : : ServiceMeshLabelsInjector ( resource . GetAttributes ( ) )
. TestOnlySerializedLabels ( )
. Ref ( ) ;
}
std : : vector < std : : pair < absl : : string_view , absl : : string_view > > LabelsFromIterable (
grpc : : internal : : MeshLabelsIterable * iterable ) {
std : : vector < std : : pair < absl : : string_view , absl : : string_view > > labels ;
while ( true ) {
auto label = iterable - > Next ( ) ;
if ( ! label . has_value ( ) ) break ;
labels . push_back ( * std : : move ( label ) ) ;
}
EXPECT_EQ ( labels . size ( ) , iterable - > Size ( ) ) ;
return labels ;
}
std : : string PrettyPrintLabels (
const std : : vector < std : : pair < absl : : string_view , absl : : string_view > > &
labels ) {
std : : vector < std : : string > strings ;
strings . reserve ( labels . size ( ) ) ;
for ( const auto & pair : labels ) {
strings . push_back (
absl : : StrFormat ( " { \" %s \" : \" %s \" } " , pair . first , pair . second ) ) ;
}
return absl : : StrJoin ( strings , " , " ) ;
}
TEST ( MeshLabelsIterableTest , NoRemoteMetadata ) {
std : : vector < std : : pair < absl : : string_view , std : : string > > local_labels = {
{ " csm.workload_canonical_service " , " canonical_service " } ,
{ " csm.mesh_id " , " mesh " } } ;
grpc : : internal : : MeshLabelsIterable iterable ( local_labels , grpc_core : : Slice ( ) ) ;
auto labels = LabelsFromIterable ( & iterable ) ;
EXPECT_FALSE ( iterable . GotRemoteLabels ( ) ) ;
EXPECT_THAT (
labels ,
ElementsAre ( Pair ( " csm.workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.mesh_id " , " mesh " ) ,
Pair ( " csm.remote_workload_type " , " unknown " ) ,
Pair ( " csm.remote_workload_canonical_service " , " unknown " ) ) )
< < PrettyPrintLabels ( labels ) ;
}
TEST ( MeshLabelsIterableTest , RemoteGceTypeMetadata ) {
std : : vector < std : : pair < absl : : string_view , std : : string > > local_labels = {
{ " csm.workload_canonical_service " , " canonical_service " } ,
{ " csm.mesh_id " , " mesh " } } ;
grpc : : internal : : MeshLabelsIterable iterable (
local_labels , RemoteMetadataSliceFromResource ( TestGceResource ( ) ) ) ;
auto labels = LabelsFromIterable ( & iterable ) ;
EXPECT_TRUE ( iterable . GotRemoteLabels ( ) ) ;
EXPECT_THAT (
labels ,
ElementsAre (
Pair ( " csm.workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.mesh_id " , " mesh " ) ,
Pair ( " csm.remote_workload_type " , " gcp_compute_engine " ) ,
Pair ( " csm.remote_workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.remote_workload_name " , " workload " ) ,
Pair ( " csm.remote_workload_location " , " zone " ) ,
Pair ( " csm.remote_workload_project_id " , " id " ) ) )
< < PrettyPrintLabels ( labels ) ;
}
TEST ( MeshLabelsIterableTest , RemoteGkeTypeMetadata ) {
std : : vector < std : : pair < absl : : string_view , std : : string > > local_labels = {
{ " csm.workload_canonical_service " , " canonical_service " } ,
{ " csm.mesh_id " , " mesh " } } ;
grpc : : internal : : MeshLabelsIterable iterable (
local_labels , RemoteMetadataSliceFromResource ( TestGkeResource ( ) ) ) ;
auto labels = LabelsFromIterable ( & iterable ) ;
EXPECT_TRUE ( iterable . GotRemoteLabels ( ) ) ;
EXPECT_THAT (
labels ,
ElementsAre (
Pair ( " csm.workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.mesh_id " , " mesh " ) ,
Pair ( " csm.remote_workload_type " , " gcp_kubernetes_engine " ) ,
Pair ( " csm.remote_workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.remote_workload_name " , " workload " ) ,
Pair ( " csm.remote_workload_namespace_name " , " namespace " ) ,
Pair ( " csm.remote_workload_cluster_name " , " cluster " ) ,
Pair ( " csm.remote_workload_location " , " region " ) ,
Pair ( " csm.remote_workload_project_id " , " id " ) ) )
< < PrettyPrintLabels ( labels ) ;
}
TEST ( MeshLabelsIterableTest , RemoteUnknownTypeMetadata ) {
std : : vector < std : : pair < absl : : string_view , std : : string > > local_labels = {
{ " csm.workload_canonical_service " , " canonical_service " } ,
{ " csm.mesh_id " , " mesh " } } ;
grpc : : internal : : MeshLabelsIterable iterable (
local_labels , RemoteMetadataSliceFromResource ( TestUnknownResource ( ) ) ) ;
auto labels = LabelsFromIterable ( & iterable ) ;
EXPECT_TRUE ( iterable . GotRemoteLabels ( ) ) ;
EXPECT_THAT (
labels ,
ElementsAre (
Pair ( " csm.workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.mesh_id " , " mesh " ) ,
Pair ( " csm.remote_workload_type " , " random " ) ,
Pair ( " csm.remote_workload_canonical_service " , " canonical_service " ) ) )
< < PrettyPrintLabels ( labels ) ;
}
TEST ( MeshLabelsIterableTest , TestResetIteratorPosition ) {
std : : vector < std : : pair < absl : : string_view , std : : string > > local_labels = {
{ " csm.workload_canonical_service " , " canonical_service " } ,
{ " csm.mesh_id " , " mesh " } } ;
grpc : : internal : : MeshLabelsIterable iterable ( local_labels , grpc_core : : Slice ( ) ) ;
auto labels = LabelsFromIterable ( & iterable ) ;
auto expected_labels_matcher = ElementsAre (
Pair ( " csm.workload_canonical_service " , " canonical_service " ) ,
Pair ( " csm.mesh_id " , " mesh " ) , Pair ( " csm.remote_workload_type " , " unknown " ) ,
Pair ( " csm.remote_workload_canonical_service " , " unknown " ) ) ;
EXPECT_THAT ( labels , expected_labels_matcher ) < < PrettyPrintLabels ( labels ) ;
// Resetting the iterable should return the entire list again.
iterable . ResetIteratorPosition ( ) ;
labels = LabelsFromIterable ( & iterable ) ;
EXPECT_THAT ( labels , expected_labels_matcher ) < < PrettyPrintLabels ( labels ) ;
}
INSTANTIATE_TEST_SUITE_P (
MetadataExchange , MetadataExchangeTest ,
: : testing : : Values (