1
0
mirror of https://github.com/golang/go synced 2024-11-14 15:00:27 -07:00
go/src/net/dnsclient_unix_test.go

259 lines
6.3 KiB
Go
Raw Normal View History

// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
import (
"io"
"io/ioutil"
"os"
"path"
"reflect"
"testing"
"time"
)
var dnsTransportFallbackTests = []struct {
server string
name string
qtype uint16
timeout int
rcode int
}{
// Querying "com." with qtype=255 usually makes an answer
// which requires more than 512 bytes.
{"8.8.8.8:53", "com.", dnsTypeALL, 2, dnsRcodeSuccess},
{"8.8.4.4:53", "com.", dnsTypeALL, 4, dnsRcodeSuccess},
}
func TestDNSTransportFallback(t *testing.T) {
if testing.Short() || !*testExternal {
t.Skip("avoid external network")
}
for _, tt := range dnsTransportFallbackTests {
timeout := time.Duration(tt.timeout) * time.Second
msg, err := exchange(tt.server, tt.name, tt.qtype, timeout)
if err != nil {
t.Error(err)
continue
}
switch msg.rcode {
case tt.rcode, dnsRcodeServerFailure:
default:
t.Errorf("got %v from %v; want %v", msg.rcode, tt.server, tt.rcode)
continue
}
}
}
// See RFC 6761 for further information about the reserved, pseudo
// domain names.
var specialDomainNameTests = []struct {
name string
qtype uint16
rcode int
}{
// Name resolution APIs and libraries should not recognize the
// followings as special.
{"1.0.168.192.in-addr.arpa.", dnsTypePTR, dnsRcodeNameError},
{"test.", dnsTypeALL, dnsRcodeNameError},
{"example.com.", dnsTypeALL, dnsRcodeSuccess},
// Name resolution APIs and libraries should recognize the
// followings as special and should not send any queries.
// Though, we test those names here for verifying nagative
// answers at DNS query-response interaction level.
{"localhost.", dnsTypeALL, dnsRcodeNameError},
{"invalid.", dnsTypeALL, dnsRcodeNameError},
}
func TestSpecialDomainName(t *testing.T) {
if testing.Short() || !*testExternal {
t.Skip("avoid external network")
}
server := "8.8.8.8:53"
for _, tt := range specialDomainNameTests {
msg, err := exchange(server, tt.name, tt.qtype, 0)
if err != nil {
t.Error(err)
continue
}
switch msg.rcode {
case tt.rcode, dnsRcodeServerFailure:
default:
t.Errorf("got %v from %v; want %v", msg.rcode, server, tt.rcode)
continue
}
}
}
type resolvConfTest struct {
*testing.T
dir string
path string
started bool
quitc chan chan struct{}
}
func newResolvConfTest(t *testing.T) *resolvConfTest {
dir, err := ioutil.TempDir("", "go-resolvconftest")
if err != nil {
t.Fatal(err)
}
// Disable the default loadConfig
onceLoadConfig.Do(func() {})
r := &resolvConfTest{
T: t,
dir: dir,
path: path.Join(dir, "resolv.conf"),
quitc: make(chan chan struct{}),
}
return r
}
func (r *resolvConfTest) Start() {
loadConfig(r.path, 100*time.Millisecond, r.quitc)
r.started = true
}
func (r *resolvConfTest) SetConf(s string) {
// Make sure the file mtime will be different once we're done here,
// even on systems with coarse (1s) mtime resolution.
time.Sleep(time.Second)
f, err := os.OpenFile(r.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
r.Fatalf("failed to create temp file %s: %v", r.path, err)
}
if _, err := io.WriteString(f, s); err != nil {
f.Close()
r.Fatalf("failed to write temp file: %v", err)
}
f.Close()
if r.started {
cfg.ch <- struct{}{} // fill buffer
cfg.ch <- struct{}{} // wait for reload to begin
cfg.ch <- struct{}{} // wait for reload to complete
}
}
func (r *resolvConfTest) WantServers(want []string) {
cfg.mu.RLock()
defer cfg.mu.RUnlock()
if got := cfg.dnsConfig.servers; !reflect.DeepEqual(got, want) {
r.Fatalf("unexpected dns server loaded, got %v want %v", got, want)
}
}
func (r *resolvConfTest) Close() {
resp := make(chan struct{})
r.quitc <- resp
<-resp
if err := os.RemoveAll(r.dir); err != nil {
r.Logf("failed to remove temp dir %s: %v", r.dir, err)
}
}
func TestReloadResolvConfFail(t *testing.T) {
if testing.Short() || !*testExternal {
t.Skip("avoid external network")
}
r := newResolvConfTest(t)
defer r.Close()
r.Start()
r.SetConf("nameserver 8.8.8.8")
if _, err := goLookupIP("golang.org"); err != nil {
t.Fatal(err)
}
// Using an empty resolv.conf should use localhost as servers
r.SetConf("")
if len(cfg.dnsConfig.servers) != len(defaultNS) {
t.Fatalf("goLookupIP(missing; good; bad) failed: servers=%v, want: %v", cfg.dnsConfig.servers, defaultNS)
}
for i := range cfg.dnsConfig.servers {
if cfg.dnsConfig.servers[i] != defaultNS[i] {
t.Fatalf("goLookupIP(missing; good; bad) failed: servers=%v, want: %v", cfg.dnsConfig.servers, defaultNS)
}
}
}
func TestReloadResolvConfChange(t *testing.T) {
if testing.Short() || !*testExternal {
t.Skip("avoid external network")
}
r := newResolvConfTest(t)
defer r.Close()
r.Start()
r.SetConf("nameserver 8.8.8.8")
if _, err := goLookupIP("golang.org"); err != nil {
t.Fatal(err)
}
r.WantServers([]string{"8.8.8.8"})
// Using an empty resolv.conf should use localhost as servers
r.SetConf("")
if len(cfg.dnsConfig.servers) != len(defaultNS) {
t.Fatalf("goLookupIP(missing; good; bad) failed: servers=%v, want: %v", cfg.dnsConfig.servers, defaultNS)
}
for i := range cfg.dnsConfig.servers {
if cfg.dnsConfig.servers[i] != defaultNS[i] {
t.Fatalf("goLookupIP(missing; good; bad) failed: servers=%v, want: %v", cfg.dnsConfig.servers, defaultNS)
}
}
// A new good config should get picked up
r.SetConf("nameserver 8.8.4.4")
r.WantServers([]string{"8.8.4.4"})
}
func BenchmarkGoLookupIP(b *testing.B) {
testHookUninstaller.Do(uninstallTestHooks)
net: add socket system call hooks for testing This change adds socket system call hooks to existing test cases for simulating a bit complicated network conditions to help making timeout and dual IP stack test cases work more properly in followup changes. Also test cases print debugging information in non-short mode like the following: Leaked goroutines: net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0) /go/src/net/timeout_test.go:170 +0x98 created by net.TestWriteTimeout /go/src/net/timeout_test.go:173 +0x745 net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00) /go/src/net/server_test.go:398 +0x667 created by net.TestTimeoutUDP /go/src/net/timeout_test.go:247 +0xc9 (snip) Leaked sockets: 3: {Cookie:615726511685632 Err:<nil> SocketErr:0} 5: {Cookie:7934075906097152 Err:<nil> SocketErr:0} Socket statistical information: {Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17} {Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636} {Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16} {Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116} {Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83} {Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52} Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda Reviewed-on: https://go-review.googlesource.com/6390 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-02-28 20:27:01 -07:00
for i := 0; i < b.N; i++ {
goLookupIP("www.example.com")
}
}
func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
testHookUninstaller.Do(uninstallTestHooks)
net: add socket system call hooks for testing This change adds socket system call hooks to existing test cases for simulating a bit complicated network conditions to help making timeout and dual IP stack test cases work more properly in followup changes. Also test cases print debugging information in non-short mode like the following: Leaked goroutines: net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0) /go/src/net/timeout_test.go:170 +0x98 created by net.TestWriteTimeout /go/src/net/timeout_test.go:173 +0x745 net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00) /go/src/net/server_test.go:398 +0x667 created by net.TestTimeoutUDP /go/src/net/timeout_test.go:247 +0xc9 (snip) Leaked sockets: 3: {Cookie:615726511685632 Err:<nil> SocketErr:0} 5: {Cookie:7934075906097152 Err:<nil> SocketErr:0} Socket statistical information: {Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17} {Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636} {Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16} {Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116} {Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83} {Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52} Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda Reviewed-on: https://go-review.googlesource.com/6390 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-02-28 20:27:01 -07:00
for i := 0; i < b.N; i++ {
goLookupIP("some.nonexistent")
}
}
func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
testHookUninstaller.Do(uninstallTestHooks)
net: add socket system call hooks for testing This change adds socket system call hooks to existing test cases for simulating a bit complicated network conditions to help making timeout and dual IP stack test cases work more properly in followup changes. Also test cases print debugging information in non-short mode like the following: Leaked goroutines: net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0) /go/src/net/timeout_test.go:170 +0x98 created by net.TestWriteTimeout /go/src/net/timeout_test.go:173 +0x745 net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00) /go/src/net/server_test.go:398 +0x667 created by net.TestTimeoutUDP /go/src/net/timeout_test.go:247 +0xc9 (snip) Leaked sockets: 3: {Cookie:615726511685632 Err:<nil> SocketErr:0} 5: {Cookie:7934075906097152 Err:<nil> SocketErr:0} Socket statistical information: {Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17} {Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636} {Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16} {Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116} {Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83} {Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52} Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda Reviewed-on: https://go-review.googlesource.com/6390 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-02-28 20:27:01 -07:00
onceLoadConfig.Do(loadDefaultConfig)
// This looks ugly but it's safe as long as benchmarks are run
// sequentially in package testing.
orig := cfg.dnsConfig
cfg.dnsConfig.servers = append([]string{"203.0.113.254"}, cfg.dnsConfig.servers...) // use TEST-NET-3 block, see RFC 5737
for i := 0; i < b.N; i++ {
goLookupIP("www.example.com")
}
cfg.dnsConfig = orig
}