package zones import ( "net" "reflect" "sort" "testing" "github.com/miekg/dns" ) func TestClosest(t *testing.T) { muxm := loadZones(t) t.Log("test closests") tests := []struct { Label string ClientIP string ExpectedA []string QType uint16 MaxHosts int }{ {"closest", "212.237.144.84", []string{"194.106.223.155"}, dns.TypeA, 1}, {"closest", "208.113.157.108", []string{"207.171.7.49", "207.171.7.59"}, dns.TypeA, 2}, {"closest", "2620:0:872::1", []string{"2607:f238:3::1:45"}, dns.TypeAAAA, 1}, // {"closest", "208.113.157.108", []string{"207.171.7.59"}, 1}, } for _, x := range tests { ip := net.ParseIP(x.ClientIP) if ip == nil { t.Fatalf("Invalid ClientIP: %s", x.ClientIP) } tz := muxm.zonelist["test.example.com"] targets, netmask, location := tz.Options.Targeting.GetTargets(ip, true) t.Logf("targets: %q, netmask: %d, location: %+v", targets, netmask, location) // This is a weird API, but it's what serve() uses now. Fixing it // isn't super straight forward. Moving some of the exceptions from serve() // into configuration and making the "find the best answer" code have // a better API should be possible though. Some day. labelMatches := tz.FindLabels( x.Label, targets, []uint16{dns.TypeMF, dns.TypeCNAME, x.QType}, ) if len(labelMatches) == 0 { t.Fatalf("no labelmatches") } for _, match := range labelMatches { label := match.Label labelQtype := match.Type records := tz.Picker(label, labelQtype, x.MaxHosts, location) if records == nil { t.Fatalf("didn't get closest records") } if len(x.ExpectedA) == 0 { if len(records) > 0 { t.Logf("Expected 0 records but got %d", len(records)) t.Fail() } } if len(x.ExpectedA) != len(records) { t.Logf("Expected %d records, got %d", len(x.ExpectedA), len(records)) t.Fail() } ips := []string{} for _, r := range records { switch rr := r.RR.(type) { case *dns.A: ips = append(ips, rr.A.String()) case *dns.AAAA: ips = append(ips, rr.AAAA.String()) default: t.Fatalf("unexpected RR type: %s", rr.Header().String()) } } sort.Strings(ips) sort.Strings(x.ExpectedA) if !reflect.DeepEqual(ips, x.ExpectedA) { t.Logf("Got '%+v', expected '%+v'", ips, x.ExpectedA) t.Fail() } } } }