Source file
src/net/ipsock_test.go
1
2
3
4
5 package net
6
7 import (
8 "reflect"
9 "testing"
10 )
11
12 var testInetaddr = func(ip IPAddr) Addr { return &TCPAddr{IP: ip.IP, Port: 5682, Zone: ip.Zone} }
13
14 var addrListTests = []struct {
15 filter func(IPAddr) bool
16 ips []IPAddr
17 inetaddr func(IPAddr) Addr
18 first Addr
19 primaries addrList
20 fallbacks addrList
21 err error
22 }{
23 {
24 nil,
25 []IPAddr{
26 {IP: IPv4(127, 0, 0, 1)},
27 {IP: IPv6loopback},
28 },
29 testInetaddr,
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}},
33 nil,
34 },
35 {
36 nil,
37 []IPAddr{
38 {IP: IPv6loopback},
39 {IP: IPv4(127, 0, 0, 1)},
40 },
41 testInetaddr,
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}},
45 nil,
46 },
47 {
48 nil,
49 []IPAddr{
50 {IP: IPv4(127, 0, 0, 1)},
51 {IP: IPv4(192, 168, 0, 1)},
52 },
53 testInetaddr,
54 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
55 addrList{
56 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
57 &TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
58 },
59 nil,
60 nil,
61 },
62 {
63 nil,
64 []IPAddr{
65 {IP: IPv6loopback},
66 {IP: ParseIP("fe80::1"), Zone: "eth0"},
67 },
68 testInetaddr,
69 &TCPAddr{IP: IPv6loopback, Port: 5682},
70 addrList{
71 &TCPAddr{IP: IPv6loopback, Port: 5682},
72 &TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
73 },
74 nil,
75 nil,
76 },
77 {
78 nil,
79 []IPAddr{
80 {IP: IPv4(127, 0, 0, 1)},
81 {IP: IPv4(192, 168, 0, 1)},
82 {IP: IPv6loopback},
83 {IP: ParseIP("fe80::1"), Zone: "eth0"},
84 },
85 testInetaddr,
86 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
87 addrList{
88 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
89 &TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
90 },
91 addrList{
92 &TCPAddr{IP: IPv6loopback, Port: 5682},
93 &TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
94 },
95 nil,
96 },
97 {
98 nil,
99 []IPAddr{
100 {IP: IPv6loopback},
101 {IP: ParseIP("fe80::1"), Zone: "eth0"},
102 {IP: IPv4(127, 0, 0, 1)},
103 {IP: IPv4(192, 168, 0, 1)},
104 },
105 testInetaddr,
106 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
107 addrList{
108 &TCPAddr{IP: IPv6loopback, Port: 5682},
109 &TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
110 },
111 addrList{
112 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
113 &TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
114 },
115 nil,
116 },
117 {
118 nil,
119 []IPAddr{
120 {IP: IPv4(127, 0, 0, 1)},
121 {IP: IPv6loopback},
122 {IP: IPv4(192, 168, 0, 1)},
123 {IP: ParseIP("fe80::1"), Zone: "eth0"},
124 },
125 testInetaddr,
126 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
127 addrList{
128 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
129 &TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
130 },
131 addrList{
132 &TCPAddr{IP: IPv6loopback, Port: 5682},
133 &TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
134 },
135 nil,
136 },
137 {
138 nil,
139 []IPAddr{
140 {IP: IPv6loopback},
141 {IP: IPv4(127, 0, 0, 1)},
142 {IP: ParseIP("fe80::1"), Zone: "eth0"},
143 {IP: IPv4(192, 168, 0, 1)},
144 },
145 testInetaddr,
146 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
147 addrList{
148 &TCPAddr{IP: IPv6loopback, Port: 5682},
149 &TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
150 },
151 addrList{
152 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
153 &TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
154 },
155 nil,
156 },
157
158 {
159 ipv4only,
160 []IPAddr{
161 {IP: IPv4(127, 0, 0, 1)},
162 {IP: IPv6loopback},
163 },
164 testInetaddr,
165 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
166 addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
167 nil,
168 nil,
169 },
170 {
171 ipv4only,
172 []IPAddr{
173 {IP: IPv6loopback},
174 {IP: IPv4(127, 0, 0, 1)},
175 },
176 testInetaddr,
177 &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
178 addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
179 nil,
180 nil,
181 },
182
183 {
184 ipv6only,
185 []IPAddr{
186 {IP: IPv4(127, 0, 0, 1)},
187 {IP: IPv6loopback},
188 },
189 testInetaddr,
190 &TCPAddr{IP: IPv6loopback, Port: 5682},
191 addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
192 nil,
193 nil,
194 },
195 {
196 ipv6only,
197 []IPAddr{
198 {IP: IPv6loopback},
199 {IP: IPv4(127, 0, 0, 1)},
200 },
201 testInetaddr,
202 &TCPAddr{IP: IPv6loopback, Port: 5682},
203 addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
204 nil,
205 nil,
206 },
207
208 {nil, nil, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
209
210 {ipv4only, nil, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
211 {ipv4only, []IPAddr{{IP: IPv6loopback}}, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
212
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"}},
215 }
216
217 func TestAddrList(t *testing.T) {
218 if !supportsIPv4() || !supportsIPv6() {
219 t.Skip("both IPv4 and IPv6 are required")
220 }
221
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)
226 }
227 if tt.err != nil {
228 if len(addrs) != 0 {
229 t.Errorf("#%v: got %v; want 0", i, len(addrs))
230 }
231 continue
232 }
233 first := addrs.first(isIPv4)
234 if !reflect.DeepEqual(first, tt.first) {
235 t.Errorf("#%v: got %v; want %v", i, first, tt.first)
236 }
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)
240 }
241 if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
242 t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
243 }
244 expectedLen := len(primaries) + len(fallbacks)
245 if len(addrs) != expectedLen {
246 t.Errorf("#%v: got %v; want %v", i, len(addrs), expectedLen)
247 }
248 }
249 }
250
251 func TestAddrListPartition(t *testing.T) {
252 addrs := addrList{
253 &IPAddr{IP: ParseIP("fe80::"), Zone: "eth0"},
254 &IPAddr{IP: ParseIP("fe80::1"), Zone: "eth0"},
255 &IPAddr{IP: ParseIP("fe80::2"), Zone: "eth0"},
256 }
257 cases := []struct {
258 lastByte byte
259 primaries addrList
260 fallbacks addrList
261 }{
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},
266 }
267 for i, tt := range cases {
268
269 for _, invert := range []bool{false, true} {
270 primaries, fallbacks := addrs.partition(func(a Addr) bool {
271 ip := a.(*IPAddr).IP
272 return (ip[len(ip)-1] == tt.lastByte) != invert
273 })
274 if !reflect.DeepEqual(primaries, tt.primaries) {
275 t.Errorf("#%v: got %v; want %v", i, primaries, tt.primaries)
276 }
277 if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
278 t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
279 }
280 }
281 }
282 }
283
View as plain text