github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/net/lookup_test.go (about) 1 // Copyright 2009 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 // TODO It would be nice to use a mock DNS server, to eliminate 6 // external dependencies. 7 8 package net 9 10 import ( 11 "flag" 12 "fmt" 13 "strings" 14 "testing" 15 "time" 16 ) 17 18 var testExternal = flag.Bool("external", true, "allow use of external networks during long test") 19 20 var lookupGoogleSRVTests = []struct { 21 service, proto, name string 22 cname, target string 23 }{ 24 { 25 "xmpp-server", "tcp", "google.com", 26 ".google.com", ".google.com", 27 }, 28 { 29 "", "", "_xmpp-server._tcp.google.com", // non-standard back door 30 ".google.com", ".google.com", 31 }, 32 } 33 34 func TestLookupGoogleSRV(t *testing.T) { 35 if testing.Short() || !*testExternal { 36 t.Skip("skipping test to avoid external network") 37 } 38 39 for _, tt := range lookupGoogleSRVTests { 40 cname, srvs, err := LookupSRV(tt.service, tt.proto, tt.name) 41 if err != nil { 42 t.Fatal(err) 43 } 44 if len(srvs) == 0 { 45 t.Error("got no record") 46 } 47 if !strings.Contains(cname, tt.cname) { 48 t.Errorf("got %q; want %q", cname, tt.cname) 49 } 50 for _, srv := range srvs { 51 if !strings.Contains(srv.Target, tt.target) { 52 t.Errorf("got %v; want a record containing %q", srv, tt.target) 53 } 54 } 55 } 56 } 57 58 func TestLookupGmailMX(t *testing.T) { 59 if testing.Short() || !*testExternal { 60 t.Skip("skipping test to avoid external network") 61 } 62 63 mxs, err := LookupMX("gmail.com") 64 if err != nil { 65 t.Fatal(err) 66 } 67 if len(mxs) == 0 { 68 t.Error("got no record") 69 } 70 for _, mx := range mxs { 71 if !strings.Contains(mx.Host, ".google.com") { 72 t.Errorf("got %v; want a record containing .google.com.", mx) 73 } 74 } 75 } 76 77 func TestLookupGmailNS(t *testing.T) { 78 if testing.Short() || !*testExternal { 79 t.Skip("skipping test to avoid external network") 80 } 81 82 nss, err := LookupNS("gmail.com") 83 if err != nil { 84 t.Fatal(err) 85 } 86 if len(nss) == 0 { 87 t.Error("got no record") 88 } 89 for _, ns := range nss { 90 if !strings.Contains(ns.Host, ".google.com") { 91 t.Errorf("got %v; want a record containing .google.com.", ns) 92 } 93 } 94 } 95 96 func TestLookupGmailTXT(t *testing.T) { 97 if testing.Short() || !*testExternal { 98 t.Skip("skipping test to avoid external network") 99 } 100 101 txts, err := LookupTXT("gmail.com") 102 if err != nil { 103 t.Fatal(err) 104 } 105 if len(txts) == 0 { 106 t.Error("got no record") 107 } 108 for _, txt := range txts { 109 if !strings.Contains(txt, "spf") { 110 t.Errorf("got %q; want a spf record", txt) 111 } 112 } 113 } 114 115 var lookupGooglePublicDNSAddrs = []struct { 116 addr string 117 name string 118 }{ 119 {"8.8.8.8", ".google.com."}, 120 {"8.8.4.4", ".google.com."}, 121 {"2001:4860:4860::8888", ".google.com."}, 122 {"2001:4860:4860::8844", ".google.com."}, 123 } 124 125 func TestLookupGooglePublicDNSAddr(t *testing.T) { 126 if testing.Short() || !*testExternal { 127 t.Skip("skipping test to avoid external network") 128 } 129 130 for _, tt := range lookupGooglePublicDNSAddrs { 131 names, err := LookupAddr(tt.addr) 132 if err != nil { 133 t.Fatal(err) 134 } 135 if len(names) == 0 { 136 t.Error("got no record") 137 } 138 for _, name := range names { 139 if !strings.HasSuffix(name, tt.name) { 140 t.Errorf("got %q; want a record containing %q", name, tt.name) 141 } 142 } 143 } 144 } 145 146 func TestLookupIANACNAME(t *testing.T) { 147 if testing.Short() || !*testExternal { 148 t.Skip("skipping test to avoid external network") 149 } 150 151 cname, err := LookupCNAME("www.iana.org") 152 if err != nil { 153 t.Fatal(err) 154 } 155 if !strings.HasSuffix(cname, ".icann.org.") { 156 t.Errorf("got %q; want a record containing .icann.org.", cname) 157 } 158 } 159 160 func TestLookupGoogleHost(t *testing.T) { 161 if testing.Short() || !*testExternal { 162 t.Skip("skipping test to avoid external network") 163 } 164 165 addrs, err := LookupHost("google.com") 166 if err != nil { 167 t.Fatal(err) 168 } 169 if len(addrs) == 0 { 170 t.Error("got no record") 171 } 172 for _, addr := range addrs { 173 if ParseIP(addr) == nil { 174 t.Errorf("got %q; want a literal ip address", addr) 175 } 176 } 177 } 178 179 func TestLookupGoogleIP(t *testing.T) { 180 if testing.Short() || !*testExternal { 181 t.Skip("skipping test to avoid external network") 182 } 183 184 ips, err := LookupIP("google.com") 185 if err != nil { 186 t.Fatal(err) 187 } 188 if len(ips) == 0 { 189 t.Error("got no record") 190 } 191 for _, ip := range ips { 192 if ip.To4() == nil && ip.To16() == nil { 193 t.Errorf("got %v; want an ip address", ip) 194 } 195 } 196 } 197 198 var revAddrTests = []struct { 199 Addr string 200 Reverse string 201 ErrPrefix string 202 }{ 203 {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""}, 204 {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""}, 205 {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""}, 206 {"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""}, 207 {"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""}, 208 {"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, 209 {"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, 210 {"1.2.3", "", "unrecognized address"}, 211 {"1.2.3.4.5", "", "unrecognized address"}, 212 {"1234:567:bcbca::89a:bcde", "", "unrecognized address"}, 213 {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"}, 214 } 215 216 func TestReverseAddress(t *testing.T) { 217 for i, tt := range revAddrTests { 218 a, err := reverseaddr(tt.Addr) 219 if len(tt.ErrPrefix) > 0 && err == nil { 220 t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix) 221 continue 222 } 223 if len(tt.ErrPrefix) == 0 && err != nil { 224 t.Errorf("#%d: expected <nil>, got %q (error)", i, err) 225 } 226 if err != nil && err.(*DNSError).Err != tt.ErrPrefix { 227 t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err) 228 } 229 if a != tt.Reverse { 230 t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a) 231 } 232 } 233 } 234 235 var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding") 236 237 func TestLookupIPDeadline(t *testing.T) { 238 if !*testDNSFlood { 239 t.Skip("test disabled; use -dnsflood to enable") 240 } 241 242 const N = 5000 243 const timeout = 3 * time.Second 244 c := make(chan error, 2*N) 245 for i := 0; i < N; i++ { 246 name := fmt.Sprintf("%d.net-test.golang.org", i) 247 go func() { 248 _, err := lookupIPDeadline(name, time.Now().Add(timeout/2)) 249 c <- err 250 }() 251 go func() { 252 _, err := lookupIPDeadline(name, time.Now().Add(timeout)) 253 c <- err 254 }() 255 } 256 qstats := struct { 257 succeeded, failed int 258 timeout, temporary, other int 259 unknown int 260 }{} 261 deadline := time.After(timeout + time.Second) 262 for i := 0; i < 2*N; i++ { 263 select { 264 case <-deadline: 265 t.Fatal("deadline exceeded") 266 case err := <-c: 267 switch err := err.(type) { 268 case nil: 269 qstats.succeeded++ 270 case Error: 271 qstats.failed++ 272 if err.Timeout() { 273 qstats.timeout++ 274 } 275 if err.Temporary() { 276 qstats.temporary++ 277 } 278 if !err.Timeout() && !err.Temporary() { 279 qstats.other++ 280 } 281 default: 282 qstats.failed++ 283 qstats.unknown++ 284 } 285 } 286 } 287 288 // A high volume of DNS queries for sub-domain of golang.org 289 // would be coordinated by authoritative or recursive server, 290 // or stub resolver which implements query-response rate 291 // limitation, so we can expect some query successes and more 292 // failures including timeout, temporary and other here. 293 // As a rule, unknown must not be shown but it might possibly 294 // happen due to issue 4856 for now. 295 t.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats.succeeded, qstats.failed, qstats.timeout, qstats.temporary, qstats.other, qstats.unknown) 296 }