github.com/c0deoo1/golang1.5@v0.0.0-20220525150107-c87c805d4593/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 package net 6 7 import ( 8 "fmt" 9 "strings" 10 "testing" 11 "time" 12 ) 13 14 func lookupLocalhost(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) { 15 switch host { 16 case "localhost": 17 return []IPAddr{ 18 {IP: IPv4(127, 0, 0, 1)}, 19 {IP: IPv6loopback}, 20 }, nil 21 default: 22 return fn(host) 23 } 24 } 25 26 // The Lookup APIs use various sources such as local database, DNS or 27 // mDNS, and may use platform-dependent DNS stub resolver if possible. 28 // The APIs accept any of forms for a query; host name in various 29 // encodings, UTF-8 encoded net name, domain name, FQDN or absolute 30 // FQDN, but the result would be one of the forms and it depends on 31 // the circumstances. 32 33 var lookupGoogleSRVTests = []struct { 34 service, proto, name string 35 cname, target string 36 }{ 37 { 38 "xmpp-server", "tcp", "google.com", 39 "google.com", "google.com", 40 }, 41 { 42 "xmpp-server", "tcp", "google.com.", 43 "google.com", "google.com", 44 }, 45 46 // non-standard back door 47 { 48 "", "", "_xmpp-server._tcp.google.com", 49 "google.com", "google.com", 50 }, 51 { 52 "", "", "_xmpp-server._tcp.google.com.", 53 "google.com", "google.com", 54 }, 55 } 56 57 func TestLookupGoogleSRV(t *testing.T) { 58 if testing.Short() || !*testExternal { 59 t.Skip("avoid external network") 60 } 61 if !supportsIPv4 || !*testIPv4 { 62 t.Skip("IPv4 is required") 63 } 64 65 for _, tt := range lookupGoogleSRVTests { 66 cname, srvs, err := LookupSRV(tt.service, tt.proto, tt.name) 67 if err != nil { 68 t.Fatal(err) 69 } 70 if len(srvs) == 0 { 71 t.Error("got no record") 72 } 73 if !strings.HasSuffix(cname, tt.cname) && !strings.HasSuffix(cname, tt.cname+".") { 74 t.Errorf("got %s; want %s", cname, tt.cname) 75 } 76 for _, srv := range srvs { 77 if !strings.HasSuffix(srv.Target, tt.target) && !strings.HasSuffix(srv.Target, tt.target+".") { 78 t.Errorf("got %v; want a record containing %s", srv, tt.target) 79 } 80 } 81 } 82 } 83 84 var lookupGmailMXTests = []struct { 85 name, host string 86 }{ 87 {"gmail.com", "google.com"}, 88 {"gmail.com.", "google.com"}, 89 } 90 91 func TestLookupGmailMX(t *testing.T) { 92 if testing.Short() || !*testExternal { 93 t.Skip("avoid external network") 94 } 95 if !supportsIPv4 || !*testIPv4 { 96 t.Skip("IPv4 is required") 97 } 98 99 for _, tt := range lookupGmailMXTests { 100 mxs, err := LookupMX(tt.name) 101 if err != nil { 102 t.Fatal(err) 103 } 104 if len(mxs) == 0 { 105 t.Error("got no record") 106 } 107 for _, mx := range mxs { 108 if !strings.HasSuffix(mx.Host, tt.host) && !strings.HasSuffix(mx.Host, tt.host+".") { 109 t.Errorf("got %v; want a record containing %s", mx, tt.host) 110 } 111 } 112 } 113 } 114 115 var lookupGmailNSTests = []struct { 116 name, host string 117 }{ 118 {"gmail.com", "google.com"}, 119 {"gmail.com.", "google.com"}, 120 } 121 122 func TestLookupGmailNS(t *testing.T) { 123 if testing.Short() || !*testExternal { 124 t.Skip("avoid external network") 125 } 126 if !supportsIPv4 || !*testIPv4 { 127 t.Skip("IPv4 is required") 128 } 129 130 for _, tt := range lookupGmailNSTests { 131 nss, err := LookupNS(tt.name) 132 if err != nil { 133 t.Fatal(err) 134 } 135 if len(nss) == 0 { 136 t.Error("got no record") 137 } 138 for _, ns := range nss { 139 if !strings.HasSuffix(ns.Host, tt.host) && !strings.HasSuffix(ns.Host, tt.host+".") { 140 t.Errorf("got %v; want a record containing %s", ns, tt.host) 141 } 142 } 143 } 144 } 145 146 var lookupGmailTXTTests = []struct { 147 name, txt, host string 148 }{ 149 {"gmail.com", "spf", "google.com"}, 150 {"gmail.com.", "spf", "google.com"}, 151 } 152 153 func TestLookupGmailTXT(t *testing.T) { 154 if testing.Short() || !*testExternal { 155 t.Skip("avoid external network") 156 } 157 if !supportsIPv4 || !*testIPv4 { 158 t.Skip("IPv4 is required") 159 } 160 161 for _, tt := range lookupGmailTXTTests { 162 txts, err := LookupTXT(tt.name) 163 if err != nil { 164 t.Fatal(err) 165 } 166 if len(txts) == 0 { 167 t.Error("got no record") 168 } 169 for _, txt := range txts { 170 if !strings.Contains(txt, tt.txt) || (!strings.HasSuffix(txt, tt.host) && !strings.HasSuffix(txt, tt.host+".")) { 171 t.Errorf("got %s; want a record containing %s, %s", txt, tt.txt, tt.host) 172 } 173 } 174 } 175 } 176 177 var lookupGooglePublicDNSAddrTests = []struct { 178 addr, name string 179 }{ 180 {"8.8.8.8", ".google.com"}, 181 {"8.8.4.4", ".google.com"}, 182 {"2001:4860:4860::8888", ".google.com"}, 183 {"2001:4860:4860::8844", ".google.com"}, 184 } 185 186 func TestLookupGooglePublicDNSAddr(t *testing.T) { 187 if testing.Short() || !*testExternal { 188 t.Skip("avoid external network") 189 } 190 if !supportsIPv4 || !supportsIPv6 || !*testIPv4 || !*testIPv6 { 191 t.Skip("both IPv4 and IPv6 are required") 192 } 193 194 for _, tt := range lookupGooglePublicDNSAddrTests { 195 names, err := LookupAddr(tt.addr) 196 if err != nil { 197 t.Fatal(err) 198 } 199 if len(names) == 0 { 200 t.Error("got no record") 201 } 202 for _, name := range names { 203 if !strings.HasSuffix(name, tt.name) && !strings.HasSuffix(name, tt.name+".") { 204 t.Errorf("got %s; want a record containing %s", name, tt.name) 205 } 206 } 207 } 208 } 209 210 var lookupIANACNAMETests = []struct { 211 name, cname string 212 }{ 213 {"www.iana.org", "icann.org"}, 214 {"www.iana.org.", "icann.org"}, 215 } 216 217 func TestLookupIANACNAME(t *testing.T) { 218 if testing.Short() || !*testExternal { 219 t.Skip("avoid external network") 220 } 221 if !supportsIPv4 || !*testIPv4 { 222 t.Skip("IPv4 is required") 223 } 224 225 for _, tt := range lookupIANACNAMETests { 226 cname, err := LookupCNAME(tt.name) 227 if err != nil { 228 t.Fatal(err) 229 } 230 if !strings.HasSuffix(cname, tt.cname) && !strings.HasSuffix(cname, tt.cname+".") { 231 t.Errorf("got %s; want a record containing %s", cname, tt.cname) 232 } 233 } 234 } 235 236 var lookupGoogleHostTests = []struct { 237 name string 238 }{ 239 {"google.com"}, 240 {"google.com."}, 241 } 242 243 func TestLookupGoogleHost(t *testing.T) { 244 if testing.Short() || !*testExternal { 245 t.Skip("avoid external network") 246 } 247 if !supportsIPv4 || !*testIPv4 { 248 t.Skip("IPv4 is required") 249 } 250 251 for _, tt := range lookupGoogleHostTests { 252 addrs, err := LookupHost(tt.name) 253 if err != nil { 254 t.Fatal(err) 255 } 256 if len(addrs) == 0 { 257 t.Error("got no record") 258 } 259 for _, addr := range addrs { 260 if ParseIP(addr) == nil { 261 t.Errorf("got %q; want a literal IP address", addr) 262 } 263 } 264 } 265 } 266 267 var lookupGoogleIPTests = []struct { 268 name string 269 }{ 270 {"google.com"}, 271 {"google.com."}, 272 } 273 274 func TestLookupGoogleIP(t *testing.T) { 275 if testing.Short() || !*testExternal { 276 t.Skip("avoid external network") 277 } 278 if !supportsIPv4 || !*testIPv4 { 279 t.Skip("IPv4 is required") 280 } 281 282 for _, tt := range lookupGoogleIPTests { 283 ips, err := LookupIP(tt.name) 284 if err != nil { 285 t.Fatal(err) 286 } 287 if len(ips) == 0 { 288 t.Error("got no record") 289 } 290 for _, ip := range ips { 291 if ip.To4() == nil && ip.To16() == nil { 292 t.Errorf("got %v; want an IP address", ip) 293 } 294 } 295 } 296 } 297 298 var revAddrTests = []struct { 299 Addr string 300 Reverse string 301 ErrPrefix string 302 }{ 303 {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""}, 304 {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""}, 305 {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""}, 306 {"::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.", ""}, 307 {"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.", ""}, 308 {"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.", ""}, 309 {"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.", ""}, 310 {"1.2.3", "", "unrecognized address"}, 311 {"1.2.3.4.5", "", "unrecognized address"}, 312 {"1234:567:bcbca::89a:bcde", "", "unrecognized address"}, 313 {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"}, 314 } 315 316 func TestReverseAddress(t *testing.T) { 317 for i, tt := range revAddrTests { 318 a, err := reverseaddr(tt.Addr) 319 if len(tt.ErrPrefix) > 0 && err == nil { 320 t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix) 321 continue 322 } 323 if len(tt.ErrPrefix) == 0 && err != nil { 324 t.Errorf("#%d: expected <nil>, got %q (error)", i, err) 325 } 326 if err != nil && err.(*DNSError).Err != tt.ErrPrefix { 327 t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err) 328 } 329 if a != tt.Reverse { 330 t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a) 331 } 332 } 333 } 334 335 func TestLookupIPDeadline(t *testing.T) { 336 if !*testDNSFlood { 337 t.Skip("test disabled; use -dnsflood to enable") 338 } 339 340 const N = 5000 341 const timeout = 3 * time.Second 342 c := make(chan error, 2*N) 343 for i := 0; i < N; i++ { 344 name := fmt.Sprintf("%d.net-test.golang.org", i) 345 go func() { 346 _, err := lookupIPDeadline(name, time.Now().Add(timeout/2)) 347 c <- err 348 }() 349 go func() { 350 _, err := lookupIPDeadline(name, time.Now().Add(timeout)) 351 c <- err 352 }() 353 } 354 qstats := struct { 355 succeeded, failed int 356 timeout, temporary, other int 357 unknown int 358 }{} 359 deadline := time.After(timeout + time.Second) 360 for i := 0; i < 2*N; i++ { 361 select { 362 case <-deadline: 363 t.Fatal("deadline exceeded") 364 case err := <-c: 365 switch err := err.(type) { 366 case nil: 367 qstats.succeeded++ 368 case Error: 369 qstats.failed++ 370 if err.Timeout() { 371 qstats.timeout++ 372 } 373 if err.Temporary() { 374 qstats.temporary++ 375 } 376 if !err.Timeout() && !err.Temporary() { 377 qstats.other++ 378 } 379 default: 380 qstats.failed++ 381 qstats.unknown++ 382 } 383 } 384 } 385 386 // A high volume of DNS queries for sub-domain of golang.org 387 // would be coordinated by authoritative or recursive server, 388 // or stub resolver which implements query-response rate 389 // limitation, so we can expect some query successes and more 390 // failures including timeout, temporary and other here. 391 // As a rule, unknown must not be shown but it might possibly 392 // happen due to issue 4856 for now. 393 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) 394 }