github.com/cilium/cilium@v1.16.2/pkg/service/store/store_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package store
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	"k8s.io/utils/ptr"
    12  
    13  	"github.com/cilium/cilium/pkg/loadbalancer"
    14  )
    15  
    16  func TestClusterService(t *testing.T) {
    17  	svc := NewClusterService("foo", "bar")
    18  	svc.Cluster = "default"
    19  
    20  	require.Equal(t, "foo", svc.Name)
    21  	require.Equal(t, "bar", svc.Namespace)
    22  
    23  	require.Equal(t, "default/bar/foo", svc.String())
    24  
    25  	b, err := svc.Marshal()
    26  	require.Nil(t, err)
    27  
    28  	unmarshal := ClusterService{}
    29  	err = unmarshal.Unmarshal("", b)
    30  	require.Nil(t, err)
    31  	require.EqualValues(t, unmarshal, svc)
    32  
    33  	require.Equal(t, "default/bar/foo", svc.GetKeyName())
    34  }
    35  
    36  func TestPortConfigurationDeepEqual(t *testing.T) {
    37  	tests := []struct {
    38  		a    PortConfiguration
    39  		b    PortConfiguration
    40  		want bool
    41  	}{
    42  
    43  		{
    44  			a: PortConfiguration{
    45  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    46  			},
    47  			b: PortConfiguration{
    48  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    49  			},
    50  			want: true,
    51  		},
    52  		{
    53  			a: PortConfiguration{
    54  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    55  			},
    56  			b: PortConfiguration{
    57  				"foz": {Protocol: loadbalancer.NONE, Port: 1},
    58  			},
    59  			want: false,
    60  		},
    61  		{
    62  			a: PortConfiguration{
    63  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    64  			},
    65  			b: PortConfiguration{
    66  				"foo": {Protocol: loadbalancer.NONE, Port: 2},
    67  			},
    68  			want: false,
    69  		},
    70  		{
    71  			a: PortConfiguration{
    72  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    73  			},
    74  			b: PortConfiguration{
    75  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    76  				"baz": {Protocol: loadbalancer.NONE, Port: 2},
    77  			},
    78  			want: false,
    79  		},
    80  		{
    81  			a: PortConfiguration{},
    82  			b: PortConfiguration{
    83  				"foo": {Protocol: loadbalancer.NONE, Port: 1},
    84  			},
    85  			want: false,
    86  		},
    87  		{
    88  			want: true,
    89  		},
    90  	}
    91  	for _, tt := range tests {
    92  		got := tt.a.DeepEqual(&tt.b)
    93  		require.Equalf(t, tt.want, got, "PortConfiguration.DeepEqual() = %v, want %v", got, tt.want)
    94  	}
    95  }
    96  
    97  func TestClusterServiceValidate(t *testing.T) {
    98  	tests := []struct {
    99  		name   string
   100  		svc    ClusterService
   101  		assert assert.ErrorAssertionFunc
   102  	}{
   103  		{
   104  			name:   "empty",
   105  			svc:    ClusterService{},
   106  			assert: assert.Error,
   107  		},
   108  		{
   109  			name:   "minimum information",
   110  			svc:    ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux"},
   111  			assert: assert.NoError,
   112  		},
   113  		{
   114  			name: "valid",
   115  			svc: ClusterService{
   116  				Cluster: "foo", Namespace: "bar", Name: "qux",
   117  				ClusterID: 99,
   118  				Frontends: map[string]PortConfiguration{"10.1.2.3": {}, "abcd::0001": {}},
   119  				Backends:  map[string]PortConfiguration{"10.3.2.1": {}, "dcba::0001": {}},
   120  			},
   121  			assert: assert.NoError,
   122  		},
   123  		{
   124  			name:   "invalid cluster ID",
   125  			svc:    ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux", ClusterID: 260},
   126  			assert: assert.Error,
   127  		},
   128  		{
   129  			name: "invalid frontend IP",
   130  			svc: ClusterService{
   131  				Cluster: "foo", Namespace: "bar", Name: "qux",
   132  				Frontends: map[string]PortConfiguration{"10.1.2.3": {}, "invalid": {}},
   133  			},
   134  			assert: assert.Error,
   135  		},
   136  		{
   137  			name: "invalid backend IP",
   138  			svc: ClusterService{
   139  				Cluster: "foo", Namespace: "bar", Name: "qux",
   140  				Backends: map[string]PortConfiguration{"invalid": {}, "dcba::0001": {}},
   141  			},
   142  			assert: assert.Error,
   143  		},
   144  	}
   145  
   146  	for _, tt := range tests {
   147  		t.Run(tt.name, func(t *testing.T) {
   148  			tt.assert(t, tt.svc.validate())
   149  		})
   150  	}
   151  }
   152  
   153  func TestValidatingClusterService(t *testing.T) {
   154  	tests := []struct {
   155  		name      string
   156  		key       string
   157  		svc       ClusterService
   158  		validator clusterServiceValidator
   159  		errstr    string
   160  	}{
   161  		{
   162  			name:      "valid cluster name",
   163  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux"},
   164  			validator: ClusterNameValidator("foo"),
   165  		},
   166  		{
   167  			name:      "invalid cluster name",
   168  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux"},
   169  			validator: ClusterNameValidator("fred"),
   170  			errstr:    "unexpected cluster name: got foo, expected fred",
   171  		},
   172  		{
   173  			name:      "valid namespaced name",
   174  			key:       "bar/qux",
   175  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux"},
   176  			validator: NamespacedNameValidator(),
   177  		},
   178  		{
   179  			name:      "invalid namespaced name",
   180  			key:       "fred/qux",
   181  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux"},
   182  			validator: NamespacedNameValidator(),
   183  			errstr:    "namespaced name does not match key: got bar/qux, expected fred/qux",
   184  		},
   185  		{
   186  			name:      "valid cluster ID",
   187  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux", ClusterID: 10},
   188  			validator: ClusterIDValidator(ptr.To[uint32](10)),
   189  		},
   190  		{
   191  			name:      "invalid cluster ID",
   192  			svc:       ClusterService{Cluster: "foo", Namespace: "bar", Name: "qux", ClusterID: 10},
   193  			validator: ClusterIDValidator(ptr.To[uint32](15)),
   194  			errstr:    "unexpected cluster ID: got 10, expected 15",
   195  		},
   196  	}
   197  
   198  	for _, tt := range tests {
   199  		t.Run(tt.name, func(t *testing.T) {
   200  			data, err := tt.svc.Marshal()
   201  			require.NoError(t, err)
   202  
   203  			got := KeyCreator(tt.validator)()
   204  			err = got.Unmarshal(tt.key, data)
   205  			if tt.errstr != "" {
   206  				require.EqualError(t, err, tt.errstr)
   207  				return
   208  			}
   209  
   210  			require.NoError(t, err)
   211  			require.Equal(t, tt.svc, got.(*ValidatingClusterService).ClusterService)
   212  		})
   213  	}
   214  }