Skip to content

Commit

Permalink
managedcluster controller test
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Bortnikov <[email protected]>
  • Loading branch information
BROngineer committed Dec 24, 2024
1 parent a198bc7 commit d375814
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ linters-settings:
- ["call-chain", "loop", "method-call", "recover", "immediate-recover", "return"]
- name: dot-imports
arguments:
- { allowedPackages: ["github.com/onsi/ginkgo/v2","github.com/onsi/gomega"] }
- { allowedPackages: ["github.com/onsi/ginkgo/v2","github.com/onsi/gomega","sigs.k8s.io/controller-runtime/pkg/envtest/komega"] }
- name: duplicated-imports
- name: early-return
- name: empty-block
Expand Down
97 changes: 95 additions & 2 deletions internal/controller/managedcluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"time"

hcv2 "github.com/fluxcd/helm-controller/api/v2"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
Expand All @@ -28,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
. "sigs.k8s.io/controller-runtime/pkg/envtest/komega"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

hmc "github.com/Mirantis/hmc/api/v1alpha1"
Expand All @@ -42,6 +44,8 @@ var _ = Describe("ManagedCluster Controller", func() {
templateName = "test-template"
svcTemplateName = "test-svc-template"
credentialName = "test-credential"

helmChartURL = "http://source-controller.hmc-system.svc.cluster.local/helmchart/hmc-system/test-chart/0.1.0.tar.gz"
)

ctx := context.Background()
Expand Down Expand Up @@ -123,6 +127,11 @@ var _ = Describe("ManagedCluster Controller", func() {
Expect(k8sClient.Create(ctx, svcTemplate)).To(Succeed())
svcTemplate.Status = hmc.ServiceTemplateStatus{
TemplateStatusCommon: hmc.TemplateStatusCommon{
ChartRef: &hcv2.CrossNamespaceSourceReference{
Kind: "HelmChart",
Name: "ref-test",
Namespace: "default",
},
TemplateValidationStatus: hmc.TemplateValidationStatus{
Valid: true,
},
Expand Down Expand Up @@ -212,17 +221,101 @@ var _ = Describe("ManagedCluster Controller", func() {
Expect(k8sClient.Delete(ctx, management)).To(Succeed())
Expect(k8sClient.Delete(ctx, namespace)).To(Succeed())
})

It("should successfully reconcile the resource", func() {
By("Reconciling the created resource")
controllerReconciler := &ManagedClusterReconciler{
Client: k8sClient,
Client: mgrClient,
Config: &rest.Config{},
}

By("Ensure finalizer is added")
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).NotTo(HaveOccurred())
Eventually(Object(managedCluster)).Should(SatisfyAll(
HaveField("Finalizers", ContainElement(hmc.ManagedClusterFinalizer)),
))

By("Reconciling resource with finalizer")
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).To(HaveOccurred())
Eventually(Object(managedCluster)).Should(SatisfyAll(
HaveField("Status.Conditions", ContainElement(SatisfyAll(
HaveField("Type", hmc.TemplateReadyCondition),
HaveField("Status", metav1.ConditionTrue),
HaveField("Reason", hmc.SucceededReason),
HaveField("Message", "Template is valid"),
))),
))

By("Creating absent required resources: HelmChart, HelmRepository")
helmRepo := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: "test-repository",
Namespace: "default",
},
Spec: sourcev1.HelmRepositorySpec{
Insecure: true,
Interval: metav1.Duration{
Duration: 10 * time.Minute,
},
Provider: "generic",
Type: "oci",
URL: "oci://hmc-local-registry:5000/charts",
},
}
Expect(k8sClient.Create(ctx, helmRepo)).To(Succeed())

helmChart := &sourcev1.HelmChart{
ObjectMeta: metav1.ObjectMeta{
Name: "ref-test",
Namespace: "default",
},
Spec: sourcev1.HelmChartSpec{
Chart: "test",
Interval: metav1.Duration{
Duration: 10 * time.Minute,
},
ReconcileStrategy: sourcev1.ReconcileStrategyChartVersion,
SourceRef: sourcev1.LocalHelmChartSourceReference{
Kind: "HelmRepository",
Name: helmRepo.Name,
},
Version: "0.1.0",
},
}
Expect(k8sClient.Create(ctx, helmChart)).To(Succeed())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).To(HaveOccurred())

By("Patching ClusterTemplate status")
Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(template), template)).Should(Succeed())
template.Status.ChartRef = &hcv2.CrossNamespaceSourceReference{
Kind: "HelmChart",
Name: "ref-test",
Namespace: "default",
}
Expect(k8sClient.Status().Update(ctx, template)).To(Succeed())

helmChart.Status.URL = helmChartURL
helmChart.Status.Artifact = &sourcev1.Artifact{
URL: helmChartURL,
LastUpdateTime: metav1.Now(),
}
Expect(k8sClient.Status().Update(ctx, helmChart)).To(Succeed())

// todo: next error occurs due to dependency on helm library. The best way to mitigate this is to
// inject an interface into the reconciler struct that can be mocked out for testing.
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).To(HaveOccurred())
})
})
})
7 changes: 7 additions & 0 deletions internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
. "sigs.k8s.io/controller-runtime/pkg/envtest/komega"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
Expand All @@ -56,6 +57,9 @@ const (
mutatingWebhookKind = "MutatingWebhookConfiguration"
validatingWebhookKind = "ValidatingWebhookConfiguration"
testSystemNamespace = "test-system-namespace"

pollingInterval = 50 * time.Millisecond
eventuallyTimeout = 3 * time.Second
)

var (
Expand All @@ -69,6 +73,8 @@ var (
)

func TestControllers(t *testing.T) {
SetDefaultEventuallyPollingInterval(pollingInterval)
SetDefaultEventuallyTimeout(eventuallyTimeout)
RegisterFailHandler(Fail)

RunSpecs(t, "Controller Suite")
Expand Down Expand Up @@ -126,6 +132,7 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())
SetClient(k8sClient)

dynamicClient, err = dynamic.NewForConfig(cfg)
Expect(err).NotTo(HaveOccurred())
Expand Down

0 comments on commit d375814

Please sign in to comment.