...

Source file src/net/dnsconfig_unix_test.go

Documentation: net

		 1  // Copyright 2013 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
		 6  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
		 7  
		 8  package net
		 9  
		10  import (
		11  	"errors"
		12  	"io/fs"
		13  	"os"
		14  	"reflect"
		15  	"strings"
		16  	"testing"
		17  	"time"
		18  )
		19  
		20  var dnsReadConfigTests = []struct {
		21  	name string
		22  	want *dnsConfig
		23  }{
		24  	{
		25  		name: "testdata/resolv.conf",
		26  		want: &dnsConfig{
		27  			servers:		[]string{"8.8.8.8:53", "[2001:4860:4860::8888]:53", "[fe80::1%lo0]:53"},
		28  			search:		 []string{"localdomain."},
		29  			ndots:			5,
		30  			timeout:		10 * time.Second,
		31  			attempts:	 3,
		32  			rotate:		 true,
		33  			unknownOpt: true, // the "options attempts 3" line
		34  		},
		35  	},
		36  	{
		37  		name: "testdata/domain-resolv.conf",
		38  		want: &dnsConfig{
		39  			servers:	[]string{"8.8.8.8:53"},
		40  			search:	 []string{"localdomain."},
		41  			ndots:		1,
		42  			timeout:	5 * time.Second,
		43  			attempts: 2,
		44  		},
		45  	},
		46  	{
		47  		name: "testdata/search-resolv.conf",
		48  		want: &dnsConfig{
		49  			servers:	[]string{"8.8.8.8:53"},
		50  			search:	 []string{"test.", "invalid."},
		51  			ndots:		1,
		52  			timeout:	5 * time.Second,
		53  			attempts: 2,
		54  		},
		55  	},
		56  	{
		57  		name: "testdata/empty-resolv.conf",
		58  		want: &dnsConfig{
		59  			servers:	defaultNS,
		60  			ndots:		1,
		61  			timeout:	5 * time.Second,
		62  			attempts: 2,
		63  			search:	 []string{"domain.local."},
		64  		},
		65  	},
		66  	{
		67  		name: "testdata/invalid-ndots-resolv.conf",
		68  		want: &dnsConfig{
		69  			servers:	defaultNS,
		70  			ndots:		0,
		71  			timeout:	5 * time.Second,
		72  			attempts: 2,
		73  			search:	 []string{"domain.local."},
		74  		},
		75  	},
		76  	{
		77  		name: "testdata/large-ndots-resolv.conf",
		78  		want: &dnsConfig{
		79  			servers:	defaultNS,
		80  			ndots:		15,
		81  			timeout:	5 * time.Second,
		82  			attempts: 2,
		83  			search:	 []string{"domain.local."},
		84  		},
		85  	},
		86  	{
		87  		name: "testdata/negative-ndots-resolv.conf",
		88  		want: &dnsConfig{
		89  			servers:	defaultNS,
		90  			ndots:		0,
		91  			timeout:	5 * time.Second,
		92  			attempts: 2,
		93  			search:	 []string{"domain.local."},
		94  		},
		95  	},
		96  	{
		97  		name: "testdata/openbsd-resolv.conf",
		98  		want: &dnsConfig{
		99  			ndots:		1,
	 100  			timeout:	5 * time.Second,
	 101  			attempts: 2,
	 102  			lookup:	 []string{"file", "bind"},
	 103  			servers:	[]string{"169.254.169.254:53", "10.240.0.1:53"},
	 104  			search:	 []string{"c.symbolic-datum-552.internal."},
	 105  		},
	 106  	},
	 107  	{
	 108  		name: "testdata/single-request-resolv.conf",
	 109  		want: &dnsConfig{
	 110  			servers:			 defaultNS,
	 111  			ndots:				 1,
	 112  			singleRequest: true,
	 113  			timeout:			 5 * time.Second,
	 114  			attempts:			2,
	 115  			search:				[]string{"domain.local."},
	 116  		},
	 117  	},
	 118  	{
	 119  		name: "testdata/single-request-reopen-resolv.conf",
	 120  		want: &dnsConfig{
	 121  			servers:			 defaultNS,
	 122  			ndots:				 1,
	 123  			singleRequest: true,
	 124  			timeout:			 5 * time.Second,
	 125  			attempts:			2,
	 126  			search:				[]string{"domain.local."},
	 127  		},
	 128  	},
	 129  	{
	 130  		name: "testdata/linux-use-vc-resolv.conf",
	 131  		want: &dnsConfig{
	 132  			servers:	defaultNS,
	 133  			ndots:		1,
	 134  			useTCP:	 true,
	 135  			timeout:	5 * time.Second,
	 136  			attempts: 2,
	 137  			search:	 []string{"domain.local."},
	 138  		},
	 139  	},
	 140  	{
	 141  		name: "testdata/freebsd-usevc-resolv.conf",
	 142  		want: &dnsConfig{
	 143  			servers:	defaultNS,
	 144  			ndots:		1,
	 145  			useTCP:	 true,
	 146  			timeout:	5 * time.Second,
	 147  			attempts: 2,
	 148  			search:	 []string{"domain.local."},
	 149  		},
	 150  	},
	 151  	{
	 152  		name: "testdata/openbsd-tcp-resolv.conf",
	 153  		want: &dnsConfig{
	 154  			servers:	defaultNS,
	 155  			ndots:		1,
	 156  			useTCP:	 true,
	 157  			timeout:	5 * time.Second,
	 158  			attempts: 2,
	 159  			search:	 []string{"domain.local."},
	 160  		},
	 161  	},
	 162  }
	 163  
	 164  func TestDNSReadConfig(t *testing.T) {
	 165  	origGetHostname := getHostname
	 166  	defer func() { getHostname = origGetHostname }()
	 167  	getHostname = func() (string, error) { return "host.domain.local", nil }
	 168  
	 169  	for _, tt := range dnsReadConfigTests {
	 170  		conf := dnsReadConfig(tt.name)
	 171  		if conf.err != nil {
	 172  			t.Fatal(conf.err)
	 173  		}
	 174  		conf.mtime = time.Time{}
	 175  		if !reflect.DeepEqual(conf, tt.want) {
	 176  			t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
	 177  		}
	 178  	}
	 179  }
	 180  
	 181  func TestDNSReadMissingFile(t *testing.T) {
	 182  	origGetHostname := getHostname
	 183  	defer func() { getHostname = origGetHostname }()
	 184  	getHostname = func() (string, error) { return "host.domain.local", nil }
	 185  
	 186  	conf := dnsReadConfig("a-nonexistent-file")
	 187  	if !os.IsNotExist(conf.err) {
	 188  		t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, fs.ErrNotExist)
	 189  	}
	 190  	conf.err = nil
	 191  	want := &dnsConfig{
	 192  		servers:	defaultNS,
	 193  		ndots:		1,
	 194  		timeout:	5 * time.Second,
	 195  		attempts: 2,
	 196  		search:	 []string{"domain.local."},
	 197  	}
	 198  	if !reflect.DeepEqual(conf, want) {
	 199  		t.Errorf("missing resolv.conf:\ngot: %+v\nwant: %+v", conf, want)
	 200  	}
	 201  }
	 202  
	 203  var dnsDefaultSearchTests = []struct {
	 204  	name string
	 205  	err	error
	 206  	want []string
	 207  }{
	 208  	{
	 209  		name: "host.long.domain.local",
	 210  		want: []string{"long.domain.local."},
	 211  	},
	 212  	{
	 213  		name: "host.local",
	 214  		want: []string{"local."},
	 215  	},
	 216  	{
	 217  		name: "host",
	 218  		want: nil,
	 219  	},
	 220  	{
	 221  		name: "host.domain.local",
	 222  		err:	errors.New("errored"),
	 223  		want: nil,
	 224  	},
	 225  	{
	 226  		// ensures we don't return []string{""}
	 227  		// which causes duplicate lookups
	 228  		name: "foo.",
	 229  		want: nil,
	 230  	},
	 231  }
	 232  
	 233  func TestDNSDefaultSearch(t *testing.T) {
	 234  	origGetHostname := getHostname
	 235  	defer func() { getHostname = origGetHostname }()
	 236  
	 237  	for _, tt := range dnsDefaultSearchTests {
	 238  		getHostname = func() (string, error) { return tt.name, tt.err }
	 239  		got := dnsDefaultSearch()
	 240  		if !reflect.DeepEqual(got, tt.want) {
	 241  			t.Errorf("dnsDefaultSearch with hostname %q and error %+v = %q, wanted %q", tt.name, tt.err, got, tt.want)
	 242  		}
	 243  	}
	 244  }
	 245  
	 246  func TestDNSNameLength(t *testing.T) {
	 247  	origGetHostname := getHostname
	 248  	defer func() { getHostname = origGetHostname }()
	 249  	getHostname = func() (string, error) { return "host.domain.local", nil }
	 250  
	 251  	var char63 = ""
	 252  	for i := 0; i < 63; i++ {
	 253  		char63 += "a"
	 254  	}
	 255  	longDomain := strings.Repeat(char63+".", 5) + "example"
	 256  
	 257  	for _, tt := range dnsReadConfigTests {
	 258  		conf := dnsReadConfig(tt.name)
	 259  		if conf.err != nil {
	 260  			t.Fatal(conf.err)
	 261  		}
	 262  
	 263  		var shortestSuffix int
	 264  		for _, suffix := range tt.want.search {
	 265  			if shortestSuffix == 0 || len(suffix) < shortestSuffix {
	 266  				shortestSuffix = len(suffix)
	 267  			}
	 268  		}
	 269  
	 270  		// Test a name that will be maximally long when prefixing the shortest
	 271  		// suffix (accounting for the intervening dot).
	 272  		longName := longDomain[len(longDomain)-254+1+shortestSuffix:]
	 273  		if longName[0] == '.' || longName[1] == '.' {
	 274  			longName = "aa." + longName[3:]
	 275  		}
	 276  		for _, fqdn := range conf.nameList(longName) {
	 277  			if len(fqdn) > 254 {
	 278  				t.Errorf("got %d; want less than or equal to 254", len(fqdn))
	 279  			}
	 280  		}
	 281  
	 282  		// Now test a name that's too long for suffixing.
	 283  		unsuffixable := "a." + longName[1:]
	 284  		unsuffixableResults := conf.nameList(unsuffixable)
	 285  		if len(unsuffixableResults) != 1 {
	 286  			t.Errorf("suffixed names %v; want []", unsuffixableResults[1:])
	 287  		}
	 288  
	 289  		// Now test a name that's too long for DNS.
	 290  		tooLong := "a." + longDomain
	 291  		tooLongResults := conf.nameList(tooLong)
	 292  		if tooLongResults != nil {
	 293  			t.Errorf("suffixed names %v; want nil", tooLongResults)
	 294  		}
	 295  	}
	 296  }
	 297  

View as plain text