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 }