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.
12 var testInetaddr
= func(ip IPAddr
) Addr
{ return &TCPAddr
{IP
: ip
.IP
, Port
: 5682, Zone
: ip
.Zone
} }
14 var addrListTests
= []struct {
15 filter
func(IPAddr
) bool
17 inetaddr
func(IPAddr
) Addr
26 {IP
: IPv4(127, 0, 0, 1)},
30 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
31 addrList
{&TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682}},
32 addrList
{&TCPAddr
{IP
: IPv6loopback
, Port
: 5682}},
39 {IP
: IPv4(127, 0, 0, 1)},
42 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
43 addrList
{&TCPAddr
{IP
: IPv6loopback
, Port
: 5682}},
44 addrList
{&TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682}},
50 {IP
: IPv4(127, 0, 0, 1)},
51 {IP
: IPv4(192, 168, 0, 1)},
54 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
56 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
57 &TCPAddr
{IP
: IPv4(192, 168, 0, 1), Port
: 5682},
66 {IP
: ParseIP("fe80::1"), Zone
: "eth0"},
69 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
71 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
72 &TCPAddr
{IP
: ParseIP("fe80::1"), Port
: 5682, Zone
: "eth0"},
80 {IP
: IPv4(127, 0, 0, 1)},
81 {IP
: IPv4(192, 168, 0, 1)},
83 {IP
: ParseIP("fe80::1"), Zone
: "eth0"},
86 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
88 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
89 &TCPAddr
{IP
: IPv4(192, 168, 0, 1), Port
: 5682},
92 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
93 &TCPAddr
{IP
: ParseIP("fe80::1"), Port
: 5682, Zone
: "eth0"},
101 {IP
: ParseIP("fe80::1"), Zone
: "eth0"},
102 {IP
: IPv4(127, 0, 0, 1)},
103 {IP
: IPv4(192, 168, 0, 1)},
106 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
108 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
109 &TCPAddr
{IP
: ParseIP("fe80::1"), Port
: 5682, Zone
: "eth0"},
112 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
113 &TCPAddr
{IP
: IPv4(192, 168, 0, 1), Port
: 5682},
120 {IP
: IPv4(127, 0, 0, 1)},
122 {IP
: IPv4(192, 168, 0, 1)},
123 {IP
: ParseIP("fe80::1"), Zone
: "eth0"},
126 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
128 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
129 &TCPAddr
{IP
: IPv4(192, 168, 0, 1), Port
: 5682},
132 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
133 &TCPAddr
{IP
: ParseIP("fe80::1"), Port
: 5682, Zone
: "eth0"},
141 {IP
: IPv4(127, 0, 0, 1)},
142 {IP
: ParseIP("fe80::1"), Zone
: "eth0"},
143 {IP
: IPv4(192, 168, 0, 1)},
146 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
148 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
149 &TCPAddr
{IP
: ParseIP("fe80::1"), Port
: 5682, Zone
: "eth0"},
152 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
153 &TCPAddr
{IP
: IPv4(192, 168, 0, 1), Port
: 5682},
161 {IP
: IPv4(127, 0, 0, 1)},
165 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
166 addrList
{&TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682}},
174 {IP
: IPv4(127, 0, 0, 1)},
177 &TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682},
178 addrList
{&TCPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 5682}},
186 {IP
: IPv4(127, 0, 0, 1)},
190 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
191 addrList
{&TCPAddr
{IP
: IPv6loopback
, Port
: 5682}},
199 {IP
: IPv4(127, 0, 0, 1)},
202 &TCPAddr
{IP
: IPv6loopback
, Port
: 5682},
203 addrList
{&TCPAddr
{IP
: IPv6loopback
, Port
: 5682}},
208 {nil, nil, testInetaddr
, nil, nil, nil, &AddrError
{errNoSuitableAddress
.Error(), "ADDR"}},
210 {ipv4only
, nil, testInetaddr
, nil, nil, nil, &AddrError
{errNoSuitableAddress
.Error(), "ADDR"}},
211 {ipv4only
, []IPAddr
{{IP
: IPv6loopback
}}, testInetaddr
, nil, nil, nil, &AddrError
{errNoSuitableAddress
.Error(), "ADDR"}},
213 {ipv6only
, nil, testInetaddr
, nil, nil, nil, &AddrError
{errNoSuitableAddress
.Error(), "ADDR"}},
214 {ipv6only
, []IPAddr
{{IP
: IPv4(127, 0, 0, 1)}}, testInetaddr
, nil, nil, nil, &AddrError
{errNoSuitableAddress
.Error(), "ADDR"}},
217 func TestAddrList(t
*testing
.T
) {
218 if !supportsIPv4() ||
!supportsIPv6() {
219 t
.Skip("both IPv4 and IPv6 are required")
222 for i
, tt
:= range addrListTests
{
223 addrs
, err
:= filterAddrList(tt
.filter
, tt
.ips
, tt
.inetaddr
, "ADDR")
224 if !reflect
.DeepEqual(err
, tt
.err
) {
225 t
.Errorf("#%v: got %v; want %v", i
, err
, tt
.err
)
229 t
.Errorf("#%v: got %v; want 0", i
, len(addrs
))
233 first
:= addrs
.first(isIPv4
)
234 if !reflect
.DeepEqual(first
, tt
.first
) {
235 t
.Errorf("#%v: got %v; want %v", i
, first
, tt
.first
)
237 primaries
, fallbacks
:= addrs
.partition(isIPv4
)
238 if !reflect
.DeepEqual(primaries
, tt
.primaries
) {
239 t
.Errorf("#%v: got %v; want %v", i
, primaries
, tt
.primaries
)
241 if !reflect
.DeepEqual(fallbacks
, tt
.fallbacks
) {
242 t
.Errorf("#%v: got %v; want %v", i
, fallbacks
, tt
.fallbacks
)
244 expectedLen
:= len(primaries
) + len(fallbacks
)
245 if len(addrs
) != expectedLen
{
246 t
.Errorf("#%v: got %v; want %v", i
, len(addrs
), expectedLen
)
251 func TestAddrListPartition(t
*testing
.T
) {
253 &IPAddr
{IP
: ParseIP("fe80::"), Zone
: "eth0"},
254 &IPAddr
{IP
: ParseIP("fe80::1"), Zone
: "eth0"},
255 &IPAddr
{IP
: ParseIP("fe80::2"), Zone
: "eth0"},
262 {0, addrList
{addrs
[0]}, addrList
{addrs
[1], addrs
[2]}},
263 {1, addrList
{addrs
[0], addrs
[2]}, addrList
{addrs
[1]}},
264 {2, addrList
{addrs
[0], addrs
[1]}, addrList
{addrs
[2]}},
265 {3, addrList
{addrs
[0], addrs
[1], addrs
[2]}, nil},
267 for i
, tt
:= range cases
{
268 // Inverting the function's output should not affect the outcome.
269 for _
, invert
:= range []bool{false, true} {
270 primaries
, fallbacks
:= addrs
.partition(func(a Addr
) bool {
272 return (ip
[len(ip
)-1] == tt
.lastByte
) != invert
274 if !reflect
.DeepEqual(primaries
, tt
.primaries
) {
275 t
.Errorf("#%v: got %v; want %v", i
, primaries
, tt
.primaries
)
277 if !reflect
.DeepEqual(fallbacks
, tt
.fallbacks
) {
278 t
.Errorf("#%v: got %v; want %v", i
, fallbacks
, tt
.fallbacks
)