Skip to content

Commit ed34b45

Browse files
authored
Additional tests (#14)
1 parent 9a377bb commit ed34b45

File tree

1 file changed

+79
-100
lines changed

1 file changed

+79
-100
lines changed

internal/controller/metalstackcluster_controller_test.go

Lines changed: 79 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ package controller
1818

1919
import (
2020
"context"
21+
"net/http"
2122

2223
. "github.com/onsi/ginkgo/v2"
2324
. "github.com/onsi/gomega"
2425
. "github.com/onsi/gomega/gstruct"
2526
"github.com/stretchr/testify/mock"
2627
"k8s.io/apimachinery/pkg/types"
2728
"k8s.io/utils/ptr"
29+
"sigs.k8s.io/controller-runtime/pkg/client"
2830
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2931

3032
corev1 "k8s.io/api/core/v1"
@@ -36,6 +38,7 @@ import (
3638
metalnetwork "github.com/metal-stack/metal-go/api/client/network"
3739
"github.com/metal-stack/metal-go/api/models"
3840
metalgoclient "github.com/metal-stack/metal-go/test/client"
41+
"github.com/metal-stack/metal-lib/httperrors"
3942
"github.com/metal-stack/metal-lib/pkg/pointer"
4043
"github.com/metal-stack/metal-lib/pkg/testcommon"
4144

@@ -270,6 +273,17 @@ var _ = Describe("MetalStackCluster Controller", func() {
270273
"Type": Equal(v1alpha1.ClusterControlPlaneEndpointEnsured),
271274
"Status": Equal(corev1.ConditionTrue),
272275
})))
276+
277+
By("ssh keypair generation")
278+
sshSecret := &corev1.Secret{
279+
ObjectMeta: metav1.ObjectMeta{
280+
Name: owner.Name + "-ssh-keypair",
281+
Namespace: resource.Namespace,
282+
},
283+
}
284+
Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(sshSecret), sshSecret)).NotTo(HaveOccurred())
285+
Expect(sshSecret.Data).To(HaveKey("id_rsa"))
286+
Expect(sshSecret.Data).To(HaveKey("id_rsa.pub"))
273287
})
274288
})
275289
Context("reconciliation when external resources are provided", func() {
@@ -377,111 +391,76 @@ var _ = Describe("MetalStackCluster Controller", func() {
377391

378392
When("referenced resources do not exist", func() {
379393
It("should fail reconciling", func() {
394+
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
380395

381-
})
382-
})
383-
})
384-
385-
Context("When reconciling a MetalStackCluster resource", func() {
386-
// const resourceName = "test-resource"
387-
388-
// var (
389-
// ctx = context.Background()
390-
391-
// resource *infrastructurev1alpha1.MetalStackCluster
392-
// typeNamespacedName = types.NamespacedName{
393-
// Name: resourceName,
394-
// Namespace: "default",
395-
// }
396-
// metalstackcluster = &infrastructurev1alpha1.MetalStackCluster{}
397-
// )
398-
399-
// BeforeEach(func() {
400-
// resource = &infrastructurev1alpha1.MetalStackCluster{
401-
// ObjectMeta: metav1.ObjectMeta{
402-
// Name: resourceName,
403-
// Namespace: "default",
404-
// },
405-
// Spec: infrastructurev1alpha1.MetalStackClusterSpec{
406-
// ControlPlaneEndpoint: infrastructurev1alpha1.APIEndpoint{},
407-
// ProjectID: "test-project",
408-
// NodeNetworkID: nil,
409-
// ControlPlaneIP: nil,
410-
// Partition: "test-partition",
411-
// Firewall: &infrastructurev1alpha1.Firewall{},
412-
// },
413-
// }
414-
415-
// By("creating the custom resource for the Kind MetalStackCluster")
416-
// err := k8sClient.Get(ctx, typeNamespacedName, metalstackcluster)
417-
// if err != nil && errors.IsNotFound(err) {
418-
// Expect(k8sClient.Create(ctx, resource)).To(Succeed())
419-
// }
420-
// })
421-
422-
// AfterEach(func() {
423-
// resource := &infrastructurev1alpha1.MetalStackCluster{}
424-
// err := k8sClient.Get(ctx, typeNamespacedName, resource)
425-
// Expect(err).NotTo(HaveOccurred())
426-
427-
// By("Cleanup the specific resource instance MetalStackCluster")
428-
// Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
429-
// })
430-
431-
// it should not do anything when the resource has no ownership yet
432-
433-
// it should reconcile successfully when the resource gets an ownership
434-
435-
// it automatically allocates dependent resources
436-
437-
// it should generate an SSH secret
438-
// it should allocate a node network
439-
// it should allocate a control plane ip
440-
// it should ensure a firewall deployment
441-
442-
// it is idempotent!
443-
// status conditions should be properly evaluated
444-
445-
// it is possible to optionally provide control plane ip, node network id and firewall
446-
447-
// it should delete the resource
448-
449-
// it should delete all managed resources
450-
451-
// it should not delete optionally provided resources
452-
453-
// Context("should successfully reconcile the resource", Ordered, func() {
454-
// It("should not do anything when the resource has no ownership yet", func() {
455-
456-
// })
457-
458-
// By("setting an ownership ownership yet")
459-
460-
// It("it should reconcile successfully", func() {
396+
By("creating the cluster resource and setting the owner reference")
397+
owner := &clusterv1beta1.Cluster{
398+
ObjectMeta: metav1.ObjectMeta{
399+
GenerateName: "owner-",
400+
Namespace: "default",
401+
},
402+
}
403+
Expect(k8sClient.Create(ctx, owner)).To(Succeed())
461404

462-
// })
405+
resource.OwnerReferences = []metav1.OwnerReference{
406+
*metav1.NewControllerRef(owner, clusterv1beta1.GroupVersion.WithKind("Cluster")),
407+
}
408+
Expect(k8sClient.Update(ctx, resource)).To(Succeed())
463409

464-
// It("it should automatically allocate dependent resources", func() {
465-
// // it should generate an SSH secret
466-
// // it should allocate a node network
467-
// // it should allocate a control plane ip
468-
// // it should ensure a firewall deployment
469-
// })
470-
// })
471-
// controllerReconciler := &MetalStackClusterReconciler{
472-
// Client: k8sClient,
473-
// Scheme: k8sClient.Scheme(),
474-
// }
410+
By("reconciling the resource")
475411

476-
// _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
477-
// NamespacedName: typeNamespacedName,
478-
// })
479-
// Expect(err).NotTo(HaveOccurred())
412+
typeNamespacedName := types.NamespacedName{
413+
Name: resource.Name,
414+
Namespace: "default",
415+
}
480416

481-
// resource := &infrastructurev1alpha1.MetalStackCluster{}
482-
// err = k8sClient.Get(ctx, typeNamespacedName, resource)
483-
// Expect(err).NotTo(HaveOccurred())
417+
controllerReconciler.MetalClient, _ = metalgoclient.NewMetalMockClient(testingT, &metalgoclient.MetalMockFns{
418+
IP: func(m *mock.Mock) {
419+
m.On("FindIP", testcommon.MatchIgnoreContext(testingT, metalip.NewFindIPParams().WithID(controlPlaneIP)), nil).
420+
Return(nil, &metalip.FindIPDefault{
421+
Payload: &httperrors.HTTPErrorResponse{
422+
StatusCode: http.StatusNotFound,
423+
Message: "ip not found",
424+
},
425+
})
426+
},
427+
Network: func(m *mock.Mock) {
428+
m.On("FindNetwork", testcommon.MatchIgnoreContext(testingT, metalnetwork.NewFindNetworkParams().WithID(nodeNetworkID)), nil).
429+
Return(nil, &metalnetwork.FindNetworkDefault{
430+
Payload: &httperrors.HTTPErrorResponse{
431+
StatusCode: http.StatusNotFound,
432+
Message: "network not found",
433+
},
434+
})
435+
},
436+
})
484437

485-
// Expect(resource.Status.Conditions).To(ContainElement("bla"))
438+
Eventually(func() error {
439+
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
440+
NamespacedName: typeNamespacedName,
441+
})
442+
return err
443+
}).Should(MatchError(ContainSubstring("not found")))
444+
445+
Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).ToNot(HaveOccurred())
446+
447+
Expect(resource.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{
448+
"Type": Equal(v1alpha1.ClusterNodeNetworkEnsured),
449+
"Status": Equal(corev1.ConditionFalse),
450+
"Reason": Equal("InternalError"),
451+
"Message": ContainSubstring("network not found"),
452+
})))
453+
Expect(resource.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{
454+
"Type": Equal(v1alpha1.ClusterFirewallDeploymentReady),
455+
"Status": Equal(corev1.ConditionTrue),
456+
})))
457+
Expect(resource.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{
458+
"Type": Equal(v1alpha1.ClusterControlPlaneEndpointEnsured),
459+
"Status": Equal(corev1.ConditionFalse),
460+
"Reason": Equal("InternalError"),
461+
"Message": ContainSubstring("ip not found"),
462+
})))
463+
})
464+
})
486465
})
487466
})

0 commit comments

Comments
 (0)