github.com/cilium/cilium@v1.16.2/pkg/k8s/endpoints_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package k8s
     5  
     6  import (
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  
    12  	cmtypes "github.com/cilium/cilium/pkg/clustermesh/types"
    13  	slim_corev1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1"
    14  	slim_discovery_v1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/discovery/v1"
    15  	slim_discovery_v1beta1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/discovery/v1beta1"
    16  	slim_metav1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1"
    17  	"github.com/cilium/cilium/pkg/loadbalancer"
    18  	"github.com/cilium/cilium/pkg/option"
    19  	serviceStore "github.com/cilium/cilium/pkg/service/store"
    20  )
    21  
    22  func TestEndpoints_DeepEqual(t *testing.T) {
    23  	type fields struct {
    24  		svcEP *Endpoints
    25  	}
    26  	type args struct {
    27  		o *Endpoints
    28  	}
    29  	tests := []struct {
    30  		name   string
    31  		fields fields
    32  		args   args
    33  		want   bool
    34  	}{
    35  
    36  		{
    37  			name: "both equal",
    38  			fields: fields{
    39  				svcEP: &Endpoints{
    40  					Backends: map[cmtypes.AddrCluster]*Backend{
    41  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
    42  							Ports: map[string]*loadbalancer.L4Addr{
    43  								"foo": {
    44  									Protocol: loadbalancer.NONE,
    45  									Port:     1,
    46  								},
    47  							},
    48  							NodeName: "k8s1",
    49  						},
    50  					},
    51  				},
    52  			},
    53  			args: args{
    54  				o: &Endpoints{
    55  					Backends: map[cmtypes.AddrCluster]*Backend{
    56  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
    57  							Ports: map[string]*loadbalancer.L4Addr{
    58  								"foo": {
    59  									Protocol: loadbalancer.NONE,
    60  									Port:     1,
    61  								},
    62  							},
    63  							NodeName: "k8s1",
    64  						},
    65  					},
    66  				},
    67  			},
    68  			want: true,
    69  		},
    70  		{
    71  			name: "different BE IPs",
    72  			fields: fields{
    73  				svcEP: &Endpoints{
    74  					Backends: map[cmtypes.AddrCluster]*Backend{
    75  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
    76  							Ports: map[string]*loadbalancer.L4Addr{
    77  								"foo": {
    78  									Protocol: loadbalancer.NONE,
    79  									Port:     1,
    80  								},
    81  							},
    82  						},
    83  					},
    84  				},
    85  			},
    86  			args: args{
    87  				o: &Endpoints{
    88  					Backends: map[cmtypes.AddrCluster]*Backend{
    89  						cmtypes.MustParseAddrCluster("172.20.0.2"): {
    90  							Ports: map[string]*loadbalancer.L4Addr{
    91  								"foo": {
    92  									Protocol: loadbalancer.NONE,
    93  									Port:     1,
    94  								},
    95  							},
    96  						},
    97  					},
    98  				},
    99  			},
   100  			want: false,
   101  		},
   102  		{
   103  			name: "ports different name",
   104  			fields: fields{
   105  				svcEP: &Endpoints{
   106  					Backends: map[cmtypes.AddrCluster]*Backend{
   107  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   108  							Ports: map[string]*loadbalancer.L4Addr{
   109  								"foo": {
   110  									Protocol: loadbalancer.NONE,
   111  									Port:     1,
   112  								},
   113  							},
   114  						},
   115  					},
   116  				},
   117  			},
   118  			args: args{
   119  				o: &Endpoints{
   120  					Backends: map[cmtypes.AddrCluster]*Backend{
   121  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   122  							Ports: map[string]*loadbalancer.L4Addr{
   123  								"foz": {
   124  									Protocol: loadbalancer.NONE,
   125  									Port:     1,
   126  								},
   127  							},
   128  						},
   129  					},
   130  				},
   131  			},
   132  			want: false,
   133  		},
   134  		{
   135  			name: "ports different content",
   136  			fields: fields{
   137  				svcEP: &Endpoints{
   138  					Backends: map[cmtypes.AddrCluster]*Backend{
   139  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   140  							Ports: map[string]*loadbalancer.L4Addr{
   141  								"foo": {
   142  									Protocol: loadbalancer.NONE,
   143  									Port:     1,
   144  								},
   145  							},
   146  						},
   147  					},
   148  				},
   149  			},
   150  			args: args{
   151  				o: &Endpoints{
   152  					Backends: map[cmtypes.AddrCluster]*Backend{
   153  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   154  							Ports: map[string]*loadbalancer.L4Addr{
   155  								"foo": {
   156  									Protocol: loadbalancer.NONE,
   157  									Port:     2,
   158  								},
   159  							},
   160  						},
   161  					},
   162  				},
   163  			},
   164  			want: false,
   165  		},
   166  		{
   167  			name: "ports different one is bigger",
   168  			fields: fields{
   169  				svcEP: &Endpoints{
   170  					Backends: map[cmtypes.AddrCluster]*Backend{
   171  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   172  							Ports: map[string]*loadbalancer.L4Addr{
   173  								"foo": {
   174  									Protocol: loadbalancer.NONE,
   175  									Port:     1,
   176  								},
   177  							},
   178  						},
   179  					},
   180  				},
   181  			},
   182  			args: args{
   183  				o: &Endpoints{
   184  					Backends: map[cmtypes.AddrCluster]*Backend{
   185  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   186  							Ports: map[string]*loadbalancer.L4Addr{
   187  								"foo": {
   188  									Protocol: loadbalancer.NONE,
   189  									Port:     1,
   190  								},
   191  								"baz": {
   192  									Protocol: loadbalancer.NONE,
   193  									Port:     2,
   194  								},
   195  							},
   196  						},
   197  					},
   198  				},
   199  			},
   200  			want: false,
   201  		},
   202  		{
   203  			name:   "backend different one is nil",
   204  			fields: fields{},
   205  			args: args{
   206  				o: &Endpoints{
   207  					Backends: map[cmtypes.AddrCluster]*Backend{
   208  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   209  							Ports: map[string]*loadbalancer.L4Addr{
   210  								"foo": {
   211  									Protocol: loadbalancer.NONE,
   212  									Port:     1,
   213  								},
   214  							},
   215  						},
   216  					},
   217  				},
   218  			},
   219  			want: false,
   220  		},
   221  		{
   222  			name: "node name different",
   223  			fields: fields{
   224  				svcEP: &Endpoints{
   225  					Backends: map[cmtypes.AddrCluster]*Backend{
   226  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   227  							NodeName: "k8s2",
   228  						},
   229  					},
   230  				},
   231  			}, args: args{
   232  				o: &Endpoints{
   233  					Backends: map[cmtypes.AddrCluster]*Backend{
   234  						cmtypes.MustParseAddrCluster("172.20.0.1"): {
   235  							NodeName: "k8s1",
   236  						},
   237  					},
   238  				},
   239  			},
   240  			want: false,
   241  		},
   242  		{
   243  			name: "both nil",
   244  			args: args{},
   245  			want: true,
   246  		},
   247  	}
   248  	for _, tt := range tests {
   249  		t.Run(tt.name, func(t *testing.T) {
   250  			if got := tt.fields.svcEP.DeepEqual(tt.args.o); got != tt.want {
   251  				t.Errorf("Endpoints.DeepEqual() = %v, want %v", got, tt.want)
   252  			}
   253  		})
   254  	}
   255  }
   256  
   257  func Test_parseK8sEPv1(t *testing.T) {
   258  	nodeName := "k8s1"
   259  	hostname := "pod-1"
   260  
   261  	meta := slim_metav1.ObjectMeta{
   262  		Name:      "foo",
   263  		Namespace: "bar",
   264  	}
   265  	sliceID := EndpointSliceID{
   266  		ServiceID:         ServiceID{Name: "foo", Namespace: "bar"},
   267  		EndpointSliceName: "foo",
   268  	}
   269  	newEmptyEndpoints := func() *Endpoints {
   270  		eps := newEndpoints()
   271  		eps.ObjectMeta = meta
   272  		eps.EndpointSliceID = sliceID
   273  		return eps
   274  	}
   275  
   276  	type args struct {
   277  		eps *slim_corev1.Endpoints
   278  	}
   279  	tests := []struct {
   280  		name        string
   281  		setupArgs   func() args
   282  		setupWanted func() *Endpoints
   283  	}{
   284  		{
   285  			name: "empty endpoint",
   286  			setupArgs: func() args {
   287  				return args{
   288  					eps: &slim_corev1.Endpoints{
   289  						ObjectMeta: meta,
   290  					},
   291  				}
   292  			},
   293  			setupWanted: newEmptyEndpoints,
   294  		},
   295  		{
   296  			name: "endpoint with an address and port",
   297  			setupArgs: func() args {
   298  				return args{
   299  					eps: &slim_corev1.Endpoints{
   300  						ObjectMeta: slim_metav1.ObjectMeta{
   301  							Name:      "foo",
   302  							Namespace: "bar",
   303  						},
   304  						Subsets: []slim_corev1.EndpointSubset{
   305  							{
   306  								Addresses: []slim_corev1.EndpointAddress{
   307  									{
   308  										IP:       "172.0.0.1",
   309  										NodeName: &nodeName,
   310  									},
   311  								},
   312  								Ports: []slim_corev1.EndpointPort{
   313  									{
   314  										Name:     "http-test-svc",
   315  										Port:     8080,
   316  										Protocol: slim_corev1.ProtocolTCP,
   317  									},
   318  								},
   319  							},
   320  						},
   321  					},
   322  				}
   323  			},
   324  			setupWanted: func() *Endpoints {
   325  				svcEP := newEmptyEndpoints()
   326  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   327  					Ports: serviceStore.PortConfiguration{
   328  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   329  					},
   330  					NodeName: nodeName,
   331  				}
   332  				return svcEP
   333  			},
   334  		},
   335  		{
   336  			name: "endpoint with an address and 2 ports",
   337  			setupArgs: func() args {
   338  				return args{
   339  					eps: &slim_corev1.Endpoints{
   340  						ObjectMeta: meta,
   341  						Subsets: []slim_corev1.EndpointSubset{
   342  							{
   343  								Addresses: []slim_corev1.EndpointAddress{
   344  									{
   345  										IP:       "172.0.0.1",
   346  										NodeName: &nodeName,
   347  										Hostname: hostname,
   348  									},
   349  								},
   350  								Ports: []slim_corev1.EndpointPort{
   351  									{
   352  										Name:     "http-test-svc",
   353  										Port:     8080,
   354  										Protocol: slim_corev1.ProtocolTCP,
   355  									},
   356  									{
   357  										Name:     "http-test-svc-2",
   358  										Port:     8081,
   359  										Protocol: slim_corev1.ProtocolTCP,
   360  									},
   361  								},
   362  							},
   363  						},
   364  					},
   365  				}
   366  			},
   367  			setupWanted: func() *Endpoints {
   368  				svcEP := newEmptyEndpoints()
   369  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   370  					Ports: serviceStore.PortConfiguration{
   371  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   372  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   373  					},
   374  					NodeName: nodeName,
   375  					Hostname: hostname,
   376  				}
   377  				return svcEP
   378  			},
   379  		},
   380  		{
   381  			name: "endpoint with 2 addresses and 2 ports",
   382  			setupArgs: func() args {
   383  				return args{
   384  					eps: &slim_corev1.Endpoints{
   385  						ObjectMeta: meta,
   386  						Subsets: []slim_corev1.EndpointSubset{
   387  							{
   388  								Addresses: []slim_corev1.EndpointAddress{
   389  									{
   390  										IP:       "172.0.0.1",
   391  										NodeName: &nodeName,
   392  									},
   393  									{
   394  										IP: "172.0.0.2",
   395  									},
   396  								},
   397  								Ports: []slim_corev1.EndpointPort{
   398  									{
   399  										Name:     "http-test-svc",
   400  										Port:     8080,
   401  										Protocol: slim_corev1.ProtocolTCP,
   402  									},
   403  									{
   404  										Name:     "http-test-svc-2",
   405  										Port:     8081,
   406  										Protocol: slim_corev1.ProtocolTCP,
   407  									},
   408  								},
   409  							},
   410  						},
   411  					},
   412  				}
   413  			},
   414  			setupWanted: func() *Endpoints {
   415  				svcEP := newEmptyEndpoints()
   416  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   417  					Ports: serviceStore.PortConfiguration{
   418  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   419  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   420  					},
   421  					NodeName: nodeName,
   422  				}
   423  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   424  					Ports: serviceStore.PortConfiguration{
   425  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   426  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   427  					},
   428  				}
   429  				return svcEP
   430  			},
   431  		},
   432  		{
   433  			name: "endpoint with 2 addresses, 1 address not ready and 2 ports",
   434  			setupArgs: func() args {
   435  				return args{
   436  					eps: &slim_corev1.Endpoints{
   437  						ObjectMeta: meta,
   438  						Subsets: []slim_corev1.EndpointSubset{
   439  							{
   440  								Addresses: []slim_corev1.EndpointAddress{
   441  									{
   442  										IP:       "172.0.0.1",
   443  										NodeName: &nodeName,
   444  									},
   445  									{
   446  										IP: "172.0.0.2",
   447  									},
   448  								},
   449  								Ports: []slim_corev1.EndpointPort{
   450  									{
   451  										Name:     "http-test-svc",
   452  										Port:     8080,
   453  										Protocol: slim_corev1.ProtocolTCP,
   454  									},
   455  									{
   456  										Name:     "http-test-svc-2",
   457  										Port:     8081,
   458  										Protocol: slim_corev1.ProtocolTCP,
   459  									},
   460  								},
   461  							},
   462  						},
   463  					},
   464  				}
   465  			},
   466  			setupWanted: func() *Endpoints {
   467  				svcEP := newEmptyEndpoints()
   468  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   469  					Ports: serviceStore.PortConfiguration{
   470  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   471  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   472  					},
   473  					NodeName: nodeName,
   474  				}
   475  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   476  					Ports: serviceStore.PortConfiguration{
   477  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   478  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   479  					},
   480  				}
   481  				return svcEP
   482  			},
   483  		},
   484  		{
   485  			name: "endpoint with SCTP addresses",
   486  			setupArgs: func() args {
   487  				return args{
   488  					eps: &slim_corev1.Endpoints{
   489  						ObjectMeta: meta,
   490  						Subsets: []slim_corev1.EndpointSubset{
   491  							{
   492  								Addresses: []slim_corev1.EndpointAddress{
   493  									{
   494  										IP:       "172.0.0.1",
   495  										NodeName: &nodeName,
   496  									},
   497  								},
   498  								Ports: []slim_corev1.EndpointPort{
   499  									{
   500  										Name:     "sctp-test-svc",
   501  										Port:     5555,
   502  										Protocol: slim_corev1.ProtocolSCTP,
   503  									},
   504  								},
   505  							},
   506  						},
   507  					},
   508  				}
   509  			},
   510  			setupWanted: func() *Endpoints {
   511  				svcEP := newEmptyEndpoints()
   512  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   513  					Ports: serviceStore.PortConfiguration{
   514  						"sctp-test-svc": loadbalancer.NewL4Addr(loadbalancer.SCTP, 5555),
   515  					},
   516  					NodeName: nodeName,
   517  				}
   518  				return svcEP
   519  			},
   520  		},
   521  	}
   522  	for _, tt := range tests {
   523  		args := tt.setupArgs()
   524  		want := tt.setupWanted()
   525  		got := ParseEndpoints(args.eps)
   526  		require.EqualValuesf(t, want, got, "Test name: %q", tt.name)
   527  	}
   528  }
   529  
   530  func TestEndpointsString(t *testing.T) {
   531  	endpoints := &slim_corev1.Endpoints{
   532  		ObjectMeta: slim_metav1.ObjectMeta{
   533  			Name:      "foo",
   534  			Namespace: "bar",
   535  		},
   536  		Subsets: []slim_corev1.EndpointSubset{
   537  			{
   538  				Addresses: []slim_corev1.EndpointAddress{
   539  					{
   540  						IP: "172.0.0.2",
   541  					},
   542  					{
   543  						IP: "172.0.0.1",
   544  					},
   545  				},
   546  				Ports: []slim_corev1.EndpointPort{
   547  					{
   548  						Name:     "http-test-svc-2",
   549  						Port:     8081,
   550  						Protocol: slim_corev1.ProtocolTCP,
   551  					},
   552  					{
   553  						Name:     "http-test-svc",
   554  						Port:     8080,
   555  						Protocol: slim_corev1.ProtocolTCP,
   556  					},
   557  					{
   558  						Name:     "sctp-test-svc",
   559  						Port:     5555,
   560  						Protocol: slim_corev1.ProtocolSCTP,
   561  					},
   562  				},
   563  			},
   564  		},
   565  	}
   566  
   567  	ep := ParseEndpoints(endpoints)
   568  	require.Equal(t, "172.0.0.1:5555/SCTP,172.0.0.1:8080/TCP,172.0.0.1:8081/TCP,172.0.0.2:5555/SCTP,172.0.0.2:8080/TCP,172.0.0.2:8081/TCP", ep.String())
   569  }
   570  
   571  func Test_parseK8sEPSlicev1Beta1(t *testing.T) {
   572  	nodeName := "k8s1"
   573  	hostname := "pod-1"
   574  
   575  	meta := slim_metav1.ObjectMeta{
   576  		Name:      "foo",
   577  		Namespace: "bar",
   578  		Labels:    map[string]string{slim_discovery_v1beta1.LabelServiceName: "quux"},
   579  	}
   580  	sliceID := EndpointSliceID{
   581  		ServiceID:         ServiceID{Name: "quux", Namespace: "bar"},
   582  		EndpointSliceName: "foo",
   583  	}
   584  
   585  	newEmptyEndpoints := func() *Endpoints {
   586  		eps := newEndpoints()
   587  		eps.ObjectMeta = meta
   588  		eps.EndpointSliceID = sliceID
   589  		return eps
   590  	}
   591  
   592  	type args struct {
   593  		eps            *slim_discovery_v1beta1.EndpointSlice
   594  		overrideConfig func()
   595  	}
   596  	tests := []struct {
   597  		name        string
   598  		setupArgs   func() args
   599  		setupWanted func() *Endpoints
   600  	}{
   601  		{
   602  			name: "empty endpoint",
   603  			setupArgs: func() args {
   604  				return args{
   605  					eps: &slim_discovery_v1beta1.EndpointSlice{
   606  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   607  						ObjectMeta:  meta,
   608  					},
   609  				}
   610  			},
   611  			setupWanted: newEmptyEndpoints,
   612  		},
   613  		{
   614  			name: "endpoint with an address and port",
   615  			setupArgs: func() args {
   616  				return args{
   617  					eps: &slim_discovery_v1beta1.EndpointSlice{
   618  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   619  						ObjectMeta:  meta,
   620  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   621  							{
   622  								Addresses: []string{
   623  									"172.0.0.1",
   624  								},
   625  								Topology: map[string]string{
   626  									"kubernetes.io/hostname": nodeName,
   627  								},
   628  								Hostname: func() *string { return &hostname }(),
   629  							},
   630  						},
   631  						Ports: []slim_discovery_v1beta1.EndpointPort{
   632  							{
   633  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   634  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   635  								Port:     func() *int32 { a := int32(8080); return &a }(),
   636  							},
   637  						},
   638  					},
   639  				}
   640  			},
   641  			setupWanted: func() *Endpoints {
   642  				svcEP := newEmptyEndpoints()
   643  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   644  					Ports: serviceStore.PortConfiguration{
   645  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   646  					},
   647  					NodeName: nodeName,
   648  					Hostname: hostname,
   649  				}
   650  				return svcEP
   651  			},
   652  		},
   653  		{
   654  			name: "endpoint with an address and 2 ports",
   655  			setupArgs: func() args {
   656  				return args{
   657  					eps: &slim_discovery_v1beta1.EndpointSlice{
   658  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   659  						ObjectMeta:  meta,
   660  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   661  							{
   662  								Addresses: []string{
   663  									"172.0.0.1",
   664  								},
   665  								Topology: map[string]string{
   666  									"kubernetes.io/hostname": nodeName,
   667  								},
   668  							},
   669  						},
   670  						Ports: []slim_discovery_v1beta1.EndpointPort{
   671  							{
   672  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   673  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   674  								Port:     func() *int32 { a := int32(8080); return &a }(),
   675  							},
   676  							{
   677  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   678  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   679  								Port:     func() *int32 { a := int32(8081); return &a }(),
   680  							},
   681  						},
   682  					},
   683  				}
   684  			},
   685  			setupWanted: func() *Endpoints {
   686  				svcEP := newEmptyEndpoints()
   687  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   688  					Ports: serviceStore.PortConfiguration{
   689  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   690  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   691  					},
   692  					NodeName: nodeName,
   693  				}
   694  				return svcEP
   695  			},
   696  		},
   697  		{
   698  			name: "endpoint with 2 addresses and 2 ports",
   699  			setupArgs: func() args {
   700  				return args{
   701  					eps: &slim_discovery_v1beta1.EndpointSlice{
   702  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   703  						ObjectMeta:  meta,
   704  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   705  							{
   706  								Addresses: []string{
   707  									"172.0.0.1",
   708  								},
   709  								Topology: map[string]string{
   710  									"kubernetes.io/hostname": nodeName,
   711  								},
   712  							},
   713  							{
   714  								Addresses: []string{
   715  									"172.0.0.2",
   716  								},
   717  							},
   718  						},
   719  						Ports: []slim_discovery_v1beta1.EndpointPort{
   720  							{
   721  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   722  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   723  								Port:     func() *int32 { a := int32(8080); return &a }(),
   724  							},
   725  							{
   726  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   727  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   728  								Port:     func() *int32 { a := int32(8081); return &a }(),
   729  							},
   730  						},
   731  					},
   732  				}
   733  			},
   734  			setupWanted: func() *Endpoints {
   735  				svcEP := newEmptyEndpoints()
   736  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   737  					Ports: serviceStore.PortConfiguration{
   738  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   739  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   740  					},
   741  					NodeName: nodeName,
   742  				}
   743  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   744  					Ports: serviceStore.PortConfiguration{
   745  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   746  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   747  					},
   748  				}
   749  				return svcEP
   750  			},
   751  		},
   752  		{
   753  			name: "endpoint with 2 addresses, 1 address not ready and 2 ports",
   754  			setupArgs: func() args {
   755  				return args{
   756  					eps: &slim_discovery_v1beta1.EndpointSlice{
   757  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   758  						ObjectMeta:  meta,
   759  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   760  							{
   761  								Addresses: []string{
   762  									"172.0.0.1",
   763  								},
   764  								Topology: map[string]string{
   765  									"kubernetes.io/hostname": nodeName,
   766  								},
   767  							},
   768  							{
   769  								Addresses: []string{
   770  									"172.0.0.2",
   771  								},
   772  							},
   773  							{
   774  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   775  									Ready: func() *bool { a := false; return &a }(),
   776  								},
   777  								Addresses: []string{
   778  									"172.0.0.3",
   779  								},
   780  							},
   781  						},
   782  						Ports: []slim_discovery_v1beta1.EndpointPort{
   783  							{
   784  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   785  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   786  								Port:     func() *int32 { a := int32(8080); return &a }(),
   787  							},
   788  							{
   789  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   790  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   791  								Port:     func() *int32 { a := int32(8081); return &a }(),
   792  							},
   793  						},
   794  					},
   795  				}
   796  			},
   797  			setupWanted: func() *Endpoints {
   798  				svcEP := newEmptyEndpoints()
   799  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   800  					Ports: serviceStore.PortConfiguration{
   801  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   802  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   803  					},
   804  					NodeName: nodeName,
   805  				}
   806  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   807  					Ports: serviceStore.PortConfiguration{
   808  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   809  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   810  					},
   811  				}
   812  				return svcEP
   813  			},
   814  		},
   815  		{
   816  			name: "endpoint with some addresses not ready and terminating",
   817  			setupArgs: func() args {
   818  				return args{
   819  					eps: &slim_discovery_v1beta1.EndpointSlice{
   820  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   821  						ObjectMeta:  meta,
   822  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   823  							{
   824  								Addresses: []string{
   825  									"172.0.0.1",
   826  								},
   827  							},
   828  							{
   829  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   830  									Ready:       func() *bool { a := false; return &a }(),
   831  									Terminating: func() *bool { a := true; return &a }(),
   832  								},
   833  								Addresses: []string{
   834  									"172.0.0.2",
   835  								},
   836  							},
   837  						},
   838  						Ports: []slim_discovery_v1beta1.EndpointPort{
   839  							{
   840  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   841  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   842  								Port:     func() *int32 { a := int32(8080); return &a }(),
   843  							},
   844  							{
   845  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   846  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   847  								Port:     func() *int32 { a := int32(8081); return &a }(),
   848  							},
   849  						},
   850  					},
   851  				}
   852  			},
   853  			setupWanted: func() *Endpoints {
   854  				svcEP := newEmptyEndpoints()
   855  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   856  					Ports: serviceStore.PortConfiguration{
   857  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   858  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   859  					},
   860  				}
   861  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   862  					Ports: serviceStore.PortConfiguration{
   863  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   864  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   865  					},
   866  					Terminating: true,
   867  				}
   868  				return svcEP
   869  			},
   870  		},
   871  		{
   872  			name: "endpoints with some addresses not ready and terminating, EnableK8sTerminatingEndpoint disabled",
   873  			setupArgs: func() args {
   874  				return args{
   875  					eps: &slim_discovery_v1beta1.EndpointSlice{
   876  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   877  						ObjectMeta:  meta,
   878  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   879  							{
   880  								Addresses: []string{
   881  									"172.0.0.1",
   882  								},
   883  							},
   884  							{
   885  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   886  									Ready:       func() *bool { a := false; return &a }(),
   887  									Terminating: func() *bool { a := true; return &a }(),
   888  								},
   889  								Addresses: []string{
   890  									"172.0.0.2",
   891  								},
   892  							},
   893  						},
   894  						Ports: []slim_discovery_v1beta1.EndpointPort{
   895  							{
   896  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   897  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   898  								Port:     func() *int32 { a := int32(8080); return &a }(),
   899  							},
   900  							{
   901  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   902  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   903  								Port:     func() *int32 { a := int32(8081); return &a }(),
   904  							},
   905  						},
   906  					},
   907  					overrideConfig: func() {
   908  						option.Config.EnableK8sTerminatingEndpoint = false
   909  					},
   910  				}
   911  			},
   912  			setupWanted: func() *Endpoints {
   913  				svcEP := newEmptyEndpoints()
   914  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   915  					Ports: serviceStore.PortConfiguration{
   916  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   917  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   918  					},
   919  				}
   920  				return svcEP
   921  			},
   922  		},
   923  		{
   924  			name: "endpoints with all addresses not ready and terminating",
   925  			setupArgs: func() args {
   926  				return args{
   927  					eps: &slim_discovery_v1beta1.EndpointSlice{
   928  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   929  						ObjectMeta:  meta,
   930  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   931  							{
   932  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   933  									Ready:       func() *bool { a := false; return &a }(),
   934  									Terminating: func() *bool { a := true; return &a }(),
   935  								},
   936  								Addresses: []string{
   937  									"172.0.0.1",
   938  								},
   939  							},
   940  							{
   941  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   942  									Ready:       func() *bool { a := false; return &a }(),
   943  									Terminating: func() *bool { a := true; return &a }(),
   944  								},
   945  								Addresses: []string{
   946  									"172.0.0.2",
   947  								},
   948  							},
   949  						},
   950  						Ports: []slim_discovery_v1beta1.EndpointPort{
   951  							{
   952  								Name:     func() *string { a := "http-test-svc"; return &a }(),
   953  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   954  								Port:     func() *int32 { a := int32(8080); return &a }(),
   955  							},
   956  							{
   957  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
   958  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
   959  								Port:     func() *int32 { a := int32(8081); return &a }(),
   960  							},
   961  						},
   962  					},
   963  				}
   964  			},
   965  			setupWanted: func() *Endpoints {
   966  				svcEP := newEmptyEndpoints()
   967  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
   968  					Ports: serviceStore.PortConfiguration{
   969  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   970  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   971  					},
   972  					Terminating: true,
   973  				}
   974  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
   975  					Ports: serviceStore.PortConfiguration{
   976  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   977  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   978  					},
   979  					Terminating: true,
   980  				}
   981  				return svcEP
   982  			},
   983  		},
   984  		{
   985  			name: "endpoints with some addresses not ready and terminating, EnableK8sTerminatingEndpoint disabled",
   986  			setupArgs: func() args {
   987  				return args{
   988  					eps: &slim_discovery_v1beta1.EndpointSlice{
   989  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
   990  						ObjectMeta:  meta,
   991  						Endpoints: []slim_discovery_v1beta1.Endpoint{
   992  							{
   993  								Addresses: []string{
   994  									"172.0.0.1",
   995  								},
   996  							},
   997  							{
   998  								Conditions: slim_discovery_v1beta1.EndpointConditions{
   999  									Ready:       func() *bool { a := false; return &a }(),
  1000  									Terminating: func() *bool { a := true; return &a }(),
  1001  								},
  1002  								Addresses: []string{
  1003  									"172.0.0.2",
  1004  								},
  1005  							},
  1006  						},
  1007  						Ports: []slim_discovery_v1beta1.EndpointPort{
  1008  							{
  1009  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1010  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1011  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1012  							},
  1013  							{
  1014  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1015  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1016  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1017  							},
  1018  						},
  1019  					},
  1020  					overrideConfig: func() {
  1021  						option.Config.EnableK8sTerminatingEndpoint = false
  1022  					},
  1023  				}
  1024  			},
  1025  			setupWanted: func() *Endpoints {
  1026  				svcEP := newEmptyEndpoints()
  1027  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1028  					Ports: serviceStore.PortConfiguration{
  1029  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1030  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1031  					},
  1032  				}
  1033  				return svcEP
  1034  			},
  1035  		},
  1036  		{
  1037  			name: "endpoints with SCTP",
  1038  			setupArgs: func() args {
  1039  				return args{
  1040  					eps: &slim_discovery_v1beta1.EndpointSlice{
  1041  						AddressType: slim_discovery_v1beta1.AddressTypeIPv4,
  1042  						ObjectMeta:  meta,
  1043  						Endpoints: []slim_discovery_v1beta1.Endpoint{
  1044  							{
  1045  								Addresses: []string{
  1046  									"172.0.0.1",
  1047  								},
  1048  							},
  1049  						},
  1050  						Ports: []slim_discovery_v1beta1.EndpointPort{
  1051  							{
  1052  								Name:     func() *string { a := "sctp-test-svc"; return &a }(),
  1053  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolSCTP; return &a }(),
  1054  								Port:     func() *int32 { a := int32(5555); return &a }(),
  1055  							},
  1056  						},
  1057  					},
  1058  				}
  1059  			},
  1060  			setupWanted: func() *Endpoints {
  1061  				svcEP := newEmptyEndpoints()
  1062  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1063  					Ports: serviceStore.PortConfiguration{
  1064  						"sctp-test-svc": loadbalancer.NewL4Addr(loadbalancer.SCTP, 5555),
  1065  					},
  1066  				}
  1067  				return svcEP
  1068  			},
  1069  		},
  1070  		{
  1071  			name: "endpoint with IPv6 address type",
  1072  			setupArgs: func() args {
  1073  				return args{
  1074  					eps: &slim_discovery_v1beta1.EndpointSlice{
  1075  						AddressType: slim_discovery_v1beta1.AddressTypeIPv6,
  1076  						ObjectMeta:  meta,
  1077  						Endpoints: []slim_discovery_v1beta1.Endpoint{
  1078  							{
  1079  								Addresses: []string{
  1080  									"fd00::1",
  1081  								},
  1082  							},
  1083  						},
  1084  						Ports: []slim_discovery_v1beta1.EndpointPort{
  1085  							{
  1086  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1087  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1088  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1089  							},
  1090  						},
  1091  					},
  1092  				}
  1093  			},
  1094  			setupWanted: func() *Endpoints {
  1095  				svcEP := newEmptyEndpoints()
  1096  				svcEP.Backends[cmtypes.MustParseAddrCluster("fd00::1")] = &Backend{
  1097  					Ports: serviceStore.PortConfiguration{
  1098  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1099  					},
  1100  				}
  1101  				return svcEP
  1102  			},
  1103  		},
  1104  		{
  1105  			name: "endpoint with FQDN address type",
  1106  			setupArgs: func() args {
  1107  				return args{
  1108  					eps: &slim_discovery_v1beta1.EndpointSlice{
  1109  						AddressType: slim_discovery_v1beta1.AddressTypeFQDN,
  1110  						ObjectMeta:  meta,
  1111  						Endpoints: []slim_discovery_v1beta1.Endpoint{
  1112  							{
  1113  								Addresses: []string{
  1114  									"foo.example.com",
  1115  								},
  1116  							},
  1117  						},
  1118  						Ports: []slim_discovery_v1beta1.EndpointPort{
  1119  							{
  1120  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1121  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1122  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1123  							},
  1124  						},
  1125  					},
  1126  				}
  1127  			},
  1128  			setupWanted: func() *Endpoints {
  1129  				// We don't support FQDN address types. Should be empty.
  1130  				return newEmptyEndpoints()
  1131  			},
  1132  		},
  1133  	}
  1134  	for _, tt := range tests {
  1135  		args := tt.setupArgs()
  1136  		want := tt.setupWanted()
  1137  		if args.overrideConfig != nil {
  1138  			args.overrideConfig()
  1139  		} else {
  1140  			option.Config.EnableK8sTerminatingEndpoint = true
  1141  		}
  1142  		got := ParseEndpointSliceV1Beta1(args.eps)
  1143  		require.EqualValuesf(t, want, got, "Test name: %q", tt.name)
  1144  	}
  1145  }
  1146  
  1147  func Test_parseEndpointPortV1Beta1(t *testing.T) {
  1148  	type args struct {
  1149  		port slim_discovery_v1beta1.EndpointPort
  1150  	}
  1151  	tests := []struct {
  1152  		name     string
  1153  		args     args
  1154  		portName string
  1155  		l4Addr   *loadbalancer.L4Addr
  1156  	}{
  1157  		{
  1158  			name: "tcp-port",
  1159  			args: args{
  1160  				port: slim_discovery_v1beta1.EndpointPort{
  1161  					Name:     func() *string { a := "http-test-svc"; return &a }(),
  1162  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1163  					Port:     func() *int32 { a := int32(8080); return &a }(),
  1164  				},
  1165  			},
  1166  			portName: "http-test-svc",
  1167  			l4Addr: &loadbalancer.L4Addr{
  1168  				Protocol: loadbalancer.TCP,
  1169  				Port:     8080,
  1170  			},
  1171  		},
  1172  		{
  1173  			name: "udp-port",
  1174  			args: args{
  1175  				port: slim_discovery_v1beta1.EndpointPort{
  1176  					Name:     func() *string { a := "http-test-svc"; return &a }(),
  1177  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolUDP; return &a }(),
  1178  					Port:     func() *int32 { a := int32(8080); return &a }(),
  1179  				},
  1180  			},
  1181  			portName: "http-test-svc",
  1182  			l4Addr: &loadbalancer.L4Addr{
  1183  				Protocol: loadbalancer.UDP,
  1184  				Port:     8080,
  1185  			},
  1186  		},
  1187  		{
  1188  			name: "sctp-port",
  1189  			args: args{
  1190  				port: slim_discovery_v1beta1.EndpointPort{
  1191  					Name:     func() *string { a := "sctp-test-svc"; return &a }(),
  1192  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolSCTP; return &a }(),
  1193  					Port:     func() *int32 { a := int32(5555); return &a }(),
  1194  				},
  1195  			},
  1196  			portName: "sctp-test-svc",
  1197  			l4Addr: &loadbalancer.L4Addr{
  1198  				Protocol: loadbalancer.SCTP,
  1199  				Port:     5555,
  1200  			},
  1201  		},
  1202  		{
  1203  			name: "unset-protocol-should-have-tcp-port",
  1204  			args: args{
  1205  				port: slim_discovery_v1beta1.EndpointPort{
  1206  					Name: func() *string { a := "http-test-svc"; return &a }(),
  1207  					Port: func() *int32 { a := int32(8080); return &a }(),
  1208  				},
  1209  			},
  1210  			portName: "http-test-svc",
  1211  			l4Addr: &loadbalancer.L4Addr{
  1212  				Protocol: loadbalancer.TCP,
  1213  				Port:     8080,
  1214  			},
  1215  		},
  1216  		{
  1217  			name: "unset-port-number-should-fail",
  1218  			args: args{
  1219  				port: slim_discovery_v1beta1.EndpointPort{
  1220  					Name: func() *string { a := "http-test-svc"; return &a }(),
  1221  				},
  1222  			},
  1223  		},
  1224  	}
  1225  	for _, tt := range tests {
  1226  		t.Run(tt.name, func(t *testing.T) {
  1227  			gotPortName, gotL4Addr := parseEndpointPortV1Beta1(tt.args.port)
  1228  			if gotPortName != tt.portName {
  1229  				t.Errorf("parseEndpointPortV1Beta1() got = %v, want %v", gotPortName, tt.portName)
  1230  			}
  1231  			if !reflect.DeepEqual(gotL4Addr, tt.l4Addr) {
  1232  				t.Errorf("parseEndpointPortV1Beta1() got1 = %v, want %v", gotL4Addr, tt.l4Addr)
  1233  			}
  1234  		})
  1235  	}
  1236  }
  1237  
  1238  func Test_parseK8sEPSlicev1(t *testing.T) {
  1239  	nodeName := "k8s1"
  1240  	hostname := "pod-1"
  1241  
  1242  	meta := slim_metav1.ObjectMeta{
  1243  		Name:      "foo",
  1244  		Namespace: "bar",
  1245  		Labels:    map[string]string{slim_discovery_v1.LabelServiceName: "quux"},
  1246  	}
  1247  	sliceID := EndpointSliceID{
  1248  		ServiceID:         ServiceID{Name: "quux", Namespace: "bar"},
  1249  		EndpointSliceName: "foo",
  1250  	}
  1251  
  1252  	newEmptyEndpoints := func() *Endpoints {
  1253  		eps := newEndpoints()
  1254  		eps.ObjectMeta = meta
  1255  		eps.EndpointSliceID = sliceID
  1256  		return eps
  1257  	}
  1258  
  1259  	type args struct {
  1260  		eps            *slim_discovery_v1.EndpointSlice
  1261  		overrideConfig func()
  1262  	}
  1263  	tests := []struct {
  1264  		name        string
  1265  		setupArgs   func() args
  1266  		setupWanted func() *Endpoints
  1267  	}{
  1268  		{
  1269  			name: "empty endpoint",
  1270  			setupArgs: func() args {
  1271  				return args{
  1272  					eps: &slim_discovery_v1.EndpointSlice{
  1273  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1274  						ObjectMeta:  meta,
  1275  					},
  1276  				}
  1277  			},
  1278  			setupWanted: newEmptyEndpoints,
  1279  		},
  1280  		{
  1281  			name: "endpoint with an address and port",
  1282  			setupArgs: func() args {
  1283  				return args{
  1284  					eps: &slim_discovery_v1.EndpointSlice{
  1285  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1286  						ObjectMeta:  meta,
  1287  						Endpoints: []slim_discovery_v1.Endpoint{
  1288  							{
  1289  								Addresses: []string{
  1290  									"172.0.0.1",
  1291  								},
  1292  								DeprecatedTopology: map[string]string{
  1293  									"kubernetes.io/hostname": nodeName,
  1294  								},
  1295  								Hostname: func() *string { return &hostname }(),
  1296  							},
  1297  						},
  1298  						Ports: []slim_discovery_v1.EndpointPort{
  1299  							{
  1300  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1301  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1302  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1303  							},
  1304  						},
  1305  					},
  1306  				}
  1307  			},
  1308  			setupWanted: func() *Endpoints {
  1309  				svcEP := newEmptyEndpoints()
  1310  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1311  					Ports: serviceStore.PortConfiguration{
  1312  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1313  					},
  1314  					NodeName: nodeName,
  1315  					Hostname: hostname,
  1316  				}
  1317  				return svcEP
  1318  			},
  1319  		},
  1320  		{
  1321  			name: "endpoint with an address and 2 ports",
  1322  			setupArgs: func() args {
  1323  				return args{
  1324  					eps: &slim_discovery_v1.EndpointSlice{
  1325  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1326  						ObjectMeta:  meta,
  1327  						Endpoints: []slim_discovery_v1.Endpoint{
  1328  							{
  1329  								Addresses: []string{
  1330  									"172.0.0.1",
  1331  								},
  1332  								DeprecatedTopology: map[string]string{
  1333  									"kubernetes.io/hostname": nodeName,
  1334  								},
  1335  							},
  1336  						},
  1337  						Ports: []slim_discovery_v1.EndpointPort{
  1338  							{
  1339  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1340  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1341  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1342  							},
  1343  							{
  1344  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1345  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1346  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1347  							},
  1348  						},
  1349  					},
  1350  				}
  1351  			},
  1352  			setupWanted: func() *Endpoints {
  1353  				svcEP := newEmptyEndpoints()
  1354  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1355  					Ports: serviceStore.PortConfiguration{
  1356  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1357  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1358  					},
  1359  					NodeName: nodeName,
  1360  				}
  1361  				return svcEP
  1362  			},
  1363  		},
  1364  		{
  1365  			name: "endpoint with 2 addresses and 2 ports",
  1366  			setupArgs: func() args {
  1367  				return args{
  1368  					eps: &slim_discovery_v1.EndpointSlice{
  1369  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1370  						ObjectMeta:  meta,
  1371  						Endpoints: []slim_discovery_v1.Endpoint{
  1372  							{
  1373  								Addresses: []string{
  1374  									"172.0.0.1",
  1375  								},
  1376  								DeprecatedTopology: map[string]string{
  1377  									"kubernetes.io/hostname": nodeName,
  1378  								},
  1379  							},
  1380  							{
  1381  								Addresses: []string{
  1382  									"172.0.0.2",
  1383  								},
  1384  							},
  1385  						},
  1386  						Ports: []slim_discovery_v1.EndpointPort{
  1387  							{
  1388  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1389  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1390  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1391  							},
  1392  							{
  1393  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1394  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1395  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1396  							},
  1397  						},
  1398  					},
  1399  				}
  1400  			},
  1401  			setupWanted: func() *Endpoints {
  1402  				svcEP := newEmptyEndpoints()
  1403  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1404  					Ports: serviceStore.PortConfiguration{
  1405  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1406  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1407  					},
  1408  					NodeName: nodeName,
  1409  				}
  1410  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
  1411  					Ports: serviceStore.PortConfiguration{
  1412  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1413  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1414  					},
  1415  				}
  1416  				return svcEP
  1417  			},
  1418  		},
  1419  		{
  1420  			name: "endpoint with 2 addresses, 1 address not ready and 2 ports",
  1421  			setupArgs: func() args {
  1422  				return args{
  1423  					eps: &slim_discovery_v1.EndpointSlice{
  1424  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1425  						ObjectMeta:  meta,
  1426  						Endpoints: []slim_discovery_v1.Endpoint{
  1427  							{
  1428  								Addresses: []string{
  1429  									"172.0.0.1",
  1430  								},
  1431  								DeprecatedTopology: map[string]string{
  1432  									"kubernetes.io/hostname": nodeName,
  1433  								},
  1434  							},
  1435  							{
  1436  								Addresses: []string{
  1437  									"172.0.0.2",
  1438  								},
  1439  							},
  1440  							{
  1441  								Conditions: slim_discovery_v1.EndpointConditions{
  1442  									Ready: func() *bool { a := false; return &a }(),
  1443  								},
  1444  								Addresses: []string{
  1445  									"172.0.0.3",
  1446  								},
  1447  							},
  1448  						},
  1449  						Ports: []slim_discovery_v1.EndpointPort{
  1450  							{
  1451  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1452  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1453  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1454  							},
  1455  							{
  1456  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1457  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1458  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1459  							},
  1460  						},
  1461  					},
  1462  				}
  1463  			},
  1464  			setupWanted: func() *Endpoints {
  1465  				svcEP := newEmptyEndpoints()
  1466  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1467  					Ports: serviceStore.PortConfiguration{
  1468  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1469  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1470  					},
  1471  					NodeName: nodeName,
  1472  				}
  1473  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
  1474  					Ports: serviceStore.PortConfiguration{
  1475  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1476  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1477  					},
  1478  				}
  1479  				return svcEP
  1480  			},
  1481  		}, {
  1482  			name: "endpoint with 2 addresses, 1 address not ready and 2 ports",
  1483  			setupArgs: func() args {
  1484  				return args{
  1485  					eps: &slim_discovery_v1.EndpointSlice{
  1486  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1487  						ObjectMeta:  meta,
  1488  						Endpoints: []slim_discovery_v1.Endpoint{
  1489  							{
  1490  								Addresses: []string{
  1491  									"172.0.0.1",
  1492  								},
  1493  								NodeName: func() *string { return &nodeName }(),
  1494  							},
  1495  							{
  1496  								Addresses: []string{
  1497  									"172.0.0.2",
  1498  								},
  1499  							},
  1500  							{
  1501  								Conditions: slim_discovery_v1.EndpointConditions{
  1502  									Ready: func() *bool { a := false; return &a }(),
  1503  								},
  1504  								Addresses: []string{
  1505  									"172.0.0.3",
  1506  								},
  1507  							},
  1508  						},
  1509  						Ports: []slim_discovery_v1.EndpointPort{
  1510  							{
  1511  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1512  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1513  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1514  							},
  1515  							{
  1516  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1517  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1518  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1519  							},
  1520  						},
  1521  					},
  1522  				}
  1523  			},
  1524  			setupWanted: func() *Endpoints {
  1525  				svcEP := newEmptyEndpoints()
  1526  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1527  					Ports: serviceStore.PortConfiguration{
  1528  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1529  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1530  					},
  1531  					NodeName: nodeName,
  1532  				}
  1533  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
  1534  					Ports: serviceStore.PortConfiguration{
  1535  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1536  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1537  					},
  1538  				}
  1539  				return svcEP
  1540  			},
  1541  		},
  1542  		{
  1543  			name: "endpoints with some addresses not ready and not serving and terminating",
  1544  			setupArgs: func() args {
  1545  				return args{
  1546  					eps: &slim_discovery_v1.EndpointSlice{
  1547  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1548  						ObjectMeta:  meta,
  1549  						Endpoints: []slim_discovery_v1.Endpoint{
  1550  							{
  1551  								Addresses: []string{
  1552  									"172.0.0.1",
  1553  								},
  1554  							},
  1555  							{
  1556  								Conditions: slim_discovery_v1.EndpointConditions{
  1557  									Ready:       func() *bool { a := false; return &a }(),
  1558  									Serving:     func() *bool { a := false; return &a }(),
  1559  									Terminating: func() *bool { a := true; return &a }(),
  1560  								},
  1561  								Addresses: []string{
  1562  									"172.0.0.2",
  1563  								},
  1564  							},
  1565  						},
  1566  						Ports: []slim_discovery_v1.EndpointPort{
  1567  							{
  1568  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1569  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1570  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1571  							},
  1572  							{
  1573  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1574  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1575  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1576  							},
  1577  						},
  1578  					},
  1579  				}
  1580  			},
  1581  			setupWanted: func() *Endpoints {
  1582  				svcEP := newEmptyEndpoints()
  1583  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1584  					Ports: serviceStore.PortConfiguration{
  1585  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1586  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1587  					},
  1588  				}
  1589  				return svcEP
  1590  			},
  1591  		},
  1592  		{
  1593  			name: "endpoints with some addresses not ready and serving and terminating",
  1594  			setupArgs: func() args {
  1595  				return args{
  1596  					eps: &slim_discovery_v1.EndpointSlice{
  1597  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1598  						ObjectMeta:  meta,
  1599  						Endpoints: []slim_discovery_v1.Endpoint{
  1600  							{
  1601  								Addresses: []string{
  1602  									"172.0.0.1",
  1603  								},
  1604  							},
  1605  							{
  1606  								Conditions: slim_discovery_v1.EndpointConditions{
  1607  									Ready:       func() *bool { a := false; return &a }(),
  1608  									Serving:     func() *bool { a := true; return &a }(),
  1609  									Terminating: func() *bool { a := true; return &a }(),
  1610  								},
  1611  								Addresses: []string{
  1612  									"172.0.0.2",
  1613  								},
  1614  							},
  1615  						},
  1616  						Ports: []slim_discovery_v1.EndpointPort{
  1617  							{
  1618  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1619  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1620  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1621  							},
  1622  							{
  1623  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1624  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1625  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1626  							},
  1627  						},
  1628  					},
  1629  				}
  1630  			},
  1631  			setupWanted: func() *Endpoints {
  1632  				svcEP := newEmptyEndpoints()
  1633  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1634  					Ports: serviceStore.PortConfiguration{
  1635  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1636  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1637  					},
  1638  				}
  1639  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
  1640  					Ports: serviceStore.PortConfiguration{
  1641  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1642  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1643  					},
  1644  					Terminating: true,
  1645  				}
  1646  				return svcEP
  1647  			},
  1648  		},
  1649  		{
  1650  			name: "endpoints with some addresses not ready and terminating, EnableK8sTerminatingEndpoint disabled",
  1651  			setupArgs: func() args {
  1652  				return args{
  1653  					eps: &slim_discovery_v1.EndpointSlice{
  1654  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1655  						ObjectMeta:  meta,
  1656  						Endpoints: []slim_discovery_v1.Endpoint{
  1657  							{
  1658  								Addresses: []string{
  1659  									"172.0.0.1",
  1660  								},
  1661  							},
  1662  							{
  1663  								Conditions: slim_discovery_v1.EndpointConditions{
  1664  									Ready:       func() *bool { a := false; return &a }(),
  1665  									Terminating: func() *bool { a := true; return &a }(),
  1666  								},
  1667  								Addresses: []string{
  1668  									"172.0.0.2",
  1669  								},
  1670  							},
  1671  						},
  1672  						Ports: []slim_discovery_v1.EndpointPort{
  1673  							{
  1674  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1675  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1676  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1677  							},
  1678  							{
  1679  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1680  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1681  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1682  							},
  1683  						},
  1684  					},
  1685  					overrideConfig: func() {
  1686  						option.Config.EnableK8sTerminatingEndpoint = false
  1687  					},
  1688  				}
  1689  			},
  1690  			setupWanted: func() *Endpoints {
  1691  				svcEP := newEmptyEndpoints()
  1692  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1693  					Ports: serviceStore.PortConfiguration{
  1694  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1695  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1696  					},
  1697  				}
  1698  				return svcEP
  1699  			},
  1700  		},
  1701  		{
  1702  			name: "endpoints with all addresses ready and serving and terminating",
  1703  			setupArgs: func() args {
  1704  				return args{
  1705  					eps: &slim_discovery_v1.EndpointSlice{
  1706  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1707  						ObjectMeta:  meta,
  1708  						Endpoints: []slim_discovery_v1.Endpoint{
  1709  							{
  1710  								Conditions: slim_discovery_v1.EndpointConditions{
  1711  									Ready:       func() *bool { a := true; return &a }(),
  1712  									Serving:     func() *bool { a := true; return &a }(),
  1713  									Terminating: func() *bool { a := true; return &a }(),
  1714  								},
  1715  								Addresses: []string{
  1716  									"172.0.0.1",
  1717  								},
  1718  							},
  1719  						},
  1720  						Ports: []slim_discovery_v1.EndpointPort{
  1721  							{
  1722  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1723  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1724  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1725  							},
  1726  							{
  1727  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1728  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1729  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1730  							},
  1731  						},
  1732  					},
  1733  				}
  1734  			},
  1735  			setupWanted: func() *Endpoints {
  1736  				svcEP := newEmptyEndpoints()
  1737  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1738  					Ports: serviceStore.PortConfiguration{
  1739  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1740  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1741  					},
  1742  				}
  1743  				return svcEP
  1744  			},
  1745  		},
  1746  		{
  1747  			name: "endpoints with all addresses not ready and not serving and terminating",
  1748  			setupArgs: func() args {
  1749  				return args{
  1750  					eps: &slim_discovery_v1.EndpointSlice{
  1751  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1752  						ObjectMeta:  meta,
  1753  						Endpoints: []slim_discovery_v1.Endpoint{
  1754  							{
  1755  								Conditions: slim_discovery_v1.EndpointConditions{
  1756  									Ready:       func() *bool { a := false; return &a }(),
  1757  									Terminating: func() *bool { a := true; return &a }(),
  1758  								},
  1759  								Addresses: []string{
  1760  									"172.0.0.1",
  1761  								},
  1762  							},
  1763  							{
  1764  								Conditions: slim_discovery_v1.EndpointConditions{
  1765  									Ready:       func() *bool { a := false; return &a }(),
  1766  									Terminating: func() *bool { a := true; return &a }(),
  1767  								},
  1768  								Addresses: []string{
  1769  									"172.0.0.2",
  1770  								},
  1771  							},
  1772  						},
  1773  						Ports: []slim_discovery_v1.EndpointPort{
  1774  							{
  1775  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1776  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1777  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1778  							},
  1779  							{
  1780  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1781  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1782  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1783  							},
  1784  						},
  1785  					},
  1786  				}
  1787  			},
  1788  			setupWanted: func() *Endpoints {
  1789  				svcEP := newEmptyEndpoints()
  1790  				return svcEP
  1791  			},
  1792  		},
  1793  		{
  1794  			name: "endpoints with all addresses not ready and serving and terminating",
  1795  			setupArgs: func() args {
  1796  				return args{
  1797  					eps: &slim_discovery_v1.EndpointSlice{
  1798  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1799  						ObjectMeta:  meta,
  1800  						Endpoints: []slim_discovery_v1.Endpoint{
  1801  							{
  1802  								Conditions: slim_discovery_v1.EndpointConditions{
  1803  									Ready:       func() *bool { a := false; return &a }(),
  1804  									Serving:     func() *bool { a := true; return &a }(),
  1805  									Terminating: func() *bool { a := true; return &a }(),
  1806  								},
  1807  								Addresses: []string{
  1808  									"172.0.0.1",
  1809  								},
  1810  							},
  1811  							{
  1812  								Conditions: slim_discovery_v1.EndpointConditions{
  1813  									Ready:       func() *bool { a := false; return &a }(),
  1814  									Serving:     func() *bool { a := true; return &a }(),
  1815  									Terminating: func() *bool { a := true; return &a }(),
  1816  								},
  1817  								Addresses: []string{
  1818  									"172.0.0.2",
  1819  								},
  1820  							},
  1821  						},
  1822  						Ports: []slim_discovery_v1.EndpointPort{
  1823  							{
  1824  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1825  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1826  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1827  							},
  1828  							{
  1829  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1830  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1831  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1832  							},
  1833  						},
  1834  					},
  1835  				}
  1836  			},
  1837  			setupWanted: func() *Endpoints {
  1838  				svcEP := newEmptyEndpoints()
  1839  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1840  					Ports: serviceStore.PortConfiguration{
  1841  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1842  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1843  					},
  1844  					Terminating: true,
  1845  				}
  1846  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.2")] = &Backend{
  1847  					Ports: serviceStore.PortConfiguration{
  1848  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1849  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1850  					},
  1851  					Terminating: true,
  1852  				}
  1853  				return svcEP
  1854  			},
  1855  		},
  1856  		{
  1857  			name: "endpoints with some addresses not ready and terminating, EnableK8sTerminatingEndpoint disabled",
  1858  			setupArgs: func() args {
  1859  				return args{
  1860  					eps: &slim_discovery_v1.EndpointSlice{
  1861  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1862  						ObjectMeta:  meta,
  1863  						Endpoints: []slim_discovery_v1.Endpoint{
  1864  							{
  1865  								Addresses: []string{
  1866  									"172.0.0.1",
  1867  								},
  1868  							},
  1869  							{
  1870  								Conditions: slim_discovery_v1.EndpointConditions{
  1871  									Ready:       func() *bool { a := false; return &a }(),
  1872  									Terminating: func() *bool { a := true; return &a }(),
  1873  								},
  1874  								Addresses: []string{
  1875  									"172.0.0.2",
  1876  								},
  1877  							},
  1878  						},
  1879  						Ports: []slim_discovery_v1.EndpointPort{
  1880  							{
  1881  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1882  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1883  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1884  							},
  1885  							{
  1886  								Name:     func() *string { a := "http-test-svc-2"; return &a }(),
  1887  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1888  								Port:     func() *int32 { a := int32(8081); return &a }(),
  1889  							},
  1890  						},
  1891  					},
  1892  					overrideConfig: func() {
  1893  						option.Config.EnableK8sTerminatingEndpoint = false
  1894  					},
  1895  				}
  1896  			},
  1897  			setupWanted: func() *Endpoints {
  1898  				svcEP := newEmptyEndpoints()
  1899  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1900  					Ports: serviceStore.PortConfiguration{
  1901  						"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1902  						"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
  1903  					},
  1904  				}
  1905  				return svcEP
  1906  			},
  1907  		},
  1908  		{
  1909  			name: "endpoints have zone hints",
  1910  			setupArgs: func() args {
  1911  				return args{
  1912  					eps: &slim_discovery_v1.EndpointSlice{
  1913  						AddressType: slim_discovery_v1.AddressTypeIPv4,
  1914  						ObjectMeta:  meta,
  1915  						Endpoints: []slim_discovery_v1.Endpoint{
  1916  							{
  1917  								Addresses: []string{"172.0.0.1"},
  1918  								Hints: &slim_discovery_v1.EndpointHints{
  1919  									ForZones: []slim_discovery_v1.ForZone{{Name: "testing"}},
  1920  								},
  1921  							},
  1922  						},
  1923  						Ports: []slim_discovery_v1.EndpointPort{
  1924  							{
  1925  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1926  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1927  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1928  							},
  1929  						},
  1930  					},
  1931  				}
  1932  			},
  1933  			setupWanted: func() *Endpoints {
  1934  				svcEP := newEmptyEndpoints()
  1935  				svcEP.Backends[cmtypes.MustParseAddrCluster("172.0.0.1")] = &Backend{
  1936  					Ports: serviceStore.PortConfiguration{
  1937  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1938  					},
  1939  					HintsForZones: []string{"testing"},
  1940  				}
  1941  				return svcEP
  1942  			},
  1943  		},
  1944  		{
  1945  			name: "endpoint with IPv6 address type",
  1946  			setupArgs: func() args {
  1947  				return args{
  1948  					eps: &slim_discovery_v1.EndpointSlice{
  1949  						AddressType: slim_discovery_v1.AddressTypeIPv6,
  1950  						ObjectMeta:  meta,
  1951  						Endpoints: []slim_discovery_v1.Endpoint{
  1952  							{
  1953  								Addresses: []string{
  1954  									"fd00::1",
  1955  								},
  1956  							},
  1957  						},
  1958  						Ports: []slim_discovery_v1.EndpointPort{
  1959  							{
  1960  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1961  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1962  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1963  							},
  1964  						},
  1965  					},
  1966  				}
  1967  			},
  1968  			setupWanted: func() *Endpoints {
  1969  				svcEP := newEmptyEndpoints()
  1970  				svcEP.Backends[cmtypes.MustParseAddrCluster("fd00::1")] = &Backend{
  1971  					Ports: serviceStore.PortConfiguration{
  1972  						"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
  1973  					},
  1974  				}
  1975  				return svcEP
  1976  			},
  1977  		},
  1978  		{
  1979  			name: "endpoint with FQDN address type",
  1980  			setupArgs: func() args {
  1981  				return args{
  1982  					eps: &slim_discovery_v1.EndpointSlice{
  1983  						AddressType: slim_discovery_v1.AddressTypeFQDN,
  1984  						ObjectMeta:  meta,
  1985  						Endpoints: []slim_discovery_v1.Endpoint{
  1986  							{
  1987  								Addresses: []string{
  1988  									"foo.example.com",
  1989  								},
  1990  							},
  1991  						},
  1992  						Ports: []slim_discovery_v1.EndpointPort{
  1993  							{
  1994  								Name:     func() *string { a := "http-test-svc"; return &a }(),
  1995  								Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  1996  								Port:     func() *int32 { a := int32(8080); return &a }(),
  1997  							},
  1998  						},
  1999  					},
  2000  				}
  2001  			},
  2002  			setupWanted: func() *Endpoints {
  2003  				// We don't support FQDN address types. Should be empty.
  2004  				return newEmptyEndpoints()
  2005  			},
  2006  		},
  2007  	}
  2008  	for _, tt := range tests {
  2009  		args := tt.setupArgs()
  2010  		want := tt.setupWanted()
  2011  		if args.overrideConfig != nil {
  2012  			args.overrideConfig()
  2013  		} else {
  2014  			option.Config.EnableK8sTerminatingEndpoint = true
  2015  		}
  2016  		got := ParseEndpointSliceV1(args.eps)
  2017  		require.EqualValues(t, want, got, "Test name: %q", tt.name)
  2018  	}
  2019  }
  2020  
  2021  func Test_parseEndpointPortV1(t *testing.T) {
  2022  	type args struct {
  2023  		port slim_discovery_v1.EndpointPort
  2024  	}
  2025  	tests := []struct {
  2026  		name     string
  2027  		args     args
  2028  		portName string
  2029  		l4Addr   *loadbalancer.L4Addr
  2030  	}{
  2031  		{
  2032  			name: "tcp-port",
  2033  			args: args{
  2034  				port: slim_discovery_v1.EndpointPort{
  2035  					Name:     func() *string { a := "http-test-svc"; return &a }(),
  2036  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolTCP; return &a }(),
  2037  					Port:     func() *int32 { a := int32(8080); return &a }(),
  2038  				},
  2039  			},
  2040  			portName: "http-test-svc",
  2041  			l4Addr: &loadbalancer.L4Addr{
  2042  				Protocol: loadbalancer.TCP,
  2043  				Port:     8080,
  2044  			},
  2045  		},
  2046  		{
  2047  			name: "udp-port",
  2048  			args: args{
  2049  				port: slim_discovery_v1.EndpointPort{
  2050  					Name:     func() *string { a := "http-test-svc"; return &a }(),
  2051  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolUDP; return &a }(),
  2052  					Port:     func() *int32 { a := int32(8080); return &a }(),
  2053  				},
  2054  			},
  2055  			portName: "http-test-svc",
  2056  			l4Addr: &loadbalancer.L4Addr{
  2057  				Protocol: loadbalancer.UDP,
  2058  				Port:     8080,
  2059  			},
  2060  		},
  2061  		{
  2062  			name: "sctp-port",
  2063  			args: args{
  2064  				port: slim_discovery_v1.EndpointPort{
  2065  					Name:     func() *string { a := "sctp-test-svc"; return &a }(),
  2066  					Protocol: func() *slim_corev1.Protocol { a := slim_corev1.ProtocolSCTP; return &a }(),
  2067  					Port:     func() *int32 { a := int32(5555); return &a }(),
  2068  				},
  2069  			},
  2070  			portName: "sctp-test-svc",
  2071  			l4Addr: &loadbalancer.L4Addr{
  2072  				Protocol: loadbalancer.SCTP,
  2073  				Port:     5555,
  2074  			},
  2075  		},
  2076  		{
  2077  			name: "unset-protocol-should-have-tcp-port",
  2078  			args: args{
  2079  				port: slim_discovery_v1.EndpointPort{
  2080  					Name: func() *string { a := "http-test-svc"; return &a }(),
  2081  					Port: func() *int32 { a := int32(8080); return &a }(),
  2082  				},
  2083  			},
  2084  			portName: "http-test-svc",
  2085  			l4Addr: &loadbalancer.L4Addr{
  2086  				Protocol: loadbalancer.TCP,
  2087  				Port:     8080,
  2088  			},
  2089  		},
  2090  		{
  2091  			name: "unset-port-number-should-fail",
  2092  			args: args{
  2093  				port: slim_discovery_v1.EndpointPort{
  2094  					Name: func() *string { a := "http-test-svc"; return &a }(),
  2095  				},
  2096  			},
  2097  		},
  2098  	}
  2099  	for _, tt := range tests {
  2100  		t.Run(tt.name, func(t *testing.T) {
  2101  			gotPortName, gotL4Addr := parseEndpointPortV1(tt.args.port)
  2102  			if gotPortName != tt.portName {
  2103  				t.Errorf("parseEndpointPortV1() got = %v, want %v", gotPortName, tt.portName)
  2104  			}
  2105  			if !reflect.DeepEqual(gotL4Addr, tt.l4Addr) {
  2106  				t.Errorf("parseEndpointPortV1() got1 = %v, want %v", gotL4Addr, tt.l4Addr)
  2107  			}
  2108  		})
  2109  	}
  2110  }