Skip to content

Commit

Permalink
dfp: more tests
Browse files Browse the repository at this point in the history
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
  • Loading branch information
alyssawilk committed Jan 22, 2024
1 parent 644c718 commit 8a5ea81
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 8a5ea81

Please sign in to comment.