Files
coredns/test/siit_test.go
Michée lengronne 3b9f85bb71 feat(siit): Initial version (#8188)
* feat(siit): Initial version

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* cleaner readme

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* linting and generating

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* improving README and removing a useless case

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* improvements

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* improvements

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* linting

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* New fixes

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* improvements

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

* improvements

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>

---------

Signed-off-by: Michée Lengronne <michee.lengronne@coppint.com>
2026-08-23 17:55:27 -07:00

81 lines
2.3 KiB
Go

package test
import (
"testing"
"github.com/coredns/coredns/plugin/pkg/dnstest"
"github.com/miekg/dns"
)
// TestSIITAfterForward is a regression test for the plugin.cfg ordering bug:
// siit must run AFTER forward in the plugin chain so it can see (and rewrite)
// the AAAA answer forward returns, rather than running before it and never
// seeing the final response.
//
// Unlike the unit tests in plugin/siit, which instantiate SIIT directly and
// wire d.Next/d.Upstream to fakes, this test drives the real plugin chain
// built from plugin.cfg via a Corefile, so a future ordering regression
// (siit placed after cache/forward again) will fail here even though it
// can't be detected by the package-level unit tests.
func TestSIITAfterForward(t *testing.T) {
// Upstream "authoritative" server: NODATA for A, a mapped AAAA for AAAA.
upstream := dnstest.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
switch r.Question[0].Qtype {
case dns.TypeA:
// NODATA: success, no answer section -- this is what makes
// siit's responseShouldSIIT return true.
case dns.TypeAAAA:
rr, err := dns.NewRR("example.org. 60 IN AAAA 64:ff9b::192.0.2.42")
if err != nil {
t.Fatalf("failed to build AAAA record: %v", err)
}
m.Answer = []dns.RR{rr}
}
w.WriteMsg(m)
})
defer upstream.Close()
corefile := `example.org:0 {
siit {
ipv6_prefix 64:ff9b::/96
}
forward . ` + upstream.Addr + `
}`
server, udp, _, err := CoreDNSServerAndPorts(corefile)
if err != nil {
t.Fatalf("could not start CoreDNS test server: %v", err)
}
defer server.Stop()
m := new(dns.Msg)
m.SetQuestion("example.org.", dns.TypeA)
resp, err := dns.Exchange(m, udp)
if err != nil {
t.Fatalf("query failed: %v", err)
}
if resp.Rcode != dns.RcodeSuccess {
t.Fatalf("expected RcodeSuccess, got %s", dns.RcodeToString[resp.Rcode])
}
if len(resp.Answer) != 1 {
t.Fatalf("expected 1 answer record, got %d: %v", len(resp.Answer), resp.Answer)
}
a, ok := resp.Answer[0].(*dns.A)
if !ok {
t.Fatalf("expected an A record in the answer, got %T: %v", resp.Answer[0], resp.Answer[0])
}
want := "192.0.2.42"
if a.A.String() != want {
t.Errorf("expected synthesized A record %s, got %s -- if this is empty/unset, siit likely ran before forward in the plugin chain and never saw the upstream's AAAA answer", want, a.A.String())
}
}