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  }