| // Copyright 2009 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. |
| |
| package net |
| |
| import ( |
| "reflect" |
| "runtime" |
| "strings" |
| "testing" |
| ) |
| |
| type staticHostEntry struct { |
| in string |
| out []string |
| } |
| |
| var lookupStaticHostTests = []struct { |
| name string |
| ents []staticHostEntry |
| }{ |
| { |
| "testdata/hosts", |
| []staticHostEntry{ |
| {"odin", []string{"127.0.0.2", "127.0.0.3", "::2"}}, |
| {"thor", []string{"127.1.1.1"}}, |
| {"ullr", []string{"127.1.1.2"}}, |
| {"ullrhost", []string{"127.1.1.2"}}, |
| {"localhost", []string{"fe80::1%lo0"}}, |
| }, |
| }, |
| { |
| "testdata/singleline-hosts", // see golang.org/issue/6646 |
| []staticHostEntry{ |
| {"odin", []string{"127.0.0.2"}}, |
| }, |
| }, |
| { |
| "testdata/ipv4-hosts", |
| []staticHostEntry{ |
| {"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}, |
| {"localhost.localdomain", []string{"127.0.0.3"}}, |
| }, |
| }, |
| { |
| "testdata/ipv6-hosts", // see golang.org/issue/8996 |
| []staticHostEntry{ |
| {"localhost", []string{"::1", "fe80::1", "fe80::2%lo0", "fe80::3%lo0"}}, |
| {"localhost.localdomain", []string{"fe80::3%lo0"}}, |
| }, |
| }, |
| { |
| "testdata/case-hosts", // see golang.org/issue/12806 |
| []staticHostEntry{ |
| {"PreserveMe", []string{"127.0.0.1", "::1"}}, |
| {"PreserveMe.local", []string{"127.0.0.1", "::1"}}, |
| }, |
| }, |
| } |
| |
| func requireTestData(t *testing.T) { |
| if runtime.GOOS == "fuchsia" { |
| t.Skip("fuchsia cannot expose testdata; directories can't be resources") |
| } |
| } |
| |
| func TestLookupStaticHost(t *testing.T) { |
| requireTestData(t) |
| defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) |
| |
| for _, tt := range lookupStaticHostTests { |
| testHookHostsPath = tt.name |
| for _, ent := range tt.ents { |
| testStaticHost(t, tt.name, ent) |
| } |
| } |
| } |
| |
| func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) { |
| ins := []string{ent.in, absDomainName(ent.in), strings.ToLower(ent.in), strings.ToUpper(ent.in)} |
| for _, in := range ins { |
| addrs, _ := lookupStaticHost(in) |
| if !reflect.DeepEqual(addrs, ent.out) { |
| t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out) |
| } |
| } |
| } |
| |
| var lookupStaticAddrTests = []struct { |
| name string |
| ents []staticHostEntry |
| }{ |
| { |
| "testdata/hosts", |
| []staticHostEntry{ |
| {"255.255.255.255", []string{"broadcasthost"}}, |
| {"127.0.0.2", []string{"odin"}}, |
| {"127.0.0.3", []string{"odin"}}, |
| {"::2", []string{"odin"}}, |
| {"127.1.1.1", []string{"thor"}}, |
| {"127.1.1.2", []string{"ullr", "ullrhost"}}, |
| {"fe80::1%lo0", []string{"localhost"}}, |
| }, |
| }, |
| { |
| "testdata/singleline-hosts", // see golang.org/issue/6646 |
| []staticHostEntry{ |
| {"127.0.0.2", []string{"odin"}}, |
| }, |
| }, |
| { |
| "testdata/ipv4-hosts", |
| []staticHostEntry{ |
| {"127.0.0.1", []string{"localhost"}}, |
| {"127.0.0.2", []string{"localhost"}}, |
| {"127.0.0.3", []string{"localhost", "localhost.localdomain"}}, |
| }, |
| }, |
| { |
| "testdata/ipv6-hosts", // see golang.org/issue/8996 |
| []staticHostEntry{ |
| {"::1", []string{"localhost"}}, |
| {"fe80::1", []string{"localhost"}}, |
| {"fe80::2%lo0", []string{"localhost"}}, |
| {"fe80::3%lo0", []string{"localhost", "localhost.localdomain"}}, |
| }, |
| }, |
| { |
| "testdata/case-hosts", // see golang.org/issue/12806 |
| []staticHostEntry{ |
| {"127.0.0.1", []string{"PreserveMe", "PreserveMe.local"}}, |
| {"::1", []string{"PreserveMe", "PreserveMe.local"}}, |
| }, |
| }, |
| } |
| |
| func TestLookupStaticAddr(t *testing.T) { |
| requireTestData(t) |
| defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) |
| |
| for _, tt := range lookupStaticAddrTests { |
| testHookHostsPath = tt.name |
| for _, ent := range tt.ents { |
| testStaticAddr(t, tt.name, ent) |
| } |
| } |
| } |
| |
| func testStaticAddr(t *testing.T, hostsPath string, ent staticHostEntry) { |
| hosts := lookupStaticAddr(ent.in) |
| for i := range ent.out { |
| ent.out[i] = absDomainName(ent.out[i]) |
| } |
| if !reflect.DeepEqual(hosts, ent.out) { |
| t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", hostsPath, ent.in, hosts, ent.out) |
| } |
| } |
| |
| func TestHostCacheModification(t *testing.T) { |
| requireTestData(t) |
| // Ensure that programs can't modify the internals of the host cache. |
| // See https://golang.org/issues/14212. |
| defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) |
| |
| testHookHostsPath = "testdata/ipv4-hosts" |
| ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}} |
| testStaticHost(t, testHookHostsPath, ent) |
| // Modify the addresses return by lookupStaticHost. |
| addrs, _ := lookupStaticHost(ent.in) |
| for i := range addrs { |
| addrs[i] += "junk" |
| } |
| testStaticHost(t, testHookHostsPath, ent) |
| |
| testHookHostsPath = "testdata/ipv6-hosts" |
| ent = staticHostEntry{"::1", []string{"localhost"}} |
| testStaticAddr(t, testHookHostsPath, ent) |
| // Modify the hosts return by lookupStaticAddr. |
| hosts := lookupStaticAddr(ent.in) |
| for i := range hosts { |
| hosts[i] += "junk" |
| } |
| testStaticAddr(t, testHookHostsPath, ent) |
| } |
| |
| var lookupStaticHostAliasesTest = []struct { |
| lookup, res string |
| }{ |
| // 127.0.0.1 |
| {"test", "test"}, |
| // 127.0.0.2 |
| {"test2.example.com", "test2.example.com"}, |
| {"2.test", "test2.example.com"}, |
| // 127.0.0.3 |
| {"test3.example.com", "3.test"}, |
| {"3.test", "3.test"}, |
| // 127.0.0.4 |
| {"example.com", "example.com"}, |
| // 127.0.0.5 |
| {"test5.example.com", "test4.example.com"}, |
| {"5.test", "test4.example.com"}, |
| {"4.test", "test4.example.com"}, |
| {"test4.example.com", "test4.example.com"}, |
| } |
| |
| func TestLookupStaticHostAliases(t *testing.T) { |
| if runtime.GOOS == "fuchsia" { |
| t.Skip("no /etc/hosts on Fuchsia") |
| } |
| defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) |
| |
| testHookHostsPath = "testdata/aliases" |
| for _, ent := range lookupStaticHostAliasesTest { |
| testLookupStaticHostAliases(t, ent.lookup, absDomainName(ent.res)) |
| } |
| } |
| |
| func testLookupStaticHostAliases(t *testing.T, lookup, lookupRes string) { |
| ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)} |
| for _, in := range ins { |
| _, res := lookupStaticHost(in) |
| if res != lookupRes { |
| t.Errorf("lookupStaticHost(%v): got %v, want %v", in, res, lookupRes) |
| } |
| } |
| } |