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  }