github.com/philhug/dnscontrol@v0.2.4-0.20180625181521-921fa9849001/pkg/normalize/validate_test.go (about) 1 package normalize 2 3 import ( 4 "testing" 5 6 "fmt" 7 8 "github.com/StackExchange/dnscontrol/models" 9 ) 10 11 func TestCheckLabel(t *testing.T) { 12 var tests = []struct { 13 label string 14 rType string 15 isError bool 16 hasSkipMeta bool 17 }{ 18 {"@", "A", false, false}, 19 {"foo.bar", "A", false, false}, 20 {"_foo", "A", true, false}, 21 {"_foo", "SRV", false, false}, 22 {"_foo", "TLSA", false, false}, 23 {"_foo", "TXT", false, false}, 24 {"test.foo.tld", "A", true, false}, 25 {"test.foo.tld", "A", false, true}, 26 } 27 28 for _, test := range tests { 29 t.Run(fmt.Sprintf("%s %s", test.label, test.rType), func(t *testing.T) { 30 meta := map[string]string{} 31 if test.hasSkipMeta { 32 meta["skip_fqdn_check"] = "true" 33 } 34 err := checkLabel(test.label, test.rType, "foo.tld", meta) 35 if err != nil && !test.isError { 36 t.Errorf(" Expected no error but got %s", err) 37 } 38 if err == nil && test.isError { 39 t.Errorf(" Expected error but got none") 40 } 41 }) 42 43 } 44 } 45 46 func checkError(t *testing.T, err error, shouldError bool, experiment string) { 47 if err != nil && !shouldError { 48 t.Errorf("%v: Error (%v)\n", experiment, err) 49 } 50 if err == nil && shouldError { 51 t.Errorf("%v: Expected error but got none \n", experiment) 52 } 53 } 54 55 func Test_assert_valid_ipv4(t *testing.T) { 56 var tests = []struct { 57 experiment string 58 isError bool 59 }{ 60 {"1.2.3.4", false}, 61 {"1.2.3.4/10", true}, 62 {"1.2.3", true}, 63 {"foo", true}, 64 } 65 66 for _, test := range tests { 67 err := checkIPv4(test.experiment) 68 checkError(t, err, test.isError, test.experiment) 69 } 70 } 71 72 func Test_assert_valid_target(t *testing.T) { 73 var tests = []struct { 74 experiment string 75 isError bool 76 }{ 77 {"@", false}, 78 {"foo", false}, 79 {"foo.bar.", false}, 80 {"foo.", false}, 81 {"foo.bar", true}, 82 {"foo&bar", true}, 83 {"foo bar", true}, 84 {"elb21.freshdesk.com/", true}, 85 {"elb21.freshdesk.com/.", true}, 86 } 87 88 for _, test := range tests { 89 err := checkTarget(test.experiment) 90 checkError(t, err, test.isError, test.experiment) 91 } 92 } 93 94 func Test_transform_cname(t *testing.T) { 95 var tests = []struct { 96 experiment string 97 expected string 98 }{ 99 {"@", "old.com.new.com."}, 100 {"foo", "foo.old.com.new.com."}, 101 {"foo.bar", "foo.bar.old.com.new.com."}, 102 {"foo.bar.", "foo.bar.new.com."}, 103 {"chat.stackexchange.com.", "chat.stackexchange.com.new.com."}, 104 } 105 106 for _, test := range tests { 107 actual := transformCNAME(test.experiment, "old.com", "new.com") 108 if test.expected != actual { 109 t.Errorf("%v: expected (%v) got (%v)\n", test.experiment, test.expected, actual) 110 } 111 } 112 } 113 114 func TestNSAtRoot(t *testing.T) { 115 // do not allow ns records for @ 116 rec := &models.RecordConfig{Type: "NS"} 117 rec.SetLabel("test", "foo.com") 118 rec.SetTarget("ns1.name.com.") 119 errs := checkTargets(rec, "foo.com") 120 if len(errs) > 0 { 121 t.Error("Expect no error with ns record on subdomain") 122 } 123 rec.SetLabel("@", "foo.com") 124 errs = checkTargets(rec, "foo.com") 125 if len(errs) != 1 { 126 t.Error("Expect error with ns record on @") 127 } 128 } 129 130 func TestTransforms(t *testing.T) { 131 var tests = []struct { 132 givenIP string 133 expectedRecords []string 134 }{ 135 {"0.0.5.5", []string{"2.0.5.5"}}, 136 {"3.0.5.5", []string{"5.5.5.5"}}, 137 {"7.0.5.5", []string{"9.9.9.9", "10.10.10.10"}}, 138 } 139 const transform = "0.0.0.0~1.0.0.0~2.0.0.0~; 3.0.0.0~4.0.0.0~~5.5.5.5; 7.0.0.0~8.0.0.0~~9.9.9.9,10.10.10.10" 140 for i, test := range tests { 141 dc := &models.DomainConfig{ 142 Records: []*models.RecordConfig{ 143 makeRC("f", "example.tld", test.givenIP, models.RecordConfig{Type: "A", Metadata: map[string]string{"transform": transform}}), 144 }, 145 } 146 err := applyRecordTransforms(dc) 147 if err != nil { 148 t.Errorf("error on test %d: %s", i, err) 149 continue 150 } 151 if len(dc.Records) != len(test.expectedRecords) { 152 t.Errorf("test %d: expect %d records but found %d", i, len(test.expectedRecords), len(dc.Records)) 153 continue 154 } 155 for r, rec := range dc.Records { 156 if rec.GetTargetField() != test.expectedRecords[r] { 157 t.Errorf("test %d at index %d: records don't match. Expect %s but found %s.", i, r, test.expectedRecords[r], rec.GetTargetField()) 158 continue 159 } 160 } 161 } 162 } 163 164 func TestCNAMEMutex(t *testing.T) { 165 var recA = &models.RecordConfig{Type: "CNAME"} 166 recA.SetLabel("foo", "foo.example.com") 167 recA.SetTarget("example.com.") 168 tests := []struct { 169 rType string 170 name string 171 fail bool 172 }{ 173 {"A", "foo", true}, 174 {"A", "foo2", false}, 175 {"CNAME", "foo", true}, 176 {"CNAME", "foo2", false}, 177 } 178 for _, tst := range tests { 179 t.Run(fmt.Sprintf("%s %s", tst.rType, tst.name), func(t *testing.T) { 180 var recB = &models.RecordConfig{Type: tst.rType} 181 recB.SetLabel(tst.name, "example.com") 182 recB.SetTarget("example2.com.") 183 dc := &models.DomainConfig{ 184 Name: "example.com", 185 Records: []*models.RecordConfig{recA, recB}, 186 } 187 errs := checkCNAMEs(dc) 188 if errs != nil && !tst.fail { 189 t.Error("Got error but expected none") 190 } 191 if errs == nil && tst.fail { 192 t.Error("Expected error but got none") 193 } 194 }) 195 } 196 } 197 198 func TestCAAValidation(t *testing.T) { 199 config := &models.DNSConfig{ 200 Domains: []*models.DomainConfig{ 201 { 202 Name: "example.com", 203 RegistrarName: "BIND", 204 Records: []*models.RecordConfig{ 205 makeRC("@", "example.com", "example.com", models.RecordConfig{Type: "CAA", CaaTag: "invalid"}), 206 }, 207 }, 208 }, 209 } 210 errs := NormalizeAndValidateConfig(config) 211 if len(errs) != 1 { 212 t.Error("Expect error on invalid CAA but got none") 213 } 214 } 215 216 func TestTLSAValidation(t *testing.T) { 217 config := &models.DNSConfig{ 218 Domains: []*models.DomainConfig{ 219 { 220 Name: "_443._tcp.example.com", 221 RegistrarName: "BIND", 222 Records: []*models.RecordConfig{ 223 makeRC("_443._tcp", "_443._tcp.example.com", "abcdef0", models.RecordConfig{ 224 Type: "TLSA", TlsaUsage: 4, TlsaSelector: 1, TlsaMatchingType: 1}), 225 }, 226 }, 227 }, 228 } 229 errs := NormalizeAndValidateConfig(config) 230 if len(errs) != 1 { 231 t.Error("Expect error on invalid TLSA but got none") 232 } 233 }