Merge lp:~axwalk/juju-core/lp1225825-netlookupip-ip into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merged at revision: 1831
Proposed branch: lp:~axwalk/juju-core/lp1225825-netlookupip-ip
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 320 lines (+116/-49)
3 files modified
environs/manual/provisioner.go (+13/-0)
instance/address.go (+20/-6)
instance/address_test.go (+83/-43)
To merge this branch: bzr merge lp:~axwalk/juju-core/lp1225825-netlookupip-ip
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+186229@code.launchpad.net

Commit message

environs/manual: reverse lookup target IP

Thus we may resolve additional addresses for the
machine. Also, we should get a consistent machine ID,
whether a name or an IP is specified.

Also, modify instance/HostAddresses to avoid passing
an IP address into net.LookupIP. This causes an error
if built with CGO_ENABLED=0.

Fixes #1225825

https://codereview.appspot.com/13504044/

Description of the change

environs/manual: reverse lookup target IP

Thus we may resolve additional addresses for the
machine. Also, we should get a consistent machine ID,
whether a name or an IP is specified.

Also, modify instance/HostAddresses to avoid passing
an IP address into net.LookupIP. This causes an error
if built with CGO_ENABLED=0.

Fixes #1225825

https://codereview.appspot.com/13504044/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :

Reviewers: mp+186229_code.launchpad.net,

Message:
Please take a look.

Description:
environs/manual: reverse lookup target IP

Thus we may resolve additional addresses for the
machine. Also, we should get a consistent machine ID,
whether a name or an IP is specified.

Also, modify instance/HostAddresses to avoid passing
an IP address into net.LookupIP. This causes an error
if built with CGO_ENABLED=0.

Fixes #1225825

https://code.launchpad.net/~axwalk/juju-core/lp1225825-netlookupip-ip/+merge/186229

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/13504044/

Affected files (+23, -2 lines):
   A [revision details]
   M environs/manual/provisioner.go
   M instance/address.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-20130917082542-j1hu82fubd89ombo
+New revision: <email address hidden>

Index: instance/address.go
=== modified file 'instance/address.go'
--- instance/address.go 2013-09-04 15:11:51 +0000
+++ instance/address.go 2013-09-18 02:36:52 +0000
@@ -61,12 +61,17 @@

  // HostAddresses looks up the IP addresses of the specified
  // host, and translates them into instance.Address values.
-func HostAddresses(host string) ([]Address, error) {
+func HostAddresses(host string) (addrs []Address, err error) {
+ hostAddr := NewAddress(host)
+ if hostAddr.Type != HostName {
+ // IPs shouldn't be fed into LookupIP.
+ return []Address{hostAddr}, nil
+ }
   ipaddrs, err := net.LookupIP(host)
   if err != nil {
    return nil, err
   }
- addrs := make([]Address, len(ipaddrs))
+ addrs = make([]Address, len(ipaddrs)+1)
   for i, ipaddr := range ipaddrs {
    switch len(ipaddr) {
    case 4:
@@ -77,6 +82,7 @@
     addrs[i].Value = ipaddr.String()
    }
   }
+ addrs[len(addrs)-1] = hostAddr
   return addrs, err
  }

Index: environs/manual/provisioner.go
=== modified file 'environs/manual/provisioner.go'
--- environs/manual/provisioner.go 2013-09-03 01:56:25 +0000
+++ environs/manual/provisioner.go 2013-09-18 02:36:52 +0000
@@ -6,6 +6,7 @@
  import (
   "errors"
   "fmt"
+ "net"
   "strings"

   "launchpad.net/loggo"
@@ -71,10 +72,22 @@
   if at := strings.Index(sshHostWithoutUser, "@"); at != -1 {
    sshHostWithoutUser = sshHostWithoutUser[at+1:]
   }
+ if ip := net.ParseIP(sshHostWithoutUser); ip != nil {
+ // Do a reverse-lookup on the IP. The IP may not have
+ // a DNS entry, so just log a warning if this fails.
+ names, err := net.LookupAddr(ip.String())
+ if err != nil {
+ logger.Warningf("failed to resolve %v: %v", ip, err)
+ } else {
+ logger.Infof("resolved %v to %v", ip, names)
+ sshHostWithoutUser = names[0]
+ }
+ }
   addrs, err := instance.HostAddresses(sshHostWithoutUser)
   if err != nil {
    return nil, err
   }
+ logger.Infof("addresses for %v: %v", sshHostWithoutUser, addrs)

   provisioned, err := checkProvisioned(args.Host)
   if err != nil {

Revision history for this message
Tim Penhey (thumper) wrote :

LGTM with a test added, also consider the logging severity.

https://codereview.appspot.com/13504044/diff/1/environs/manual/provisioner.go
File environs/manual/provisioner.go (right):

https://codereview.appspot.com/13504044/diff/1/environs/manual/provisioner.go#newcode80
environs/manual/provisioner.go:80: logger.Warningf("failed to resolve
%v: %v", ip, err)
Is it really a warning if we can't do a reverse lookup? Is it something
that we should be fixing later?

Perhaps just log with info or debug, certainly not really a big deal is
it?

https://codereview.appspot.com/13504044/diff/1/instance/address.go
File instance/address.go (right):

https://codereview.appspot.com/13504044/diff/1/instance/address.go#newcode64
instance/address.go:64: func HostAddresses(host string) (addrs
[]Address, err error) {
How about a test for this?

https://codereview.appspot.com/13504044/

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Revision history for this message
Andrew Wilkins (axwalk) wrote :

https://codereview.appspot.com/13504044/diff/1/environs/manual/provisioner.go
File environs/manual/provisioner.go (right):

https://codereview.appspot.com/13504044/diff/1/environs/manual/provisioner.go#newcode80
environs/manual/provisioner.go:80: logger.Warningf("failed to resolve
%v: %v", ip, err)
On 2013/09/18 03:52:12, thumper wrote:
> Is it really a warning if we can't do a reverse lookup? Is it
something that we
> should be fixing later?

Hmm, yeah, it's not necessarily a problem.

> Perhaps just log with info or debug, certainly not really a big deal
is it?

I'll log it as INFO.

https://codereview.appspot.com/13504044/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (17.5 KiB)

The attempt to merge lp:~axwalk/juju-core/lp1225825-netlookupip-ip into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core/agent 0.733s
ok launchpad.net/juju-core/agent/tools 0.297s
ok launchpad.net/juju-core/bzr 8.078s
ok launchpad.net/juju-core/cert 2.532s
ok launchpad.net/juju-core/charm 0.603s
? launchpad.net/juju-core/charm/hooks [no test files]
ok launchpad.net/juju-core/cloudinit 0.021s
ok launchpad.net/juju-core/cmd 0.213s
? launchpad.net/juju-core/cmd/builddb [no test files]
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]

----------------------------------------------------------------------
PANIC: addmachine.go:0: AddUnitSuite.SetUpTest

... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-5765484004404056823: file exists (PC=0x414321)

/usr/lib/go/src/pkg/runtime/panic.c:229
  in panic
/home/tarmac/trees/src/launchpad.net/gocheck/gocheck.go:137
  in tempDir.newPath
/home/tarmac/trees/src/launchpad.net/gocheck/gocheck.go:159
  in C.MkDir
/home/tarmac/trees/src/launchpad.net/juju-core/juju/testing/conn.go:128
  in JujuConnSuite.SetUpTest
/home/tarmac/trees/src/launchpad.net/juju-core/juju/testing/repo.go:27
  in RepoSuite.SetUpTest

----------------------------------------------------------------------
PANIC: addmachine.go:0: AddUnitSuite.TearDownTest

... Panic: runtime error: invalid memory address or nil pointer dereference (PC=0x414321)

/usr/lib/go/src/pkg/runtime/panic.c:229
  in panic
/usr/lib/go/src/pkg/runtime/panic.c:487
  in panicstring
/usr/lib/go/src/pkg/runtime/os_linux.c:236
  in sigpanic
/home/tarmac/trees/src/launchpad.net/juju-core/state/state.go:1050
  in State.SetAdminMongoPassword
/home/tarmac/trees/src/launchpad.net/juju-core/juju/testing/conn.go:280
  in JujuConnSuite.tearDownConn
/home/tarmac/trees/src/launchpad.net/juju-core/juju/testing/conn.go:136
  in JujuConnSuite.TearDownTest
/home/tarmac/trees/src/launchpad.net/juju-core/juju/testing/repo.go:46
  in RepoSuite.TearDownTest

----------------------------------------------------------------------
PANIC: addunit_test.go:60: AddUnitSuite.TestAddUnit

... Panic: Fixture has panicked (see related PANIC)
listing available tools
found 4 tools
found 4 recent tools (version 1.2.0)
listing target bucket
found 3 tools in target; 4 tools to be copied
copying 1.2.0-precise-amd64 from http://127.0.0.1:40557/tools/juju-1.2.0-precise-amd64.tgz
copying tools/releases/juju-1.2.0-precise-amd64.tgz
downloaded tools/releases/juju-1.2.0-precise-amd64.tgz (0kB), uploading
download 0kB, uploading
copying 1.2.0-quantal-amd64 from http://127.0.0.1:40557/tools/juju-1.2.0-quantal-amd64.tgz
copying tools/releases/juju-1.2.0-quantal-amd64.tgz
downloaded tools/releases/juju-1.2.0-quantal-amd64.tgz (0kB), uploading
download 0kB, uploading
copying 1.2.0-quantal-i386 from http://127.0.0.1:40557/tools/juju-1.2.0-quantal-i386.tgz
copying tools/releases/juju-1.2.0-quantal-i386.tgz
downloaded tools/releases/juju-1.2.0-quantal-i386.tgz (0kB), uploading
download 0kB, uploading
copying 1.2.0-raring-amd64 from http://127.0.0.1:40557/tools/juju-1.2.0-raring-...

Revision history for this message
John A Meinel (jameinel) wrote :

The bot failure is because go check doesn't seed its random-directory generator, and we hit 100 leaked directories.

I think we have a bug somewhere that is causing us to not clean up a dir during testing, but unfortunately I thought of that right after I nuked all the dirs, so it will be hard to figure out where until this happens again.

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Thanks jam. When I have my MPs in order, I'll run some tests locally to see if I can find the culprits.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'environs/manual/provisioner.go'
--- environs/manual/provisioner.go 2013-09-03 01:56:25 +0000
+++ environs/manual/provisioner.go 2013-09-18 04:44:17 +0000
@@ -6,6 +6,7 @@
6import (6import (
7 "errors"7 "errors"
8 "fmt"8 "fmt"
9 "net"
9 "strings"10 "strings"
1011
11 "launchpad.net/loggo"12 "launchpad.net/loggo"
@@ -71,10 +72,22 @@
71 if at := strings.Index(sshHostWithoutUser, "@"); at != -1 {72 if at := strings.Index(sshHostWithoutUser, "@"); at != -1 {
72 sshHostWithoutUser = sshHostWithoutUser[at+1:]73 sshHostWithoutUser = sshHostWithoutUser[at+1:]
73 }74 }
75 if ip := net.ParseIP(sshHostWithoutUser); ip != nil {
76 // Do a reverse-lookup on the IP. The IP may not have
77 // a DNS entry, so just log a warning if this fails.
78 names, err := net.LookupAddr(ip.String())
79 if err != nil {
80 logger.Infof("failed to resolve %v: %v", ip, err)
81 } else {
82 logger.Infof("resolved %v to %v", ip, names)
83 sshHostWithoutUser = names[0]
84 }
85 }
74 addrs, err := instance.HostAddresses(sshHostWithoutUser)86 addrs, err := instance.HostAddresses(sshHostWithoutUser)
75 if err != nil {87 if err != nil {
76 return nil, err88 return nil, err
77 }89 }
90 logger.Infof("addresses for %v: %v", sshHostWithoutUser, addrs)
7891
79 provisioned, err := checkProvisioned(args.Host)92 provisioned, err := checkProvisioned(args.Host)
80 if err != nil {93 if err != nil {
8194
=== modified file 'instance/address.go'
--- instance/address.go 2013-09-04 15:11:51 +0000
+++ instance/address.go 2013-09-18 04:44:17 +0000
@@ -59,24 +59,38 @@
59 return Address{value, addresstype, "", NetworkUnknown}59 return Address{value, addresstype, "", NetworkUnknown}
60}60}
6161
62// netLookupIP is a var for testing.
63var netLookupIP = net.LookupIP
64
62// HostAddresses looks up the IP addresses of the specified65// HostAddresses looks up the IP addresses of the specified
63// host, and translates them into instance.Address values.66// host, and translates them into instance.Address values.
64func HostAddresses(host string) ([]Address, error) {67func HostAddresses(host string) (addrs []Address, err error) {
65 ipaddrs, err := net.LookupIP(host)68 hostAddr := NewAddress(host)
69 if hostAddr.Type != HostName {
70 // IPs shouldn't be fed into LookupIP.
71 return []Address{hostAddr}, nil
72 }
73 ipaddrs, err := netLookupIP(host)
66 if err != nil {74 if err != nil {
67 return nil, err75 return nil, err
68 }76 }
69 addrs := make([]Address, len(ipaddrs))77 addrs = make([]Address, len(ipaddrs)+1)
70 for i, ipaddr := range ipaddrs {78 for i, ipaddr := range ipaddrs {
71 switch len(ipaddr) {79 switch len(ipaddr) {
72 case 4:80 case net.IPv4len:
73 addrs[i].Type = Ipv4Address81 addrs[i].Type = Ipv4Address
74 addrs[i].Value = ipaddr.String()82 addrs[i].Value = ipaddr.String()
75 case 16:83 case net.IPv6len:
76 addrs[i].Type = Ipv6Address84 if ipaddr.To4() != nil {
85 // ipaddr is an IPv4 address represented in 16 bytes.
86 addrs[i].Type = Ipv4Address
87 } else {
88 addrs[i].Type = Ipv6Address
89 }
77 addrs[i].Value = ipaddr.String()90 addrs[i].Value = ipaddr.String()
78 }91 }
79 }92 }
93 addrs[len(addrs)-1] = hostAddr
80 return addrs, err94 return addrs, err
81}95}
8296
8397
=== modified file 'instance/address_test.go'
--- instance/address_test.go 2013-09-05 16:02:35 +0000
+++ instance/address_test.go 2013-09-18 04:44:17 +0000
@@ -1,12 +1,15 @@
1// Copyright 2013 Canonical Ltd.1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.2// Licensed under the AGPLv3, see LICENCE file for details.
33
4package instance_test4package instance
55
6import (6import (
7 "errors"
8 "net"
9
7 gc "launchpad.net/gocheck"10 gc "launchpad.net/gocheck"
811
9 "launchpad.net/juju-core/instance"12 jc "launchpad.net/juju-core/testing/checkers"
10)13)
1114
12type AddressSuite struct{}15type AddressSuite struct{}
@@ -14,64 +17,64 @@
14var _ = gc.Suite(&AddressSuite{})17var _ = gc.Suite(&AddressSuite{})
1518
16func (s *AddressSuite) TestNewAddressIpv4(c *gc.C) {19func (s *AddressSuite) TestNewAddressIpv4(c *gc.C) {
17 addr := instance.NewAddress("127.0.0.1")20 addr := NewAddress("127.0.0.1")
18 c.Check(addr.Value, gc.Equals, "127.0.0.1")21 c.Check(addr.Value, gc.Equals, "127.0.0.1")
19 c.Check(addr.Type, gc.Equals, instance.Ipv4Address)22 c.Check(addr.Type, gc.Equals, Ipv4Address)
20}23}
2124
22func (s *AddressSuite) TestNewAddressIpv6(c *gc.C) {25func (s *AddressSuite) TestNewAddressIpv6(c *gc.C) {
23 addr := instance.NewAddress("::1")26 addr := NewAddress("::1")
24 c.Check(addr.Value, gc.Equals, "::1")27 c.Check(addr.Value, gc.Equals, "::1")
25 c.Check(addr.Type, gc.Equals, instance.Ipv6Address)28 c.Check(addr.Type, gc.Equals, Ipv6Address)
26}29}
2730
28func (s *AddressSuite) TestNewAddressHostname(c *gc.C) {31func (s *AddressSuite) TestNewAddressHostname(c *gc.C) {
29 addr := instance.NewAddress("localhost")32 addr := NewAddress("localhost")
30 c.Check(addr.Value, gc.Equals, "localhost")33 c.Check(addr.Value, gc.Equals, "localhost")
31 c.Check(addr.Type, gc.Equals, instance.HostName)34 c.Check(addr.Type, gc.Equals, HostName)
32}35}
3336
34type selectTests struct {37type selectTests struct {
35 about string38 about string
36 addresses []instance.Address39 addresses []Address
37 expected string40 expected string
38}41}
3942
40var selectPublicTests = []selectTests{{43var selectPublicTests = []selectTests{{
41 "no addresses gives empty string result",44 "no addresses gives empty string result",
42 []instance.Address{},45 []Address{},
43 "",46 "",
44}, {47}, {
45 "a public address is selected",48 "a public address is selected",
46 []instance.Address{49 []Address{
47 {"8.8.8.8", instance.Ipv4Address, "public", instance.NetworkPublic},50 {"8.8.8.8", Ipv4Address, "public", NetworkPublic},
48 },51 },
49 "8.8.8.8",52 "8.8.8.8",
50}, {53}, {
51 "a machine local address is not selected",54 "a machine local address is not selected",
52 []instance.Address{55 []Address{
53 {"127.0.0.1", instance.Ipv4Address, "machine", instance.NetworkMachineLocal},56 {"127.0.0.1", Ipv4Address, "machine", NetworkMachineLocal},
54 },57 },
55 "",58 "",
56}, {59}, {
57 "an ipv6 address is not selected",60 "an ipv6 address is not selected",
58 []instance.Address{61 []Address{
59 {"2001:DB8::1", instance.Ipv6Address, "", instance.NetworkPublic},62 {"2001:DB8::1", Ipv6Address, "", NetworkPublic},
60 },63 },
61 "",64 "",
62}, {65}, {
63 "a public name is preferred to an unknown or cloud local address",66 "a public name is preferred to an unknown or cloud local address",
64 []instance.Address{67 []Address{
65 {"127.0.0.1", instance.Ipv4Address, "local", instance.NetworkUnknown},68 {"127.0.0.1", Ipv4Address, "local", NetworkUnknown},
66 {"10.0.0.1", instance.Ipv4Address, "cloud", instance.NetworkCloudLocal},69 {"10.0.0.1", Ipv4Address, "cloud", NetworkCloudLocal},
67 {"public.invalid.testing", instance.HostName, "public", instance.NetworkPublic},70 {"public.invalid.testing", HostName, "public", NetworkPublic},
68 },71 },
69 "public.invalid.testing",72 "public.invalid.testing",
70}, {73}, {
71 "last unknown address selected",74 "last unknown address selected",
72 []instance.Address{75 []Address{
73 {"10.0.0.1", instance.Ipv4Address, "cloud", instance.NetworkUnknown},76 {"10.0.0.1", Ipv4Address, "cloud", NetworkUnknown},
74 {"8.8.8.8", instance.Ipv4Address, "floating", instance.NetworkUnknown},77 {"8.8.8.8", Ipv4Address, "floating", NetworkUnknown},
75 },78 },
76 "8.8.8.8",79 "8.8.8.8",
77}}80}}
@@ -79,43 +82,43 @@
79func (s *AddressSuite) TestSelectPublicAddressEmpty(c *gc.C) {82func (s *AddressSuite) TestSelectPublicAddressEmpty(c *gc.C) {
80 for i, t := range selectPublicTests {83 for i, t := range selectPublicTests {
81 c.Logf("test %d. %s", i, t.about)84 c.Logf("test %d. %s", i, t.about)
82 c.Check(instance.SelectPublicAddress(t.addresses), gc.Equals, t.expected)85 c.Check(SelectPublicAddress(t.addresses), gc.Equals, t.expected)
83 }86 }
84}87}
8588
86var selectInternalTests = []selectTests{{89var selectInternalTests = []selectTests{{
87 "no addresses gives empty string result",90 "no addresses gives empty string result",
88 []instance.Address{},91 []Address{},
89 "",92 "",
90}, {93}, {
91 "a public address is selected",94 "a public address is selected",
92 []instance.Address{95 []Address{
93 {"8.8.8.8", instance.Ipv4Address, "public", instance.NetworkPublic},96 {"8.8.8.8", Ipv4Address, "public", NetworkPublic},
94 },97 },
95 "8.8.8.8",98 "8.8.8.8",
96}, {99}, {
97 "a cloud local address is selected",100 "a cloud local address is selected",
98 []instance.Address{101 []Address{
99 {"10.0.0.1", instance.Ipv4Address, "private", instance.NetworkCloudLocal},102 {"10.0.0.1", Ipv4Address, "private", NetworkCloudLocal},
100 },103 },
101 "10.0.0.1",104 "10.0.0.1",
102}, {105}, {
103 "a machine local address is not selected",106 "a machine local address is not selected",
104 []instance.Address{107 []Address{
105 {"127.0.0.1", instance.Ipv4Address, "machine", instance.NetworkMachineLocal},108 {"127.0.0.1", Ipv4Address, "machine", NetworkMachineLocal},
106 },109 },
107 "",110 "",
108}, {111}, {
109 "ipv6 addresses are not selected",112 "ipv6 addresses are not selected",
110 []instance.Address{113 []Address{
111 {"::1", instance.Ipv6Address, "", instance.NetworkCloudLocal},114 {"::1", Ipv6Address, "", NetworkCloudLocal},
112 },115 },
113 "",116 "",
114}, {117}, {
115 "a cloud local address is preferred to a public address",118 "a cloud local address is preferred to a public address",
116 []instance.Address{119 []Address{
117 {"10.0.0.1", instance.Ipv4Address, "cloud", instance.NetworkCloudLocal},120 {"10.0.0.1", Ipv4Address, "cloud", NetworkCloudLocal},
118 {"8.8.8.8", instance.Ipv4Address, "public", instance.NetworkPublic},121 {"8.8.8.8", Ipv4Address, "public", NetworkPublic},
119 },122 },
120 "10.0.0.1",123 "10.0.0.1",
121}}124}}
@@ -123,20 +126,20 @@
123func (s *AddressSuite) TestSelectInternalAddress(c *gc.C) {126func (s *AddressSuite) TestSelectInternalAddress(c *gc.C) {
124 for i, t := range selectInternalTests {127 for i, t := range selectInternalTests {
125 c.Logf("test %d. %s", i, t.about)128 c.Logf("test %d. %s", i, t.about)
126 c.Check(instance.SelectInternalAddress(t.addresses, false), gc.Equals, t.expected)129 c.Check(SelectInternalAddress(t.addresses, false), gc.Equals, t.expected)
127 }130 }
128}131}
129132
130var selectInternalMachineTests = []selectTests{{133var selectInternalMachineTests = []selectTests{{
131 "a cloud local address is selected",134 "a cloud local address is selected",
132 []instance.Address{135 []Address{
133 {"10.0.0.1", instance.Ipv4Address, "cloud", instance.NetworkCloudLocal},136 {"10.0.0.1", Ipv4Address, "cloud", NetworkCloudLocal},
134 },137 },
135 "10.0.0.1",138 "10.0.0.1",
136}, {139}, {
137 "a machine local address is selected",140 "a machine local address is selected",
138 []instance.Address{141 []Address{
139 {"127.0.0.1", instance.Ipv4Address, "container", instance.NetworkMachineLocal},142 {"127.0.0.1", Ipv4Address, "container", NetworkMachineLocal},
140 },143 },
141 "127.0.0.1",144 "127.0.0.1",
142}}145}}
@@ -144,6 +147,43 @@
144func (s *AddressSuite) TestSelectInternalMachineAddress(c *gc.C) {147func (s *AddressSuite) TestSelectInternalMachineAddress(c *gc.C) {
145 for i, t := range selectInternalMachineTests {148 for i, t := range selectInternalMachineTests {
146 c.Logf("test %d. %s", i, t.about)149 c.Logf("test %d. %s", i, t.about)
147 c.Check(instance.SelectInternalAddress(t.addresses, true), gc.Equals, t.expected)150 c.Check(SelectInternalAddress(t.addresses, true), gc.Equals, t.expected)
148 }151 }
152}
153
154func (*AddressSuite) TestHostAddresses(c *gc.C) {
155 // Mock the call to net.LookupIP made from HostAddresses.
156 var lookupIPs []net.IP
157 var lookupErr error
158 lookupIP := func(addr string) ([]net.IP, error) {
159 return append([]net.IP{}, lookupIPs...), lookupErr
160 }
161 defer jc.Set(&netLookupIP, lookupIP).Restore()
162
163 // err is only non-nil if net.LookupIP fails.
164 addrs, err := HostAddresses("")
165 c.Assert(err, gc.IsNil)
166 // addrs always contains the input address.
167 c.Assert(addrs, gc.HasLen, 1)
168 c.Assert(addrs[0], gc.Equals, NewAddress(""))
169
170 loopback := net.ParseIP("127.0.0.1").To4()
171 lookupIPs = []net.IP{net.IPv6loopback, net.IPv4zero, loopback}
172 addrs, err = HostAddresses("localhost")
173 c.Assert(err, gc.IsNil)
174 c.Assert(addrs, gc.HasLen, 4)
175 c.Assert(addrs[0], gc.Equals, NewAddress(net.IPv6loopback.String()))
176 c.Assert(addrs[1], gc.Equals, NewAddress(net.IPv4zero.String()))
177 c.Assert(addrs[2], gc.Equals, NewAddress(loopback.String()))
178 c.Assert(addrs[3], gc.Equals, NewAddress("localhost"))
179
180 lookupErr = errors.New("what happened?")
181 addrs, err = HostAddresses("localhost")
182 c.Assert(err, gc.Equals, lookupErr)
183
184 // If the input address is an IP, the call to net.LookupIP is elided.
185 addrs, err = HostAddresses("127.0.0.1")
186 c.Assert(err, gc.IsNil)
187 c.Assert(addrs, gc.HasLen, 1)
188 c.Assert(addrs[0], gc.Equals, NewAddress("127.0.0.1"))
149}189}

Subscribers

People subscribed via source and target branches

to status/vote changes: