github.com/kyma-project/kyma/components/asset-store-controller-manager@v0.0.0-20191203152857-3792b5df17c5/internal/store/store_test.go (about) 1 package store_test 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "testing" 8 9 "github.com/kyma-project/kyma/components/asset-store-controller-manager/internal/store" 10 "github.com/kyma-project/kyma/components/asset-store-controller-manager/internal/store/automock" 11 "github.com/kyma-project/kyma/components/asset-store-controller-manager/pkg/apis/assetstore/v1alpha2" 12 "github.com/minio/minio-go" 13 "github.com/onsi/gomega" 14 "github.com/pkg/errors" 15 "github.com/stretchr/testify/mock" 16 ) 17 18 func TestStore_BucketExists(t *testing.T) { 19 t.Run("Exists", func(t *testing.T) { 20 // Given 21 g := gomega.NewGomegaWithT(t) 22 name := "test-bucket" 23 24 minio := new(automock.MinioClient) 25 minio.On("BucketExists", name).Return(true, nil).Once() 26 defer minio.AssertExpectations(t) 27 28 store := store.New(minio, 1) 29 30 // When 31 exists, err := store.BucketExists(name) 32 33 // Then 34 g.Expect(err).NotTo(gomega.HaveOccurred()) 35 g.Expect(exists).To(gomega.Equal(true)) 36 }) 37 38 t.Run("NotExists", func(t *testing.T) { 39 // Given 40 g := gomega.NewGomegaWithT(t) 41 name := "test-bucket" 42 43 minio := new(automock.MinioClient) 44 minio.On("BucketExists", name).Return(false, nil).Once() 45 defer minio.AssertExpectations(t) 46 47 store := store.New(minio, 1) 48 49 // When 50 exists, err := store.BucketExists(name) 51 52 // Then 53 g.Expect(err).NotTo(gomega.HaveOccurred()) 54 g.Expect(exists).To(gomega.Equal(false)) 55 }) 56 57 t.Run("Error", func(t *testing.T) { 58 // Given 59 g := gomega.NewGomegaWithT(t) 60 name := "test-bucket" 61 62 minio := new(automock.MinioClient) 63 minio.On("BucketExists", name).Return(false, fmt.Errorf("test error")).Once() 64 defer minio.AssertExpectations(t) 65 66 store := store.New(minio, 1) 67 68 // When 69 exists, err := store.BucketExists(name) 70 71 // Then 72 g.Expect(err).To(gomega.HaveOccurred()) 73 g.Expect(exists).To(gomega.Equal(false)) 74 }) 75 } 76 77 func TestStore_CompareBucketPolicy(t *testing.T) { 78 t.Run("SuccessNone", func(t *testing.T) { 79 // Given 80 g := gomega.NewGomegaWithT(t) 81 bucketName := "test-bucket" 82 expectedPolicy := v1alpha2.BucketPolicyNone 83 remotePolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[]}" 84 85 minio := new(automock.MinioClient) 86 minio.On("GetBucketPolicy", bucketName).Return(remotePolicy, nil).Once() 87 defer minio.AssertExpectations(t) 88 89 store := store.New(minio, 1) 90 91 // When 92 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 93 94 // Then 95 g.Expect(err).NotTo(gomega.HaveOccurred()) 96 g.Expect(equal).To(gomega.Equal(true)) 97 }) 98 99 t.Run("SuccessReadOnly", func(t *testing.T) { 100 // Given 101 g := gomega.NewGomegaWithT(t) 102 bucketName := "test-bucket" 103 expectedPolicy := v1alpha2.BucketPolicyReadOnly 104 remotePolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:GetObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 105 106 minio := new(automock.MinioClient) 107 minio.On("GetBucketPolicy", bucketName).Return(remotePolicy, nil).Once() 108 defer minio.AssertExpectations(t) 109 110 store := store.New(minio, 1) 111 112 // When 113 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 114 115 // Then 116 g.Expect(err).NotTo(gomega.HaveOccurred()) 117 g.Expect(equal).To(gomega.Equal(true)) 118 }) 119 120 t.Run("SuccessWriteOnly", func(t *testing.T) { 121 // Given 122 g := gomega.NewGomegaWithT(t) 123 bucketName := "test-bucket" 124 expectedPolicy := v1alpha2.BucketPolicyWriteOnly 125 remotePolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 126 127 minio := new(automock.MinioClient) 128 minio.On("GetBucketPolicy", bucketName).Return(remotePolicy, nil).Once() 129 defer minio.AssertExpectations(t) 130 131 store := store.New(minio, 1) 132 133 // When 134 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 135 136 // Then 137 g.Expect(err).NotTo(gomega.HaveOccurred()) 138 g.Expect(equal).To(gomega.Equal(true)) 139 }) 140 141 t.Run("SuccessReadWrite", func(t *testing.T) { 142 // Given 143 g := gomega.NewGomegaWithT(t) 144 bucketName := "test-bucket" 145 expectedPolicy := v1alpha2.BucketPolicyReadWrite 146 remotePolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 147 148 minio := new(automock.MinioClient) 149 minio.On("GetBucketPolicy", bucketName).Return(remotePolicy, nil).Once() 150 defer minio.AssertExpectations(t) 151 152 store := store.New(minio, 1) 153 154 // When 155 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 156 157 // Then 158 g.Expect(err).NotTo(gomega.HaveOccurred()) 159 g.Expect(equal).To(gomega.Equal(true)) 160 }) 161 162 t.Run("SuccessMerged", func(t *testing.T) { 163 // Given 164 g := gomega.NewGomegaWithT(t) 165 bucketName := "test-bucket" 166 expectedPolicy := v1alpha2.BucketPolicyReadOnly 167 remotePolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:GetObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\",\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 168 169 minio := new(automock.MinioClient) 170 minio.On("GetBucketPolicy", bucketName).Return(remotePolicy, nil).Once() 171 defer minio.AssertExpectations(t) 172 173 store := store.New(minio, 1) 174 175 // When 176 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 177 178 // Then 179 g.Expect(err).NotTo(gomega.HaveOccurred()) 180 g.Expect(equal).To(gomega.Equal(true)) 181 }) 182 183 t.Run("EmptyRemotePolicy", func(t *testing.T) { 184 // Given 185 g := gomega.NewGomegaWithT(t) 186 bucketName := "test-bucket" 187 expectedPolicy := v1alpha2.BucketPolicyNone 188 189 minio := new(automock.MinioClient) 190 minio.On("GetBucketPolicy", bucketName).Return("", nil).Once() 191 defer minio.AssertExpectations(t) 192 193 store := store.New(minio, 1) 194 195 // When 196 equal, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 197 198 // Then 199 g.Expect(err).NotTo(gomega.HaveOccurred()) 200 g.Expect(equal).To(gomega.Equal(false)) 201 }) 202 203 t.Run("Error", func(t *testing.T) { 204 // Given 205 g := gomega.NewGomegaWithT(t) 206 bucketName := "test-bucket" 207 expectedPolicy := v1alpha2.BucketPolicyNone 208 209 minio := new(automock.MinioClient) 210 minio.On("GetBucketPolicy", bucketName).Return("", errors.New("test-error")).Once() 211 defer minio.AssertExpectations(t) 212 213 store := store.New(minio, 1) 214 215 // When 216 _, err := store.CompareBucketPolicy(bucketName, expectedPolicy) 217 218 // Then 219 g.Expect(err).To(gomega.HaveOccurred()) 220 }) 221 } 222 223 func TestStore_ContainsAllObjects(t *testing.T) { 224 t.Run("Success", func(t *testing.T) { 225 // Given 226 g := gomega.NewGomegaWithT(t) 227 bucketName := "test-bucket" 228 assetName := "test-asset" 229 files := []string{"test/a.txt", "test/b/c/d.txt"} 230 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "test-asset/test/a.txt"}, minio.ObjectInfo{Key: "test-asset/test/b/c/d.txt"}) 231 ctx := context.TODO() 232 233 minio := new(automock.MinioClient) 234 minio.On("ListObjects", bucketName, assetName, true, ctx.Done()).Return(objCh).Once() 235 defer minio.AssertExpectations(t) 236 237 store := store.New(minio, 1) 238 239 // When 240 contains, err := store.ContainsAllObjects(ctx, bucketName, assetName, files) 241 242 // Then 243 g.Expect(err).NotTo(gomega.HaveOccurred()) 244 g.Expect(contains).To(gomega.Equal(true)) 245 }) 246 247 t.Run("MissingFiles", func(t *testing.T) { 248 // Given 249 g := gomega.NewGomegaWithT(t) 250 bucketName := "test-bucket" 251 assetName := "test-asset" 252 files := []string{"test/a.txt", "test/b/c/d.txt"} 253 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "test-asset/test/a.txt"}) 254 ctx := context.TODO() 255 256 minio := new(automock.MinioClient) 257 minio.On("ListObjects", bucketName, assetName, true, ctx.Done()).Return(objCh).Once() 258 defer minio.AssertExpectations(t) 259 260 store := store.New(minio, 1) 261 262 // When 263 contains, err := store.ContainsAllObjects(ctx, bucketName, assetName, files) 264 265 // Then 266 g.Expect(err).NotTo(gomega.HaveOccurred()) 267 g.Expect(contains).To(gomega.Equal(false)) 268 }) 269 270 t.Run("EmptyBucket", func(t *testing.T) { 271 // Given 272 g := gomega.NewGomegaWithT(t) 273 bucketName := "test-bucket" 274 assetName := "test-asset" 275 files := []string{"test/a.txt", "test/b/c/d.txt"} 276 objCh := fixObjectsChannel() 277 ctx := context.TODO() 278 279 minio := new(automock.MinioClient) 280 minio.On("ListObjects", bucketName, assetName, true, ctx.Done()).Return(objCh).Once() 281 defer minio.AssertExpectations(t) 282 283 store := store.New(minio, 1) 284 285 // When 286 contains, err := store.ContainsAllObjects(ctx, bucketName, assetName, files) 287 288 // Then 289 g.Expect(err).NotTo(gomega.HaveOccurred()) 290 g.Expect(contains).To(gomega.Equal(false)) 291 }) 292 293 t.Run("EmptyAsset", func(t *testing.T) { 294 // Given 295 g := gomega.NewGomegaWithT(t) 296 bucketName := "test-bucket" 297 assetName := "test-asset" 298 files := make([]string, 0) 299 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "test-asset/test/a.txt"}) 300 ctx := context.TODO() 301 302 minio := new(automock.MinioClient) 303 minio.On("ListObjects", bucketName, assetName, true, ctx.Done()).Return(objCh).Once() 304 defer minio.AssertExpectations(t) 305 306 store := store.New(minio, 1) 307 308 // When 309 contains, err := store.ContainsAllObjects(ctx, bucketName, assetName, files) 310 311 // Then 312 g.Expect(err).NotTo(gomega.HaveOccurred()) 313 g.Expect(contains).To(gomega.Equal(true)) 314 }) 315 316 t.Run("ListObjectsError", func(t *testing.T) { 317 // Given 318 g := gomega.NewGomegaWithT(t) 319 bucketName := "test-bucket" 320 assetName := "test-asset" 321 files := make([]string, 0) 322 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "test-asset/test/a.txt", Err: errors.New("test-err")}) 323 ctx := context.TODO() 324 325 minio := new(automock.MinioClient) 326 minio.On("ListObjects", bucketName, assetName, true, ctx.Done()).Return(objCh).Once() 327 defer minio.AssertExpectations(t) 328 329 store := store.New(minio, 1) 330 331 // When 332 _, err := store.ContainsAllObjects(ctx, bucketName, assetName, files) 333 334 // Then 335 g.Expect(err).To(gomega.HaveOccurred()) 336 }) 337 } 338 339 func TestStore_CreateBucket(t *testing.T) { 340 t.Run("SuccessNamespaced", func(t *testing.T) { 341 // Given 342 g := gomega.NewGomegaWithT(t) 343 namespace := "space" 344 crName := "test-bucket" 345 region := "asia" 346 347 minio := new(automock.MinioClient) 348 minio.On("BucketExists", mock.AnythingOfType("string")).Return(false, nil).Once() 349 minio.On("MakeBucket", mock.AnythingOfType("string"), region).Return(nil).Once() 350 defer minio.AssertExpectations(t) 351 352 store := store.New(minio, 1) 353 354 // When 355 name, err := store.CreateBucket(namespace, crName, region) 356 357 // Then 358 g.Expect(err).NotTo(gomega.HaveOccurred()) 359 g.Expect(name).To(gomega.HavePrefix(crName)) 360 g.Expect(name).ToNot(gomega.HaveSuffix(crName)) 361 }) 362 363 t.Run("SuccessClusterWide", func(t *testing.T) { 364 // Given 365 g := gomega.NewGomegaWithT(t) 366 crName := "test-bucket" 367 region := "asia" 368 369 minio := new(automock.MinioClient) 370 minio.On("BucketExists", mock.AnythingOfType("string")).Return(false, nil).Once() 371 minio.On("MakeBucket", mock.AnythingOfType("string"), region).Return(nil).Once() 372 defer minio.AssertExpectations(t) 373 374 store := store.New(minio, 1) 375 376 // When 377 name, err := store.CreateBucket("", crName, region) 378 379 // Then 380 g.Expect(err).NotTo(gomega.HaveOccurred()) 381 g.Expect(name).To(gomega.HavePrefix(crName)) 382 g.Expect(name).ToNot(gomega.HaveSuffix(crName)) 383 }) 384 385 t.Run("BucketExists", func(t *testing.T) { 386 // Given 387 g := gomega.NewGomegaWithT(t) 388 namespace := "space" 389 crName := "test-bucket" 390 region := "asia" 391 392 minio := new(automock.MinioClient) 393 minio.On("BucketExists", mock.AnythingOfType("string")).Return(true, nil).Once() 394 minio.On("BucketExists", mock.AnythingOfType("string")).Return(false, nil).Once() 395 minio.On("MakeBucket", mock.AnythingOfType("string"), region).Return(nil).Once() 396 defer minio.AssertExpectations(t) 397 398 store := store.New(minio, 1) 399 400 // When 401 name, err := store.CreateBucket(namespace, crName, region) 402 403 // Then 404 g.Expect(err).NotTo(gomega.HaveOccurred()) 405 g.Expect(name).To(gomega.HavePrefix(crName)) 406 g.Expect(name).ToNot(gomega.HaveSuffix(crName)) 407 }) 408 409 t.Run("CannotFindBucketName", func(t *testing.T) { 410 // Given 411 g := gomega.NewGomegaWithT(t) 412 namespace := "space" 413 crName := "test-bucket" 414 region := "asia" 415 416 minio := new(automock.MinioClient) 417 minio.On("BucketExists", mock.AnythingOfType("string")).Return(true, nil).Times(10) 418 defer minio.AssertExpectations(t) 419 420 store := store.New(minio, 1) 421 422 // When 423 _, err := store.CreateBucket(namespace, crName, region) 424 425 // Then 426 g.Expect(err).To(gomega.HaveOccurred()) 427 }) 428 429 t.Run("BucketExistsError", func(t *testing.T) { 430 // Given 431 g := gomega.NewGomegaWithT(t) 432 namespace := "space" 433 crName := "test-bucket" 434 region := "asia" 435 436 minio := new(automock.MinioClient) 437 minio.On("BucketExists", mock.AnythingOfType("string")).Return(false, errors.New("test-err")).Once() 438 defer minio.AssertExpectations(t) 439 440 store := store.New(minio, 1) 441 442 // When 443 _, err := store.CreateBucket(namespace, crName, region) 444 445 // Then 446 g.Expect(err).To(gomega.HaveOccurred()) 447 }) 448 449 t.Run("MakeBucketError", func(t *testing.T) { 450 // Given 451 g := gomega.NewGomegaWithT(t) 452 namespace := "space" 453 crName := "test-bucket" 454 region := "asia" 455 456 minio := new(automock.MinioClient) 457 minio.On("BucketExists", mock.AnythingOfType("string")).Return(false, nil).Once() 458 minio.On("MakeBucket", mock.AnythingOfType("string"), region).Return(errors.New("test-error")).Once() 459 460 defer minio.AssertExpectations(t) 461 462 store := store.New(minio, 1) 463 464 // When 465 _, err := store.CreateBucket(namespace, crName, region) 466 467 // Then 468 g.Expect(err).To(gomega.HaveOccurred()) 469 }) 470 } 471 472 func TestStore_DeleteBucket(t *testing.T) { 473 t.Run("Success", func(t *testing.T) { 474 // Given 475 g := gomega.NewGomegaWithT(t) 476 name := "test-bucket" 477 ctx := context.TODO() 478 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2"}, minio.ObjectInfo{Key: "obj3"}) 479 errCh := fixRemoveObjectErrorChannel() 480 481 minio := new(automock.MinioClient) 482 minio.On("BucketExists", name).Return(true, nil).Once() 483 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 484 minio.On("RemoveObjectsWithContext", ctx, name, mock.Anything).Return(errCh).Once() 485 minio.On("RemoveBucket", name).Return(nil).Once() 486 defer minio.AssertExpectations(t) 487 488 store := store.New(minio, 1) 489 490 // When 491 err := store.DeleteBucket(ctx, name) 492 493 // Then 494 g.Expect(err).NotTo(gomega.HaveOccurred()) 495 }) 496 497 t.Run("EmptyBucket", func(t *testing.T) { 498 // Given 499 g := gomega.NewGomegaWithT(t) 500 name := "test-bucket" 501 ctx := context.TODO() 502 objCh := fixObjectsChannel() 503 504 minio := new(automock.MinioClient) 505 minio.On("BucketExists", name).Return(true, nil).Once() 506 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 507 minio.On("RemoveBucket", name).Return(nil).Once() 508 defer minio.AssertExpectations(t) 509 510 store := store.New(minio, 1) 511 512 // When 513 err := store.DeleteBucket(ctx, name) 514 515 // Then 516 g.Expect(err).NotTo(gomega.HaveOccurred()) 517 }) 518 519 t.Run("BucketNotExists", func(t *testing.T) { 520 // Given 521 g := gomega.NewGomegaWithT(t) 522 name := "test-bucket" 523 ctx := context.TODO() 524 525 minio := new(automock.MinioClient) 526 minio.On("BucketExists", name).Return(false, nil).Once() 527 defer minio.AssertExpectations(t) 528 529 store := store.New(minio, 1) 530 531 // When 532 err := store.DeleteBucket(ctx, name) 533 534 // Then 535 g.Expect(err).NotTo(gomega.HaveOccurred()) 536 }) 537 538 t.Run("BucketExistsError", func(t *testing.T) { 539 // Given 540 g := gomega.NewGomegaWithT(t) 541 name := "test-bucket" 542 ctx := context.TODO() 543 544 minio := new(automock.MinioClient) 545 minio.On("BucketExists", name).Return(false, fmt.Errorf("test error")).Once() 546 defer minio.AssertExpectations(t) 547 548 store := store.New(minio, 1) 549 550 // When 551 err := store.DeleteBucket(ctx, name) 552 553 // Then 554 g.Expect(err).To(gomega.HaveOccurred()) 555 }) 556 557 t.Run("ListObjectsError", func(t *testing.T) { 558 // Given 559 g := gomega.NewGomegaWithT(t) 560 name := "test-bucket" 561 ctx := context.TODO() 562 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2", Err: fmt.Errorf("test error")}) 563 564 minio := new(automock.MinioClient) 565 minio.On("BucketExists", name).Return(true, nil).Once() 566 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 567 defer minio.AssertExpectations(t) 568 569 store := store.New(minio, 1) 570 571 // When 572 err := store.DeleteBucket(ctx, name) 573 574 // Then 575 g.Expect(err).To(gomega.HaveOccurred()) 576 }) 577 578 t.Run("RemoveBucketError", func(t *testing.T) { 579 // Given 580 g := gomega.NewGomegaWithT(t) 581 name := "test-bucket" 582 ctx := context.TODO() 583 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2"}, minio.ObjectInfo{Key: "obj3"}) 584 errCh := fixRemoveObjectErrorChannel() 585 586 minio := new(automock.MinioClient) 587 minio.On("BucketExists", name).Return(true, nil).Once() 588 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 589 minio.On("RemoveObjectsWithContext", ctx, name, mock.Anything).Return(errCh).Once() 590 minio.On("RemoveBucket", name).Return(errors.New("test-error")).Once() 591 defer minio.AssertExpectations(t) 592 593 store := store.New(minio, 1) 594 595 // When 596 err := store.DeleteBucket(ctx, name) 597 598 // Then 599 g.Expect(err).To(gomega.HaveOccurred()) 600 }) 601 } 602 603 func TestStore_DeleteObjects(t *testing.T) { 604 t.Run("Success", func(t *testing.T) { 605 // Given 606 g := gomega.NewGomegaWithT(t) 607 name := "test-bucket" 608 ctx := context.TODO() 609 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2"}, minio.ObjectInfo{Key: "obj3"}) 610 errCh := fixRemoveObjectErrorChannel() 611 612 minio := new(automock.MinioClient) 613 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 614 minio.On("RemoveObjectsWithContext", ctx, name, mock.Anything).Return(errCh).Once() 615 defer minio.AssertExpectations(t) 616 617 store := store.New(minio, 1) 618 619 // When 620 err := store.DeleteObjects(ctx, name, "") 621 622 // Then 623 g.Expect(err).NotTo(gomega.HaveOccurred()) 624 }) 625 626 t.Run("SuccessWithPrefix", func(t *testing.T) { 627 // Given 628 g := gomega.NewGomegaWithT(t) 629 name := "test-bucket" 630 prefix := "test" 631 ctx := context.TODO() 632 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "test/obj1"}, minio.ObjectInfo{Key: "test/obj2"}, minio.ObjectInfo{Key: "test/obj3"}) 633 errCh := fixRemoveObjectErrorChannel() 634 635 minio := new(automock.MinioClient) 636 minio.On("ListObjects", name, prefix, true, ctx.Done()).Return(objCh).Once() 637 minio.On("RemoveObjectsWithContext", ctx, name, mock.Anything).Return(errCh).Once() 638 defer minio.AssertExpectations(t) 639 640 store := store.New(minio, 1) 641 642 // When 643 err := store.DeleteObjects(ctx, name, prefix) 644 645 // Then 646 g.Expect(err).NotTo(gomega.HaveOccurred()) 647 }) 648 649 t.Run("NoObjects", func(t *testing.T) { 650 // Given 651 g := gomega.NewGomegaWithT(t) 652 name := "test-bucket" 653 ctx := context.TODO() 654 objCh := fixObjectsChannel() 655 656 minio := new(automock.MinioClient) 657 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 658 defer minio.AssertExpectations(t) 659 660 store := store.New(minio, 1) 661 662 // When 663 err := store.DeleteObjects(ctx, name, "") 664 665 // Then 666 g.Expect(err).NotTo(gomega.HaveOccurred()) 667 }) 668 669 t.Run("ListObjectsError", func(t *testing.T) { 670 // Given 671 g := gomega.NewGomegaWithT(t) 672 name := "test-bucket" 673 ctx := context.TODO() 674 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2", Err: fmt.Errorf("test error")}) 675 676 minio := new(automock.MinioClient) 677 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 678 defer minio.AssertExpectations(t) 679 680 store := store.New(minio, 1) 681 682 // When 683 err := store.DeleteObjects(ctx, name, "") 684 685 // Then 686 g.Expect(err).To(gomega.HaveOccurred()) 687 }) 688 689 t.Run("RemoveObjectsError", func(t *testing.T) { 690 // Given 691 g := gomega.NewGomegaWithT(t) 692 name := "test-bucket" 693 ctx := context.TODO() 694 objCh := fixObjectsChannel(minio.ObjectInfo{Key: "obj1"}, minio.ObjectInfo{Key: "obj2"}, minio.ObjectInfo{Key: "obj3"}) 695 errCh := fixRemoveObjectErrorChannel(errors.New("test-error")) 696 697 minio := new(automock.MinioClient) 698 minio.On("ListObjects", name, "", true, ctx.Done()).Return(objCh).Once() 699 minio.On("RemoveObjectsWithContext", ctx, name, mock.Anything).Return(errCh).Once() 700 defer minio.AssertExpectations(t) 701 702 store := store.New(minio, 1) 703 704 // When 705 err := store.DeleteObjects(ctx, name, "") 706 707 // Then 708 g.Expect(err).To(gomega.HaveOccurred()) 709 }) 710 } 711 712 func TestStore_PutObjects(t *testing.T) { 713 t.Run("Success", func(t *testing.T) { 714 // Given 715 g := gomega.NewGomegaWithT(t) 716 bucketName := "test-bucket" 717 assetName := "test-asset" 718 sourceBasePath := "/tmp" 719 files := []string{"test/a.txt", "test/b.txt"} 720 ctx := context.TODO() 721 722 minio := new(automock.MinioClient) 723 minio.On("FPutObjectWithContext", ctx, bucketName, filepath.Join(assetName, files[0]), filepath.Join(sourceBasePath, files[0]), mock.Anything).Return(int64(1), nil).Once() 724 minio.On("FPutObjectWithContext", ctx, bucketName, filepath.Join(assetName, files[1]), filepath.Join(sourceBasePath, files[1]), mock.Anything).Return(int64(1), nil).Once() 725 defer minio.AssertExpectations(t) 726 727 store := store.New(minio, 2) 728 729 // When 730 err := store.PutObjects(ctx, bucketName, assetName, sourceBasePath, files) 731 732 // Then 733 g.Expect(err).NotTo(gomega.HaveOccurred()) 734 }) 735 736 t.Run("Error", func(t *testing.T) { 737 // Given 738 g := gomega.NewGomegaWithT(t) 739 bucketName := "test-bucket" 740 assetName := "test-asset" 741 sourceBasePath := "/tmp" 742 files := []string{"test/a.txt", "test/b.txt"} 743 ctx := context.TODO() 744 745 minio := new(automock.MinioClient) 746 minio.On("FPutObjectWithContext", ctx, bucketName, filepath.Join(assetName, files[0]), filepath.Join(sourceBasePath, files[0]), mock.Anything).Return(int64(1), nil).Once() 747 minio.On("FPutObjectWithContext", ctx, bucketName, filepath.Join(assetName, files[1]), filepath.Join(sourceBasePath, files[1]), mock.Anything).Return(int64(1), errors.New("test-error")).Once() 748 defer minio.AssertExpectations(t) 749 750 store := store.New(minio, 1) 751 752 // When 753 err := store.PutObjects(ctx, bucketName, assetName, sourceBasePath, files) 754 755 // Then 756 g.Expect(err).To(gomega.HaveOccurred()) 757 }) 758 759 t.Run("NoFiles", func(t *testing.T) { 760 // Given 761 g := gomega.NewGomegaWithT(t) 762 bucketName := "test-bucket" 763 assetName := "test-asset" 764 sourceBasePath := "/tmp" 765 files := make([]string, 0) 766 ctx := context.TODO() 767 768 minio := new(automock.MinioClient) 769 defer minio.AssertExpectations(t) 770 771 store := store.New(minio, 1) 772 773 // When 774 err := store.PutObjects(ctx, bucketName, assetName, sourceBasePath, files) 775 776 // Then 777 g.Expect(err).ToNot(gomega.HaveOccurred()) 778 }) 779 } 780 781 func TestStore_SetBucketPolicy(t *testing.T) { 782 t.Run("SuccessNone", func(t *testing.T) { 783 // Given 784 g := gomega.NewGomegaWithT(t) 785 bucketName := "test-bucket" 786 policy := v1alpha2.BucketPolicyNone 787 marshaledPolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[]}" 788 789 minio := new(automock.MinioClient) 790 minio.On("SetBucketPolicy", bucketName, marshaledPolicy).Return(nil).Once() 791 defer minio.AssertExpectations(t) 792 793 store := store.New(minio, 1) 794 795 // When 796 err := store.SetBucketPolicy(bucketName, policy) 797 798 // Then 799 g.Expect(err).NotTo(gomega.HaveOccurred()) 800 }) 801 802 t.Run("SuccessReadOnly", func(t *testing.T) { 803 // Given 804 g := gomega.NewGomegaWithT(t) 805 bucketName := "test-bucket" 806 expectedPolicy := v1alpha2.BucketPolicyReadOnly 807 marshaledPolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:GetObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 808 809 minio := new(automock.MinioClient) 810 minio.On("SetBucketPolicy", bucketName, marshaledPolicy).Return(nil).Once() 811 defer minio.AssertExpectations(t) 812 813 store := store.New(minio, 1) 814 815 // When 816 err := store.SetBucketPolicy(bucketName, expectedPolicy) 817 818 // Then 819 g.Expect(err).NotTo(gomega.HaveOccurred()) 820 }) 821 822 t.Run("SuccessWriteOnly", func(t *testing.T) { 823 // Given 824 g := gomega.NewGomegaWithT(t) 825 bucketName := "test-bucket" 826 expectedPolicy := v1alpha2.BucketPolicyWriteOnly 827 marshaledPolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 828 829 minio := new(automock.MinioClient) 830 minio.On("SetBucketPolicy", bucketName, marshaledPolicy).Return(nil).Once() 831 defer minio.AssertExpectations(t) 832 833 store := store.New(minio, 1) 834 835 // When 836 err := store.SetBucketPolicy(bucketName, expectedPolicy) 837 838 // Then 839 g.Expect(err).NotTo(gomega.HaveOccurred()) 840 }) 841 842 t.Run("SuccessReadWrite", func(t *testing.T) { 843 // Given 844 g := gomega.NewGomegaWithT(t) 845 bucketName := "test-bucket" 846 expectedPolicy := v1alpha2.BucketPolicyReadWrite 847 marshaledPolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket\"],\"Sid\":\"\"},{\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::test-bucket/*\"],\"Sid\":\"\"}]}" 848 849 minio := new(automock.MinioClient) 850 minio.On("SetBucketPolicy", bucketName, marshaledPolicy).Return(nil).Once() 851 defer minio.AssertExpectations(t) 852 853 store := store.New(minio, 1) 854 855 // When 856 err := store.SetBucketPolicy(bucketName, expectedPolicy) 857 858 // Then 859 g.Expect(err).NotTo(gomega.HaveOccurred()) 860 }) 861 862 t.Run("Error", func(t *testing.T) { 863 // Given 864 g := gomega.NewGomegaWithT(t) 865 bucketName := "test-bucket" 866 expectedPolicy := v1alpha2.BucketPolicyNone 867 marshaledPolicy := "{\"Version\":\"2012-10-17\",\"Statement\":[]}" 868 869 minio := new(automock.MinioClient) 870 minio.On("SetBucketPolicy", bucketName, marshaledPolicy).Return(errors.New("test-error")).Once() 871 defer minio.AssertExpectations(t) 872 873 store := store.New(minio, 1) 874 875 // When 876 err := store.SetBucketPolicy(bucketName, expectedPolicy) 877 878 // Then 879 g.Expect(err).To(gomega.HaveOccurred()) 880 }) 881 } 882 883 func fixObjectsChannel(objects ...minio.ObjectInfo) <-chan minio.ObjectInfo { 884 objCh := make(chan minio.ObjectInfo, len(objects)+1) 885 defer close(objCh) 886 for _, object := range objects { 887 objCh <- object 888 } 889 890 return objCh 891 } 892 893 func fixRemoveObjectErrorChannel(errs ...error) <-chan minio.RemoveObjectError { 894 objCh := make(chan minio.RemoveObjectError, len(errs)+1) 895 defer close(objCh) 896 for _, err := range errs { 897 info := minio.RemoveObjectError{ 898 Err: err, 899 } 900 901 objCh <- info 902 } 903 904 return objCh 905 }