aboutsummaryrefslogtreecommitdiff
path: root/test/core
diff options
context:
space:
mode:
authorMark D. Roth <roth@google.com>2024-01-09 15:38:55 -0800
committerCopybara-Service <copybara-worker@google.com>2024-01-09 15:41:22 -0800
commit20e5b2c4bb1f52221b8234176a46e90f50bb4cec (patch)
tree7a683db93f0794e23541eb9dea318f1b24e37b3b /test/core
parent55b74dbe55e0ae56ea79d923303afb00f47c879e (diff)
downloadgrpc-grpc-20e5b2c4bb1f52221b8234176a46e90f50bb4cec.tar.gz
[xDS] read connection idle timeout from CDS resource (#35395)
Part of the work needed for in-progress gRFC A75 (https://github.com/grpc/proposal/pull/405). Closes #35395 PiperOrigin-RevId: 597064473
Diffstat (limited to 'test/core')
-rw-r--r--test/core/xds/BUILD1
-rw-r--r--test/core/xds/xds_cluster_resource_type_test.cc204
2 files changed, 205 insertions, 0 deletions
diff --git a/test/core/xds/BUILD b/test/core/xds/BUILD
index 4dc271f1cf..26030f839f 100644
--- a/test/core/xds/BUILD
+++ b/test/core/xds/BUILD
@@ -306,6 +306,7 @@ grpc_cc_test(
"//src/core:grpc_xds_client",
"//src/proto/grpc/testing/xds/v3:aggregate_cluster_proto",
"//src/proto/grpc/testing/xds/v3:cluster_proto",
+ "//src/proto/grpc/testing/xds/v3:http_protocol_options_proto",
"//src/proto/grpc/testing/xds/v3:round_robin_proto",
"//src/proto/grpc/testing/xds/v3:tls_proto",
"//src/proto/grpc/testing/xds/v3:typed_struct_proto",
diff --git a/test/core/xds/xds_cluster_resource_type_test.cc b/test/core/xds/xds_cluster_resource_type_test.cc
index 27bb75935f..2feb6199fc 100644
--- a/test/core/xds/xds_cluster_resource_type_test.cc
+++ b/test/core/xds/xds_cluster_resource_type_test.cc
@@ -57,6 +57,7 @@
#include "src/proto/grpc/testing/xds/v3/endpoint.pb.h"
#include "src/proto/grpc/testing/xds/v3/extension.pb.h"
#include "src/proto/grpc/testing/xds/v3/health_check.pb.h"
+#include "src/proto/grpc/testing/xds/v3/http_protocol_options.pb.h"
#include "src/proto/grpc/testing/xds/v3/outlier_detection.pb.h"
#include "src/proto/grpc/testing/xds/v3/round_robin.pb.h"
#include "src/proto/grpc/testing/xds/v3/tls.pb.h"
@@ -69,6 +70,7 @@ using envoy::extensions::clusters::aggregate::v3::ClusterConfig;
using envoy::extensions::load_balancing_policies::round_robin::v3::RoundRobin;
using envoy::extensions::load_balancing_policies::wrr_locality::v3::WrrLocality;
using envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext;
+using envoy::extensions::upstreams::http::v3::HttpProtocolOptions;
using xds::type::v3::TypedStruct;
namespace grpc_core {
@@ -1128,6 +1130,208 @@ TEST_F(LrsTest, NotSelfConfigSource) {
}
//
+// upstream config tests
+//
+
+using UpstreamConfigTest = XdsClusterTest;
+
+TEST_F(UpstreamConfigTest, DefaultWithNoUpstreamConfig) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ auto& resource =
+ static_cast<const XdsClusterResource&>(**decode_result.resource);
+ EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1));
+}
+
+TEST_F(UpstreamConfigTest, DefaultWithNoCommonHttpProtocolOptions) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ HttpProtocolOptions http_protocol_options;
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ http_protocol_options);
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ auto& resource =
+ static_cast<const XdsClusterResource&>(**decode_result.resource);
+ EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1));
+}
+
+TEST_F(UpstreamConfigTest, DefaultWithFieldUnset) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ HttpProtocolOptions http_protocol_options;
+ http_protocol_options.mutable_common_http_protocol_options();
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ http_protocol_options);
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ auto& resource =
+ static_cast<const XdsClusterResource&>(**decode_result.resource);
+ EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1));
+}
+
+TEST_F(UpstreamConfigTest, ExplicitlySet) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ HttpProtocolOptions http_protocol_options;
+ http_protocol_options.mutable_common_http_protocol_options()
+ ->mutable_idle_timeout()
+ ->set_seconds(1);
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ http_protocol_options);
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ auto& resource =
+ static_cast<const XdsClusterResource&>(**decode_result.resource);
+ EXPECT_EQ(resource.connection_idle_timeout, Duration::Seconds(1));
+}
+
+TEST_F(UpstreamConfigTest, UnknownUpstreamConfigType) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ Cluster());
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ EXPECT_EQ(decode_result.resource.status().code(),
+ absl::StatusCode::kInvalidArgument);
+ EXPECT_EQ(decode_result.resource.status().message(),
+ "errors validating Cluster resource: ["
+ "field:upstream_config.typed_config.value["
+ "envoy.config.cluster.v3.Cluster].type_url "
+ "error:unsupported upstream config type]")
+ << decode_result.resource.status();
+}
+
+TEST_F(UpstreamConfigTest, UnparseableHttpProtocolOptions) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ auto* typed_config =
+ cluster.mutable_upstream_config()->mutable_typed_config();
+ typed_config->PackFrom(HttpProtocolOptions());
+ typed_config->set_value(std::string("\0", 1));
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ EXPECT_EQ(decode_result.resource.status().code(),
+ absl::StatusCode::kInvalidArgument);
+ EXPECT_EQ(decode_result.resource.status().message(),
+ "errors validating Cluster resource: ["
+ "field:upstream_config.typed_config.value["
+ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions] "
+ "error:can't decode HttpProtocolOptions]")
+ << decode_result.resource.status();
+}
+
+TEST_F(UpstreamConfigTest, HttpProtocolOptionsInTypedStruct) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ xds::type::v3::TypedStruct typed_struct;
+ typed_struct.set_type_url(
+ "types.googleapis.com/"
+ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions");
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ typed_struct);
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ EXPECT_EQ(decode_result.resource.status().code(),
+ absl::StatusCode::kInvalidArgument);
+ EXPECT_EQ(decode_result.resource.status().message(),
+ "errors validating Cluster resource: ["
+ "field:upstream_config.typed_config.value["
+ "xds.type.v3.TypedStruct].value["
+ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions] "
+ "error:can't decode HttpProtocolOptions]")
+ << decode_result.resource.status();
+}
+
+// This is just one example of where ParseDuration() will generate an error,
+// to show that we're propagating any such errors correctly. An exhaustive
+// set of tests for ParseDuration() is in xds_common_types_test.cc.
+TEST_F(UpstreamConfigTest, ErrorsParsingDurations) {
+ Cluster cluster;
+ cluster.set_name("foo");
+ cluster.set_type(cluster.EDS);
+ cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
+ HttpProtocolOptions http_protocol_options;
+ http_protocol_options.mutable_common_http_protocol_options()
+ ->mutable_idle_timeout()
+ ->set_seconds(-1);
+ cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom(
+ http_protocol_options);
+ std::string serialized_resource;
+ ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
+ auto* resource_type = XdsClusterResourceType::Get();
+ auto decode_result =
+ resource_type->Decode(decode_context_, serialized_resource);
+ ASSERT_TRUE(decode_result.name.has_value());
+ EXPECT_EQ(*decode_result.name, "foo");
+ EXPECT_EQ(decode_result.resource.status().code(),
+ absl::StatusCode::kInvalidArgument);
+ EXPECT_EQ(decode_result.resource.status().message(),
+ "errors validating Cluster resource: ["
+ "field:upstream_config.typed_config.value["
+ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions]"
+ ".common_http_protocol_options.idle_timeout.seconds "
+ "error:value must be in the range [0, 315576000000]]")
+ << decode_result.resource.status();
+}
+
+//
// circuit breaker tests
//