github.com/letsencrypt/boulder@v0.20251208.0/observer/probers/dns/dns_conf_test.go (about)

     1  package probers
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/letsencrypt/boulder/observer/probers"
     8  	"github.com/letsencrypt/boulder/test"
     9  	"gopkg.in/yaml.v3"
    10  )
    11  
    12  func TestDNSConf_validateServer(t *testing.T) {
    13  	type fields struct {
    14  		Server string
    15  	}
    16  	tests := []struct {
    17  		name    string
    18  		fields  fields
    19  		wantErr bool
    20  	}{
    21  		// ipv4 cases
    22  		{"ipv4 with port", fields{"1.1.1.1:53"}, false},
    23  		{"ipv4 without port", fields{"1.1.1.1"}, true},
    24  		{"ipv4 port num missing", fields{"1.1.1.1:"}, true},
    25  		{"ipv4 string for port", fields{"1.1.1.1:foo"}, true},
    26  		{"ipv4 port out of range high", fields{"1.1.1.1:65536"}, true},
    27  		{"ipv4 port out of range low", fields{"1.1.1.1:0"}, true},
    28  
    29  		// ipv6 cases
    30  		{"ipv6 with port", fields{"[2606:4700:4700::1111]:53"}, false},
    31  		{"ipv6 without port", fields{"[2606:4700:4700::1111]"}, true},
    32  		{"ipv6 port num missing", fields{"[2606:4700:4700::1111]:"}, true},
    33  		{"ipv6 string for port", fields{"[2606:4700:4700::1111]:foo"}, true},
    34  		{"ipv6 port out of range high", fields{"[2606:4700:4700::1111]:65536"}, true},
    35  		{"ipv6 port out of range low", fields{"[2606:4700:4700::1111]:0"}, true},
    36  
    37  		// hostname cases
    38  		{"hostname with port", fields{"foo:53"}, false},
    39  		{"hostname without port", fields{"foo"}, true},
    40  		{"hostname port num missing", fields{"foo:"}, true},
    41  		{"hostname string for port", fields{"foo:bar"}, true},
    42  		{"hostname port out of range high", fields{"foo:65536"}, true},
    43  		{"hostname port out of range low", fields{"foo:0"}, true},
    44  
    45  		// fqdn cases
    46  		{"fqdn with port", fields{"bar.foo.baz:53"}, false},
    47  		{"fqdn without port", fields{"bar.foo.baz"}, true},
    48  		{"fqdn port num missing", fields{"bar.foo.baz:"}, true},
    49  		{"fqdn string for port", fields{"bar.foo.baz:bar"}, true},
    50  		{"fqdn port out of range high", fields{"bar.foo.baz:65536"}, true},
    51  		{"fqdn port out of range low", fields{"bar.foo.baz:0"}, true},
    52  	}
    53  	for _, tt := range tests {
    54  		t.Run(tt.name, func(t *testing.T) {
    55  			c := DNSConf{
    56  				Server: tt.fields.Server,
    57  			}
    58  			err := c.validateServer()
    59  			if tt.wantErr {
    60  				test.AssertError(t, err, "DNSConf.validateServer() should have errored")
    61  			} else {
    62  				test.AssertNotError(t, err, "DNSConf.validateServer() shouldn't have errored")
    63  			}
    64  		})
    65  	}
    66  }
    67  
    68  func TestDNSConf_validateQType(t *testing.T) {
    69  	type fields struct {
    70  		QType string
    71  	}
    72  	tests := []struct {
    73  		name    string
    74  		fields  fields
    75  		wantErr bool
    76  	}{
    77  		// valid
    78  		{"A", fields{"A"}, false},
    79  		{"AAAA", fields{"AAAA"}, false},
    80  		{"TXT", fields{"TXT"}, false},
    81  		// invalid
    82  		{"AAA", fields{"AAA"}, true},
    83  		{"TXTT", fields{"TXTT"}, true},
    84  		{"D", fields{"D"}, true},
    85  	}
    86  	for _, tt := range tests {
    87  		t.Run(tt.name, func(t *testing.T) {
    88  			c := DNSConf{
    89  				QType: tt.fields.QType,
    90  			}
    91  			err := c.validateQType()
    92  			if tt.wantErr {
    93  				test.AssertError(t, err, "DNSConf.validateQType() should have errored")
    94  			} else {
    95  				test.AssertNotError(t, err, "DNSConf.validateQType() shouldn't have errored")
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  func TestDNSConf_validateProto(t *testing.T) {
   102  	type fields struct {
   103  		Proto string
   104  	}
   105  	tests := []struct {
   106  		name    string
   107  		fields  fields
   108  		wantErr bool
   109  	}{
   110  		// valid
   111  		{"tcp", fields{"tcp"}, false},
   112  		{"udp", fields{"udp"}, false},
   113  		// invalid
   114  		{"foo", fields{"foo"}, true},
   115  	}
   116  	for _, tt := range tests {
   117  		t.Run(tt.name, func(t *testing.T) {
   118  			c := DNSConf{
   119  				Proto: tt.fields.Proto,
   120  			}
   121  			err := c.validateProto()
   122  			if tt.wantErr {
   123  				test.AssertError(t, err, "DNSConf.validateProto() should have errored")
   124  			} else {
   125  				test.AssertNotError(t, err, "DNSConf.validateProto() shouldn't have errored")
   126  			}
   127  		})
   128  	}
   129  }
   130  
   131  func TestDNSConf_MakeProber(t *testing.T) {
   132  	type fields struct {
   133  		Proto   string
   134  		Server  string
   135  		Recurse bool
   136  		QName   string
   137  		QType   string
   138  	}
   139  	tests := []struct {
   140  		name    string
   141  		fields  fields
   142  		wantErr bool
   143  	}{
   144  		// valid
   145  		{"valid", fields{"udp", "1.1.1.1:53", true, "google.com", "A"}, false},
   146  		// invalid
   147  		{"bad proto", fields{"can with string", "1.1.1.1:53", true, "google.com", "A"}, true},
   148  		{"bad server", fields{"udp", "1.1.1.1:9000000", true, "google.com", "A"}, true},
   149  		{"bad qtype", fields{"udp", "1.1.1.1:9000000", true, "google.com", "BAZ"}, true},
   150  	}
   151  	for _, tt := range tests {
   152  		t.Run(tt.name, func(t *testing.T) {
   153  			c := DNSConf{
   154  				Proto:   tt.fields.Proto,
   155  				Server:  tt.fields.Server,
   156  				Recurse: tt.fields.Recurse,
   157  				QName:   tt.fields.QName,
   158  				QType:   tt.fields.QType,
   159  			}
   160  			_, err := c.MakeProber(nil)
   161  			if tt.wantErr {
   162  				test.AssertError(t, err, "DNSConf.MakeProber() should have errored")
   163  			} else {
   164  				test.AssertNotError(t, err, "DNSConf.MakeProber() shouldn't have errored")
   165  			}
   166  		})
   167  	}
   168  }
   169  
   170  func TestDNSConf_UnmarshalSettings(t *testing.T) {
   171  	type fields struct {
   172  		protocol   any
   173  		server     any
   174  		recurse    any
   175  		query_name any
   176  		query_type any
   177  	}
   178  	tests := []struct {
   179  		name    string
   180  		fields  fields
   181  		want    probers.Configurer
   182  		wantErr bool
   183  	}{
   184  		{"valid", fields{"udp", "1.1.1.1:53", true, "google.com", "A"}, DNSConf{"udp", "1.1.1.1:53", true, "google.com", "A"}, false},
   185  		{"invalid", fields{42, 42, 42, 42, 42}, nil, true},
   186  	}
   187  	for _, tt := range tests {
   188  		t.Run(tt.name, func(t *testing.T) {
   189  			settings := probers.Settings{
   190  				"protocol":   tt.fields.protocol,
   191  				"server":     tt.fields.server,
   192  				"recurse":    tt.fields.recurse,
   193  				"query_name": tt.fields.query_name,
   194  				"query_type": tt.fields.query_type,
   195  			}
   196  			settingsBytes, _ := yaml.Marshal(settings)
   197  			c := DNSConf{}
   198  			got, err := c.UnmarshalSettings(settingsBytes)
   199  			if (err != nil) != tt.wantErr {
   200  				t.Errorf("DNSConf.UnmarshalSettings() error = %v, wantErr %v", err, tt.wantErr)
   201  				return
   202  			}
   203  			if !reflect.DeepEqual(got, tt.want) {
   204  				t.Errorf("DNSConf.UnmarshalSettings() = %v, want %v", got, tt.want)
   205  			}
   206  		})
   207  	}
   208  }