github.com/kyma-project/kyma/components/asset-store-controller-manager@v0.0.0-20191203152857-3792b5df17c5/internal/controllers/clusterasset_controller_test.go (about) 1 package controllers 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/kyma-project/kyma/components/asset-store-controller-manager/internal/finalizer" 9 assetstorev1alpha2 "github.com/kyma-project/kyma/components/asset-store-controller-manager/pkg/apis/assetstore/v1alpha2" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 "github.com/stretchr/testify/mock" 13 apiErrors "k8s.io/apimachinery/pkg/api/errors" 14 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/apimachinery/pkg/types" 16 "k8s.io/apimachinery/pkg/util/uuid" 17 "k8s.io/client-go/tools/record" 18 ctrl "sigs.k8s.io/controller-runtime" 19 "sigs.k8s.io/controller-runtime/pkg/runtime/log" 20 ) 21 22 var _ = Describe("ClusterAsset", func() { 23 var ( 24 asset *assetstorev1alpha2.ClusterAsset 25 baseURL string 26 reconciler *ClusterAssetReconciler 27 mocks *MockContainer 28 t GinkgoTInterface 29 request ctrl.Request 30 ) 31 32 BeforeEach(func() { 33 bucket := newFixClusterBucket() 34 bucket.Status.Phase = assetstorev1alpha2.BucketReady 35 bucket.Status.RemoteName = bucket.Name 36 Expect(k8sClient.Create(context.TODO(), bucket)).To(Succeed()) 37 Expect(k8sClient.Status().Update(context.TODO(), bucket)).To(Succeed()) 38 39 asset = newFixClusterAsset(bucket.Name) 40 Expect(k8sClient.Create(context.TODO(), asset)).To(Succeed()) 41 baseURL = fmt.Sprintf("%s/%s", bucket.Status.URL, asset.Name) 42 43 t = GinkgoT() 44 mocks = NewMockContainer() 45 46 request = ctrl.Request{ 47 NamespacedName: types.NamespacedName{ 48 Name: asset.Name, 49 Namespace: asset.Namespace, 50 }, 51 } 52 53 reconciler = &ClusterAssetReconciler{ 54 Client: k8sClient, 55 cacheSynchronizer: func(stop <-chan struct{}) bool { return true }, 56 Log: log.Log, 57 recorder: record.NewFakeRecorder(100), 58 relistInterval: 60 * time.Hour, 59 store: mocks.Store, 60 loader: mocks.Loader, 61 finalizer: finalizer.New("test"), 62 validator: mocks.Validator, 63 mutator: mocks.Mutator, 64 metadataExtractor: mocks.Extractor, 65 maxConcurrentReconciles: 1, 66 } 67 }) 68 69 AfterEach(func() { 70 mocks.AssertExpetactions(t) 71 }) 72 73 It("should successfully create, update and delete ClusterAsset", func() { 74 By("creating the ClusterAsset") 75 // On scheduled 76 result, err := reconciler.Reconcile(request) 77 validateReconcilation(err, result) 78 asset = &assetstorev1alpha2.ClusterAsset{} 79 Expect(k8sClient.Get(context.TODO(), request.NamespacedName, asset)).To(Succeed()) 80 validateAsset(asset.Status.CommonAssetStatus, asset.ObjectMeta, "", []string{}, assetstorev1alpha2.AssetPending, assetstorev1alpha2.AssetScheduled) 81 82 // On pending 83 mocks.Store.On("ListObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name).Return([]string{}, nil).Once() 84 mocks.Loader.On("Load", asset.Spec.Source.URL, asset.Name, asset.Spec.Source.Mode, asset.Spec.Source.Filter).Return("/tmp", []string{"test.file1", "test.file2"}, nil).Once() 85 mocks.Loader.On("Clean", "/tmp").Return(nil).Once() 86 mocks.Store.On("PutObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name, "/tmp", []string{"test.file1", "test.file2"}).Return(nil).Once() 87 88 result, err = reconciler.Reconcile(request) 89 validateReconcilation(err, result) 90 asset = &assetstorev1alpha2.ClusterAsset{} 91 Expect(k8sClient.Get(context.TODO(), request.NamespacedName, asset)).To(Succeed()) 92 validateAsset(asset.Status.CommonAssetStatus, asset.ObjectMeta, baseURL, []string{"test.file1", "test.file2"}, assetstorev1alpha2.AssetReady, assetstorev1alpha2.AssetUploaded) 93 94 By("updating the ClusterAsset") 95 asset.Spec.Source.URL = "example.com/test.file" 96 asset.Spec.Source.Mode = assetstorev1alpha2.AssetSingle 97 Expect(k8sClient.Update(context.TODO(), asset)).To(Succeed()) 98 99 // On scheduled 100 result, err = reconciler.Reconcile(request) 101 validateReconcilation(err, result) 102 asset = &assetstorev1alpha2.ClusterAsset{} 103 Expect(k8sClient.Get(context.TODO(), request.NamespacedName, asset)).To(Succeed()) 104 validateAsset(asset.Status.CommonAssetStatus, asset.ObjectMeta, "", []string{}, assetstorev1alpha2.AssetPending, assetstorev1alpha2.AssetScheduled) 105 106 // On pending 107 mocks.Store.On("ListObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name).Return([]string{"test.file1", "test.file2"}, nil).Once() 108 mocks.Store.On("DeleteObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name).Return(nil).Once() 109 mocks.Loader.On("Load", asset.Spec.Source.URL, asset.Name, asset.Spec.Source.Mode, asset.Spec.Source.Filter).Return("/tmp", []string{"test.file"}, nil).Once() 110 mocks.Loader.On("Clean", "/tmp").Return(nil).Once() 111 mocks.Store.On("PutObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name, "/tmp", []string{"test.file"}).Return(nil).Once() 112 113 result, err = reconciler.Reconcile(request) 114 validateReconcilation(err, result) 115 asset = &assetstorev1alpha2.ClusterAsset{} 116 Expect(k8sClient.Get(context.TODO(), request.NamespacedName, asset)).To(Succeed()) 117 validateAsset(asset.Status.CommonAssetStatus, asset.ObjectMeta, baseURL, []string{"test.file"}, assetstorev1alpha2.AssetReady, assetstorev1alpha2.AssetUploaded) 118 119 By("deleting the ClusterAsset") 120 Expect(k8sClient.Delete(context.TODO(), asset)).To(Succeed()) 121 122 // On delete 123 mocks.Store.On("ListObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name).Return([]string{"test.file"}, nil).Once() 124 mocks.Store.On("DeleteObjects", mock.Anything, asset.Spec.BucketRef.Name, asset.Name).Return(nil).Once() 125 126 result, err = reconciler.Reconcile(request) 127 validateReconcilation(err, result) 128 129 asset = &assetstorev1alpha2.ClusterAsset{} 130 err = k8sClient.Get(context.TODO(), request.NamespacedName, asset) 131 Expect(err).To(HaveOccurred()) 132 Expect(apiErrors.IsNotFound(err)).To(BeTrue()) 133 }) 134 }) 135 136 func newFixClusterAsset(bucketName string) *assetstorev1alpha2.ClusterAsset { 137 return &assetstorev1alpha2.ClusterAsset{ 138 ObjectMeta: ctrl.ObjectMeta{ 139 Name: string(uuid.NewUUID()), 140 }, 141 Spec: assetstorev1alpha2.ClusterAssetSpec{ 142 CommonAssetSpec: assetstorev1alpha2.CommonAssetSpec{ 143 Source: assetstorev1alpha2.AssetSource{ 144 URL: "example.com/test.zip", 145 Mode: assetstorev1alpha2.AssetPackage, 146 }, 147 BucketRef: assetstorev1alpha2.AssetBucketRef{ 148 Name: bucketName, 149 }, 150 }, 151 }, 152 Status: assetstorev1alpha2.ClusterAssetStatus{CommonAssetStatus: assetstorev1alpha2.CommonAssetStatus{ 153 LastHeartbeatTime: v1.Now(), 154 }}, 155 } 156 }