Skip to content

Commit

Permalink
Add unit tests for failure domains
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickstruyf3 committed Nov 30, 2023
1 parent eb5abd5 commit f14b504
Show file tree
Hide file tree
Showing 2 changed files with 244 additions and 21 deletions.
123 changes: 123 additions & 0 deletions controllers/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
Copyright 2023 Nutanix
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package controllers

import (
"context"
"testing"

credentialTypes "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/cluster-api/util"

infrav1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestControllerHelpers(t *testing.T) {
g := NewWithT(t)

_ = Describe("ControllerHelpers", func() {
const (
fd1Name = "fd-1"
fd2Name = "fd-2"
)

var (
ntnxCluster *infrav1.NutanixCluster
ctx context.Context
)

BeforeEach(func() {
ctx = context.Background()
ntnxCluster = &infrav1.NutanixCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
},
Spec: infrav1.NutanixClusterSpec{
PrismCentral: &credentialTypes.NutanixPrismEndpoint{
// Adding port info to override default value (0)
Port: 9440,
},
},
}
})

AfterEach(func() {
err := k8sClient.Delete(ctx, ntnxCluster)
Expect(err).NotTo(HaveOccurred())
})

Context("Get failure domains", func() {
It("should error when passing empty failure domain name", func() {
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
_, err := GetFailureDomain("", ntnxCluster)
Expect(err).To(HaveOccurred())
})
It("should error when passing nil cluster", func() {
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
_, err := GetFailureDomain(fd1Name, nil)
Expect(err).To(HaveOccurred())
})
It("should error when no failure domain has been found", func() {
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
_, err := GetFailureDomain(fd1Name, ntnxCluster)
Expect(err).To(HaveOccurred())
})
It("should return the correct failuredomain", func() {
r := util.RandomString(10)
fd1 := infrav1.NutanixFailureDomain{
Name: fd1Name,
Cluster: infrav1.NutanixResourceIdentifier{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
Subnets: []infrav1.NutanixResourceIdentifier{
{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
},
}
fd2 := infrav1.NutanixFailureDomain{
Name: fd2Name,
Cluster: infrav1.NutanixResourceIdentifier{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
Subnets: []infrav1.NutanixResourceIdentifier{
{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
},
}
ntnxCluster.Spec.FailureDomains = []infrav1.NutanixFailureDomain{
fd1,
fd2,
}
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
fd, err := GetFailureDomain(fd2Name, ntnxCluster)
Expect(err).ToNot(HaveOccurred())
Expect(*fd).To(Equal(fd2))
})
})
})
}
142 changes: 121 additions & 21 deletions controllers/nutanixcluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,80 @@ import (
"testing"

credentialTypes "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/cluster-api/util"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

infrav1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"
nctx "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/pkg/context"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gstruct"
)

func TestNutanixClusterReconciler(t *testing.T) {
g := NewWithT(t)

_ = Describe("NutanixClusterReconciler", func() {
Context("Reconcile an NutanixCluster", func() {
It("should not error and not requeue the request", func() {
ctx := context.Background()
reconciler := &NutanixClusterReconciler{
Client: k8sClient,
Scheme: runtime.NewScheme(),
}
const (
fd1Name = "fd-1"
fd2Name = "fd-2"
)

ntnxCluster := &infrav1.NutanixCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
var (
ntnxCluster *infrav1.NutanixCluster
ctx context.Context
fd1 infrav1.NutanixFailureDomain
reconciler *NutanixClusterReconciler
)

BeforeEach(func() {
ctx = context.Background()
ntnxCluster = &infrav1.NutanixCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
},
Spec: infrav1.NutanixClusterSpec{
PrismCentral: &credentialTypes.NutanixPrismEndpoint{
// Adding port info to override default value (0)
Port: 9440,
},
Spec: infrav1.NutanixClusterSpec{
PrismCentral: &credentialTypes.NutanixPrismEndpoint{
// Adding port info to override default value (0)
Port: 9440,
},
},
}
r := util.RandomString(10)
fd1 = infrav1.NutanixFailureDomain{
Name: fd1Name,
Cluster: infrav1.NutanixResourceIdentifier{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
Subnets: []infrav1.NutanixResourceIdentifier{
{
Type: infrav1.NutanixIdentifierName,
Name: &r,
},
}
},
}
reconciler = &NutanixClusterReconciler{
Client: k8sClient,
Scheme: runtime.NewScheme(),
}
})

AfterEach(func() {
err := k8sClient.Delete(ctx, ntnxCluster)
Expect(err).NotTo(HaveOccurred())
})

Context("Reconcile an NutanixCluster", func() {
It("should not error and not requeue the request", func() {
// Create the NutanixCluster object and expect the Reconcile to be created
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
defer func() {
err := k8sClient.Delete(ctx, ntnxCluster)
Expect(err).NotTo(HaveOccurred())
}()

result, err := reconciler.Reconcile(ctx, ctrl.Request{
NamespacedName: client.ObjectKey{
Expand All @@ -75,5 +107,73 @@ func TestNutanixClusterReconciler(t *testing.T) {
g.Expect(result.Requeue).To(BeFalse())
})
})

Context("Reconcile failure domains", func() {
It("sets the failure domains in the nutanixcluster status and failure domain reconciled condition", func() {
ntnxCluster.Spec.FailureDomains = []infrav1.NutanixFailureDomain{
fd1,
}

// Create the NutanixCluster object and expect the Reconcile to be created
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
// Retrieve the applied nutanix cluster objects
appliedNtnxCluster := &infrav1.NutanixCluster{}
k8sClient.Get(ctx, client.ObjectKey{
Namespace: ntnxCluster.Namespace,
Name: ntnxCluster.Name,
}, appliedNtnxCluster)

err := reconciler.reconcileFailureDomains(&nctx.ClusterContext{
Context: ctx,
NutanixCluster: appliedNtnxCluster,
})
g.Expect(err).NotTo(HaveOccurred())

g.Expect(appliedNtnxCluster.Status.Conditions).To(ContainElement(
gstruct.MatchFields(
gstruct.IgnoreExtras,
gstruct.Fields{
"Type": Equal(infrav1.FailureDomainsReconciled),
"Status": Equal(corev1.ConditionTrue),
},
),
))
g.Expect(appliedNtnxCluster.Status.FailureDomains).To(HaveKey(fd1Name))
g.Expect(appliedNtnxCluster.Status.FailureDomains[fd1Name]).To(gstruct.MatchFields(
gstruct.IgnoreExtras,
gstruct.Fields{
"ControlPlane": Equal(fd1.ControlPlane),
},
))
})

It("sets the NoFailureDomainsReconciled condition when no failure domains are set", func() {
// Create the NutanixCluster object and expect the Reconcile to be created
g.Expect(k8sClient.Create(ctx, ntnxCluster)).To(Succeed())
// Retrieve the applied nutanix cluster objects
appliedNtnxCluster := &infrav1.NutanixCluster{}
k8sClient.Get(ctx, client.ObjectKey{
Namespace: ntnxCluster.Namespace,
Name: ntnxCluster.Name,
}, appliedNtnxCluster)

err := reconciler.reconcileFailureDomains(&nctx.ClusterContext{
Context: ctx,
NutanixCluster: appliedNtnxCluster,
})
g.Expect(err).NotTo(HaveOccurred())

g.Expect(appliedNtnxCluster.Status.Conditions).To(ContainElement(
gstruct.MatchFields(
gstruct.IgnoreExtras,
gstruct.Fields{
"Type": Equal(infrav1.NoFailureDomainsReconciled),
"Status": Equal(corev1.ConditionTrue),
},
),
))
g.Expect(appliedNtnxCluster.Status.FailureDomains).To(BeEmpty())
})
})
})
}

0 comments on commit f14b504

Please sign in to comment.