Files
coredns/test/auto_test.go
Nikolaus Schuetz af1e34ebc8 test: poll instead of fixed sleeps across several tests (#8275)
Several tests slept a fixed duration then took a single snapshot of an
async result, racing whatever they waited on:
- forward health tests waited 20ms for the health-check goroutine to bump
  an atomic counter,
- the auto plugin tests (dns + metrics) waited 50-110ms for a file-watch
  reload to be picked up,
- the file ZoneReload test waited 30ms (self-described as could still be
  racy) for a reload,
- the overloaded health test slept 1s for its background goroutine to fire
  its first request.

Replace each with a bounded poll of the actual condition (the atomic
counter, a dns.Exchange response, a metrics scrape, z.ApexIfDefined, or a
channel signalled by the test's own handler) so they pass as soon as the
awaited state is reached and no longer flake when it is slower than the
fixed wait. Test-only.

Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
2026-07-10 15:20:57 -07:00

167 lines
3.4 KiB
Go

package test
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/miekg/dns"
)
func TestAuto(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir()
corefile := `org:0 {
auto {
directory ` + tmpdir + ` db\.(.*) {1}
reload 0.01s
}
}`
i, udp, _, err := CoreDNSServerAndPorts(corefile)
if err != nil {
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
}
defer i.Stop()
m := new(dns.Msg)
m.SetQuestion("www.example.org.", dns.TypeA)
resp, err := dns.Exchange(m, udp)
if err != nil {
t.Fatal("Expected to receive reply, but didn't")
}
if resp.Rcode != dns.RcodeRefused {
t.Fatalf("Expected reply to be REFUSED, got %d", resp.Rcode)
}
// Write db.example.org to get example.org.
if err = os.WriteFile(filepath.Join(tmpdir, "db.example.org"), []byte(zoneContent), 0644); err != nil {
t.Fatal(err)
}
for start := time.Now(); time.Since(start) < 5*time.Second; {
resp, err = dns.Exchange(m, udp)
if err != nil {
t.Fatal("Expected to receive reply, but didn't")
}
if len(resp.Answer) == 1 {
break
}
time.Sleep(10 * time.Millisecond)
}
if len(resp.Answer) != 1 {
t.Fatalf("Expected 1 RR in the answer section, got %d", len(resp.Answer))
}
// Remove db.example.org again.
os.Remove(filepath.Join(tmpdir, "db.example.org"))
for start := time.Now(); time.Since(start) < 5*time.Second; {
resp, err = dns.Exchange(m, udp)
if err != nil {
t.Fatal("Expected to receive reply, but didn't")
}
if resp.Rcode == dns.RcodeRefused {
break
}
time.Sleep(10 * time.Millisecond)
}
if resp.Rcode != dns.RcodeRefused {
t.Fatalf("Expected reply to be REFUSED, got %d", resp.Rcode)
}
}
func TestAutoNonExistentZone(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir()
corefile := `.:0 {
auto {
directory ` + tmpdir + ` (.*) {1}
reload 0.01s
}
errors stdout
}`
i, err := CoreDNSServer(corefile)
if err != nil {
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
}
udp, _ := CoreDNSServerPorts(i, 0)
if udp == "" {
t.Fatal("Could not get UDP listening port")
}
defer i.Stop()
m := new(dns.Msg)
m.SetQuestion("example.org.", dns.TypeA)
resp, err := dns.Exchange(m, udp)
if err != nil {
t.Fatal("Expected to receive reply, but didn't")
}
if resp.Rcode != dns.RcodeRefused {
t.Fatalf("Expected reply to be REFUSED, got %d", resp.Rcode)
}
}
func TestAutoAXFR(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir()
corefile := `org:0 {
auto {
directory ` + tmpdir + ` db\.(.*) {1}
reload 0.01s
}
transfer {
to *
}
}`
i, err := CoreDNSServer(corefile)
if err != nil {
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
}
_, tcp := CoreDNSServerPorts(i, 0)
if tcp == "" {
t.Fatal("Could not get TCP listening port")
}
defer i.Stop()
// Write db.example.org to get example.org.
if err = os.WriteFile(filepath.Join(tmpdir, "db.example.org"), []byte(zoneContent), 0644); err != nil {
t.Fatal(err)
}
time.Sleep(50 * time.Millisecond) // wait for it to be picked up
tr := new(dns.Transfer)
m := new(dns.Msg)
m.SetAxfr("example.org.")
c, err := tr.In(m, tcp)
if err != nil {
t.Fatal("Expected to receive reply, but didn't")
}
l := 0
for e := range c {
l += len(e.RR)
}
if l != 5 {
t.Fatalf("Expected response with %d RRs, got %d", 5, l)
}
}
const zoneContent = `; testzone
@ IN SOA sns.dns.icann.org. noc.dns.icann.org. 2016082534 7200 3600 1209600 3600
IN NS a.iana-servers.net.
IN NS b.iana-servers.net.
www IN A 127.0.0.1
`