github.com/imran-kn/cilium-fork@v1.6.9/pkg/k8s/endpoints_test.go (about)

     1  // Copyright 2018-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build !privileged_tests
    16  
    17  package k8s
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/cilium/cilium/pkg/checker"
    23  	"github.com/cilium/cilium/pkg/k8s/types"
    24  	"github.com/cilium/cilium/pkg/loadbalancer"
    25  	"github.com/cilium/cilium/pkg/service"
    26  
    27  	"gopkg.in/check.v1"
    28  	"k8s.io/api/core/v1"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  )
    31  
    32  func TestEndpoints_DeepEqual(t *testing.T) {
    33  	type fields struct {
    34  		svcEP *Endpoints
    35  	}
    36  	type args struct {
    37  		o *Endpoints
    38  	}
    39  	tests := []struct {
    40  		name   string
    41  		fields fields
    42  		args   args
    43  		want   bool
    44  	}{
    45  
    46  		{
    47  			name: "both equal",
    48  			fields: fields{
    49  				svcEP: &Endpoints{
    50  					Backends: map[string]service.PortConfiguration{
    51  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
    52  							"foo": {
    53  								Protocol: loadbalancer.NONE,
    54  								Port:     1,
    55  							},
    56  						},
    57  					},
    58  				},
    59  			},
    60  			args: args{
    61  				o: &Endpoints{
    62  					Backends: map[string]service.PortConfiguration{
    63  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
    64  							"foo": {
    65  								Protocol: loadbalancer.NONE,
    66  								Port:     1,
    67  							},
    68  						},
    69  					},
    70  				},
    71  			},
    72  			want: true,
    73  		},
    74  		{
    75  			name: "different BE IPs",
    76  			fields: fields{
    77  				svcEP: &Endpoints{
    78  					Backends: map[string]service.PortConfiguration{
    79  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
    80  							"foo": {
    81  								Protocol: loadbalancer.NONE,
    82  								Port:     1,
    83  							},
    84  						},
    85  					},
    86  				},
    87  			},
    88  			args: args{
    89  				o: &Endpoints{
    90  					Backends: map[string]service.PortConfiguration{
    91  						"172.20.0.2": map[string]*loadbalancer.L4Addr{
    92  							"foo": {
    93  								Protocol: loadbalancer.NONE,
    94  								Port:     1,
    95  							},
    96  						},
    97  					},
    98  				},
    99  			},
   100  			want: false,
   101  		},
   102  		{
   103  			name: "ports different name",
   104  			fields: fields{
   105  				svcEP: &Endpoints{
   106  					Backends: map[string]service.PortConfiguration{
   107  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   108  							"foo": {
   109  								Protocol: loadbalancer.NONE,
   110  								Port:     1,
   111  							},
   112  						},
   113  					},
   114  				},
   115  			},
   116  			args: args{
   117  				o: &Endpoints{
   118  					Backends: map[string]service.PortConfiguration{
   119  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   120  							"foz": {
   121  								Protocol: loadbalancer.NONE,
   122  								Port:     1,
   123  							},
   124  						},
   125  					},
   126  				},
   127  			},
   128  			want: false,
   129  		},
   130  		{
   131  			name: "ports different content",
   132  			fields: fields{
   133  				svcEP: &Endpoints{
   134  					Backends: map[string]service.PortConfiguration{
   135  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   136  							"foo": {
   137  								Protocol: loadbalancer.NONE,
   138  								Port:     1,
   139  							},
   140  						},
   141  					},
   142  				},
   143  			},
   144  			args: args{
   145  				o: &Endpoints{
   146  					Backends: map[string]service.PortConfiguration{
   147  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   148  							"foo": {
   149  								Protocol: loadbalancer.NONE,
   150  								Port:     2,
   151  							},
   152  						},
   153  					},
   154  				},
   155  			},
   156  			want: false,
   157  		},
   158  		{
   159  			name: "ports different one is bigger",
   160  			fields: fields{
   161  				svcEP: &Endpoints{
   162  					Backends: map[string]service.PortConfiguration{
   163  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   164  							"foo": {
   165  								Protocol: loadbalancer.NONE,
   166  								Port:     1,
   167  							},
   168  						},
   169  					},
   170  				},
   171  			},
   172  			args: args{
   173  				o: &Endpoints{
   174  					Backends: map[string]service.PortConfiguration{
   175  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   176  							"foo": {
   177  								Protocol: loadbalancer.NONE,
   178  								Port:     1,
   179  							},
   180  							"baz": {
   181  								Protocol: loadbalancer.NONE,
   182  								Port:     2,
   183  							},
   184  						},
   185  					},
   186  				},
   187  			},
   188  			want: false,
   189  		},
   190  		{
   191  			name:   "ports different one is nil",
   192  			fields: fields{},
   193  			args: args{
   194  				o: &Endpoints{
   195  					Backends: map[string]service.PortConfiguration{
   196  						"172.20.0.1": map[string]*loadbalancer.L4Addr{
   197  							"foo": {
   198  								Protocol: loadbalancer.NONE,
   199  								Port:     1,
   200  							},
   201  						},
   202  					},
   203  				},
   204  			},
   205  			want: false,
   206  		},
   207  		{
   208  			name: "both nil",
   209  			args: args{},
   210  			want: true,
   211  		},
   212  	}
   213  	for _, tt := range tests {
   214  		t.Run(tt.name, func(t *testing.T) {
   215  			if got := tt.fields.svcEP.DeepEquals(tt.args.o); got != tt.want {
   216  				t.Errorf("Endpoints.DeepEqual() = %v, want %v", got, tt.want)
   217  			}
   218  		})
   219  	}
   220  }
   221  
   222  func (s *K8sSuite) Test_parseK8sEPv1(c *check.C) {
   223  	type args struct {
   224  		eps *types.Endpoints
   225  	}
   226  	tests := []struct {
   227  		name        string
   228  		setupArgs   func() args
   229  		setupWanted func() *Endpoints
   230  	}{
   231  		{
   232  			name: "empty endpoint",
   233  			setupArgs: func() args {
   234  				return args{
   235  					eps: &types.Endpoints{
   236  						Endpoints: &v1.Endpoints{
   237  							ObjectMeta: metav1.ObjectMeta{
   238  								Name:      "foo",
   239  								Namespace: "bar",
   240  							},
   241  						},
   242  					},
   243  				}
   244  			},
   245  			setupWanted: func() *Endpoints {
   246  				return newEndpoints()
   247  			},
   248  		},
   249  		{
   250  			name: "endpoint with an address and port",
   251  			setupArgs: func() args {
   252  				return args{
   253  					eps: &types.Endpoints{
   254  						Endpoints: &v1.Endpoints{
   255  							ObjectMeta: metav1.ObjectMeta{
   256  								Name:      "foo",
   257  								Namespace: "bar",
   258  							},
   259  							Subsets: []v1.EndpointSubset{
   260  								{
   261  									Addresses: []v1.EndpointAddress{
   262  										{
   263  											IP: "172.0.0.1",
   264  										},
   265  									},
   266  									Ports: []v1.EndpointPort{
   267  										{
   268  											Name:     "http-test-svc",
   269  											Port:     8080,
   270  											Protocol: v1.ProtocolTCP,
   271  										},
   272  									},
   273  								},
   274  							},
   275  						},
   276  					},
   277  				}
   278  			},
   279  			setupWanted: func() *Endpoints {
   280  				svcEP := newEndpoints()
   281  				svcEP.Backends["172.0.0.1"] = service.PortConfiguration{
   282  					"http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   283  				}
   284  				return svcEP
   285  			},
   286  		},
   287  		{
   288  			name: "endpoint with an address and 2 ports",
   289  			setupArgs: func() args {
   290  				return args{
   291  					eps: &types.Endpoints{
   292  						Endpoints: &v1.Endpoints{
   293  							ObjectMeta: metav1.ObjectMeta{
   294  								Name:      "foo",
   295  								Namespace: "bar",
   296  							},
   297  							Subsets: []v1.EndpointSubset{
   298  								{
   299  									Addresses: []v1.EndpointAddress{
   300  										{
   301  											IP: "172.0.0.1",
   302  										},
   303  									},
   304  									Ports: []v1.EndpointPort{
   305  										{
   306  											Name:     "http-test-svc",
   307  											Port:     8080,
   308  											Protocol: v1.ProtocolTCP,
   309  										},
   310  										{
   311  											Name:     "http-test-svc-2",
   312  											Port:     8081,
   313  											Protocol: v1.ProtocolTCP,
   314  										},
   315  									},
   316  								},
   317  							},
   318  						},
   319  					},
   320  				}
   321  			},
   322  			setupWanted: func() *Endpoints {
   323  				svcEP := newEndpoints()
   324  				svcEP.Backends["172.0.0.1"] = service.PortConfiguration{
   325  					"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   326  					"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   327  				}
   328  				return svcEP
   329  			},
   330  		},
   331  		{
   332  			name: "endpoint with 2 addresses and 2 ports",
   333  			setupArgs: func() args {
   334  				return args{
   335  					eps: &types.Endpoints{
   336  						Endpoints: &v1.Endpoints{
   337  							ObjectMeta: metav1.ObjectMeta{
   338  								Name:      "foo",
   339  								Namespace: "bar",
   340  							},
   341  							Subsets: []v1.EndpointSubset{
   342  								{
   343  									Addresses: []v1.EndpointAddress{
   344  										{
   345  											IP: "172.0.0.1",
   346  										},
   347  										{
   348  											IP: "172.0.0.2",
   349  										},
   350  									},
   351  									Ports: []v1.EndpointPort{
   352  										{
   353  											Name:     "http-test-svc",
   354  											Port:     8080,
   355  											Protocol: v1.ProtocolTCP,
   356  										},
   357  										{
   358  											Name:     "http-test-svc-2",
   359  											Port:     8081,
   360  											Protocol: v1.ProtocolTCP,
   361  										},
   362  									},
   363  								},
   364  							},
   365  						},
   366  					},
   367  				}
   368  			},
   369  			setupWanted: func() *Endpoints {
   370  				svcEP := newEndpoints()
   371  				svcEP.Backends["172.0.0.1"] = service.PortConfiguration{
   372  					"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   373  					"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   374  				}
   375  				svcEP.Backends["172.0.0.2"] = service.PortConfiguration{
   376  					"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   377  					"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   378  				}
   379  				return svcEP
   380  			},
   381  		},
   382  		{
   383  			name: "endpoint with 2 addresses, 1 address not ready and 2 ports",
   384  			setupArgs: func() args {
   385  				return args{
   386  					eps: &types.Endpoints{
   387  						Endpoints: &v1.Endpoints{
   388  							ObjectMeta: metav1.ObjectMeta{
   389  								Name:      "foo",
   390  								Namespace: "bar",
   391  							},
   392  							Subsets: []v1.EndpointSubset{
   393  								{
   394  									NotReadyAddresses: []v1.EndpointAddress{
   395  										{
   396  											IP: "172.0.0.3",
   397  										},
   398  									},
   399  									Addresses: []v1.EndpointAddress{
   400  										{
   401  											IP: "172.0.0.1",
   402  										},
   403  										{
   404  											IP: "172.0.0.2",
   405  										},
   406  									},
   407  									Ports: []v1.EndpointPort{
   408  										{
   409  											Name:     "http-test-svc",
   410  											Port:     8080,
   411  											Protocol: v1.ProtocolTCP,
   412  										},
   413  										{
   414  											Name:     "http-test-svc-2",
   415  											Port:     8081,
   416  											Protocol: v1.ProtocolTCP,
   417  										},
   418  									},
   419  								},
   420  							},
   421  						},
   422  					},
   423  				}
   424  			},
   425  			setupWanted: func() *Endpoints {
   426  				svcEP := newEndpoints()
   427  				svcEP.Backends["172.0.0.1"] = service.PortConfiguration{
   428  					"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   429  					"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   430  				}
   431  				svcEP.Backends["172.0.0.2"] = service.PortConfiguration{
   432  					"http-test-svc":   loadbalancer.NewL4Addr(loadbalancer.TCP, 8080),
   433  					"http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081),
   434  				}
   435  				return svcEP
   436  			},
   437  		},
   438  	}
   439  	for _, tt := range tests {
   440  		args := tt.setupArgs()
   441  		want := tt.setupWanted()
   442  		_, got := ParseEndpoints(args.eps)
   443  		c.Assert(got, checker.DeepEquals, want, check.Commentf("Test name: %q", tt.name))
   444  	}
   445  }
   446  
   447  func (s *K8sSuite) TestEndpointsString(c *check.C) {
   448  	endpoints := &types.Endpoints{
   449  		Endpoints: &v1.Endpoints{
   450  			ObjectMeta: metav1.ObjectMeta{
   451  				Name:      "foo",
   452  				Namespace: "bar",
   453  			},
   454  			Subsets: []v1.EndpointSubset{
   455  				{
   456  					Addresses: []v1.EndpointAddress{
   457  						{
   458  							IP: "172.0.0.2",
   459  						},
   460  						{
   461  							IP: "172.0.0.1",
   462  						},
   463  					},
   464  					Ports: []v1.EndpointPort{
   465  						{
   466  							Name:     "http-test-svc-2",
   467  							Port:     8081,
   468  							Protocol: v1.ProtocolTCP,
   469  						},
   470  						{
   471  							Name:     "http-test-svc",
   472  							Port:     8080,
   473  							Protocol: v1.ProtocolTCP,
   474  						},
   475  					},
   476  				},
   477  			},
   478  		},
   479  	}
   480  
   481  	_, ep := ParseEndpoints(endpoints)
   482  	c.Assert(ep.String(), check.Equals, "172.0.0.1:8080/TCP,172.0.0.1:8081/TCP,172.0.0.2:8080/TCP,172.0.0.2:8081/TCP")
   483  }