Skip to content

Commit

Permalink
VirtualNode: unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cheina97 authored and adamjensenbot committed Jul 25, 2023
1 parent c8a93fe commit 58d2cdb
Show file tree
Hide file tree
Showing 18 changed files with 244 additions and 124 deletions.
3 changes: 3 additions & 0 deletions apis/virtualkubelet/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ var (
// NamespaceMapGroupVersionResource is groupResourceVersion used to register these objects.
NamespaceMapGroupVersionResource = SchemeGroupVersion.WithResource(NamespaceMapResource)

// VirtualNodeKind is the kind name used to register the VirtualNode CRD.
VirtualNodeKind = "VirtualNode"

// VirtualNodeResource is the resource name used to register the VirtualNode CRD.
VirtualNodeResource = "virtualnodes"

Expand Down
13 changes: 8 additions & 5 deletions pkg/liqo-controller-manager/foreign-cluster-operator/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,8 @@ func (r *ForeignClusterReconciler) ensureRemoteIdentity(ctx context.Context,
}()

config, err := r.IdentityManager.GetConfig(foreignCluster.Spec.ClusterIdentity, foreignCluster.Status.TenantNamespace.Local)
if err != nil && !kerrors.IsNotFound(err) {
return err
}

if err != nil {
switch {
case kerrors.IsNotFound(err):
if err = r.validateIdentity(ctx, foreignCluster); err != nil {
if errors.Is(err, identityEmptyDeniedError{}) {
status = discoveryv1alpha1.PeeringConditionStatusEmptyDenied
Expand All @@ -93,6 +90,12 @@ func (r *ForeignClusterReconciler) ensureRemoteIdentity(ctx context.Context,
}
return err
}
if config, err = r.IdentityManager.GetConfig(foreignCluster.Spec.ClusterIdentity, foreignCluster.Status.TenantNamespace.Local); err != nil {
return err
}
// If the error is not NotFound this case is matched.
case err != nil:
return err
}

status = discoveryv1alpha1.PeeringConditionStatusEstablished
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ var _ = Describe("Test Storage Provisioner", func() {
}
Expect(state).To(Equal(controller.ProvisioningFinished))
Expect(pv).ToNot(BeNil())
Expect(pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Key).To(Equal(corev1.LabelHostname))
Expect(pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Key).To(Equal(liqoconst.RemoteClusterID))
Expect(pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Operator).To(Equal(corev1.NodeSelectorOpIn))
Expect(pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values).To(ContainElement(virtualNodeName))
Expect(pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values).To(ContainElement(remoteClusterID))
Expect(pv.Spec.StorageClassName).To(Equal(virtualStorageClassName))

_, err = testEnvClient.CoreV1().PersistentVolumeClaims(RemoteNamespace).Get(ctx, pvcName, metav1.GetOptions{})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (r *VirtualNodeReconciler) ensureNamespaceMapPresence(ctx context.Context,

result, err := ctrlutils.CreateOrUpdate(ctx, r.Client, nm, func() error {
nm.Labels = labels.Merge(nm.Labels, l)
return nil
return ctrlutils.SetControllerReference(vn, nm, r.Scheme)
})

if err != nil {
Expand Down
36 changes: 26 additions & 10 deletions pkg/liqo-controller-manager/virtualnode-controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
liqoconst "github.com/liqotech/liqo/pkg/consts"
"github.com/liqotech/liqo/pkg/discovery"
"github.com/liqotech/liqo/pkg/utils/testutil"
"github.com/liqotech/liqo/pkg/vkMachinery/forge"
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
Expand All @@ -51,7 +52,9 @@ const (
nameVirtualNode2 = "virtual-node-2"
nameSimpleNode = "simple-node"
remoteClusterID1 = "6a0e9f-b52-4ed0"
remoteClusterName1 = "remote-1"
remoteClusterID2 = "899890-dsd-323"
remoteClusterName2 = "remote-2"
remoteClusterIDSimpleNode = "909030-sd-3231"
tenantNamespaceNameID1 = "liqo-tenant-namespace-1"
tenantNamespaceNameID2 = "liqo-tenant-namespace-2"
Expand All @@ -65,9 +68,15 @@ var (
ctx context.Context
cancel context.CancelFunc

nms *mapsv1alpha1.NamespaceMapList
virtualNode1 *corev1.Node
virtualNode2 *corev1.Node
localIdentity = discoveryv1alpha1.ClusterIdentity{
ClusterID: "local-ID",
ClusterName: "local-name",
}

nms *mapsv1alpha1.NamespaceMapList

virtualNode1 *mapsv1alpha1.VirtualNode
virtualNode2 *mapsv1alpha1.VirtualNode
simpleNode *corev1.Node
tenantNamespace1 *corev1.Namespace
tenantNamespace2 *corev1.Namespace
Expand Down Expand Up @@ -110,20 +119,27 @@ var _ = BeforeSuite(func() {
})
Expect(err).ToNot(HaveOccurred())

err = (&VirtualNodeReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
k8sClient = k8sManager.GetClient()
Expect(k8sClient).ToNot(BeNil())

vnr, err := NewVirtualNodeReconciler(ctx,
k8sClient,
k8sClient,
scheme.Scheme,
k8sManager.GetEventRecorderFor("virtualnode-controller"),
&localIdentity,
&forge.VirtualKubeletOpts{},
)
Expect(err).ToNot(HaveOccurred())

err = (vnr).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

go func() {
err = k8sManager.Start(ctx)
Expect(err).ToNot(HaveOccurred())
}()

k8sClient = k8sManager.GetClient()
Expect(k8sClient).ToNot(BeNil())

nms = &mapsv1alpha1.NamespaceMapList{}

tenantNamespace1 = &corev1.Namespace{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,28 @@ var deploymentHandler = &handler.Funcs{
},
}

var namespaceMapHandler = handler.EnqueueRequestsFromMapFunc(
func(ctx context.Context, o client.Object) []reconcile.Request {
nm, ok := o.(*virtualkubeletv1alpha1.NamespaceMap)
if !ok {
return []reconcile.Request{}
}
requests := []reconcile.Request{}
for _, ns := range nm.ObjectMeta.OwnerReferences {
if ns.Kind != virtualkubeletv1alpha1.VirtualNodeKind {
continue
}
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: ns.Name,
Namespace: nm.Namespace,
},
})
}
return requests
},
)

// SetupWithManager register the VirtualNodeReconciler to the manager.
func (r *VirtualNodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
// select virtual kubelet deployments only
Expand All @@ -167,5 +189,8 @@ func (r *VirtualNodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
&appsv1.Deployment{},
deploymentHandler,
builder.WithPredicates(deployPredicate),
).Watches(
&virtualkubeletv1alpha1.NamespaceMap{},
namespaceMapHandler,
).Complete(r)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,60 +16,100 @@ package virtualnodectrl

import (
"fmt"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/pterm/pterm"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

discoveryv1alpha1 "github.com/liqotech/liqo/apis/discovery/v1alpha1"
virtualkubeletv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1"
liqoconst "github.com/liqotech/liqo/pkg/consts"
)

var _ = Describe("VirtualNode controller", func() {

Context("Check if resources VirtualNodes and NamespaceMaps are correctly initialized", func() {

BeforeEach(func() {
virtualNode1 = &corev1.Node{
func ForgeFakeVirtualNode(nameVirtualNode, tenantNamespaceName, remoteClusterID string) *virtualkubeletv1alpha1.VirtualNode {
return &virtualkubeletv1alpha1.VirtualNode{
ObjectMeta: metav1.ObjectMeta{
Name: nameVirtualNode,
Namespace: tenantNamespaceName,
},
Spec: virtualkubeletv1alpha1.VirtualNodeSpec{
ClusterIdentity: &discoveryv1alpha1.ClusterIdentity{
ClusterID: remoteClusterID,
ClusterName: remoteClusterName1,
},
Template: &virtualkubeletv1alpha1.DeploymentTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: nameVirtualNode1,
Name: nameVirtualNode,
Namespace: tenantNamespaceName,
Labels: map[string]string{
liqoconst.TypeLabel: liqoconst.TypeNode,
liqoconst.RemoteClusterID: remoteClusterID1,
"virtual-node": nameVirtualNode,
},
},
}
virtualNode2 = &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: nameVirtualNode2,
Labels: map[string]string{
liqoconst.TypeLabel: liqoconst.TypeNode,
liqoconst.RemoteClusterID: remoteClusterID2,
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"virtual-node": nameVirtualNode,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"virtual-node": nameVirtualNode,
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "virtual-kubelet",
Image: "virtual-kubelet-image",
},
},
},
},
},
}
},
},
}
}

var _ = Describe("VirtualNode controller", func() {

Context("Check if resources VirtualNodes and NamespaceMaps are correctly initialized", func() {

BeforeEach(func() {
virtualNode1 = ForgeFakeVirtualNode(nameVirtualNode1, tenantNamespaceNameID1, remoteClusterID1)

virtualNode2 = ForgeFakeVirtualNode(nameVirtualNode2, tenantNamespaceNameID2, remoteClusterID2)

time.Sleep(2 * time.Second)
By(fmt.Sprintf("Create the virtual-node '%s'", nameVirtualNode1))
Expect(k8sClient.Create(ctx, virtualNode1)).Should(Succeed())
By(fmt.Sprintf("Create the virtual-node '%s'", nameVirtualNode2))
Expect(k8sClient.Create(ctx, virtualNode2)).Should(Succeed())
})

AfterEach(func() {
vn := &virtualkubeletv1alpha1.VirtualNode{}
By(fmt.Sprintf("Delete the virtual-node '%s'", nameVirtualNode1))
Expect(k8sClient.Delete(ctx, virtualNode1)).Should(Succeed())
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1, Namespace: tenantNamespace1.Name}, vn)).Should(Succeed())
Expect(k8sClient.Delete(ctx, vn)).Should(Succeed())
Eventually(func() bool {
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1}, virtualNode1)
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1, Namespace: tenantNamespace1.Name}, virtualNode1)
return apierrors.IsNotFound(err)
}, timeout, interval).Should(BeTrue())
By(fmt.Sprintf("Delete the virtual-node '%s'", nameVirtualNode2))
Expect(k8sClient.Delete(ctx, virtualNode2)).Should(Succeed())
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2, Namespace: tenantNamespace2.Name}, vn)).Should(Succeed())
Expect(k8sClient.Delete(ctx, vn)).Should(Succeed())
Eventually(func() bool {
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2}, virtualNode2)
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2, Namespace: tenantNamespace2.Name}, virtualNode2)
return apierrors.IsNotFound(err)
}, timeout, interval).Should(BeTrue())
})
Expand All @@ -91,16 +131,18 @@ var _ = Describe("VirtualNode controller", func() {
client.MatchingLabels{liqoconst.RemoteClusterID: remoteClusterID2}); err != nil {
return false
}
pterm.BgYellow.Printfln("nms: %v", nms)
pterm.BgYellow.Printfln("nms len: %v", len(nms.Items))
return len(nms.Items) == 1
}, timeout, interval).Should(BeTrue())

})

It(fmt.Sprintf("Check if finalizers and ownerReference are correctly created for %s", nameVirtualNode1), func() {
It(fmt.Sprintf("Check if finalizers are correctly created for %s", nameVirtualNode1), func() {

By(fmt.Sprintf("Try to get virtual-node: %s", nameVirtualNode1))
Eventually(func() bool {
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1}, virtualNode1)
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1, Namespace: tenantNamespace1.Name}, virtualNode1)
return err == nil
}, timeout, interval).Should(BeTrue())

Expand All @@ -113,21 +155,9 @@ var _ = Describe("VirtualNode controller", func() {
return len(nms.Items) == 1
}, timeout, interval).Should(BeTrue())

expectedOwnerReference := metav1.OwnerReference{
APIVersion: "v1",
BlockOwnerDeletion: pointer.BoolPtr(true),
Kind: "Node",
Name: virtualNode1.GetName(),
UID: virtualNode1.GetUID(),
Controller: pointer.BoolPtr(true),
}

By(fmt.Sprintf("Try to check the ownership of the NamespaceMap: %s", nms.Items[0].GetName()))
Expect(nms.Items[0].GetOwnerReferences()).To(ContainElement(expectedOwnerReference))

By(fmt.Sprintf("Try to check presence of finalizer on the virtual-Node: %s", virtualNode1.GetName()))
Eventually(func() bool {
if err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1},
if err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode1, Namespace: tenantNamespace1.Name},
virtualNode1); err != nil {
return false
}
Expand All @@ -136,11 +166,11 @@ var _ = Describe("VirtualNode controller", func() {

})

It(fmt.Sprintf("Check if finalizers and ownerReference are correctly created for %s", nameVirtualNode2), func() {
It(fmt.Sprintf("Check if finalizers are correctly created for %s", nameVirtualNode2), func() {

By(fmt.Sprintf("Try to get virtual-node: %s", nameVirtualNode2))
Eventually(func() bool {
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2}, virtualNode2)
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2, Namespace: tenantNamespace2.Name}, virtualNode2)
return err == nil
}, timeout, interval).Should(BeTrue())

Expand All @@ -153,22 +183,9 @@ var _ = Describe("VirtualNode controller", func() {
return len(nms.Items) == 1
}, timeout, interval).Should(BeTrue())

expectedOwnerReference := metav1.OwnerReference{
APIVersion: "v1",
BlockOwnerDeletion: pointer.BoolPtr(true),
Kind: "Node",
Name: virtualNode2.GetName(),
UID: virtualNode2.GetUID(),
Controller: pointer.BoolPtr(true),
}

By(fmt.Sprintf("Try to check ownership of NamespaceMap: %s", nms.Items[0].GetName()))
Expect(nms.Items[0].GetOwnerReferences()).To(ContainElement(expectedOwnerReference))

By(fmt.Sprintf("Try to check presence of finalizer in VirtualNode: %s", virtualNode2.GetName()))
// i have to update my node instance, because finalizer could be updated after my first get
By(fmt.Sprintf("Try to check presence of finalizer on the virtual-Node: %s", virtualNode2.GetName()))
Eventually(func() bool {
if err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2},
if err := k8sClient.Get(ctx, types.NamespacedName{Name: nameVirtualNode2, Namespace: tenantNamespace2.Name},
virtualNode2); err != nil {
return false
}
Expand Down Expand Up @@ -222,15 +239,7 @@ var _ = Describe("VirtualNode controller", func() {

It(fmt.Sprintf("Check regeneration of NamespaceMap associated to %s", remoteClusterID1), func() {

virtualNode1 = &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: nameVirtualNode1,
Labels: map[string]string{
liqoconst.TypeLabel: liqoconst.TypeNode,
liqoconst.RemoteClusterID: remoteClusterID1,
},
},
}
virtualNode1 = ForgeFakeVirtualNode(nameVirtualNode1, tenantNamespaceNameID1, remoteClusterID1)
By(fmt.Sprintf("Create the virtual-node '%s'", nameVirtualNode1))
Expect(k8sClient.Create(ctx, virtualNode1)).Should(Succeed())

Expand Down
Loading

0 comments on commit 58d2cdb

Please sign in to comment.