From 8a5ea818883863fea5cf96c2294f8217b9eee3b7 Mon Sep 17 00:00:00 2001 From: Alyssa Wilk Date: Mon, 22 Jan 2024 14:37:47 -0500 Subject: [PATCH 1/2] dfp: more tests Signed-off-by: Alyssa Wilk --- .../dynamic_forward_proxy/v3/dns_cache.proto | 4 +- .../proxy_filter_integration_test.cc | 64 ++++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto b/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto index d8f9b717fb00..eae3b8f74261 100644 --- a/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto +++ b/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto @@ -67,9 +67,9 @@ message DnsCacheConfig { // The minimum rate that DNS resolution will occur. Per ``dns_refresh_rate``, once a host is // resolved, the DNS TTL will be used, with a minimum set by ``dns_min_refresh_rate``. - // ``dns_min_refresh_rate`` defaults to 5s and must also be >= 5s. + // ``dns_min_refresh_rate`` defaults to 5s and must also be >= 1s. google.protobuf.Duration dns_min_refresh_rate = 14 - [(validate.rules).duration = {gte {seconds: 5}}]; + [(validate.rules).duration = {gte {seconds: 1}}]; // The TTL for hosts that are unused. Hosts that have not been used in the configured time // interval will be purged. If not specified defaults to 5m. diff --git a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc index df443ae619cc..806135fae878 100644 --- a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc +++ b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc @@ -50,9 +50,11 @@ name: dynamic_forward_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig dns_cache_config: + dns_min_refresh_rate: 1s name: foo dns_lookup_family: {} max_hosts: {} + host_ttl: 1s dns_cache_circuit_breaker: max_pending_requests: {}{}{} )EOF", @@ -127,9 +129,11 @@ name: envoy.clusters.dynamic_forward_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig dns_cache_config: + dns_min_refresh_rate: 1s name: foo dns_lookup_family: {} max_hosts: {} + host_ttl: 1s dns_cache_circuit_breaker: max_pending_requests: {}{}{} )EOF", @@ -162,9 +166,8 @@ name: envoy.clusters.dynamic_forward_proxy if (use_cache_file_) { cache_file_value_contents_ += absl::StrCat(Network::Test::getLoopbackAddressUrlString(version_), ":", - fake_upstreams_[0]->localAddress()->ip()->port(), "|1000000|0"); - std::string host = - fmt::format("localhost:{}", fake_upstreams_[0]->localAddress()->ip()->port()); + fake_upstreams_[0]->localAddress()->ip()->port(), "|", dns_cache_ttl_ , "|0"); + std::string host = fmt::format("{}:{}", dns_hostname_, fake_upstreams_[0]->localAddress()->ip()->port()); TestEnvironment::writeStringToFileForTest("dns_cache.txt", absl::StrCat(host.length(), "\n", host, cache_file_value_contents_.length(), @@ -254,8 +257,10 @@ name: envoy.clusters.dynamic_forward_proxy envoy::config::cluster::v3::Cluster cluster_; std::string cache_file_value_contents_; bool use_cache_file_{}; + uint32_t dns_cache_ttl_{1000000}; std::string filename_; std::string key_value_config_; + std::string dns_hostname_{"localhost"}; }; int64_t getHeaderValue(const Http::ResponseHeaderMap& headers, absl::string_view name) { @@ -646,6 +651,59 @@ TEST_P(ProxyFilterIntegrationTest, UseCacheFile) { EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.upstream_cx_http1_total")->value()); } +TEST_P(ProxyFilterIntegrationTest, UseCacheFileShortTtl) { + upstream_tls_ = false; // avoid cert errors for unknown hostname + use_cache_file_ = true; + dns_cache_ttl_ = 2; + + dns_hostname_ = "not_actually_localhost"; // Set to a name that won't resolve. + initializeWithArgs(); + std::string host = fmt::format("{}:{}", dns_hostname_, fake_upstreams_[0]->localAddress()->ip()->port()); + codec_client_ = makeHttpConnection(lookupPort("http")); + const Http::TestRequestHeaderMapImpl request_headers{ + {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", host}}; + + auto response = + sendRequestAndWaitForResponse(request_headers, 1024, default_response_headers_, 1024); + checkSimpleRequestSuccess(1024, 1024, response.get()); + EXPECT_EQ(1, test_server_->counter("dns_cache.foo.cache_load")->value()); + EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.upstream_cx_http1_total")->value()); + + // Wait for the host to be removed due to short TTL + test_server_->waitForCounterGe("dns_cache.foo.host_removed", 1); + + // Send a request and expect an error due to 1) removed host and 2) DNS resolution fail. + response = codec_client_->makeHeaderOnlyRequest(request_headers); + ASSERT_TRUE(response->waitForEndStream()); + EXPECT_EQ("503", response->headers().getStatusValue()); +} + +TEST_P(ProxyFilterIntegrationTest, UseCacheFileShortTtlHostActive) { + upstream_tls_ = false; // avoid cert errors for unknown hostname + use_cache_file_ = true; + dns_cache_ttl_ = 2; + + dns_hostname_ = "not_actually_localhost"; // Set to a name that won't resolve. + initializeWithArgs(); + std::string host = fmt::format("{}:{}", dns_hostname_, fake_upstreams_[0]->localAddress()->ip()->port()); + codec_client_ = makeHttpConnection(lookupPort("http")); + const Http::TestRequestHeaderMapImpl request_headers{ + {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", host}}; + + auto response = codec_client_->makeHeaderOnlyRequest(request_headers); + waitForNextUpstreamRequest(); + + // Wait for the host to be removed due to short TTL + test_server_->waitForCounterGe("dns_cache.foo.host_removed", 1); + + // Finish the response. + upstream_request_->encodeHeaders(default_response_headers_, true); + + // The disconnect will trigger failure. + ASSERT_TRUE(response->waitForEndStream()); + EXPECT_EQ("200", response->headers().getStatusValue()); +} + TEST_P(ProxyFilterIntegrationTest, UseCacheFileAndTestHappyEyeballs) { upstream_tls_ = false; // upstream creation doesn't handle autonomous_upstream_ autonomous_upstream_ = true; From 89d447cb9f561205b4df271b990927dce3aea911 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:43:12 +0000 Subject: [PATCH 2/2] build(deps-dev): bump eslint-plugin-n in /examples/single-page-app/ui Bumps [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) from 16.6.1 to 16.6.2. - [Release notes](https://github.com/eslint-community/eslint-plugin-n/releases) - [Commits](https://github.com/eslint-community/eslint-plugin-n/compare/16.6.1...16.6.2) --- updated-dependencies: - dependency-name: eslint-plugin-n dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- examples/single-page-app/ui/package.json | 2 +- examples/single-page-app/ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/single-page-app/ui/package.json b/examples/single-page-app/ui/package.json index 84cd045cdf9e..b6862a78b3cd 100644 --- a/examples/single-page-app/ui/package.json +++ b/examples/single-page-app/ui/package.json @@ -29,7 +29,7 @@ "eslint": "^8.0.1", "eslint-config-standard-with-typescript": "^43.0.0", "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-n": "^16.6.2", "eslint-plugin-promise": "^6.0.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/examples/single-page-app/ui/yarn.lock b/examples/single-page-app/ui/yarn.lock index 5d0f48705fd9..875d60c996a3 100644 --- a/examples/single-page-app/ui/yarn.lock +++ b/examples/single-page-app/ui/yarn.lock @@ -2255,10 +2255,10 @@ eslint-plugin-import@^2.25.2: semver "^6.3.1" tsconfig-paths "^3.15.0" -"eslint-plugin-n@^15.0.0 || ^16.0.0 ": - version "16.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.6.1.tgz#b16e0033bc9ce592b1c3512cb1cee24f84ecb5ae" - integrity sha512-M1kE5bVQRLBMDYRZwDhWzlzbp370SRRRC1MHqq4I3L2Tatey+9/2csc5mwLDPlmhJaDvkojbrNUME5/llpRyDg== +eslint-plugin-n@^16.6.2: + version "16.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz#6a60a1a376870064c906742272074d5d0b412b0b" + integrity sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" builtins "^5.0.1"