diff --git a/pkg/controller/pod_volume_backup_controller_ginkgo_test.go b/pkg/controller/pod_volume_backup_controller_ginkgo_test.go deleted file mode 100644 index 2bd594a995..0000000000 --- a/pkg/controller/pod_volume_backup_controller_ginkgo_test.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright The Velero contributors. - -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 controller - -import ( - "context" - "time" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" - apierrors "k8s.io/apimachinery/pkg/api/errors" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/clock" - "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - kbclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/builder" - "github.com/vmware-tanzu/velero/pkg/metrics" - velerotest "github.com/vmware-tanzu/velero/pkg/test" -) - -const ( - name = "pvb-1" -) - -func pvbBuilder() *builder.PodVolumeBackupBuilder { - return builder.ForPodVolumeBackup(velerov1api.DefaultNamespace, name) -} - -func podBuilder() *builder.PodBuilder { - return builder.ForPod(velerov1api.DefaultNamespace, name) -} - -var _ = Describe("Pod Volume Backup Reconciler", func() { - type request struct { - pvb *velerov1api.PodVolumeBackup - pod *corev1.Pod - - expected *velerov1api.PodVolumeBackup - expectedRequeue ctrl.Result - expectedErrMsg string - } - - // `now` will be used to set the fake clock's time; capture - // it here so it can be referenced in the test case defs. - now, err := time.Parse(time.RFC1123, time.RFC1123) - Expect(err).To(BeNil()) - now = now.Local() - - DescribeTable("a pod volume backup", - func(test request) { - // Setup reconciler - Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed()) - r := PodVolumeBackupReconciler{ - Client: fake.NewFakeClientWithScheme(scheme.Scheme, test.pvb), - Ctx: context.Background(), - Clock: clock.NewFakeClock(now), - Metrics: metrics.NewResticServerMetrics(), - NodeName: "foo", - Log: velerotest.NewLogger(), - } - - err := r.Client.Create(r.Ctx, test.pod) - Expect(err).To(BeNil()) - - actualResult, err := r.Reconcile(r.Ctx, ctrl.Request{ - NamespacedName: types.NamespacedName{ - Namespace: velerov1api.DefaultNamespace, - Name: test.pvb.Name, - }, - }) - - Expect(actualResult).To(BeEquivalentTo(test.expectedRequeue)) - if test.expectedErrMsg == "" { - Expect(err).To(BeNil()) - } else { - Expect(err.Error()).To(BeEquivalentTo(test.expectedErrMsg)) - } - - pvb := velerov1api.PodVolumeBackup{} - err = r.Client.Get(ctx, kbclient.ObjectKey{ - Name: test.pvb.Name, - Namespace: test.pvb.Namespace, - }, &pvb) - - // Assertions - if test.expected == nil { - Expect(apierrors.IsNotFound(err)).To(BeTrue()) - } else { - Expect(err).To(BeNil()) - Eventually(pvb.Status.Phase).Should(Equal(test.expected.Status.Phase)) - } - }, - Entry("with with phase=empty will be processed and phase successfully patched", request{ - pvb: pvbBuilder(). - Node("foo"). - PodName(name). - PodNamespace(velerov1api.DefaultNamespace). - Volume("pvb-1-volume"). - Result(), - pod: podBuilder(). - Volumes(&corev1.Volume{Name: "pvb-1-volume"}). - Result(), - expected: pvbBuilder(). - Phase(velerov1api.PodVolumeBackupPhaseNew). - Result(), - expectedRequeue: ctrl.Result{}, - }), - ) -}) diff --git a/pkg/controller/pod_volume_backup_controller_test.go b/pkg/controller/pod_volume_backup_controller_test.go index b2b864074c..2bd594a995 100644 --- a/pkg/controller/pod_volume_backup_controller_test.go +++ b/pkg/controller/pod_volume_backup_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Velero contributors. +Copyright The Velero contributors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,157 +17,114 @@ limitations under the License. package controller import ( - "testing" + "context" + "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" + apierrors "k8s.io/apimachinery/pkg/api/errors" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/clock" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + kbclient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/metrics" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) -func TestPVBHandler(t *testing.T) { - controllerNode := "foo" - - tests := []struct { - name string - obj *velerov1api.PodVolumeBackup - shouldEnqueue bool - }{ - { - name: "Empty phase pvb on same node should be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: controllerNode, - }, - }, - shouldEnqueue: true, - }, - { - name: "New phase pvb on same node should be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: controllerNode, - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseNew, - }, - }, - shouldEnqueue: true, - }, - { - name: "InProgress phase pvb on same node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: controllerNode, - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseInProgress, - }, - }, - shouldEnqueue: false, - }, - { - name: "Completed phase pvb on same node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: controllerNode, - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseCompleted, - }, - }, - shouldEnqueue: false, - }, - { - name: "Failed phase pvb on same node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: controllerNode, - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseFailed, - }, - }, - shouldEnqueue: false, - }, +const ( + name = "pvb-1" +) - { - name: "Empty phase pvb on different node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: "some-other-node", - }, - }, - shouldEnqueue: false, - }, - { - name: "New phase pvb on different node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: "some-other-node", - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseNew, - }, - }, - shouldEnqueue: false, - }, - { - name: "InProgress phase pvb on different node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: "some-other-node", - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseInProgress, - }, - }, - shouldEnqueue: false, - }, - { - name: "Completed phase pvb on different node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: "some-other-node", - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseCompleted, - }, - }, - shouldEnqueue: false, - }, - { - name: "Failed phase pvb on different node should not be enqueued", - obj: &velerov1api.PodVolumeBackup{ - Spec: velerov1api.PodVolumeBackupSpec{ - Node: "some-other-node", - }, - Status: velerov1api.PodVolumeBackupStatus{ - Phase: velerov1api.PodVolumeBackupPhaseFailed, - }, - }, - shouldEnqueue: false, - }, +func pvbBuilder() *builder.PodVolumeBackupBuilder { + return builder.ForPodVolumeBackup(velerov1api.DefaultNamespace, name) +} + +func podBuilder() *builder.PodBuilder { + return builder.ForPod(velerov1api.DefaultNamespace, name) +} + +var _ = Describe("Pod Volume Backup Reconciler", func() { + type request struct { + pvb *velerov1api.PodVolumeBackup + pod *corev1.Pod + + expected *velerov1api.PodVolumeBackup + expectedRequeue ctrl.Result + expectedErrMsg string } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - c := &podVolumeBackupController{ - genericController: newGenericController(PodVolumeBackup, velerotest.NewLogger()), - nodeName: controllerNode, - metrics: metrics.NewResticServerMetrics(), + // `now` will be used to set the fake clock's time; capture + // it here so it can be referenced in the test case defs. + now, err := time.Parse(time.RFC1123, time.RFC1123) + Expect(err).To(BeNil()) + now = now.Local() + + DescribeTable("a pod volume backup", + func(test request) { + // Setup reconciler + Expect(velerov1api.AddToScheme(scheme.Scheme)).To(Succeed()) + r := PodVolumeBackupReconciler{ + Client: fake.NewFakeClientWithScheme(scheme.Scheme, test.pvb), + Ctx: context.Background(), + Clock: clock.NewFakeClock(now), + Metrics: metrics.NewResticServerMetrics(), + NodeName: "foo", + Log: velerotest.NewLogger(), } - c.pvbHandler(test.obj) + err := r.Client.Create(r.Ctx, test.pod) + Expect(err).To(BeNil()) + + actualResult, err := r.Reconcile(r.Ctx, ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: velerov1api.DefaultNamespace, + Name: test.pvb.Name, + }, + }) - if !test.shouldEnqueue { - assert.Equal(t, 0, c.queue.Len()) - return + Expect(actualResult).To(BeEquivalentTo(test.expectedRequeue)) + if test.expectedErrMsg == "" { + Expect(err).To(BeNil()) + } else { + Expect(err.Error()).To(BeEquivalentTo(test.expectedErrMsg)) } - require.Equal(t, 1, c.queue.Len()) - }) - } -} + pvb := velerov1api.PodVolumeBackup{} + err = r.Client.Get(ctx, kbclient.ObjectKey{ + Name: test.pvb.Name, + Namespace: test.pvb.Namespace, + }, &pvb) + + // Assertions + if test.expected == nil { + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + } else { + Expect(err).To(BeNil()) + Eventually(pvb.Status.Phase).Should(Equal(test.expected.Status.Phase)) + } + }, + Entry("with with phase=empty will be processed and phase successfully patched", request{ + pvb: pvbBuilder(). + Node("foo"). + PodName(name). + PodNamespace(velerov1api.DefaultNamespace). + Volume("pvb-1-volume"). + Result(), + pod: podBuilder(). + Volumes(&corev1.Volume{Name: "pvb-1-volume"}). + Result(), + expected: pvbBuilder(). + Phase(velerov1api.PodVolumeBackupPhaseNew). + Result(), + expectedRequeue: ctrl.Result{}, + }), + ) +})