agones.dev/agones@v1.54.0/cmd/allocator/main_test.go (about) 1 // Copyright 2019 Google LLC All Rights Reserved. 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 package main 15 16 import ( 17 "context" 18 "crypto/tls" 19 "crypto/x509" 20 "encoding/pem" 21 "net/http" 22 "os" 23 "testing" 24 25 pb "agones.dev/agones/pkg/allocation/go" 26 allocationv1 "agones.dev/agones/pkg/apis/allocation/v1" 27 "github.com/stretchr/testify/assert" 28 "google.golang.org/grpc/codes" 29 "google.golang.org/grpc/status" 30 corev1 "k8s.io/api/core/v1" 31 k8serror "k8s.io/apimachinery/pkg/api/errors" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 k8sruntime "k8s.io/apimachinery/pkg/runtime" 34 ) 35 36 func TestAllocateHandler(t *testing.T) { 37 t.Parallel() 38 39 h := serviceHandler{ 40 allocationCallback: func(_ *allocationv1.GameServerAllocation) (k8sruntime.Object, error) { 41 return &allocationv1.GameServerAllocation{ 42 ObjectMeta: metav1.ObjectMeta{ 43 Namespace: "default", 44 }, 45 Status: allocationv1.GameServerAllocationStatus{ 46 State: allocationv1.GameServerAllocationContention, 47 }, 48 }, nil 49 }, 50 } 51 52 request := &pb.AllocationRequest{ 53 Namespace: "ns", 54 MultiClusterSetting: &pb.MultiClusterSetting{ 55 Enabled: true, 56 }, 57 } 58 59 response, err := h.Allocate(context.Background(), request) 60 if !assert.Nil(t, response) { 61 return 62 } 63 st, ok := status.FromError(err) 64 if !assert.True(t, ok) { 65 return 66 } 67 assert.Equal(t, st.Code(), codes.Aborted) 68 } 69 70 func TestAllocateHandlerReturnsError(t *testing.T) { 71 t.Parallel() 72 73 h := serviceHandler{ 74 allocationCallback: func(_ *allocationv1.GameServerAllocation) (k8sruntime.Object, error) { 75 return nil, k8serror.NewBadRequest("error") 76 }, 77 } 78 79 request := &pb.AllocationRequest{} 80 _, err := h.Allocate(context.Background(), request) 81 if assert.Error(t, err) { 82 assert.Equal(t, "error", err.Error()) 83 } 84 } 85 86 func TestGetTlsCert(t *testing.T) { 87 t.Parallel() 88 cert1, err := tls.X509KeyPair(serverCert1, serverKey1) 89 assert.Nil(t, err, "expected (serverCert1, serverKey1) to create a cert") 90 91 cert2, err := tls.X509KeyPair(serverCert2, serverKey2) 92 assert.Nil(t, err, "expected (serverCert2, serverKey2) to create a cert") 93 94 h := serviceHandler{ 95 tlsCert: &cert1, 96 } 97 98 retrievedCert1, err := h.getTLSCert(nil) 99 assert.Nil(t, err, "expected getTlsCert() to not fail") 100 assert.Equal(t, cert1.Certificate, retrievedCert1.Certificate, "expected the retrieved cert to be equal to the original one") 101 102 h.tlsCert = &cert2 103 retrievedCert2, err := h.getTLSCert(nil) 104 assert.Nil(t, err, "expected getTlsCert() to not fail") 105 assert.Equal(t, cert2.Certificate, retrievedCert2.Certificate, "expected the retrieved cert to be equal to the original one") 106 } 107 108 func TestHandlingStatus(t *testing.T) { 109 t.Parallel() 110 111 errorMessage := "GameServerAllocation is invalid" 112 h := serviceHandler{ 113 allocationCallback: func(_ *allocationv1.GameServerAllocation) (k8sruntime.Object, error) { 114 return &metav1.Status{ 115 Status: metav1.StatusFailure, 116 Message: errorMessage, 117 Reason: metav1.StatusReasonInvalid, 118 Details: &metav1.StatusDetails{ 119 Kind: "GameServerAllocation", 120 Group: allocationv1.SchemeGroupVersion.Group, 121 }, 122 Code: http.StatusUnprocessableEntity, 123 }, nil 124 }, 125 } 126 127 request := &pb.AllocationRequest{} 128 _, err := h.Allocate(context.Background(), request) 129 if !assert.Error(t, err, "expecting failure") { 130 return 131 } 132 133 st, ok := status.FromError(err) 134 if !ok { 135 t.Errorf("expecting status error: %v", err) 136 } 137 assert.Equal(t, 422, int(st.Code())) 138 assert.Contains(t, st.Message(), errorMessage) 139 } 140 141 func TestBadReturnType(t *testing.T) { 142 t.Parallel() 143 144 h := serviceHandler{ 145 allocationCallback: func(_ *allocationv1.GameServerAllocation) (k8sruntime.Object, error) { 146 return &corev1.Secret{}, nil 147 }, 148 } 149 150 request := &pb.AllocationRequest{} 151 _, err := h.Allocate(context.Background(), request) 152 if !assert.Error(t, err, "expecting failure") { 153 return 154 } 155 156 st, ok := status.FromError(err) 157 if !ok { 158 t.Errorf("expecting status error: %v", err) 159 } 160 assert.Equal(t, codes.Internal, st.Code()) 161 assert.Contains(t, st.Message(), "internal server error") 162 } 163 164 func TestVerifyClientCertificateSucceeds(t *testing.T) { 165 t.Parallel() 166 167 crt := []byte(clientCert) 168 certPool := x509.NewCertPool() 169 assert.True(t, certPool.AppendCertsFromPEM(crt)) 170 171 h := serviceHandler{ 172 caCertPool: certPool, 173 } 174 175 block, _ := pem.Decode(crt) 176 input := [][]byte{block.Bytes} 177 assert.Nil(t, h.verifyClientCertificate(input, nil), 178 "verifyClientCertificate failed.") 179 } 180 181 func TestVerifyClientCertificateFails(t *testing.T) { 182 t.Parallel() 183 184 crt := []byte(clientCert) 185 certPool := x509.NewCertPool() 186 h := serviceHandler{ 187 caCertPool: certPool, 188 } 189 190 block, _ := pem.Decode(crt) 191 input := [][]byte{block.Bytes} 192 assert.Error(t, h.verifyClientCertificate(input, nil), 193 "verifyClientCertificate() succeeded, expected error.") 194 } 195 196 func TestGettingCaCert(t *testing.T) { 197 t.Parallel() 198 199 file, err := os.CreateTemp(".", "*.crt") 200 if assert.Nil(t, err) { 201 defer os.Remove(file.Name()) // nolint: errcheck 202 _, err = file.WriteString(clientCert) 203 if assert.Nil(t, err) { 204 certPool, err := getCACertPool("./") 205 if assert.Nil(t, err) { 206 // linting complaints certPool.Subjects() has been deprecated since Go 1.18. 207 // But since this cert doesn't come from SystemCertPool, it doesn't seem behavior 208 // should be impacted. So marking the lint as ignored. 209 assert.Len(t, certPool.Subjects(), 1) // nolint 210 } 211 } 212 } 213 } 214 215 var clientCert = `-----BEGIN CERTIFICATE----- 216 MIIDuzCCAqOgAwIBAgIUduDWtqpUsp3rZhCEfUrzI05laVIwDQYJKoZIhvcNAQEL 217 BQAwbTELMAkGA1UEBhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9u 218 ZG9uMRgwFgYDVQQKDA9HbG9iYWwgU2VjdXJpdHkxFjAUBgNVBAsMDUlUIERlcGFy 219 dG1lbnQxCjAIBgNVBAMMASowHhcNMTkwNTAyMjIzMDQ3WhcNMjkwNDI5MjIzMDQ3 220 WjBtMQswCQYDVQQGEwJHQjEPMA0GA1UECAwGTG9uZG9uMQ8wDQYDVQQHDAZMb25k 221 b24xGDAWBgNVBAoMD0dsb2JhbCBTZWN1cml0eTEWMBQGA1UECwwNSVQgRGVwYXJ0 222 bWVudDEKMAgGA1UEAwwBKjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 223 AKGDasjadVwe0bXUEQfZCkMEAkzn0qTud3RYytympmaS0c01SWFNZwPRO0rpdIOZ 224 fyXVXVOAhgmgCR6QuXySmyQIoYl/D6tVhc5r9FyWPIBtzQKCJTX0mZOZwMn22qvo 225 bfnDnVsZ1Ny3RLZIF3um3xovvePXyg1z7D/NvCogNuYpyUUEITPZX6ss5ods/U78 226 BxLhKrT8iyu61ZC+ZegbHQqFRngbeb348gE1JwKTslDfe4oH7tZ+bNDZxnGcvh9j 227 eyagpM0zys4gFfQf/vfD2aEsUJ+GesUQC6uGVoGnTFshFhBsAK6vpIQ4ZQujaJ0r 228 NKgJ/ccBJFiJXMCR44yWFY0CAwEAAaNTMFEwHQYDVR0OBBYEFEe1gDd8JpzgnvOo 229 1AEloAXxmxHCMB8GA1UdIwQYMBaAFEe1gDd8JpzgnvOo1AEloAXxmxHCMA8GA1Ud 230 EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI5GyuakVgunerCGCSN7Ghsr 231 ys9vJytbyT+BLmxNBPSXWQwcm3g9yCDdgf0Y3q3Eef7IEZu4I428318iLzhfKln1 232 ua4fxvmTFKJ65lQKNkc6Y4e3w1t+C2HOl6fOIVT231qsCoM5SAwQQpqAzEUj6kZl 233 x+3avw9KSlXqR/mCAkePyoKvprxeb6RVDdq92Ug0qzoAHLpvIkuHdlF0dNp6/kO0 234 1pVL0BqW+6UTimSSvH8F/cMeYKbkhpE1u2c/NtNwsR2jN4M9kl3KHqkynk67PfZv 235 pwlCqZx4M8FpdfCbOZeRLzClUBdD5qzev0L3RNUx7UJzEIN+4LCBv37DIojNOyA= 236 -----END CERTIFICATE----- 237 ` 238 239 var serverCert1 = []byte(`-----BEGIN CERTIFICATE----- 240 MIIFazCCA1OgAwIBAgIUD7ekqktGEe+F+pq3ACvxKLgSsK8wDQYJKoZIhvcNAQEL 241 BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 242 GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA2MjAwNTUxMzZaFw0yMTA2 243 MjAwNTUxMzZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw 244 HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB 245 AQUAA4ICDwAwggIKAoICAQCta6IXgSJHiScouNAQxGKiLWVvjdJRAkjW3eiCDq9Y 246 iOvM44282yBGOHs6RM9PL3egG5pTNMDDLHGEs+37h3nfxSmMav86g7wmOT989VX4 247 HfvLaOygFS2u2brU/9exHfgqIiYsosG5njh7waQ07t+MmzRyZhH4WC3JXXCE/ixi 248 9hYa7nFONWRJ7bgwfI1OjW77Bsu8nDJyYhqhJi7y4SC89vs1fxnW15iKGGCH9bs/ 249 jbYJox4egIPcDXm1t75eWP8yr9atyQp6IHYQeLw6UTiLHH7bWpOP5whtVvJAT95o 250 WfFRBHyrgnHI/q3OBMGpMCPJEWWN6AwBiSb5AqMDjuwrWams/mfR8doAeHihYoAV 251 4a7Oeo/uR51orsT5xHtsQUyD89O/nvcTG/awz4fqbidUrRuD0e04pxB/uqr6zsAg 252 RxBto42cgFsABYnVf1GH9uKBFoVxhiR933JXo8XkaRl7LRRKp6Dun8sf85frU+P/ 253 ciFrhC3MzPb2mQa8dnVO4OsYmkl3PlZv6deyZVCAyskEBkCXCjcXAm9T/HopTr6y 254 y4J5DNDvECs76yAPyVPKKF5F+aLTxhC7604FRTaDO6cNyhG1hOS2xU4qitZyl5Wo 255 pPE7q8EnXcgVi0k6IV42qCV+vpTB4m77C0ffsbGhzEwjAJi5+JZJ5OlMN1bMp3D3 256 NQIDAQABo1MwUTAdBgNVHQ4EFgQUPPx1Wuca7S2LCbVWfCstv+a7nAwwHwYDVR0j 257 BBgwFoAUPPx1Wuca7S2LCbVWfCstv+a7nAwwDwYDVR0TAQH/BAUwAwEB/zANBgkq 258 hkiG9w0BAQsFAAOCAgEAqFYw/cHnjCo9eF4SJZf6/zUaTWvr/5st7CotnThpMEPz 259 4HSjhXNW35b9a5a/PW/geFvkvftGCV21iCiNjySgAhoORsOHz6/FtVdmBflW7Rpf 260 dJ1jXPjJbscYNN1zcwIPOrHHq9TJHFibYI7E3J3L2G61DemBjPondsNlC+0gIJdA 261 YYvXQSTg+hhs6RjSLshbzS615Yh87N39+LvXE4sN5+uw+WrTqakn0CDvjzEMVrJk 262 cDHnC0201NYa/hbv+urwOQCY4bdnWqNXOCJGcUVuODs2VO7P99rU30Da0Yc2V0H3 263 CjWiM4Qy0/ETkE62+1lF34rzRDHxur2FPT8hu8nbN5KhgDTybce1dOUkYOJKEOTT 264 IitPCVXiVg2kloMT9vhx5oerxi8xqjHK4WaW3yIkbu2oDMjG8R/lKC4WdylDoQqk 265 K5WkRdrQQp2eMZwXdHtiyaITNE6Rbx7z10uFeOyZyHqsIRZnPz3YMXLrM0oeNtL9 266 fQpoiBeBJTvlQSjD8nWyeg/xSYLvO0jnWjfPbvmyhzmH8DERxsO1xq3OmVM04QhX 267 nj+x2nLIp3Ql0rQStHIpkFVKS96WTQFTNBUIWcXgFPZgbRw3BkRPLa4kbyT/n8y+ 268 BABcbxYpuM3TRnIMPai/1Vkg2H3FYladd4UJScSV9YUC23KJKQynrS+EXLamKdc= 269 -----END CERTIFICATE-----`) 270 var serverCert2 = []byte(`-----BEGIN CERTIFICATE----- 271 MIIFazCCA1OgAwIBAgIUJ/m4g8RwmRn5jh7C2wbTbmXGDNMwDQYJKoZIhvcNAQEL 272 BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 273 GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA2MjAwNTU0MDdaFw0yMTA2 274 MjAwNTU0MDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw 275 HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB 276 AQUAA4ICDwAwggIKAoICAQC0bL5NaI0OOcYzyWwtoNfHok2A9r4QdD7BlRwPkJqy 277 9N+VjMHw44IfLmmP3vmWMBt9tlIWqu8uUt8Hj2ExK+9H1TKsS1sf/FFpAb3m/Lvf 278 uahqYIu0IyAy+AmXnEkby7pggn2EPiVp5anisICQiyz0k9uh3vthztb+hxhMTkfp 279 HY4QHj2/yIvwPtIouPZEa3TVl4S89t4csngbZeCNvbHnovV9KmfZe6By4CvLYiBO 280 ui1RU07jw5NSeAyb/0gZ3HCqJZZzzK6pGpZBMjAQLVkxBjWevm8QZIu+O6RMj1Fe 281 45dumo3DQe8w119c/pPgYbgNqjWTR3qDyf8LbarKXOhWdSovb5vPXQodKOSC45/b 282 EyqMpYpeye2puK3Cd9k1+G7V2PYEeRhD6kSjbuikF5xlaEWksTLDHltQgGNrWG6T 283 /1MldsYzHwjAFVkDEDwpW9Rk2J7u4dFQYUq40StR8878iEZ7G3ljUJPpTUPbZz3L 284 lrIRWv4xrS5n8sYs33H/CmfkfXHcUvEKr3vd//DxtbIOSvoi0gJnf+BbekOWbN+A 285 2kYb3Obs0+pEEWW2WvArBAxPkcRZ4UUuQpAK7+IJ/pyE4ZiFT60PxsxktsMTaOqx 286 7KFfL9uo9hibT/ixcOzvZFQ3j2eeonulc3pNEfqfRu6VmMc3smzkiU/tGKXQRqxT 287 vQIDAQABo1MwUTAdBgNVHQ4EFgQUN3nVFUq0PIlf0zldkr7/GlqVnyUwHwYDVR0j 288 BBgwFoAUN3nVFUq0PIlf0zldkr7/GlqVnyUwDwYDVR0TAQH/BAUwAwEB/zANBgkq 289 hkiG9w0BAQsFAAOCAgEABX2nkrHmp5v731XVWETWgLNpi11pe9rQRlO4sdFgfVYB 290 GuArap0HsooULPO0AKECELwKZ6NpW0Kqkul0jSQEusDbTsMwCW44HYYnR93suJ2D 291 7X4SY/G5aSnyj/6JotSKFTCnSu2DGdxaKs7ufKJf0G5n8FLSJJaeCUNrklXSRObG 292 qrk533Du97RT19us1/48YxuDiSFrlElVVleTZRLwI8zDf3ikXsESUJmMVRw5dxWm 293 WCNgdYY3hjeMLGHa3l5CzmmcGNaZVjrSxn1aE8Qiau2q/u5ScqFOtT7aMYvXSAEn 294 fv86V46If/jXZ9MnjMXcwO7Dh/bdgCaNBXsATcQVsyNfAv0PM5TRTLYI+q+tZr6a 295 TAwx78VoBkD/C3E9wquj2bBxtrjKHwQkVfgOinvHNYU20pW4J8AdrZvuEPyV60zs 296 uZnCH1E21KO20U0DdBUJ2sVCFjw2tF/T9sFpd10nGthMBrPamSD3anG3C+En2usE 297 YsJtdsxpNyMnV1cq7E/8rXmarQ3fHtAq1AlcMe0Dtz7tc4JLhNxu1qwjkHW+Wddc 298 D8ky1I78OMA3rj1Z6etXve+K+3BwP2CNWCN2iTZzlY4k4X1QUX6cBD/UbykEvpp6 299 jVgXv9Y4mMlGeJOaOqEysMXltsGL0f6E0QBUBMs8z/5NU7WkoMUdH3UY8QP6hLA= 300 -----END CERTIFICATE-----`) 301 302 var serverKey1 = []byte(`-----BEGIN PRIVATE KEY----- 303 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 352 kEIJI+7KY0lG3Ig3y5XPRM6kzYKGjA== 353 -----END PRIVATE KEY-----`) 354 var serverKey2 = []byte(`-----BEGIN PRIVATE KEY----- 355 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 404 xA2QN+Zomk0SRjSeYzZO/DT3LTykJXE= 405 -----END PRIVATE KEY-----`)