mirror of
https://github.com/namecoin/ncdns
synced 2024-11-13 13:10:33 +00:00
4959056021
©! I, Hugo Landau <hlandau@devever.net>, hereby licence these changes under the ©! licence with SHA256 hash ©! fd80a26fbb3f644af1fa994134446702932968519797227e07a1368dea80f0bc.
265 lines
14 KiB
Go
265 lines
14 KiB
Go
package ncdomain_test
|
|
|
|
import "github.com/namecoin/ncdns/ncdomain"
|
|
import "github.com/namecoin/ncdns/testutil"
|
|
import _ "github.com/hlandau/nctestsuite"
|
|
import "testing"
|
|
import "fmt"
|
|
import "strings"
|
|
import "sort"
|
|
|
|
func TestSuite(t *testing.T) {
|
|
items := testutil.SuiteReader(t)
|
|
for ti := range items {
|
|
resolve := func(name string) (string, error) {
|
|
v, ok := ti.Names[name]
|
|
if !ok {
|
|
return "", fmt.Errorf("not found")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
for k, jsonValue := range ti.Names {
|
|
dnsName, err := convertName(k)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
errCount := 0
|
|
errFunc := func(err error, isWarning bool) {
|
|
if !isWarning {
|
|
errCount++
|
|
}
|
|
//fmt.Printf("Error: %v\n", err)
|
|
}
|
|
|
|
v := ncdomain.ParseValue(k, jsonValue, resolve, errFunc)
|
|
if v == nil {
|
|
// TODO
|
|
continue
|
|
}
|
|
|
|
rrstrs := []string{}
|
|
rrs, _ := v.RRsRecursive(nil, dnsName+".bit.", dnsName+".bit.")
|
|
for _, rr := range rrs {
|
|
s := rr.String()
|
|
s = strings.Replace(s, "\t600\t", "\t", -1) // XXX
|
|
rrstrs = append(rrstrs, strings.Replace(s, "\t", " ", -1))
|
|
}
|
|
sort.Strings(rrstrs)
|
|
rrstr := strings.Join(rrstrs, "\n")
|
|
|
|
// CHECK MATCH
|
|
if rrstr != ti.Records {
|
|
t.Errorf("Didn't match: %s\n%+v\n !=\n%+v\n\n%#v\n\n%#v", ti.ID, rrstr, ti.Records, v, rrs)
|
|
}
|
|
|
|
if errCount != ti.NumErrors {
|
|
t.Errorf("Error count didn't match: %d != %d (%s)\n", errCount, ti.NumErrors, ti.ID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func convertName(n string) (string, error) {
|
|
if len(n) < 3 || len(n) > 65 {
|
|
return "", fmt.Errorf("invalid name")
|
|
}
|
|
if n[0:2] != "d/" {
|
|
return "", fmt.Errorf("not a domain")
|
|
}
|
|
return n[2:], nil
|
|
}
|
|
|
|
/*
|
|
type item struct {
|
|
jsonValue string
|
|
value *ncdomain.Value
|
|
expectedError error
|
|
merges map[string]string
|
|
rrstr string
|
|
}
|
|
|
|
var suite = []item{
|
|
item{`{}`, &ncdomain.Value{}, nil, nil, ""},
|
|
item{`{"ip":"1.2.3.4"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
|
|
item{`{"ip":["1.2.3.4"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
|
|
item{`{"ip":["1.2.3.4","200.200.200.200"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4"), net.ParseIP("200.200.200.200")}}, nil, nil, "bit. 600 IN A 1.2.3.4\nbit. 600 IN A 200.200.200.200"},
|
|
item{`{"ip6":"dead:b33f::deca:fbad"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad"},
|
|
item{`{"ip6":["dead:b33f::deca:fbad"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad"},
|
|
item{`{"ip6":["dead:b33f::deca:fbad","1234:abcd:5678:bcde:9876:fedc:5432:ba98"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad"), net.ParseIP("1234:abcd:5678:bcde:9876:fedc:5432:ba98")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad\nbit. 600 IN AAAA 1234:abcd:5678:bcde:9876:fedc:5432:ba98"},
|
|
item{`{"ns":"alpha.beta.gamma.delta"}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta."},
|
|
item{`{"ns":["alpha.beta.gamma.delta"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta."},
|
|
item{`{"ns":["alpha.beta.gamma.delta","delta.gamma.beta.alpha"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta", "delta.gamma.beta.alpha"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta.\nbit. 600 IN NS delta.gamma.beta.alpha."},
|
|
item{`{"mx":[[10,"alpha.beta.gamma.delta"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}}}, nil, nil, "bit. 600 IN MX 10 alpha.beta.gamma.delta."},
|
|
item{`{"mx":[[10,"alpha.beta.gamma.delta"],[20,"epsilon.example"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}, &dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 20, Mx: "epsilon.example"}}}, nil, nil, "bit. 600 IN MX 10 alpha.beta.gamma.delta.\nbit. 600 IN MX 20 epsilon.example."},
|
|
item{`{"alias":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Alias: "alpha.beta.gamma.delta"}, nil, nil, "bit. 600 IN CNAME alpha.beta.gamma.delta."},
|
|
item{`{"translate":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Translate: "alpha.beta.gamma.delta"}, nil, nil, "bit. 600 IN DNAME alpha.beta.gamma.delta."},
|
|
item{`{"txt":"text record"}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil, "bit. 600 IN TXT \"text record\""},
|
|
item{`{"txt":"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]"}`, &ncdomain.Value{TXT: [][]string{[]string{"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]", "[text ... record]"}}}, nil, nil, ""},
|
|
item{`{"txt":["text record"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil, "bit. 600 IN TXT \"text record\""},
|
|
item{`{"txt":["text record","text record 2"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}, []string{"text record 2"}}}, nil, nil, "bit. 600 IN TXT \"text record\"\nbit. 600 IN TXT \"text record 2\""},
|
|
item{`{"txt":[["text", "record"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}}}, nil, nil, "bit. 600 IN TXT \"text\" \"record\""},
|
|
item{`{"txt":[["text", "record"],["text", "record", "2"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}, []string{"text", "record", "2"}}}, nil, nil, "bit. 600 IN TXT \"text\" \"record\"\nbit. 600 IN TXT \"text\" \"record\" \"2\""},
|
|
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}}}, nil, nil, "_http._tcp.bit. IN SRV 1 2 80 alpha.beta.gamma.delta."},
|
|
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"], ["https","tcp",1,2,443,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}, &dns.SRV{Hdr: dns.RR_Header{Name: "_https._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 443, Target: "alpha.beta.gamma.delta"}}}, nil, nil, "_http._tcp.bit. 600 IN SRV 1 2 80 alpha.beta.gamma.delta.\n_https._tcp.bit. 600 IN SRV 1 2 443 alpha.beta.gamma.delta."},
|
|
item{`{"map":{ "": { } }}`, &ncdomain.Value{}, nil, nil, ""},
|
|
item{`{"map":{ "": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
|
|
item{`{"map":{ "www": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil, "www.bit. 600 IN A 1.2.3.4"},
|
|
item{`{"map":{ "": "1.2.3.4" }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
|
|
item{`{"map":{ "www": "1.2.3.4" }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil, "www.bit. 600 IN A 1.2.3.4"},
|
|
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil, "bit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
|
|
item{`{"ds":[[54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="],[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}, &dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil, "bit. 600 IN DS 54321 8 1 E6C1716CFB6BDC84E84CE1AB5510DAC69173B5B2\nbit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
|
|
item{`{"email":"hostmaster@example.com"}`, &ncdomain.Value{Hostmaster: "hostmaster@example.com"}, nil, nil, ""},
|
|
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}, "bit. 600 IN A 1.2.3.4\nbit. 600 IN AAAA ::beef"},
|
|
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip":["2.3.4.5"],"ip6":["::beef"]}`}, "bit. 600 IN A 1.2.3.4\nbit. 600 IN AAAA ::beef"},
|
|
item{`{"ns":["alpha.beta"],"import":"d/example"}`, &ncdomain.Value{NS: []string{"alpha.beta"}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ns":["gamma.delta"],"ip6":["::beef"]}`}, "bit. 600 IN NS alpha.beta."},
|
|
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]],"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}, "bit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
|
|
item{`{"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}, "bit. 600 IN DS 54321 8 1 E6C1716CFB6BDC84E84CE1AB5510DAC69173B5B2"},
|
|
item{`{"ip":["1.2.3.4"],"delegate":"d/example"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}, "bit. 600 IN AAAA ::beef"},
|
|
}
|
|
|
|
func TestConversion(t *testing.T) {
|
|
for i, item := range suite {
|
|
resolve := func(name string) (string, error) {
|
|
if item.merges == nil {
|
|
return "", fmt.Errorf("not found")
|
|
}
|
|
|
|
if s, ok := item.merges[name]; ok {
|
|
return s, nil
|
|
} else {
|
|
return "", fmt.Errorf("not found")
|
|
}
|
|
}
|
|
v, err := ncdomain.ParseValue(item.jsonValue, resolve)
|
|
if err != item.expectedError {
|
|
t.Errorf("Item %d did not match expected error: got %+v but expected %+v", i, err, item.expectedError)
|
|
}
|
|
if !equals(v, item.value) {
|
|
t.Errorf("Item %d value did not match expected value: got %+v but expected %+v", i, v, item.value)
|
|
}
|
|
if item.rrstr != "" {
|
|
rrstr := ""
|
|
rrs, _ := v.RRsRecursive(nil, "bit.")
|
|
for _, rr := range rrs {
|
|
rrstr += strings.Replace(rr.String(), "\t", " ", -1)
|
|
rrstr += "\n"
|
|
}
|
|
rrstr = strings.Trim(rrstr, "\n")
|
|
if item.rrstr != rrstr {
|
|
t.Errorf("Item %d rrstr did not match the expected value: got %+v but expected %+v", i, rrstr, item.rrstr)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// utility functions for testing equality
|
|
|
|
func equals(v1 *ncdomain.Value, v2 *ncdomain.Value) bool {
|
|
return (v1 != nil) == (v2 != nil) &&
|
|
eqIPArray(v1.IP, v2.IP) &&
|
|
eqIPArray(v1.IP6, v2.IP6) &&
|
|
eqStringArray(v1.NS, v2.NS) &&
|
|
v1.Alias == v2.Alias &&
|
|
v1.Translate == v2.Translate &&
|
|
eqDSArray(v1.DS, v2.DS) &&
|
|
eqStringArrayArray(v1.TXT, v2.TXT) &&
|
|
eqServiceArray(v1.Service, v2.Service) &&
|
|
eqValueMap(v1, v2) &&
|
|
v1.Hostmaster == v2.Hostmaster
|
|
}
|
|
|
|
func eqIPArray(a []net.IP, b []net.IP) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if !a[i].Equal(b[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqStringArray(a []string, b []string) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if a[i] != b[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqDSArray(a []*dns.DS, b []*dns.DS) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if !eqDS(a[i], b[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqDS(a *dns.DS, b *dns.DS) bool {
|
|
return a.KeyTag == b.KeyTag && a.Algorithm == b.Algorithm &&
|
|
a.DigestType == b.DigestType && a.Digest == b.Digest && eqHdr(a.Hdr, b.Hdr)
|
|
}
|
|
|
|
func eqHdr(a dns.RR_Header, b dns.RR_Header) bool {
|
|
return a.Name == b.Name && a.Rrtype == b.Rrtype && a.Class == b.Class && a.Ttl == b.Ttl
|
|
}
|
|
|
|
func eqStringArrayArray(a [][]string, b [][]string) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if !eqStringArray(a[i], b[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqServiceArray(a []*dns.SRV, b []*dns.SRV) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if !eqService(a[i], b[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqService(a *dns.SRV, b *dns.SRV) bool {
|
|
return a.Priority == b.Priority && a.Weight == b.Weight &&
|
|
a.Port == b.Port && a.Target == b.Target && eqHdr(a.Hdr, b.Hdr)
|
|
}
|
|
|
|
func eqValueMap(a *ncdomain.Value, b *ncdomain.Value) bool {
|
|
if len(a.Map) != len(b.Map) {
|
|
return false
|
|
}
|
|
|
|
for k, v1 := range a.Map {
|
|
v2, ok := b.Map[k]
|
|
if !ok {
|
|
return false
|
|
}
|
|
if !equals(v1, v2) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}*/
|