From 4715c04c987c0d0f410c256c324d7cbdbbdc804e Mon Sep 17 00:00:00 2001 From: James Phillips Date: Fri, 13 Nov 2015 17:18:15 -0800 Subject: [PATCH] Adds a test to make sure a stale retry terminates. --- command/agent/dns.go | 4 +++- command/agent/dns_test.go | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/command/agent/dns.go b/command/agent/dns.go index 83bc980b40..bab2e90e82 100644 --- a/command/agent/dns.go +++ b/command/agent/dns.go @@ -560,7 +560,9 @@ func (d *DNSServer) preparedQueryLookup(network, datacenter, query string, req, // with dup filtering done at this level we need to get everything to // match the previous behavior. We can optimize by pushing more filtering // into the query execution, but for now I think we need to get the full - // response. + // response. We could also choose a large arbitrary number that will + // likely work in practice, like 10*maxServiceResponses which should help + // reduce bandwidth if there are thousands of nodes available. endpoint := d.agent.getEndpoint(preparedQueryEndpoint) var out structs.PreparedQueryExecuteResponse diff --git a/command/agent/dns_test.go b/command/agent/dns_test.go index b27befcea1..f8d641e5a6 100644 --- a/command/agent/dns_test.go +++ b/command/agent/dns_test.go @@ -2734,3 +2734,52 @@ func TestDNS_NonExistingLookupEmptyAorAAAA(t *testing.T) { } } } + +func TestDNS_PreparedQuery_AllowStale(t *testing.T) { + confFn := func(c *DNSConfig) { + c.AllowStale = true + c.MaxStale = time.Second + } + dir, srv := makeDNSServerConfig(t, nil, confFn) + defer os.RemoveAll(dir) + defer srv.agent.Shutdown() + + testutil.WaitForLeader(t, srv.agent.RPC, "dc1") + + m := MockPreparedQuery{} + if err := srv.agent.InjectEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } + + m.executeFn = func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + // Return a response that's perpetually too stale. + reply.LastContact = 2 * time.Second + return nil + } + + // Make sure that the lookup terminates and results in an SOA since + // the query doesn't exist. + { + m := new(dns.Msg) + m.SetQuestion("nope.query.consul.", dns.TypeSRV) + + c := new(dns.Client) + addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS) + in, _, err := c.Exchange(m, addr.String()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Ns) != 1 { + t.Fatalf("Bad: %#v", in) + } + + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + } +}