2015-05-18 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / libgo / go / net / dnsclient_unix_test.go
blob1167c26b39dacbfb98863ad4bd5af2633e6dda49
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.
5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
7 package net
9 import (
10 "io"
11 "io/ioutil"
12 "os"
13 "path"
14 "reflect"
15 "testing"
16 "time"
19 var dnsTransportFallbackTests = []struct {
20 server string
21 name string
22 qtype uint16
23 timeout int
24 rcode int
26 // Querying "com." with qtype=255 usually makes an answer
27 // which requires more than 512 bytes.
28 {"8.8.8.8:53", "com.", dnsTypeALL, 2, dnsRcodeSuccess},
29 {"8.8.4.4:53", "com.", dnsTypeALL, 4, dnsRcodeSuccess},
32 func TestDNSTransportFallback(t *testing.T) {
33 if testing.Short() || !*testExternal {
34 t.Skip("skipping test to avoid external network")
37 for _, tt := range dnsTransportFallbackTests {
38 timeout := time.Duration(tt.timeout) * time.Second
39 msg, err := exchange(tt.server, tt.name, tt.qtype, timeout)
40 if err != nil {
41 t.Error(err)
42 continue
44 switch msg.rcode {
45 case tt.rcode, dnsRcodeServerFailure:
46 default:
47 t.Errorf("got %v from %v; want %v", msg.rcode, tt.server, tt.rcode)
48 continue
53 // See RFC 6761 for further information about the reserved, pseudo
54 // domain names.
55 var specialDomainNameTests = []struct {
56 name string
57 qtype uint16
58 rcode int
60 // Name resoltion APIs and libraries should not recongnize the
61 // followings as special.
62 {"1.0.168.192.in-addr.arpa.", dnsTypePTR, dnsRcodeNameError},
63 {"test.", dnsTypeALL, dnsRcodeNameError},
64 {"example.com.", dnsTypeALL, dnsRcodeSuccess},
66 // Name resoltion APIs and libraries should recongnize the
67 // followings as special and should not send any queries.
68 // Though, we test those names here for verifying nagative
69 // answers at DNS query-response interaction level.
70 {"localhost.", dnsTypeALL, dnsRcodeNameError},
71 {"invalid.", dnsTypeALL, dnsRcodeNameError},
74 func TestSpecialDomainName(t *testing.T) {
75 if testing.Short() || !*testExternal {
76 t.Skip("skipping test to avoid external network")
79 server := "8.8.8.8:53"
80 for _, tt := range specialDomainNameTests {
81 msg, err := exchange(server, tt.name, tt.qtype, 0)
82 if err != nil {
83 t.Error(err)
84 continue
86 switch msg.rcode {
87 case tt.rcode, dnsRcodeServerFailure:
88 default:
89 t.Errorf("got %v from %v; want %v", msg.rcode, server, tt.rcode)
90 continue
95 type resolvConfTest struct {
96 *testing.T
97 dir string
98 path string
99 started bool
100 quitc chan chan struct{}
103 func newResolvConfTest(t *testing.T) *resolvConfTest {
104 dir, err := ioutil.TempDir("", "resolvConfTest")
105 if err != nil {
106 t.Fatalf("could not create temp dir: %v", err)
109 // Disable the default loadConfig
110 onceLoadConfig.Do(func() {})
112 r := &resolvConfTest{
113 T: t,
114 dir: dir,
115 path: path.Join(dir, "resolv.conf"),
116 quitc: make(chan chan struct{}),
119 return r
122 func (r *resolvConfTest) Start() {
123 loadConfig(r.path, 100*time.Millisecond, r.quitc)
124 r.started = true
127 func (r *resolvConfTest) SetConf(s string) {
128 // Make sure the file mtime will be different once we're done here,
129 // even on systems with coarse (1s) mtime resolution.
130 time.Sleep(time.Second)
132 f, err := os.OpenFile(r.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
133 if err != nil {
134 r.Fatalf("failed to create temp file %s: %v", r.path, err)
136 if _, err := io.WriteString(f, s); err != nil {
137 f.Close()
138 r.Fatalf("failed to write temp file: %v", err)
140 f.Close()
142 if r.started {
143 cfg.ch <- struct{}{} // fill buffer
144 cfg.ch <- struct{}{} // wait for reload to begin
145 cfg.ch <- struct{}{} // wait for reload to complete
149 func (r *resolvConfTest) WantServers(want []string) {
150 cfg.mu.RLock()
151 defer cfg.mu.RUnlock()
152 if got := cfg.dnsConfig.servers; !reflect.DeepEqual(got, want) {
153 r.Fatalf("Unexpected dns server loaded, got %v want %v", got, want)
157 func (r *resolvConfTest) Close() {
158 resp := make(chan struct{})
159 r.quitc <- resp
160 <-resp
161 if err := os.RemoveAll(r.dir); err != nil {
162 r.Logf("failed to remove temp dir %s: %v", r.dir, err)
166 func TestReloadResolvConfFail(t *testing.T) {
167 if testing.Short() || !*testExternal {
168 t.Skip("skipping test to avoid external network")
171 r := newResolvConfTest(t)
172 defer r.Close()
174 // resolv.conf.tmp does not exist yet
175 r.Start()
176 if _, err := goLookupIP("golang.org"); err == nil {
177 t.Fatal("goLookupIP(missing) succeeded")
180 r.SetConf("nameserver 8.8.8.8")
181 if _, err := goLookupIP("golang.org"); err != nil {
182 t.Fatalf("goLookupIP(missing; good) failed: %v", err)
185 // Using a bad resolv.conf while we had a good
186 // one before should not update the config
187 r.SetConf("")
188 if _, err := goLookupIP("golang.org"); err != nil {
189 t.Fatalf("goLookupIP(missing; good; bad) failed: %v", err)
193 func TestReloadResolvConfChange(t *testing.T) {
194 if testing.Short() || !*testExternal {
195 t.Skip("skipping test to avoid external network")
198 r := newResolvConfTest(t)
199 defer r.Close()
201 r.SetConf("nameserver 8.8.8.8")
202 r.Start()
204 if _, err := goLookupIP("golang.org"); err != nil {
205 t.Fatalf("goLookupIP(good) failed: %v", err)
207 r.WantServers([]string{"8.8.8.8"})
209 // Using a bad resolv.conf when we had a good one
210 // before should not update the config
211 r.SetConf("")
212 if _, err := goLookupIP("golang.org"); err != nil {
213 t.Fatalf("goLookupIP(good; bad) failed: %v", err)
216 // A new good config should get picked up
217 r.SetConf("nameserver 8.8.4.4")
218 r.WantServers([]string{"8.8.4.4"})
221 func BenchmarkGoLookupIP(b *testing.B) {
222 for i := 0; i < b.N; i++ {
223 goLookupIP("www.example.com")
227 func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
228 for i := 0; i < b.N; i++ {
229 goLookupIP("some.nonexistent")
233 func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
234 onceLoadConfig.Do(loadDefaultConfig)
235 if cfg.dnserr != nil || cfg.dnsConfig == nil {
236 b.Fatalf("loadConfig failed: %v", cfg.dnserr)
238 // This looks ugly but it's safe as long as benchmarks are run
239 // sequentially in package testing.
240 orig := cfg.dnsConfig
241 cfg.dnsConfig.servers = append([]string{"203.0.113.254"}, cfg.dnsConfig.servers...) // use TEST-NET-3 block, see RFC 5737
242 for i := 0; i < b.N; i++ {
243 goLookupIP("www.example.com")
245 cfg.dnsConfig = orig