spb/internetpressure
Public
TypeScript 36.3%
Python 31.8%
Go 18%
JavaScript 9.8%
Shell 1.9%
SQL 1.4%
CSS 0.5%
1package dns23import (4 "context"5 "errors"6 "net"7 "testing"8 "time"910 mdns "github.com/miekg/dns"1112 "internetpressure.io/probe-agent/internal/protocol"13)1415type timeoutErr struct{}1617func (timeoutErr) Error() string { return "i/o timeout" }18func (timeoutErr) Timeout() bool { return true }19func (timeoutErr) Temporary() bool { return true }2021func TestClassify(t *testing.T) {22 cases := []struct {23 err error24 rcode string25 want string26 }{27 {nil, "TIMEOUT", protocol.ErrDNSTimeout},28 {nil, "SERVFAIL", protocol.ErrDNSServfail},29 {nil, "NXDOMAIN", protocol.ErrDNSNxdomain},30 {nil, "REFUSED", protocol.ErrDNSFail},31 {timeoutErr{}, "ERROR", protocol.ErrDNSTimeout},32 {context.DeadlineExceeded, "", protocol.ErrDNSTimeout},33 {errors.New("boom"), "ERROR", protocol.ErrDNSFail},34 }35 for _, c := range cases {36 if got := classify(c.err, c.rcode); got != c.want {37 t.Errorf("classify(%v,%q)=%q want %q", c.err, c.rcode, got, c.want)38 }39 }40}4142// A tiny in-process authoritative server answers example.test with two A records and NXDOMAIN otherwise.43func startServer(t *testing.T) string {44 pc, err := net.ListenPacket("udp", "127.0.0.1:0")45 if err != nil {46 t.Fatal(err)47 }48 srv := &mdns.Server{PacketConn: pc, Handler: mdns.HandlerFunc(func(w mdns.ResponseWriter, r *mdns.Msg) {49 m := new(mdns.Msg)50 m.SetReply(r)51 switch r.Question[0].Name {52 case "example.test.":53 m.Answer = append(m.Answer,54 &mdns.A{Hdr: mdns.RR_Header{Name: "example.test.", Rrtype: mdns.TypeA, Class: mdns.ClassINET, Ttl: 60}, A: net.ParseIP("10.0.0.2")},55 &mdns.A{Hdr: mdns.RR_Header{Name: "example.test.", Rrtype: mdns.TypeA, Class: mdns.ClassINET, Ttl: 60}, A: net.ParseIP("10.0.0.1")})56 case "fail.test.":57 m.Rcode = mdns.RcodeServerFailure58 case "slow.test.":59 return // never answers → timeout60 default:61 m.Rcode = mdns.RcodeNameError62 }63 _ = w.WriteMsg(m)64 })}65 go srv.ActivateAndServe()66 t.Cleanup(func() { srv.Shutdown() })67 return pc.LocalAddr().String()68}6970func TestQueryServer(t *testing.T) {71 addr := startServer(t)72 c := &Checker{}73 res := []protocol.Resolver{{ID: "local", Address: addr}}7475 ms := c.Run(context.Background(), protocol.Target{TargetID: "t", Hostname: "example.test"}, res)76 if len(ms) != 1 {77 t.Fatalf("expected 1 measurement, got %d", len(ms))78 }79 m := ms[0]80 if !m.OK || m.Error != "" || m.DNSRcode != "NOERROR" || m.Resolver != "local" || m.Kind != "dns" {81 t.Fatalf("unexpected: %+v", m)82 }83 if len(m.DNSAnswers) != 2 || m.DNSAnswers[0] != "10.0.0.1" || m.DNSAnswers[1] != "10.0.0.2" {84 t.Fatalf("answers not sorted: %v", m.DNSAnswers)85 }86 if m.DNSMs == nil || *m.DNSMs < 0 {87 t.Fatalf("dns_ms missing")88 }8990 m = c.Run(context.Background(), protocol.Target{TargetID: "t", Hostname: "nope.test"}, res)[0]91 if m.OK || m.Error != protocol.ErrDNSNxdomain || m.DNSRcode != "NXDOMAIN" {92 t.Fatalf("nxdomain: %+v", m)93 }94 m = c.Run(context.Background(), protocol.Target{TargetID: "t", Hostname: "fail.test"}, res)[0]95 if m.OK || m.Error != protocol.ErrDNSServfail || m.DNSRcode != "SERVFAIL" {96 t.Fatalf("servfail: %+v", m)97 }9899 ctx, cancel := context.WithTimeout(context.Background(), 700*time.Millisecond)100 defer cancel()101 m = c.Run(ctx, protocol.Target{TargetID: "t", Hostname: "slow.test"}, res)[0]102 if m.OK || m.Error != protocol.ErrDNSTimeout || m.DNSRcode != "TIMEOUT" {103 t.Fatalf("timeout: %+v", m)104 }105}106