Implement fake and ignored headers.

Take care to ensure we use fake headers in testing so we don't
conflict with headers used by census.
pull/23539/head
Donna Dionne 4 years ago
parent 94a2b5d40c
commit 0d6ee9b309
  1. 15
      src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc
  2. 110
      test/cpp/end2end/xds_end2end_test.cc

@ -264,8 +264,19 @@ bool HeaderMatchHelper(
const XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher& header_matcher,
LoadBalancingPolicy::MetadataInterface* initial_metadata) {
std::string concatenated_value;
auto value = GetMetadataValue(header_matcher.name, initial_metadata,
&concatenated_value);
absl::optional<absl::string_view> value;
// Note: If we ever allow binary headers here, we still need to
// special-case ignore "grpc-tags-bin" and "grpc-trace-bin", since
// they are not visible to the LB policy in grpc-go.
if (absl::EndsWith(header_matcher.name, "-bin") ||
header_matcher.name == "grpc-previous-rpc-attempts") {
value = absl::nullopt;
} else if (header_matcher.name == "content-type") {
value = "application/grpc";
} else {
value = GetMetadataValue(header_matcher.name, initial_metadata,
&concatenated_value);
}
if (!value.has_value()) {
if (header_matcher.type == XdsApi::RdsUpdate::RdsRoute::Matchers::
HeaderMatcher::HeaderMatcherType::PRESENT) {

@ -3477,6 +3477,116 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) {
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED);
}
TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) {
const char* kNewCluster1Name = "new_cluster_1";
const size_t kNumEchoRpcs = 100;
SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers();
// Populate new EDS resources.
AdsServiceImpl::EdsResourceArgs args({
{"locality0", GetBackendPorts(0, 1)},
});
AdsServiceImpl::EdsResourceArgs args1({
{"locality0", GetBackendPorts(1, 2)},
});
balancers_[0]->ads_service()->SetEdsResource(
AdsServiceImpl::BuildEdsResource(args));
balancers_[0]->ads_service()->SetEdsResource(
AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name));
// Populate new CDS resources.
Cluster new_cluster1 = balancers_[0]->ads_service()->default_cluster();
new_cluster1.set_name(kNewCluster1Name);
balancers_[0]->ads_service()->SetCdsResource(new_cluster1);
// Populating Route Configurations for LDS.
RouteConfiguration route_config =
balancers_[0]->ads_service()->default_route_config();
auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
route1->mutable_match()->set_prefix("");
auto* header_matcher1 = route1->mutable_match()->add_headers();
header_matcher1->set_name("content-type");
header_matcher1->set_exact_match("notapplication/grpc");
route1->mutable_route()->set_cluster(kNewCluster1Name);
auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
default_route->mutable_match()->set_prefix("");
auto* header_matcher2 = default_route->mutable_match()->add_headers();
header_matcher2->set_name("content-type");
header_matcher2->set_exact_match("application/grpc");
default_route->mutable_route()->set_cluster(kDefaultResourceName);
SetRouteConfiguration(0, route_config);
// Make sure the backend is up.
WaitForAllBackends(0, 1);
// Send RPCs.
CheckRpcSendOk(kNumEchoRpcs);
EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
const auto& response_state = RouteConfigurationResponseState(0);
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED);
}
TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) {
const char* kNewCluster1Name = "new_cluster_1";
const char* kNewCluster2Name = "new_cluster_2";
const size_t kNumEchoRpcs = 100;
SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers();
// Populate new EDS resources.
AdsServiceImpl::EdsResourceArgs args({
{"locality0", GetBackendPorts(0, 1)},
});
AdsServiceImpl::EdsResourceArgs args1({
{"locality0", GetBackendPorts(1, 2)},
});
AdsServiceImpl::EdsResourceArgs args2({
{"locality0", GetBackendPorts(2, 3)},
});
balancers_[0]->ads_service()->SetEdsResource(
AdsServiceImpl::BuildEdsResource(args));
balancers_[0]->ads_service()->SetEdsResource(
AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name));
balancers_[0]->ads_service()->SetEdsResource(
AdsServiceImpl::BuildEdsResource(args2, kNewCluster2Name));
// Populate new CDS resources.
Cluster new_cluster1 = balancers_[0]->ads_service()->default_cluster();
new_cluster1.set_name(kNewCluster1Name);
balancers_[0]->ads_service()->SetCdsResource(new_cluster1);
Cluster new_cluster2 = balancers_[0]->ads_service()->default_cluster();
new_cluster2.set_name(kNewCluster2Name);
balancers_[0]->ads_service()->SetCdsResource(new_cluster2);
// Populating Route Configurations for LDS.
RouteConfiguration route_config =
balancers_[0]->ads_service()->default_route_config();
auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
route1->mutable_match()->set_prefix("");
auto* header_matcher1 = route1->mutable_match()->add_headers();
header_matcher1->set_name("grpc-foo-bin");
header_matcher1->set_present_match(true);
route1->mutable_route()->set_cluster(kNewCluster1Name);
auto route2 = route_config.mutable_virtual_hosts(0)->add_routes();
route2->mutable_match()->set_prefix("");
auto* header_matcher2 = route2->mutable_match()->add_headers();
header_matcher2->set_name("grpc-previous-rpc-attempts");
header_matcher2->set_present_match(true);
route2->mutable_route()->set_cluster(kNewCluster2Name);
auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
default_route->mutable_match()->set_prefix("");
default_route->mutable_route()->set_cluster(kDefaultResourceName);
SetRouteConfiguration(0, route_config);
// Send headers which will mismatch each route
std::vector<std::pair<std::string, std::string>> metadata = {
{"grpc-foo-bin", "grpc-foo-bin"},
{"grpc-previous-rpc-attempts", "grpc-previous-rpc-attempts"},
};
WaitForAllBackends(0, 1);
CheckRpcSendOk(kNumEchoRpcs, RpcOptions().set_metadata(metadata));
// Verify that only the default backend got RPCs since all previous routes
// were mismatched.
EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
const auto& response_state = RouteConfigurationResponseState(0);
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED);
}
TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) {
const char* kNewCluster1Name = "new_cluster_1";
const size_t kNumRpcs = 1000;

Loading…
Cancel
Save