1
16
17 package util
18
19 import (
20 "net"
21 "reflect"
22 "testing"
23
24 v1 "k8s.io/api/core/v1"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/util/sets"
27 netutils "k8s.io/utils/net"
28 )
29
30 func TestValidateWorks(t *testing.T) {
31 if isValidEndpoint("", 0) {
32 t.Errorf("Didn't fail for empty set")
33 }
34 if isValidEndpoint("foobar", 0) {
35 t.Errorf("Didn't fail with invalid port")
36 }
37 if isValidEndpoint("foobar", -1) {
38 t.Errorf("Didn't fail with a negative port")
39 }
40 if !isValidEndpoint("foobar", 8080) {
41 t.Errorf("Failed a valid config.")
42 }
43 }
44
45 func TestBuildPortsToEndpointsMap(t *testing.T) {
46 endpoints := &v1.Endpoints{
47 ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "testnamespace"},
48 Subsets: []v1.EndpointSubset{
49 {
50 Addresses: []v1.EndpointAddress{
51 {IP: "10.0.0.1"},
52 {IP: "10.0.0.2"},
53 },
54 Ports: []v1.EndpointPort{
55 {Name: "http", Port: 80},
56 {Name: "https", Port: 443},
57 },
58 },
59 {
60 Addresses: []v1.EndpointAddress{
61 {IP: "10.0.0.1"},
62 {IP: "10.0.0.3"},
63 },
64 Ports: []v1.EndpointPort{
65 {Name: "http", Port: 8080},
66 {Name: "dns", Port: 53},
67 },
68 },
69 {
70 Addresses: []v1.EndpointAddress{},
71 Ports: []v1.EndpointPort{
72 {Name: "http", Port: 8888},
73 {Name: "ssh", Port: 22},
74 },
75 },
76 {
77 Addresses: []v1.EndpointAddress{
78 {IP: "10.0.0.1"},
79 },
80 Ports: []v1.EndpointPort{},
81 },
82 },
83 }
84 expectedPortsToEndpoints := map[string][]string{
85 "http": {"10.0.0.1:80", "10.0.0.2:80", "10.0.0.1:8080", "10.0.0.3:8080"},
86 "https": {"10.0.0.1:443", "10.0.0.2:443"},
87 "dns": {"10.0.0.1:53", "10.0.0.3:53"},
88 }
89
90 portsToEndpoints := BuildPortsToEndpointsMap(endpoints)
91 if !reflect.DeepEqual(expectedPortsToEndpoints, portsToEndpoints) {
92 t.Errorf("expected ports to endpoints not seen")
93 }
94 }
95
96 func TestShouldSkipService(t *testing.T) {
97 testCases := []struct {
98 service *v1.Service
99 shouldSkip bool
100 }{
101 {
102
103 service: &v1.Service{
104 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
105 Spec: v1.ServiceSpec{
106 ClusterIP: v1.ClusterIPNone,
107 },
108 },
109 shouldSkip: true,
110 },
111 {
112
113 service: &v1.Service{
114 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
115 Spec: v1.ServiceSpec{
116 ClusterIP: "",
117 },
118 },
119 shouldSkip: true,
120 },
121 {
122
123 service: &v1.Service{
124 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
125 Spec: v1.ServiceSpec{
126 ClusterIP: "1.2.3.4",
127 Type: v1.ServiceTypeExternalName,
128 },
129 },
130 shouldSkip: true,
131 },
132 {
133
134 service: &v1.Service{
135 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
136 Spec: v1.ServiceSpec{
137 ClusterIP: "1.2.3.4",
138 Type: v1.ServiceTypeClusterIP,
139 },
140 },
141 shouldSkip: false,
142 },
143 {
144
145 service: &v1.Service{
146 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
147 Spec: v1.ServiceSpec{
148 ClusterIP: "1.2.3.4",
149 Type: v1.ServiceTypeNodePort,
150 },
151 },
152 shouldSkip: false,
153 },
154 {
155
156 service: &v1.Service{
157 ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
158 Spec: v1.ServiceSpec{
159 ClusterIP: "1.2.3.4",
160 Type: v1.ServiceTypeLoadBalancer,
161 },
162 },
163 shouldSkip: false,
164 },
165 }
166
167 for i := range testCases {
168 skip := ShouldSkipService(testCases[i].service)
169 if skip != testCases[i].shouldSkip {
170 t.Errorf("case %d: expect %v, got %v", i, testCases[i].shouldSkip, skip)
171 }
172 }
173 }
174
175 func TestAppendPortIfNeeded(t *testing.T) {
176 testCases := []struct {
177 name string
178 addr string
179 port int32
180 expect string
181 }{
182 {
183 name: "IPv4 all-zeros bind address has port",
184 addr: "0.0.0.0:12345",
185 port: 23456,
186 expect: "0.0.0.0:12345",
187 },
188 {
189 name: "non-zeros IPv4 config",
190 addr: "9.8.7.6",
191 port: 12345,
192 expect: "9.8.7.6:12345",
193 },
194 {
195 name: "IPv6 \"[::]\" bind address has port",
196 addr: "[::]:12345",
197 port: 23456,
198 expect: "[::]:12345",
199 },
200 {
201 name: "IPv6 config",
202 addr: "fd00:1::5",
203 port: 23456,
204 expect: "[fd00:1::5]:23456",
205 },
206 {
207 name: "Invalid IPv6 Config",
208 addr: "[fd00:1::5]",
209 port: 12345,
210 expect: "[fd00:1::5]",
211 },
212 }
213
214 for i := range testCases {
215 got := AppendPortIfNeeded(testCases[i].addr, testCases[i].port)
216 if testCases[i].expect != got {
217 t.Errorf("case %s: expected %v, got %v", testCases[i].name, testCases[i].expect, got)
218 }
219 }
220 }
221
222 func TestShuffleStrings(t *testing.T) {
223 var src []string
224 dest := ShuffleStrings(src)
225
226 if dest != nil {
227 t.Errorf("ShuffleStrings for a nil slice got a non-nil slice")
228 }
229
230 src = []string{"a", "b", "c", "d", "e", "f"}
231 dest = ShuffleStrings(src)
232
233 if len(src) != len(dest) {
234 t.Errorf("Shuffled slice is wrong length, expected %v got %v", len(src), len(dest))
235 }
236
237 m := make(map[string]bool, len(dest))
238 for _, s := range dest {
239 m[s] = true
240 }
241
242 for _, k := range src {
243 if _, exists := m[k]; !exists {
244 t.Errorf("Element %v missing from shuffled slice", k)
245 }
246 }
247 }
248
249 func TestMapIPsByIPFamily(t *testing.T) {
250 testCases := []struct {
251 desc string
252 ipString []string
253 wantIPv6 bool
254 expectCorrect []string
255 expectIncorrect []string
256 }{
257 {
258 desc: "empty input IPv4",
259 ipString: []string{},
260 wantIPv6: false,
261 expectCorrect: nil,
262 expectIncorrect: nil,
263 },
264 {
265 desc: "empty input IPv6",
266 ipString: []string{},
267 wantIPv6: true,
268 expectCorrect: nil,
269 expectIncorrect: nil,
270 },
271 {
272 desc: "want IPv4 and receive IPv6",
273 ipString: []string{"fd00:20::1"},
274 wantIPv6: false,
275 expectCorrect: nil,
276 expectIncorrect: []string{"fd00:20::1"},
277 },
278 {
279 desc: "want IPv6 and receive IPv4",
280 ipString: []string{"192.168.200.2"},
281 wantIPv6: true,
282 expectCorrect: nil,
283 expectIncorrect: []string{"192.168.200.2"},
284 },
285 {
286 desc: "want IPv6 and receive IPv4 and IPv6",
287 ipString: []string{"192.168.200.2", "192.1.34.23", "fd00:20::1", "2001:db9::3"},
288 wantIPv6: true,
289 expectCorrect: []string{"fd00:20::1", "2001:db9::3"},
290 expectIncorrect: []string{"192.168.200.2", "192.1.34.23"},
291 },
292 {
293 desc: "want IPv4 and receive IPv4 and IPv6",
294 ipString: []string{"192.168.200.2", "192.1.34.23", "fd00:20::1", "2001:db9::3"},
295 wantIPv6: false,
296 expectCorrect: []string{"192.168.200.2", "192.1.34.23"},
297 expectIncorrect: []string{"fd00:20::1", "2001:db9::3"},
298 },
299 {
300 desc: "want IPv4 and receive IPv4 only",
301 ipString: []string{"192.168.200.2", "192.1.34.23"},
302 wantIPv6: false,
303 expectCorrect: []string{"192.168.200.2", "192.1.34.23"},
304 expectIncorrect: nil,
305 },
306 {
307 desc: "want IPv6 and receive IPv4 only",
308 ipString: []string{"192.168.200.2", "192.1.34.23"},
309 wantIPv6: true,
310 expectCorrect: nil,
311 expectIncorrect: []string{"192.168.200.2", "192.1.34.23"},
312 },
313 {
314 desc: "want IPv4 and receive IPv6 only",
315 ipString: []string{"fd00:20::1", "2001:db9::3"},
316 wantIPv6: false,
317 expectCorrect: nil,
318 expectIncorrect: []string{"fd00:20::1", "2001:db9::3"},
319 },
320 {
321 desc: "want IPv6 and receive IPv6 only",
322 ipString: []string{"fd00:20::1", "2001:db9::3"},
323 wantIPv6: true,
324 expectCorrect: []string{"fd00:20::1", "2001:db9::3"},
325 expectIncorrect: nil,
326 },
327 }
328
329 for _, testcase := range testCases {
330 t.Run(testcase.desc, func(t *testing.T) {
331 ipFamily := v1.IPv4Protocol
332 otherIPFamily := v1.IPv6Protocol
333
334 if testcase.wantIPv6 {
335 ipFamily = v1.IPv6Protocol
336 otherIPFamily = v1.IPv4Protocol
337 }
338
339 ipMap := MapIPsByIPFamily(testcase.ipString)
340
341 var ipStr []string
342 for _, ip := range ipMap[ipFamily] {
343 ipStr = append(ipStr, ip.String())
344 }
345 if !reflect.DeepEqual(testcase.expectCorrect, ipStr) {
346 t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectCorrect, ipMap[ipFamily])
347 }
348 ipStr = nil
349 for _, ip := range ipMap[otherIPFamily] {
350 ipStr = append(ipStr, ip.String())
351 }
352 if !reflect.DeepEqual(testcase.expectIncorrect, ipStr) {
353 t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectIncorrect, ipMap[otherIPFamily])
354 }
355 })
356 }
357 }
358
359 func TestMapCIDRsByIPFamily(t *testing.T) {
360 testCases := []struct {
361 desc string
362 ipString []string
363 wantIPv6 bool
364 expectCorrect []string
365 expectIncorrect []string
366 }{
367 {
368 desc: "empty input IPv4",
369 ipString: []string{},
370 wantIPv6: false,
371 expectCorrect: nil,
372 expectIncorrect: nil,
373 },
374 {
375 desc: "empty input IPv6",
376 ipString: []string{},
377 wantIPv6: true,
378 expectCorrect: nil,
379 expectIncorrect: nil,
380 },
381 {
382 desc: "want IPv4 and receive IPv6",
383 ipString: []string{"fd00:20::/64"},
384 wantIPv6: false,
385 expectCorrect: nil,
386 expectIncorrect: []string{"fd00:20::/64"},
387 },
388 {
389 desc: "want IPv6 and receive IPv4",
390 ipString: []string{"192.168.200.0/24"},
391 wantIPv6: true,
392 expectCorrect: nil,
393 expectIncorrect: []string{"192.168.200.0/24"},
394 },
395 {
396 desc: "want IPv6 and receive IPv4 and IPv6",
397 ipString: []string{"192.168.200.0/24", "192.1.34.0/24", "fd00:20::/64", "2001:db9::/64"},
398 wantIPv6: true,
399 expectCorrect: []string{"fd00:20::/64", "2001:db9::/64"},
400 expectIncorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
401 },
402 {
403 desc: "want IPv4 and receive IPv4 and IPv6",
404 ipString: []string{"192.168.200.0/24", "192.1.34.0/24", "fd00:20::/64", "2001:db9::/64"},
405 wantIPv6: false,
406 expectCorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
407 expectIncorrect: []string{"fd00:20::/64", "2001:db9::/64"},
408 },
409 {
410 desc: "want IPv4 and receive IPv4 only",
411 ipString: []string{"192.168.200.0/24", "192.1.34.0/24"},
412 wantIPv6: false,
413 expectCorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
414 expectIncorrect: nil,
415 },
416 {
417 desc: "want IPv6 and receive IPv4 only",
418 ipString: []string{"192.168.200.0/24", "192.1.34.0/24"},
419 wantIPv6: true,
420 expectCorrect: nil,
421 expectIncorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
422 },
423 {
424 desc: "want IPv4 and receive IPv6 only",
425 ipString: []string{"fd00:20::/64", "2001:db9::/64"},
426 wantIPv6: false,
427 expectCorrect: nil,
428 expectIncorrect: []string{"fd00:20::/64", "2001:db9::/64"},
429 },
430 {
431 desc: "want IPv6 and receive IPv6 only",
432 ipString: []string{"fd00:20::/64", "2001:db9::/64"},
433 wantIPv6: true,
434 expectCorrect: []string{"fd00:20::/64", "2001:db9::/64"},
435 expectIncorrect: nil,
436 },
437 }
438
439 for _, testcase := range testCases {
440 t.Run(testcase.desc, func(t *testing.T) {
441 ipFamily := v1.IPv4Protocol
442 otherIPFamily := v1.IPv6Protocol
443
444 if testcase.wantIPv6 {
445 ipFamily = v1.IPv6Protocol
446 otherIPFamily = v1.IPv4Protocol
447 }
448
449 cidrMap := MapCIDRsByIPFamily(testcase.ipString)
450
451 var cidrStr []string
452 for _, cidr := range cidrMap[ipFamily] {
453 cidrStr = append(cidrStr, cidr.String())
454 }
455 var cidrStrOther []string
456 for _, cidr := range cidrMap[otherIPFamily] {
457 cidrStrOther = append(cidrStrOther, cidr.String())
458 }
459
460 if !reflect.DeepEqual(testcase.expectCorrect, cidrStr) {
461 t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectCorrect, cidrStr)
462 }
463 if !reflect.DeepEqual(testcase.expectIncorrect, cidrStrOther) {
464 t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectIncorrect, cidrStrOther)
465 }
466 })
467 }
468 }
469
470 func TestGetClusterIPByFamily(t *testing.T) {
471 testCases := []struct {
472 name string
473 service v1.Service
474 requestFamily v1.IPFamily
475 expectedResult string
476 }{
477 {
478 name: "old style service ipv4. want ipv4",
479 requestFamily: v1.IPv4Protocol,
480 expectedResult: "10.0.0.10",
481 service: v1.Service{
482 Spec: v1.ServiceSpec{
483 ClusterIP: "10.0.0.10",
484 },
485 },
486 },
487
488 {
489 name: "old style service ipv4. want ipv6",
490 requestFamily: v1.IPv6Protocol,
491 expectedResult: "",
492 service: v1.Service{
493 Spec: v1.ServiceSpec{
494 ClusterIP: "10.0.0.10",
495 },
496 },
497 },
498
499 {
500 name: "old style service ipv6. want ipv6",
501 requestFamily: v1.IPv6Protocol,
502 expectedResult: "2000::1",
503 service: v1.Service{
504 Spec: v1.ServiceSpec{
505 ClusterIP: "2000::1",
506 },
507 },
508 },
509
510 {
511 name: "old style service ipv6. want ipv4",
512 requestFamily: v1.IPv4Protocol,
513 expectedResult: "",
514 service: v1.Service{
515 Spec: v1.ServiceSpec{
516 ClusterIP: "2000::1",
517 },
518 },
519 },
520
521 {
522 name: "service single stack ipv4. want ipv4",
523 requestFamily: v1.IPv4Protocol,
524 expectedResult: "10.0.0.10",
525 service: v1.Service{
526 Spec: v1.ServiceSpec{
527 ClusterIPs: []string{"10.0.0.10"},
528 IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
529 },
530 },
531 },
532
533 {
534 name: "service single stack ipv4. want ipv6",
535 requestFamily: v1.IPv6Protocol,
536 expectedResult: "",
537 service: v1.Service{
538 Spec: v1.ServiceSpec{
539 ClusterIPs: []string{"10.0.0.10"},
540 IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
541 },
542 },
543 },
544
545 {
546 name: "service single stack ipv6. want ipv6",
547 requestFamily: v1.IPv6Protocol,
548 expectedResult: "2000::1",
549 service: v1.Service{
550 Spec: v1.ServiceSpec{
551 ClusterIPs: []string{"2000::1"},
552 IPFamilies: []v1.IPFamily{v1.IPv6Protocol},
553 },
554 },
555 },
556
557 {
558 name: "service single stack ipv6. want ipv4",
559 requestFamily: v1.IPv4Protocol,
560 expectedResult: "",
561 service: v1.Service{
562 Spec: v1.ServiceSpec{
563 ClusterIPs: []string{"2000::1"},
564 IPFamilies: []v1.IPFamily{v1.IPv6Protocol},
565 },
566 },
567 },
568
569 {
570 name: "service dual stack ipv4,6. want ipv4",
571 requestFamily: v1.IPv4Protocol,
572 expectedResult: "10.0.0.10",
573 service: v1.Service{
574 Spec: v1.ServiceSpec{
575 ClusterIPs: []string{"10.0.0.10", "2000::1"},
576 IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
577 },
578 },
579 },
580
581 {
582 name: "service dual stack ipv4,6. want ipv6",
583 requestFamily: v1.IPv6Protocol,
584 expectedResult: "2000::1",
585 service: v1.Service{
586 Spec: v1.ServiceSpec{
587 ClusterIPs: []string{"10.0.0.10", "2000::1"},
588 IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
589 },
590 },
591 },
592
593 {
594 name: "service dual stack ipv6,4. want ipv6",
595 requestFamily: v1.IPv6Protocol,
596 expectedResult: "2000::1",
597 service: v1.Service{
598 Spec: v1.ServiceSpec{
599 ClusterIPs: []string{"2000::1", "10.0.0.10"},
600 IPFamilies: []v1.IPFamily{v1.IPv6Protocol, v1.IPv4Protocol},
601 },
602 },
603 },
604
605 {
606 name: "service dual stack ipv6,4. want ipv4",
607 requestFamily: v1.IPv4Protocol,
608 expectedResult: "10.0.0.10",
609 service: v1.Service{
610 Spec: v1.ServiceSpec{
611 ClusterIPs: []string{"2000::1", "10.0.0.10"},
612 IPFamilies: []v1.IPFamily{v1.IPv6Protocol, v1.IPv4Protocol},
613 },
614 },
615 },
616 }
617
618 for _, testCase := range testCases {
619 t.Run(testCase.name, func(t *testing.T) {
620 ip := GetClusterIPByFamily(testCase.requestFamily, &testCase.service)
621 if ip != testCase.expectedResult {
622 t.Fatalf("expected ip:%v got %v", testCase.expectedResult, ip)
623 }
624 })
625 }
626 }
627
628 type fakeClosable struct {
629 closed bool
630 }
631
632 func (c *fakeClosable) Close() error {
633 c.closed = true
634 return nil
635 }
636
637 func TestRevertPorts(t *testing.T) {
638 testCases := []struct {
639 replacementPorts []netutils.LocalPort
640 existingPorts []netutils.LocalPort
641 expectToBeClose []bool
642 }{
643 {
644 replacementPorts: []netutils.LocalPort{
645 {Port: 5001},
646 {Port: 5002},
647 {Port: 5003},
648 },
649 existingPorts: []netutils.LocalPort{},
650 expectToBeClose: []bool{true, true, true},
651 },
652 {
653 replacementPorts: []netutils.LocalPort{},
654 existingPorts: []netutils.LocalPort{
655 {Port: 5001},
656 {Port: 5002},
657 {Port: 5003},
658 },
659 expectToBeClose: []bool{},
660 },
661 {
662 replacementPorts: []netutils.LocalPort{
663 {Port: 5001},
664 {Port: 5002},
665 {Port: 5003},
666 },
667 existingPorts: []netutils.LocalPort{
668 {Port: 5001},
669 {Port: 5002},
670 {Port: 5003},
671 },
672 expectToBeClose: []bool{false, false, false},
673 },
674 {
675 replacementPorts: []netutils.LocalPort{
676 {Port: 5001},
677 {Port: 5002},
678 {Port: 5003},
679 },
680 existingPorts: []netutils.LocalPort{
681 {Port: 5001},
682 {Port: 5003},
683 },
684 expectToBeClose: []bool{false, true, false},
685 },
686 {
687 replacementPorts: []netutils.LocalPort{
688 {Port: 5001},
689 {Port: 5002},
690 {Port: 5003},
691 },
692 existingPorts: []netutils.LocalPort{
693 {Port: 5001},
694 {Port: 5002},
695 {Port: 5003},
696 {Port: 5004},
697 },
698 expectToBeClose: []bool{false, false, false},
699 },
700 }
701
702 for i, tc := range testCases {
703 replacementPortsMap := make(map[netutils.LocalPort]netutils.Closeable)
704 for _, lp := range tc.replacementPorts {
705 replacementPortsMap[lp] = &fakeClosable{}
706 }
707 existingPortsMap := make(map[netutils.LocalPort]netutils.Closeable)
708 for _, lp := range tc.existingPorts {
709 existingPortsMap[lp] = &fakeClosable{}
710 }
711 RevertPorts(replacementPortsMap, existingPortsMap)
712 for j, expectation := range tc.expectToBeClose {
713 if replacementPortsMap[tc.replacementPorts[j]].(*fakeClosable).closed != expectation {
714 t.Errorf("Expect replacement localport %v to be %v in test case %v", tc.replacementPorts[j], expectation, i)
715 }
716 }
717 for _, lp := range tc.existingPorts {
718 if existingPortsMap[lp].(*fakeClosable).closed {
719 t.Errorf("Expect existing localport %v to be false in test case %v", lp, i)
720 }
721 }
722 }
723 }
724
725 func mustParseIPAddr(str string) net.Addr {
726 a, err := net.ResolveIPAddr("ip", str)
727 if err != nil {
728 panic("mustParseIPAddr")
729 }
730 return a
731 }
732 func mustParseIPNet(str string) net.Addr {
733 _, n, err := netutils.ParseCIDRSloppy(str)
734 if err != nil {
735 panic("mustParseIPNet")
736 }
737 return n
738 }
739 func mustParseUnix(str string) net.Addr {
740 n, err := net.ResolveUnixAddr("unix", str)
741 if err != nil {
742 panic("mustParseUnix")
743 }
744 return n
745 }
746
747 type cidrValidator struct {
748 cidr *net.IPNet
749 }
750
751 func (v *cidrValidator) isValid(ip net.IP) bool {
752 return v.cidr.Contains(ip)
753 }
754 func newCidrValidator(cidr string) func(ip net.IP) bool {
755 _, n, err := netutils.ParseCIDRSloppy(cidr)
756 if err != nil {
757 panic("mustParseIPNet")
758 }
759 obj := cidrValidator{n}
760 return obj.isValid
761 }
762
763 func TestAddressSet(t *testing.T) {
764 testCases := []struct {
765 name string
766 validator func(ip net.IP) bool
767 input []net.Addr
768 expected sets.Set[string]
769 }{
770 {
771 "Empty",
772 func(ip net.IP) bool { return false },
773 nil,
774 nil,
775 },
776 {
777 "Reject IPAddr x 2",
778 func(ip net.IP) bool { return false },
779 []net.Addr{
780 mustParseIPAddr("8.8.8.8"),
781 mustParseIPAddr("1000::"),
782 },
783 nil,
784 },
785 {
786 "Accept IPAddr x 2",
787 func(ip net.IP) bool { return true },
788 []net.Addr{
789 mustParseIPAddr("8.8.8.8"),
790 mustParseIPAddr("1000::"),
791 },
792 sets.New("8.8.8.8", "1000::"),
793 },
794 {
795 "Accept IPNet x 2",
796 func(ip net.IP) bool { return true },
797 []net.Addr{
798 mustParseIPNet("8.8.8.8/32"),
799 mustParseIPNet("1000::/128"),
800 },
801 sets.New("8.8.8.8", "1000::"),
802 },
803 {
804 "Accept Unix x 2",
805 func(ip net.IP) bool { return true },
806 []net.Addr{
807 mustParseUnix("/tmp/sock1"),
808 mustParseUnix("/tmp/sock2"),
809 },
810 nil,
811 },
812 {
813 "Cidr IPv4",
814 newCidrValidator("192.168.1.0/24"),
815 []net.Addr{
816 mustParseIPAddr("8.8.8.8"),
817 mustParseIPAddr("1000::"),
818 mustParseIPAddr("192.168.1.1"),
819 },
820 sets.New("192.168.1.1"),
821 },
822 {
823 "Cidr IPv6",
824 newCidrValidator("1000::/64"),
825 []net.Addr{
826 mustParseIPAddr("8.8.8.8"),
827 mustParseIPAddr("1000::"),
828 mustParseIPAddr("192.168.1.1"),
829 },
830 sets.New("1000::"),
831 },
832 }
833
834 for _, tc := range testCases {
835 if !tc.expected.Equal(AddressSet(tc.validator, tc.input)) {
836 t.Errorf("%s", tc.name)
837 }
838 }
839 }
840
841 func TestIsZeroCIDR(t *testing.T) {
842 testCases := []struct {
843 name string
844 input string
845 expected bool
846 }{
847 {
848 name: "invalide cidr",
849 input: "",
850 expected: false,
851 },
852 {
853 name: "ipv4 cidr",
854 input: "172.10.0.0/16",
855 expected: false,
856 },
857 {
858 name: "ipv4 zero cidr",
859 input: IPv4ZeroCIDR,
860 expected: true,
861 },
862 {
863 name: "ipv6 cidr",
864 input: "::/128",
865 expected: false,
866 },
867 {
868 name: "ipv6 zero cidr",
869 input: IPv6ZeroCIDR,
870 expected: true,
871 },
872 }
873 for _, tc := range testCases {
874 t.Run(tc.name, func(t *testing.T) {
875 if got := IsZeroCIDR(tc.input); tc.expected != got {
876 t.Errorf("IsZeroCIDR() = %t, want %t", got, tc.expected)
877 }
878 })
879 }
880 }
881
View as plain text