Skip to content

Commit

Permalink
Improve negative TTL caching tests.
Browse files Browse the repository at this point in the history
To better clarify usage and add a second test to ensure the negative TTL
setting is actually being used, rather than the timing just happening to
work for the default TTL (which we saw in a separate branch working on
this with Trafficserver's DNS).
  • Loading branch information
GUI committed May 22, 2018
1 parent 8c7d1c5 commit 3e44b1a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 13 deletions.
64 changes: 51 additions & 13 deletions test/proxy/dns/test_negative_caching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,71 @@ def after_all
override_config_reset("--router")
end

def test_failed_host_down_after_ttl_expires
def test_caches_failed_lookups_before_retrying
assert_negative_ttl(NEGATIVE_TTL)
end

def test_negative_ttl_can_be_configured
negative_ttl = 3

# Ensure this negative TTL is different enough than the default that we can
# distinguish the results in tests.
assert_operator(negative_ttl, :<=, (NEGATIVE_TTL - TTL_BUFFER_POS).floor)

override_config({
"dns_resolver" => {
"nameservers" => ["[127.0.0.1]:#{$config["unbound"]["port"]}"],
"max_stale" => 0,
"negative_ttl" => negative_ttl,
},
}, "--router") do
assert_negative_ttl(negative_ttl)
end
end

private

def assert_negative_ttl(negative_ttl)
prepend_api_backends([
{
:frontend_host => "127.0.0.1",
:backend_host => "negative-caching-invalid-hostname-begins-resolving.ooga",
:servers => [{ :host => "negative-caching-invalid-hostname-begins-resolving.ooga", :port => 9444 }],
:url_matches => [{ :frontend_prefix => "/#{unique_test_id}/negative-caching-invalid-hostname-begins-resolving/", :backend_prefix => "/info/" }],
:backend_host => unique_test_hostname,
:servers => [{ :host => unique_test_hostname, :port => 9444 }],
:url_matches => [{ :frontend_prefix => "/#{unique_test_id}/", :backend_prefix => "/info/" }],
},
]) do
# The negative TTL caching really begins as soon as the initial
# configuration is put into place by runServer (since that's when the
# hostname is first seen and the unresolvable status is cached). So start
# our timer here.
# Make an initial request, which we expect to not succeed, since the
# hostname is bad.
wait_for_response("/#{unique_test_id}/", {
:code => 502,
})

# The negative TTL caching begins after TrafficServer sees the first
# request and tries to resolve it. So start our timer after the first
# request.
start_time = Time.now.utc

wait_for_response("/#{unique_test_id}/negative-caching-invalid-hostname-begins-resolving/", {
# Add the DNS record for the previously invalid domain.
set_dns_records(["#{unique_test_hostname} 60 A 127.0.0.1"])

# Ensure that negative caching is in place and the hostname is still not
# resolving (despite the DNS being installed now).
wait_for_response("/#{unique_test_id}/", {
:code => 502,
})

set_dns_records(["negative-caching-invalid-hostname-begins-resolving.ooga 60 A 127.0.0.1"])
wait_for_response("/#{unique_test_id}/negative-caching-invalid-hostname-begins-resolving/", {
# Wait for the successful response to resolve once the negative TTL has
# expired.
wait_for_response("/#{unique_test_id}/", {
:code => 200,
:local_interface_ip => "127.0.0.1",
})

# Sanity check the results to ensure the results fit within the expected
# negative TTL values.
duration = Time.now.utc - start_time
min_duration = NEGATIVE_TTL - TTL_BUFFER_NEG
max_duration = NEGATIVE_TTL + TTL_BUFFER_POS
min_duration = negative_ttl - TTL_BUFFER_NEG
max_duration = negative_ttl + TTL_BUFFER_POS
assert_operator(min_duration, :>, 0)
assert_operator(duration, :>=, min_duration)
assert_operator(duration, :<, max_duration)
Expand Down
24 changes: 24 additions & 0 deletions test/support/api_umbrella_test_helpers/setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,30 @@ def unique_test_id
@unique_test_id ||= self.location.gsub(/[^\w]+/, "-")
end

def unique_test_hostname
unless @unique_test_hostname
# Replace all non alpha-numeric chars (namely underscores that might be
# in the ID) with dashes (since underscores aren't valid for
# hostnames).
hostname = unique_test_id.downcase.gsub(/[^a-z0-9]+/, "-")

# Truncate the hostname so the label will fit in unbound's 63 char
# limit.
hostname = hostname[-56..-1] || hostname

# Strip first char if it happens to be a dash.
hostname.gsub!(/^-/, "")

# Since we've truncated the test ID, it's possible it's no longer
# unique, so append some random chars (but still, fitting within the 63
# char limit).
hostname = "#{hostname}-#{SecureRandom.hex(3)}"

@unique_test_hostname = "#{hostname}.test"
end
@unique_test_hostname
end

def next_unique_ip_addr
@@incrementing_unique_ip_addr = @@incrementing_unique_ip_addr.succ
@@incrementing_unique_ip_addr.to_s
Expand Down

0 comments on commit 3e44b1a

Please sign in to comment.