mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 17:16:59 +02:00
971 lines
20 KiB
Go
971 lines
20 KiB
Go
/*
|
|
Copyright 2017 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package endpoint
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestNewEndpoint(t *testing.T) {
|
|
e := NewEndpoint("example.org", "CNAME", "foo.com")
|
|
if e.DNSName != "example.org" || e.Targets[0] != "foo.com" || e.RecordType != "CNAME" {
|
|
t.Error("endpoint is not initialized correctly")
|
|
}
|
|
if e.Labels == nil {
|
|
t.Error("Labels is not initialized")
|
|
}
|
|
|
|
w := NewEndpoint("example.org.", "", "load-balancer.com.")
|
|
if w.DNSName != "example.org" || w.Targets[0] != "load-balancer.com" || w.RecordType != "" {
|
|
t.Error("endpoint is not initialized correctly")
|
|
}
|
|
}
|
|
|
|
func TestNewTargets(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
input []string
|
|
expected Targets
|
|
}{
|
|
{
|
|
name: "no targets",
|
|
input: []string{},
|
|
expected: Targets{},
|
|
},
|
|
{
|
|
name: "single target",
|
|
input: []string{"1.2.3.4"},
|
|
expected: Targets{"1.2.3.4"},
|
|
},
|
|
{
|
|
name: "multiple targets",
|
|
input: []string{"example.com", "8.8.8.8", "::0001"},
|
|
expected: Targets{"example.com", "8.8.8.8", "::0001"},
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
Targets := NewTargets(c.input...)
|
|
changedTarget := Targets.String()
|
|
assert.Equal(t, c.expected.String(), changedTarget)
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTargetsSame(t *testing.T) {
|
|
tests := []Targets{
|
|
{""},
|
|
{"1.2.3.4"},
|
|
{"8.8.8.8", "8.8.4.4"},
|
|
{"dd:dd::01", "::1", "::0001"},
|
|
{"example.org", "EXAMPLE.ORG"},
|
|
}
|
|
|
|
for _, d := range tests {
|
|
if d.Same(d) != true {
|
|
t.Errorf("%#v should equal %#v", d, d)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSameSuccess(t *testing.T) {
|
|
tests := []struct {
|
|
a Targets
|
|
b Targets
|
|
}{
|
|
{
|
|
[]string{"::1"},
|
|
[]string{"::0001"},
|
|
},
|
|
{
|
|
[]string{"::1", "dd:dd::01"},
|
|
[]string{"dd:00dd::0001", "::0001"},
|
|
},
|
|
|
|
{
|
|
[]string{"::1", "dd:dd::01"},
|
|
[]string{"00dd:dd::0001", "::0001"},
|
|
},
|
|
{
|
|
[]string{"::1", "1.1.1.1", "2600.com", "3.3.3.3"},
|
|
[]string{"2600.com", "::0001", "3.3.3.3", "1.1.1.1"},
|
|
},
|
|
}
|
|
|
|
for _, d := range tests {
|
|
if d.a.Same(d.b) == false {
|
|
t.Errorf("%#v should equal %#v", d.a, d.b)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSameFailures(t *testing.T) {
|
|
tests := []struct {
|
|
a Targets
|
|
b Targets
|
|
}{
|
|
{
|
|
[]string{"1.2.3.4"},
|
|
[]string{"4.3.2.1"},
|
|
}, {
|
|
[]string{"1.2.3.4"},
|
|
[]string{"1.2.3.4", "4.3.2.1"},
|
|
}, {
|
|
[]string{"1.2.3.4", "4.3.2.1"},
|
|
[]string{"1.2.3.4"},
|
|
}, {
|
|
[]string{"1.2.3.4", "4.3.2.1"},
|
|
[]string{"8.8.8.8", "8.8.4.4"},
|
|
},
|
|
{
|
|
[]string{"::1", "2600.com", "3.3.3.3"},
|
|
[]string{"2600.com", "3.3.3.3", "1.1.1.1"},
|
|
},
|
|
}
|
|
|
|
for _, d := range tests {
|
|
if d.a.Same(d.b) == true {
|
|
t.Errorf("%#v should not equal %#v", d.a, d.b)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsLess(t *testing.T) {
|
|
testsA := []Targets{
|
|
{""},
|
|
{"1.2.3.4"},
|
|
{"1.2.3.4"},
|
|
{"example.org", "example.com"},
|
|
{"8.8.8.8", "8.8.4.4"},
|
|
{"1-2-3-4.example.org", "EXAMPLE.ORG"},
|
|
{"1-2-3-4.example.org", "EXAMPLE.ORG", "1.2.3.4"},
|
|
{"example.com", "example.org"},
|
|
}
|
|
testsB := []Targets{
|
|
{"", ""},
|
|
{"1-2-3-4.example.org"},
|
|
{"1.2.3.5"},
|
|
{"example.com", "examplea.org"},
|
|
{"8.8.8.8"},
|
|
{"1.2.3.4", "EXAMPLE.ORG"},
|
|
{"1-2-3-4.example.org", "EXAMPLE.ORG"},
|
|
{"example.com", "example.org"},
|
|
}
|
|
expected := []bool{
|
|
true,
|
|
true,
|
|
true,
|
|
true,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
}
|
|
|
|
for i, d := range testsA {
|
|
if d.IsLess(testsB[i]) != expected[i] {
|
|
t.Errorf("%v < %v is expected to be %v", d, testsB[i], expected[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetProviderSpecificProperty(t *testing.T) {
|
|
e := &Endpoint{
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name",
|
|
Value: "value",
|
|
},
|
|
},
|
|
}
|
|
|
|
t.Run("key is not present in provider specific", func(t *testing.T) {
|
|
val, ok := e.GetProviderSpecificProperty("hello")
|
|
assert.False(t, ok)
|
|
assert.Empty(t, val)
|
|
})
|
|
|
|
t.Run("key is present in provider specific", func(t *testing.T) {
|
|
val, ok := e.GetProviderSpecificProperty("name")
|
|
assert.True(t, ok)
|
|
assert.NotEmpty(t, val)
|
|
|
|
})
|
|
}
|
|
|
|
func TestSetProviderSpecficProperty(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
endpoint Endpoint
|
|
key string
|
|
value string
|
|
expectedIdentifier string
|
|
expected []ProviderSpecificProperty
|
|
}{
|
|
{
|
|
name: "endpoint is empty",
|
|
endpoint: Endpoint{},
|
|
key: "key1",
|
|
value: "value1",
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "key1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "name and key are not matching",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.org",
|
|
RecordTTL: TTL(0),
|
|
RecordType: RecordTypeA,
|
|
SetIdentifier: "newIdentifier",
|
|
Targets: Targets{
|
|
"example.org", "example.com", "1.2.4.5",
|
|
},
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
expectedIdentifier: "newIdentifier",
|
|
key: "name2",
|
|
value: "value2",
|
|
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
{
|
|
Name: "name2",
|
|
Value: "value2",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "some keys are matching and some are not matching ",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.org",
|
|
RecordTTL: TTL(0),
|
|
RecordType: RecordTypeA,
|
|
SetIdentifier: "newIdentifier",
|
|
Targets: Targets{
|
|
"example.org", "example.com", "1.2.4.5",
|
|
},
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
{
|
|
Name: "name2",
|
|
Value: "value2",
|
|
},
|
|
{
|
|
Name: "name3",
|
|
Value: "value3",
|
|
},
|
|
},
|
|
},
|
|
key: "name2",
|
|
value: "value2",
|
|
expectedIdentifier: "newIdentifier",
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
{
|
|
Name: "name2",
|
|
Value: "value2",
|
|
},
|
|
{
|
|
Name: "name3",
|
|
Value: "value3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "name and key are not matching",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.org",
|
|
RecordTTL: TTL(0),
|
|
RecordType: RecordTypeA,
|
|
SetIdentifier: "identifier",
|
|
Targets: Targets{
|
|
"example.org", "example.com", "1.2.4.5",
|
|
},
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
key: "name1",
|
|
value: "value2",
|
|
expectedIdentifier: "identifier",
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value2",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
c.endpoint.WithProviderSpecific(c.key, c.value)
|
|
expectedString := fmt.Sprintf("%s %d IN %s %s %s %s", c.endpoint.DNSName, c.endpoint.RecordTTL, c.endpoint.RecordType, c.endpoint.SetIdentifier, c.endpoint.Targets, c.endpoint.ProviderSpecific)
|
|
identifier := c.endpoint.WithSetIdentifier(c.endpoint.SetIdentifier)
|
|
assert.Equal(t, c.expectedIdentifier, identifier.SetIdentifier)
|
|
assert.Equal(t, expectedString, c.endpoint.String())
|
|
if !reflect.DeepEqual([]ProviderSpecificProperty(c.endpoint.ProviderSpecific), c.expected) {
|
|
t.Errorf("unexpected ProviderSpecific:\nGot: %#v\nExpected: %#v", c.endpoint.ProviderSpecific, c.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteProviderSpecificProperty(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
endpoint Endpoint
|
|
key string
|
|
expected []ProviderSpecificProperty
|
|
}{
|
|
{
|
|
name: "name and key are not matching",
|
|
endpoint: Endpoint{
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
key: "name2",
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "some keys are matching and some keys are not matching",
|
|
endpoint: Endpoint{
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
{
|
|
Name: "name2",
|
|
Value: "value2",
|
|
},
|
|
{
|
|
Name: "name3",
|
|
Value: "value3",
|
|
},
|
|
},
|
|
},
|
|
key: "name2",
|
|
expected: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
{
|
|
Name: "name3",
|
|
Value: "value3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "name and key are matching",
|
|
endpoint: Endpoint{
|
|
ProviderSpecific: []ProviderSpecificProperty{
|
|
{
|
|
Name: "name1",
|
|
Value: "value1",
|
|
},
|
|
},
|
|
},
|
|
key: "name1",
|
|
expected: []ProviderSpecificProperty{},
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
c.endpoint.DeleteProviderSpecificProperty(c.key)
|
|
if !reflect.DeepEqual([]ProviderSpecificProperty(c.endpoint.ProviderSpecific), c.expected) {
|
|
t.Errorf("unexpected ProviderSpecific:\nGot: %#v\nExpected: %#v", c.endpoint.ProviderSpecific, c.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterEndpointsByOwnerIDWithRecordTypeA(t *testing.T) {
|
|
foo1 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo2 := &Endpoint{
|
|
DNSName: "foo2.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
bar := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "bar",
|
|
},
|
|
}
|
|
type args struct {
|
|
ownerID string
|
|
eps []*Endpoint
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Endpoint
|
|
}{
|
|
{
|
|
name: "filter values",
|
|
args: args{
|
|
ownerID: "foo",
|
|
eps: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
bar,
|
|
},
|
|
},
|
|
want: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := FilterEndpointsByOwnerID(tt.args.ownerID, tt.args.eps); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("ApplyEndpointFilter() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterEndpointsByOwnerIDWithRecordTypeCNAME(t *testing.T) {
|
|
foo1 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeCNAME,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo2 := &Endpoint{
|
|
DNSName: "foo2.com",
|
|
RecordType: RecordTypeCNAME,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
bar := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeCNAME,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "bar",
|
|
},
|
|
}
|
|
type args struct {
|
|
ownerID string
|
|
eps []*Endpoint
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Endpoint
|
|
}{
|
|
{
|
|
name: "filter values",
|
|
args: args{
|
|
ownerID: "foo",
|
|
eps: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
bar,
|
|
},
|
|
},
|
|
want: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := FilterEndpointsByOwnerID(tt.args.ownerID, tt.args.eps); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("ApplyEndpointFilter() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsOwnedBy(t *testing.T) {
|
|
type fields struct {
|
|
Labels Labels
|
|
}
|
|
type args struct {
|
|
ownerID string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "empty labels",
|
|
fields: fields{Labels: Labels{}},
|
|
args: args{ownerID: "foo"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "owner label not match",
|
|
fields: fields{Labels: Labels{OwnerLabelKey: "bar"}},
|
|
args: args{ownerID: "foo"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "owner label match",
|
|
fields: fields{Labels: Labels{OwnerLabelKey: "foo"}},
|
|
args: args{ownerID: "foo"},
|
|
want: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := &Endpoint{
|
|
Labels: tt.fields.Labels,
|
|
}
|
|
if got := e.IsOwnedBy(tt.args.ownerID); got != tt.want {
|
|
t.Errorf("Endpoint.IsOwnedBy() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDuplicatedEndpointsWithSimpleZone(t *testing.T) {
|
|
foo1 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo2 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
bar := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "bar",
|
|
},
|
|
}
|
|
|
|
type args struct {
|
|
eps []*Endpoint
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Endpoint
|
|
}{
|
|
{
|
|
name: "filter values",
|
|
args: args{
|
|
eps: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
bar,
|
|
},
|
|
},
|
|
want: []*Endpoint{
|
|
foo1,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := RemoveDuplicates(tt.args.eps); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("RemoveDuplicates() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDuplicatedEndpointsWithOverlappingZones(t *testing.T) {
|
|
foo1 := &Endpoint{
|
|
DNSName: "internal.foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo2 := &Endpoint{
|
|
DNSName: "internal.foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo3 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
foo4 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "foo",
|
|
},
|
|
}
|
|
bar := &Endpoint{
|
|
DNSName: "internal.foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "bar",
|
|
},
|
|
}
|
|
bar2 := &Endpoint{
|
|
DNSName: "foo.com",
|
|
RecordType: RecordTypeA,
|
|
Labels: Labels{
|
|
OwnerLabelKey: "bar",
|
|
},
|
|
}
|
|
|
|
type args struct {
|
|
eps []*Endpoint
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Endpoint
|
|
}{
|
|
{
|
|
name: "filter values",
|
|
args: args{
|
|
eps: []*Endpoint{
|
|
foo1,
|
|
foo2,
|
|
foo3,
|
|
foo4,
|
|
bar,
|
|
bar2,
|
|
},
|
|
},
|
|
want: []*Endpoint{
|
|
foo1,
|
|
foo3,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := RemoveDuplicates(tt.args.eps); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("RemoveDuplicates() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPDNScheckEndpoint(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
endpoint Endpoint
|
|
expected bool
|
|
}{
|
|
{
|
|
description: "Valid MX record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"10 example.com"},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
description: "Valid MX record with multiple targets",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"10 example.com", "20 backup.example.com"},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
description: "MX record with valid and invalid targets",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"example.com", "backup.example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Invalid MX record with missing priority value",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Invalid MX record with too many arguments",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"10 example.com abc"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Invalid MX record with non-integer priority",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"abc example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Valid SRV record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "_service._tls.example.com",
|
|
RecordType: RecordTypeSRV,
|
|
Targets: Targets{"10 20 5060 service.example.com"},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
description: "Invalid SRV record with missing part",
|
|
endpoint: Endpoint{
|
|
DNSName: "_service._tls.example.com",
|
|
RecordType: RecordTypeSRV,
|
|
Targets: Targets{"10 20 5060"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Invalid SRV record with non-integer part",
|
|
endpoint: Endpoint{
|
|
DNSName: "_service._tls.example.com",
|
|
RecordType: RecordTypeSRV,
|
|
Targets: Targets{"10 20 abc service.example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
actual := tt.endpoint.CheckEndpoint()
|
|
assert.Equal(t, tt.expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestNewMXTarget(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
target string
|
|
expected *MXTarget
|
|
expectError bool
|
|
}{
|
|
{
|
|
description: "Valid MX record",
|
|
target: "10 example.com",
|
|
expected: &MXTarget{priority: 10, host: "example.com"},
|
|
expectError: false,
|
|
},
|
|
{
|
|
description: "Invalid MX record with missing priority",
|
|
target: "example.com",
|
|
expectError: true,
|
|
},
|
|
{
|
|
description: "Invalid MX record with non-integer priority",
|
|
target: "abc example.com",
|
|
expectError: true,
|
|
},
|
|
{
|
|
description: "Invalid MX record with too many parts",
|
|
target: "10 example.com extra",
|
|
expectError: true,
|
|
},
|
|
{
|
|
description: "Missing host",
|
|
target: "10 ",
|
|
expected: nil,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
actual, err := NewMXRecord(tt.target)
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.expected, actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckEndpoint(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
endpoint Endpoint
|
|
expected bool
|
|
}{
|
|
{
|
|
description: "Valid MX record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"10 example.com"},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
description: "Invalid MX record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeMX,
|
|
Targets: Targets{"example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Valid SRV record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "_service._tcp.example.com",
|
|
RecordType: RecordTypeSRV,
|
|
Targets: Targets{"10 5 5060 example.com"},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
description: "Invalid SRV record target",
|
|
endpoint: Endpoint{
|
|
DNSName: "_service._tcp.example.com",
|
|
RecordType: RecordTypeSRV,
|
|
Targets: Targets{"10 5 example.com"},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
description: "Non-MX/SRV record type",
|
|
endpoint: Endpoint{
|
|
DNSName: "example.com",
|
|
RecordType: RecordTypeA,
|
|
Targets: Targets{"192.168.1.1"},
|
|
},
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
actual := tt.endpoint.CheckEndpoint()
|
|
assert.Equal(t, tt.expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEndpoint_UniqueOrderedTargets(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
targets []string
|
|
expected Targets
|
|
want bool
|
|
}{
|
|
{
|
|
name: "no duplicates",
|
|
targets: []string{"b.example.com", "a.example.com"},
|
|
expected: Targets{"a.example.com", "b.example.com"},
|
|
},
|
|
{
|
|
name: "with duplicates",
|
|
targets: []string{"a.example.com", "b.example.com", "a.example.com"},
|
|
expected: Targets{"a.example.com", "b.example.com"},
|
|
},
|
|
{
|
|
name: "already sorted",
|
|
targets: []string{"a.example.com", "b.example.com"},
|
|
expected: Targets{"a.example.com", "b.example.com"},
|
|
},
|
|
{
|
|
name: "all duplicates",
|
|
targets: []string{"a.example.com", "a.example.com", "a.example.com"},
|
|
expected: Targets{"a.example.com"},
|
|
},
|
|
{
|
|
name: "empty",
|
|
targets: []string{},
|
|
expected: Targets{},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ep := &Endpoint{Targets: tt.targets}
|
|
ep.UniqueOrderedTargets()
|
|
assert.Equal(t, tt.expected, ep.Targets)
|
|
})
|
|
}
|
|
}
|