Skip to content

Commit

Permalink
Add unit tests for synchronizer (#204)
Browse files Browse the repository at this point in the history
* Add test case to check invalid apiversion

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Add test case to get appsub

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Add test case to check namespace

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Fix test case delete single subscribed resource

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Fix spelling of override

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Start synchronizer cache before test cases

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Add test case to ProcessSubResources

Signed-off-by: Jonathan Marcantonio <[email protected]>

* Organize naming of appsubs

Signed-off-by: Jonathan Marcantonio <[email protected]>
  • Loading branch information
lennysgarage authored Jun 29, 2022
1 parent d27a7f8 commit 5f118cc
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pkg/synchronizer/kubernetes/synchronizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (sync *KubeSynchronizer) ProcessSubResources(appsub *appv1alpha1.Subscripti
appSubUnitStatus.Message = err.Error()
appSubUnitStatuses = append(appSubUnitStatuses, appSubUnitStatus)

klog.Infof("Failed to overrifde resource. err: %v", err)
klog.Infof("Failed to override resource. err: %v", err)

continue
}
Expand Down
296 changes: 290 additions & 6 deletions pkg/synchronizer/kubernetes/synchronizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,35 @@ import (
apps "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
appv1alpha1 "open-cluster-management.io/multicloud-operators-subscription/pkg/apis/apps/v1"
appSubStatusV1alpha1 "open-cluster-management.io/multicloud-operators-subscription/pkg/apis/apps/v1alpha1"
"open-cluster-management.io/multicloud-operators-subscription/pkg/utils"
)

var (
host = types.NamespacedName{
Name: "cluster1",
Namespace: "cluster1",
}

hostworkload4 = types.NamespacedName{
Name: "subscription-4",
Namespace: "default",
}
hostworkload5 = types.NamespacedName{
Name: "github-resource-subscription-local",
Namespace: "default",
}
hostSub = types.NamespacedName{
Name: "appsub-1",
Namespace: "appsub-ns-1",
}

selector = map[string]string{"a": "b"}

workload1Configmap = corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
Expand All @@ -45,11 +59,11 @@ var (
ObjectMeta: metav1.ObjectMeta{
Name: "configmap1",
Namespace: "default",
Annotations: map[string]string{
appv1alpha1.AnnotationHosting: hostSub.Namespace + "/" + hostSub.Name,
},
},
}

selector = map[string]string{"a": "b"}

workload2Deployment = apps.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
Expand All @@ -58,6 +72,9 @@ var (
ObjectMeta: metav1.ObjectMeta{
Name: "deployment1",
Namespace: "default",
Annotations: map[string]string{
appv1alpha1.AnnotationHosting: hostSub.Namespace + "/" + hostSub.Name,
},
},
Spec: apps.DeploymentSpec{
Replicas: func() *int32 { i := int32(1); return &i }(),
Expand All @@ -77,13 +94,67 @@ var (
},
},
}
workload3Configmap = corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap2",
Namespace: "default",
Annotations: map[string]string{
appv1alpha1.AnnotationHosting: "not owned",
},
},
}
workload4Subscription = appv1alpha1.Subscription{
TypeMeta: metav1.TypeMeta{
Kind: "Subscription",
APIVersion: "apps.open-cluster-management.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: hostworkload4.Name,
Namespace: hostworkload4.Namespace,
Annotations: map[string]string{
appv1alpha1.AnnotationHosting: hostworkload4.Namespace + "/" + hostworkload4.Name,
},
},
}
workload5Subscription = appv1alpha1.Subscription{
TypeMeta: metav1.TypeMeta{
Kind: "Subscription",
APIVersion: "apps.open-cluster-management.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: hostworkload5.Name,
Namespace: hostworkload5.Namespace,
Annotations: map[string]string{
appv1alpha1.AnnotationResourceReconcileOption: "merge",
appv1alpha1.AnnotationHosting: hostworkload5.Namespace + "/" + hostworkload5.Name,
},
Labels: map[string]string{
"label1": "label",
},
},
}
)

var _ = Describe("test Delete Single Subscribed Resource", func() {
It("should delete the confimap and deployment without failure", func() {
sync, err := CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
var sync *KubeSynchronizer
var err error

BeforeEach(func() {
sync, err = CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
Expect(err).NotTo(HaveOccurred())

err = sync.Start(context.TODO())
if err != nil {
klog.Error(err)
return
}
})

It("should delete the confimap and deployment without failure", func() {
workload1 := workload1Configmap.DeepCopy()
Expect(k8sClient.Create(context.TODO(), workload1)).NotTo(HaveOccurred())

Expand Down Expand Up @@ -114,4 +185,217 @@ var _ = Describe("test Delete Single Subscribed Resource", func() {
err = sync.DeleteSingleSubscribedResource(hostSub, pkgStatus)
Expect(err).NotTo(HaveOccurred())
})

It("should have an invalid apiversion pkgStatus", func() {
workload1 := workload1Configmap.DeepCopy()
Expect(k8sClient.Create(context.TODO(), workload1)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), workload1)

pkgStatus := appSubStatusV1alpha1.SubscriptionUnitStatus{
Name: "configmap1",
Namespace: "default",
APIVersion: "",
Kind: "ConfigMap",
}

err = sync.DeleteSingleSubscribedResource(hostSub, pkgStatus)
Expect(err).To(HaveOccurred())
})

It("should not be owned by the subscription", func() {
sync, err := CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
Expect(err).NotTo(HaveOccurred())

workload1 := workload3Configmap.DeepCopy()
Expect(k8sClient.Create(context.TODO(), workload1)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), workload1)

pkgStatus := appSubStatusV1alpha1.SubscriptionUnitStatus{
Name: "configmap2",
Namespace: "default",
APIVersion: "v1",
Kind: "ConfigMap",
}

err = sync.DeleteSingleSubscribedResource(hostSub, pkgStatus)
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("test PurgeAllSubscribedResources", func() {
var sync *KubeSynchronizer
var err error

BeforeEach(func() {
sync, err = CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, true, false)
Expect(err).NotTo(HaveOccurred())

err = sync.Start(context.TODO())
if err != nil {
klog.Error(err)
return
}
})

It("should not find appSubStatus", func() {
appsub := workload5Subscription.DeepCopy()
// Not actually creating subscription

err = sync.PurgeAllSubscribedResources(appsub)
Expect(err).NotTo(HaveOccurred())
})

It("should purge everything", func() {
appsub := workload5Subscription.DeepCopy()
// Actually creating the subscription
Expect(k8sClient.Create(context.TODO(), appsub)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), appsub)

subAnnotations := make(map[string]string)
subAnnotations[appv1alpha1.AnnotationClusterAdmin] = "true"
subAnnotations[appv1alpha1.AnnotationResourceReconcileOption] = "merge"
subAnnotations[appv1alpha1.AnnotationGitBranch] = "main"
appsub.SetAnnotations(subAnnotations)

err = sync.PurgeAllSubscribedResources(appsub)
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("test ProcessSubResources", func() {
var sync *KubeSynchronizer
var err error

BeforeEach(func() {
sync, err = CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
Expect(err).NotTo(HaveOccurred())

err = sync.Start(context.TODO())
if err != nil {
klog.Error(err)
return
}
})

It("should create a single new resource", func() {
appsub := workload5Subscription.DeepCopy()
// Actually creating the subscription
Expect(k8sClient.Create(context.TODO(), appsub)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), appsub)

// Create a single resource
resource := &unstructured.Unstructured{}
resource.SetNamespace("default")
resource.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: "apps.open-cluster-management.io/v1",
Kind: "Subscription",
})
resource.SetAnnotations(make(map[string]string))
resource.SetLabels(map[string]string{"app.kubernetes.io/part-of": "appsub-obj-1"})
resource.SetOwnerReferences([]metav1.OwnerReference{{
APIVersion: "apps.open-cluster-management.io/v1",
Kind: "Subscription",
Name: appsub.Name,
UID: appsub.UID,
}})

resourceList := []ResourceUnit{{Resource: resource, Gvk: resource.GetObjectKind().GroupVersionKind()}}
allowedGroupResources, deniedGroupResources := utils.GetAllowDenyLists(*appsub)

err = sync.ProcessSubResources(appsub, resourceList, allowedGroupResources, deniedGroupResources, false)
Expect(err).NotTo(HaveOccurred())
})

It("should have 0 resources", func() {
appsub := workload5Subscription.DeepCopy()
// Actually creating the subscription
Expect(k8sClient.Create(context.TODO(), appsub)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), appsub)

resourceList := []ResourceUnit{}
allowedGroupResources, deniedGroupResources := utils.GetAllowDenyLists(*appsub)

err = sync.ProcessSubResources(appsub, resourceList, allowedGroupResources, deniedGroupResources, false)
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("test IsResourceNamespaced", func() {
var sync *KubeSynchronizer
var err error

BeforeEach(func() {
sync, err = CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
Expect(err).NotTo(HaveOccurred())

err = sync.Start(context.TODO())
if err != nil {
klog.Error(err)
return
}
})

It("should pass finding GVR", func() {
resource := unstructured.Unstructured{}
resource.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: "apps/v1",
Kind: "Deployment",
})

isNamespaced := sync.IsResourceNamespaced(&resource)
Expect(isNamespaced).To(BeTrue())
})

It("should fail finding GVR", func() {
resource := unstructured.Unstructured{}
resource.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: "",
Kind: "",
})

isNamespaced := sync.IsResourceNamespaced(&resource)
Expect(isNamespaced).To(BeFalse())
})
})

var _ = Describe("test getHostingAppSub", func() {
var sync *KubeSynchronizer
var err error

BeforeEach(func() {
sync, err = CreateSynchronizer(k8sManager.GetConfig(), k8sManager.GetConfig(), k8sManager.GetScheme(), &host, 2, nil, false, false)
Expect(err).NotTo(HaveOccurred())

err = sync.Start(context.TODO())
if err != nil {
klog.Error(err)
return
}
})

It("should not find hosting appsub", func() {
// No actual subscription should exist
subscription, err := sync.getHostingAppSub(hostSub)
Expect(err).To(HaveOccurred())
Expect(subscription).To(BeNil())
})

It("should find hosting appsub", func() {
workload1 := workload4Subscription.DeepCopy()
// Actually creating the subscription
Expect(k8sClient.Create(context.TODO(), workload1)).NotTo(HaveOccurred())

defer k8sClient.Delete(context.TODO(), workload1)

_, err := sync.getHostingAppSub(hostworkload4)
Expect(err).NotTo(HaveOccurred())
})
})

0 comments on commit 5f118cc

Please sign in to comment.