k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/proxy/util/utils_test.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    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 TestShouldSkipService(t *testing.T) {
    46  	testCases := []struct {
    47  		service    *v1.Service
    48  		shouldSkip bool
    49  	}{
    50  		{
    51  			// Cluster IP is None
    52  			service: &v1.Service{
    53  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
    54  				Spec: v1.ServiceSpec{
    55  					ClusterIP: v1.ClusterIPNone,
    56  				},
    57  			},
    58  			shouldSkip: true,
    59  		},
    60  		{
    61  			// Cluster IP is empty
    62  			service: &v1.Service{
    63  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
    64  				Spec: v1.ServiceSpec{
    65  					ClusterIP: "",
    66  				},
    67  			},
    68  			shouldSkip: true,
    69  		},
    70  		{
    71  			// ExternalName type service
    72  			service: &v1.Service{
    73  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
    74  				Spec: v1.ServiceSpec{
    75  					ClusterIP: "1.2.3.4",
    76  					Type:      v1.ServiceTypeExternalName,
    77  				},
    78  			},
    79  			shouldSkip: true,
    80  		},
    81  		{
    82  			// ClusterIP type service with ClusterIP set
    83  			service: &v1.Service{
    84  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
    85  				Spec: v1.ServiceSpec{
    86  					ClusterIP: "1.2.3.4",
    87  					Type:      v1.ServiceTypeClusterIP,
    88  				},
    89  			},
    90  			shouldSkip: false,
    91  		},
    92  		{
    93  			// NodePort type service with ClusterIP set
    94  			service: &v1.Service{
    95  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
    96  				Spec: v1.ServiceSpec{
    97  					ClusterIP: "1.2.3.4",
    98  					Type:      v1.ServiceTypeNodePort,
    99  				},
   100  			},
   101  			shouldSkip: false,
   102  		},
   103  		{
   104  			// LoadBalancer type service with ClusterIP set
   105  			service: &v1.Service{
   106  				ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
   107  				Spec: v1.ServiceSpec{
   108  					ClusterIP: "1.2.3.4",
   109  					Type:      v1.ServiceTypeLoadBalancer,
   110  				},
   111  			},
   112  			shouldSkip: false,
   113  		},
   114  	}
   115  
   116  	for i := range testCases {
   117  		skip := ShouldSkipService(testCases[i].service)
   118  		if skip != testCases[i].shouldSkip {
   119  			t.Errorf("case %d: expect %v, got %v", i, testCases[i].shouldSkip, skip)
   120  		}
   121  	}
   122  }
   123  
   124  func TestAppendPortIfNeeded(t *testing.T) {
   125  	testCases := []struct {
   126  		name   string
   127  		addr   string
   128  		port   int32
   129  		expect string
   130  	}{
   131  		{
   132  			name:   "IPv4 all-zeros bind address has port",
   133  			addr:   "0.0.0.0:12345",
   134  			port:   23456,
   135  			expect: "0.0.0.0:12345",
   136  		},
   137  		{
   138  			name:   "non-zeros IPv4 config",
   139  			addr:   "9.8.7.6",
   140  			port:   12345,
   141  			expect: "9.8.7.6:12345",
   142  		},
   143  		{
   144  			name:   "IPv6 \"[::]\" bind address has port",
   145  			addr:   "[::]:12345",
   146  			port:   23456,
   147  			expect: "[::]:12345",
   148  		},
   149  		{
   150  			name:   "IPv6 config",
   151  			addr:   "fd00:1::5",
   152  			port:   23456,
   153  			expect: "[fd00:1::5]:23456",
   154  		},
   155  		{
   156  			name:   "Invalid IPv6 Config",
   157  			addr:   "[fd00:1::5]",
   158  			port:   12345,
   159  			expect: "[fd00:1::5]",
   160  		},
   161  	}
   162  
   163  	for i := range testCases {
   164  		got := AppendPortIfNeeded(testCases[i].addr, testCases[i].port)
   165  		if testCases[i].expect != got {
   166  			t.Errorf("case %s: expected %v, got %v", testCases[i].name, testCases[i].expect, got)
   167  		}
   168  	}
   169  }
   170  
   171  func TestMapIPsByIPFamily(t *testing.T) {
   172  	testCases := []struct {
   173  		desc            string
   174  		ipString        []string
   175  		wantIPv6        bool
   176  		expectCorrect   []string
   177  		expectIncorrect []string
   178  	}{
   179  		{
   180  			desc:            "empty input IPv4",
   181  			ipString:        []string{},
   182  			wantIPv6:        false,
   183  			expectCorrect:   nil,
   184  			expectIncorrect: nil,
   185  		},
   186  		{
   187  			desc:            "empty input IPv6",
   188  			ipString:        []string{},
   189  			wantIPv6:        true,
   190  			expectCorrect:   nil,
   191  			expectIncorrect: nil,
   192  		},
   193  		{
   194  			desc:            "want IPv4 and receive IPv6",
   195  			ipString:        []string{"fd00:20::1"},
   196  			wantIPv6:        false,
   197  			expectCorrect:   nil,
   198  			expectIncorrect: []string{"fd00:20::1"},
   199  		},
   200  		{
   201  			desc:            "want IPv6 and receive IPv4",
   202  			ipString:        []string{"192.168.200.2"},
   203  			wantIPv6:        true,
   204  			expectCorrect:   nil,
   205  			expectIncorrect: []string{"192.168.200.2"},
   206  		},
   207  		{
   208  			desc:            "want IPv6 and receive IPv4 and IPv6",
   209  			ipString:        []string{"192.168.200.2", "192.1.34.23", "fd00:20::1", "2001:db9::3"},
   210  			wantIPv6:        true,
   211  			expectCorrect:   []string{"fd00:20::1", "2001:db9::3"},
   212  			expectIncorrect: []string{"192.168.200.2", "192.1.34.23"},
   213  		},
   214  		{
   215  			desc:            "want IPv4 and receive IPv4 and IPv6",
   216  			ipString:        []string{"192.168.200.2", "192.1.34.23", "fd00:20::1", "2001:db9::3"},
   217  			wantIPv6:        false,
   218  			expectCorrect:   []string{"192.168.200.2", "192.1.34.23"},
   219  			expectIncorrect: []string{"fd00:20::1", "2001:db9::3"},
   220  		},
   221  		{
   222  			desc:            "want IPv4 and receive IPv4 only",
   223  			ipString:        []string{"192.168.200.2", "192.1.34.23"},
   224  			wantIPv6:        false,
   225  			expectCorrect:   []string{"192.168.200.2", "192.1.34.23"},
   226  			expectIncorrect: nil,
   227  		},
   228  		{
   229  			desc:            "want IPv6 and receive IPv4 only",
   230  			ipString:        []string{"192.168.200.2", "192.1.34.23"},
   231  			wantIPv6:        true,
   232  			expectCorrect:   nil,
   233  			expectIncorrect: []string{"192.168.200.2", "192.1.34.23"},
   234  		},
   235  		{
   236  			desc:            "want IPv4 and receive IPv6 only",
   237  			ipString:        []string{"fd00:20::1", "2001:db9::3"},
   238  			wantIPv6:        false,
   239  			expectCorrect:   nil,
   240  			expectIncorrect: []string{"fd00:20::1", "2001:db9::3"},
   241  		},
   242  		{
   243  			desc:            "want IPv6 and receive IPv6 only",
   244  			ipString:        []string{"fd00:20::1", "2001:db9::3"},
   245  			wantIPv6:        true,
   246  			expectCorrect:   []string{"fd00:20::1", "2001:db9::3"},
   247  			expectIncorrect: nil,
   248  		},
   249  	}
   250  
   251  	for _, testcase := range testCases {
   252  		t.Run(testcase.desc, func(t *testing.T) {
   253  			ipFamily := v1.IPv4Protocol
   254  			otherIPFamily := v1.IPv6Protocol
   255  
   256  			if testcase.wantIPv6 {
   257  				ipFamily = v1.IPv6Protocol
   258  				otherIPFamily = v1.IPv4Protocol
   259  			}
   260  
   261  			ipMap := MapIPsByIPFamily(testcase.ipString)
   262  
   263  			var ipStr []string
   264  			for _, ip := range ipMap[ipFamily] {
   265  				ipStr = append(ipStr, ip.String())
   266  			}
   267  			if !reflect.DeepEqual(testcase.expectCorrect, ipStr) {
   268  				t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectCorrect, ipMap[ipFamily])
   269  			}
   270  			ipStr = nil
   271  			for _, ip := range ipMap[otherIPFamily] {
   272  				ipStr = append(ipStr, ip.String())
   273  			}
   274  			if !reflect.DeepEqual(testcase.expectIncorrect, ipStr) {
   275  				t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectIncorrect, ipMap[otherIPFamily])
   276  			}
   277  		})
   278  	}
   279  }
   280  
   281  func TestMapCIDRsByIPFamily(t *testing.T) {
   282  	testCases := []struct {
   283  		desc            string
   284  		ipString        []string
   285  		wantIPv6        bool
   286  		expectCorrect   []string
   287  		expectIncorrect []string
   288  	}{
   289  		{
   290  			desc:            "empty input IPv4",
   291  			ipString:        []string{},
   292  			wantIPv6:        false,
   293  			expectCorrect:   nil,
   294  			expectIncorrect: nil,
   295  		},
   296  		{
   297  			desc:            "empty input IPv6",
   298  			ipString:        []string{},
   299  			wantIPv6:        true,
   300  			expectCorrect:   nil,
   301  			expectIncorrect: nil,
   302  		},
   303  		{
   304  			desc:            "want IPv4 and receive IPv6",
   305  			ipString:        []string{"fd00:20::/64"},
   306  			wantIPv6:        false,
   307  			expectCorrect:   nil,
   308  			expectIncorrect: []string{"fd00:20::/64"},
   309  		},
   310  		{
   311  			desc:            "want IPv6 and receive IPv4",
   312  			ipString:        []string{"192.168.200.0/24"},
   313  			wantIPv6:        true,
   314  			expectCorrect:   nil,
   315  			expectIncorrect: []string{"192.168.200.0/24"},
   316  		},
   317  		{
   318  			desc:            "want IPv6 and receive IPv4 and IPv6",
   319  			ipString:        []string{"192.168.200.0/24", "192.1.34.0/24", "fd00:20::/64", "2001:db9::/64"},
   320  			wantIPv6:        true,
   321  			expectCorrect:   []string{"fd00:20::/64", "2001:db9::/64"},
   322  			expectIncorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
   323  		},
   324  		{
   325  			desc:            "want IPv4 and receive IPv4 and IPv6",
   326  			ipString:        []string{"192.168.200.0/24", "192.1.34.0/24", "fd00:20::/64", "2001:db9::/64"},
   327  			wantIPv6:        false,
   328  			expectCorrect:   []string{"192.168.200.0/24", "192.1.34.0/24"},
   329  			expectIncorrect: []string{"fd00:20::/64", "2001:db9::/64"},
   330  		},
   331  		{
   332  			desc:            "want IPv4 and receive IPv4 only",
   333  			ipString:        []string{"192.168.200.0/24", "192.1.34.0/24"},
   334  			wantIPv6:        false,
   335  			expectCorrect:   []string{"192.168.200.0/24", "192.1.34.0/24"},
   336  			expectIncorrect: nil,
   337  		},
   338  		{
   339  			desc:            "want IPv6 and receive IPv4 only",
   340  			ipString:        []string{"192.168.200.0/24", "192.1.34.0/24"},
   341  			wantIPv6:        true,
   342  			expectCorrect:   nil,
   343  			expectIncorrect: []string{"192.168.200.0/24", "192.1.34.0/24"},
   344  		},
   345  		{
   346  			desc:            "want IPv4 and receive IPv6 only",
   347  			ipString:        []string{"fd00:20::/64", "2001:db9::/64"},
   348  			wantIPv6:        false,
   349  			expectCorrect:   nil,
   350  			expectIncorrect: []string{"fd00:20::/64", "2001:db9::/64"},
   351  		},
   352  		{
   353  			desc:            "want IPv6 and receive IPv6 only",
   354  			ipString:        []string{"fd00:20::/64", "2001:db9::/64"},
   355  			wantIPv6:        true,
   356  			expectCorrect:   []string{"fd00:20::/64", "2001:db9::/64"},
   357  			expectIncorrect: nil,
   358  		},
   359  	}
   360  
   361  	for _, testcase := range testCases {
   362  		t.Run(testcase.desc, func(t *testing.T) {
   363  			ipFamily := v1.IPv4Protocol
   364  			otherIPFamily := v1.IPv6Protocol
   365  
   366  			if testcase.wantIPv6 {
   367  				ipFamily = v1.IPv6Protocol
   368  				otherIPFamily = v1.IPv4Protocol
   369  			}
   370  
   371  			cidrMap := MapCIDRsByIPFamily(testcase.ipString)
   372  
   373  			var cidrStr []string
   374  			for _, cidr := range cidrMap[ipFamily] {
   375  				cidrStr = append(cidrStr, cidr.String())
   376  			}
   377  			var cidrStrOther []string
   378  			for _, cidr := range cidrMap[otherIPFamily] {
   379  				cidrStrOther = append(cidrStrOther, cidr.String())
   380  			}
   381  
   382  			if !reflect.DeepEqual(testcase.expectCorrect, cidrStr) {
   383  				t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectCorrect, cidrStr)
   384  			}
   385  			if !reflect.DeepEqual(testcase.expectIncorrect, cidrStrOther) {
   386  				t.Errorf("Test %v failed: expected %v, got %v", testcase.desc, testcase.expectIncorrect, cidrStrOther)
   387  			}
   388  		})
   389  	}
   390  }
   391  
   392  func TestGetClusterIPByFamily(t *testing.T) {
   393  	testCases := []struct {
   394  		name           string
   395  		service        v1.Service
   396  		requestFamily  v1.IPFamily
   397  		expectedResult string
   398  	}{
   399  		{
   400  			name:           "old style service ipv4. want ipv4",
   401  			requestFamily:  v1.IPv4Protocol,
   402  			expectedResult: "10.0.0.10",
   403  			service: v1.Service{
   404  				Spec: v1.ServiceSpec{
   405  					ClusterIP: "10.0.0.10",
   406  				},
   407  			},
   408  		},
   409  
   410  		{
   411  			name:           "old style service ipv4. want ipv6",
   412  			requestFamily:  v1.IPv6Protocol,
   413  			expectedResult: "",
   414  			service: v1.Service{
   415  				Spec: v1.ServiceSpec{
   416  					ClusterIP: "10.0.0.10",
   417  				},
   418  			},
   419  		},
   420  
   421  		{
   422  			name:           "old style service ipv6. want ipv6",
   423  			requestFamily:  v1.IPv6Protocol,
   424  			expectedResult: "2000::1",
   425  			service: v1.Service{
   426  				Spec: v1.ServiceSpec{
   427  					ClusterIP: "2000::1",
   428  				},
   429  			},
   430  		},
   431  
   432  		{
   433  			name:           "old style service ipv6. want ipv4",
   434  			requestFamily:  v1.IPv4Protocol,
   435  			expectedResult: "",
   436  			service: v1.Service{
   437  				Spec: v1.ServiceSpec{
   438  					ClusterIP: "2000::1",
   439  				},
   440  			},
   441  		},
   442  
   443  		{
   444  			name:           "service single stack ipv4. want ipv4",
   445  			requestFamily:  v1.IPv4Protocol,
   446  			expectedResult: "10.0.0.10",
   447  			service: v1.Service{
   448  				Spec: v1.ServiceSpec{
   449  					ClusterIPs: []string{"10.0.0.10"},
   450  					IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
   451  				},
   452  			},
   453  		},
   454  
   455  		{
   456  			name:           "service single stack ipv4. want ipv6",
   457  			requestFamily:  v1.IPv6Protocol,
   458  			expectedResult: "",
   459  			service: v1.Service{
   460  				Spec: v1.ServiceSpec{
   461  					ClusterIPs: []string{"10.0.0.10"},
   462  					IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
   463  				},
   464  			},
   465  		},
   466  
   467  		{
   468  			name:           "service single stack ipv6. want ipv6",
   469  			requestFamily:  v1.IPv6Protocol,
   470  			expectedResult: "2000::1",
   471  			service: v1.Service{
   472  				Spec: v1.ServiceSpec{
   473  					ClusterIPs: []string{"2000::1"},
   474  					IPFamilies: []v1.IPFamily{v1.IPv6Protocol},
   475  				},
   476  			},
   477  		},
   478  
   479  		{
   480  			name:           "service single stack ipv6. want ipv4",
   481  			requestFamily:  v1.IPv4Protocol,
   482  			expectedResult: "",
   483  			service: v1.Service{
   484  				Spec: v1.ServiceSpec{
   485  					ClusterIPs: []string{"2000::1"},
   486  					IPFamilies: []v1.IPFamily{v1.IPv6Protocol},
   487  				},
   488  			},
   489  		},
   490  		// dual stack
   491  		{
   492  			name:           "service dual stack ipv4,6. want ipv4",
   493  			requestFamily:  v1.IPv4Protocol,
   494  			expectedResult: "10.0.0.10",
   495  			service: v1.Service{
   496  				Spec: v1.ServiceSpec{
   497  					ClusterIPs: []string{"10.0.0.10", "2000::1"},
   498  					IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
   499  				},
   500  			},
   501  		},
   502  
   503  		{
   504  			name:           "service dual stack ipv4,6. want ipv6",
   505  			requestFamily:  v1.IPv6Protocol,
   506  			expectedResult: "2000::1",
   507  			service: v1.Service{
   508  				Spec: v1.ServiceSpec{
   509  					ClusterIPs: []string{"10.0.0.10", "2000::1"},
   510  					IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
   511  				},
   512  			},
   513  		},
   514  
   515  		{
   516  			name:           "service dual stack ipv6,4. want ipv6",
   517  			requestFamily:  v1.IPv6Protocol,
   518  			expectedResult: "2000::1",
   519  			service: v1.Service{
   520  				Spec: v1.ServiceSpec{
   521  					ClusterIPs: []string{"2000::1", "10.0.0.10"},
   522  					IPFamilies: []v1.IPFamily{v1.IPv6Protocol, v1.IPv4Protocol},
   523  				},
   524  			},
   525  		},
   526  
   527  		{
   528  			name:           "service dual stack ipv6,4. want ipv4",
   529  			requestFamily:  v1.IPv4Protocol,
   530  			expectedResult: "10.0.0.10",
   531  			service: v1.Service{
   532  				Spec: v1.ServiceSpec{
   533  					ClusterIPs: []string{"2000::1", "10.0.0.10"},
   534  					IPFamilies: []v1.IPFamily{v1.IPv6Protocol, v1.IPv4Protocol},
   535  				},
   536  			},
   537  		},
   538  	}
   539  
   540  	for _, testCase := range testCases {
   541  		t.Run(testCase.name, func(t *testing.T) {
   542  			ip := GetClusterIPByFamily(testCase.requestFamily, &testCase.service)
   543  			if ip != testCase.expectedResult {
   544  				t.Fatalf("expected ip:%v got %v", testCase.expectedResult, ip)
   545  			}
   546  		})
   547  	}
   548  }
   549  
   550  func mustParseIPAddr(str string) net.Addr {
   551  	a, err := net.ResolveIPAddr("ip", str)
   552  	if err != nil {
   553  		panic("mustParseIPAddr")
   554  	}
   555  	return a
   556  }
   557  func mustParseIPNet(str string) net.Addr {
   558  	_, n, err := netutils.ParseCIDRSloppy(str)
   559  	if err != nil {
   560  		panic("mustParseIPNet")
   561  	}
   562  	return n
   563  }
   564  func mustParseUnix(str string) net.Addr {
   565  	n, err := net.ResolveUnixAddr("unix", str)
   566  	if err != nil {
   567  		panic("mustParseUnix")
   568  	}
   569  	return n
   570  }
   571  
   572  type cidrValidator struct {
   573  	cidr *net.IPNet
   574  }
   575  
   576  func (v *cidrValidator) isValid(ip net.IP) bool {
   577  	return v.cidr.Contains(ip)
   578  }
   579  func newCidrValidator(cidr string) func(ip net.IP) bool {
   580  	_, n, err := netutils.ParseCIDRSloppy(cidr)
   581  	if err != nil {
   582  		panic("mustParseIPNet")
   583  	}
   584  	obj := cidrValidator{n}
   585  	return obj.isValid
   586  }
   587  
   588  func TestAddressSet(t *testing.T) {
   589  	testCases := []struct {
   590  		name      string
   591  		validator func(ip net.IP) bool
   592  		input     []net.Addr
   593  		expected  sets.Set[string]
   594  	}{
   595  		{
   596  			"Empty",
   597  			func(ip net.IP) bool { return false },
   598  			nil,
   599  			nil,
   600  		},
   601  		{
   602  			"Reject IPAddr x 2",
   603  			func(ip net.IP) bool { return false },
   604  			[]net.Addr{
   605  				mustParseIPAddr("8.8.8.8"),
   606  				mustParseIPAddr("1000::"),
   607  			},
   608  			nil,
   609  		},
   610  		{
   611  			"Accept IPAddr x 2",
   612  			func(ip net.IP) bool { return true },
   613  			[]net.Addr{
   614  				mustParseIPAddr("8.8.8.8"),
   615  				mustParseIPAddr("1000::"),
   616  			},
   617  			sets.New("8.8.8.8", "1000::"),
   618  		},
   619  		{
   620  			"Accept IPNet x 2",
   621  			func(ip net.IP) bool { return true },
   622  			[]net.Addr{
   623  				mustParseIPNet("8.8.8.8/32"),
   624  				mustParseIPNet("1000::/128"),
   625  			},
   626  			sets.New("8.8.8.8", "1000::"),
   627  		},
   628  		{
   629  			"Accept Unix x 2",
   630  			func(ip net.IP) bool { return true },
   631  			[]net.Addr{
   632  				mustParseUnix("/tmp/sock1"),
   633  				mustParseUnix("/tmp/sock2"),
   634  			},
   635  			nil,
   636  		},
   637  		{
   638  			"Cidr IPv4",
   639  			newCidrValidator("192.168.1.0/24"),
   640  			[]net.Addr{
   641  				mustParseIPAddr("8.8.8.8"),
   642  				mustParseIPAddr("1000::"),
   643  				mustParseIPAddr("192.168.1.1"),
   644  			},
   645  			sets.New("192.168.1.1"),
   646  		},
   647  		{
   648  			"Cidr IPv6",
   649  			newCidrValidator("1000::/64"),
   650  			[]net.Addr{
   651  				mustParseIPAddr("8.8.8.8"),
   652  				mustParseIPAddr("1000::"),
   653  				mustParseIPAddr("192.168.1.1"),
   654  			},
   655  			sets.New("1000::"),
   656  		},
   657  	}
   658  
   659  	for _, tc := range testCases {
   660  		if !tc.expected.Equal(AddressSet(tc.validator, tc.input)) {
   661  			t.Errorf("%s", tc.name)
   662  		}
   663  	}
   664  }
   665  
   666  func TestIsZeroCIDR(t *testing.T) {
   667  	testCases := []struct {
   668  		name     string
   669  		input    string
   670  		expected bool
   671  	}{
   672  		{
   673  			name:     "invalide cidr",
   674  			input:    "",
   675  			expected: false,
   676  		},
   677  		{
   678  			name:     "ipv4 cidr",
   679  			input:    "172.10.0.0/16",
   680  			expected: false,
   681  		},
   682  		{
   683  			name:     "ipv4 zero cidr",
   684  			input:    IPv4ZeroCIDR,
   685  			expected: true,
   686  		},
   687  		{
   688  			name:     "ipv6 cidr",
   689  			input:    "::/128",
   690  			expected: false,
   691  		},
   692  		{
   693  			name:     "ipv6 zero cidr",
   694  			input:    IPv6ZeroCIDR,
   695  			expected: true,
   696  		},
   697  	}
   698  	for _, tc := range testCases {
   699  		t.Run(tc.name, func(t *testing.T) {
   700  			if got := IsZeroCIDR(tc.input); tc.expected != got {
   701  				t.Errorf("IsZeroCIDR() = %t, want %t", got, tc.expected)
   702  			}
   703  		})
   704  	}
   705  }