Skip to content

Commit efe0538

Browse files
committed
Extend test to cover wider scope
Signed-off-by: Ales Raszka <[email protected]>
1 parent afacdec commit efe0538

File tree

2 files changed

+159
-1
lines changed

2 files changed

+159
-1
lines changed

controllers/backupcronjob/backupcronjob_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ func (r *BackupCronJobReconciler) getWorkspacePVCName(workspace *dw.DevWorkspace
464464
if dwOperatorConfig.Config.Workspace.PVCName != "" {
465465
pvcName = dwOperatorConfig.Config.Workspace.PVCName
466466
}
467-
return pvcName, workspace.Status.DevWorkspaceId + "/" + constants.DefaultProjectsSourcesRoot, nil
467+
return pvcName, workspace.Status.DevWorkspaceId + constants.DefaultProjectsSourcesRoot, nil
468468
}
469469
return "", "", nil
470470
}

controllers/backupcronjob/backupcronjob_controller_test.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
dwv2 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
3939
controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
4040
"github.com/devfile/devworkspace-operator/pkg/conditions"
41+
"github.com/devfile/devworkspace-operator/pkg/constants"
4142
)
4243

4344
var _ = Describe("BackupCronJobReconciler", func() {
@@ -152,6 +153,39 @@ var _ = Describe("BackupCronJobReconciler", func() {
152153
Expect(reconciler.cron.Entries()).To(HaveLen(1))
153154
})
154155

156+
It("Should stop cron if cron is disabled", func() {
157+
enabled := true
158+
schedule := "* * * * *"
159+
dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{
160+
ObjectMeta: metav1.ObjectMeta{Name: nameNamespace.Name, Namespace: nameNamespace.Namespace},
161+
Config: &controllerv1alpha1.OperatorConfiguration{
162+
Workspace: &controllerv1alpha1.WorkspaceConfig{
163+
BackupCronJob: &controllerv1alpha1.BackupCronJobConfig{
164+
Enable: &enabled,
165+
Schedule: schedule,
166+
Registry: &controllerv1alpha1.RegistryConfig{
167+
Path: "fake-registry",
168+
},
169+
},
170+
},
171+
},
172+
}
173+
Expect(fakeClient.Create(ctx, dwoc)).To(Succeed())
174+
175+
result, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: nameNamespace})
176+
Expect(err).ToNot(HaveOccurred())
177+
Expect(result).To(Equal(ctrl.Result{}))
178+
Expect(reconciler.cron.Entries()).To(HaveLen(1))
179+
180+
disabled := false
181+
dwoc.Config.Workspace.BackupCronJob.Enable = &disabled
182+
Expect(fakeClient.Update(ctx, dwoc)).To(Succeed())
183+
result, err = reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: nameNamespace})
184+
Expect(err).ToNot(HaveOccurred())
185+
Expect(result).To(Equal(ctrl.Result{}))
186+
Expect(reconciler.cron.Entries()).To(HaveLen(0))
187+
})
188+
155189
It("Should update cron schedule if DevWorkspaceOperatorConfig is updated", func() {
156190
enabled := true
157191
schedule1 := "* * * * *"
@@ -188,6 +222,32 @@ var _ = Describe("BackupCronJobReconciler", func() {
188222
Expect(reconciler.cron.Entries()[0].ID).NotTo(Equal(entryID))
189223
})
190224

225+
It("Should stop cron schedule if cron value is invalid", func() {
226+
enabled := true
227+
schedule1 := "invalid schedule"
228+
dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{
229+
ObjectMeta: metav1.ObjectMeta{Name: nameNamespace.Name, Namespace: nameNamespace.Namespace},
230+
Config: &controllerv1alpha1.OperatorConfiguration{
231+
Workspace: &controllerv1alpha1.WorkspaceConfig{
232+
BackupCronJob: &controllerv1alpha1.BackupCronJobConfig{
233+
Enable: &enabled,
234+
Schedule: schedule1,
235+
Registry: &controllerv1alpha1.RegistryConfig{
236+
Path: "fake-registry",
237+
},
238+
},
239+
},
240+
},
241+
}
242+
Expect(fakeClient.Create(ctx, dwoc)).To(Succeed())
243+
244+
result, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: nameNamespace})
245+
Expect(err).ToNot(HaveOccurred())
246+
Expect(result).To(Equal(ctrl.Result{}))
247+
Expect(reconciler.cron.Entries()).To(HaveLen(0))
248+
249+
})
250+
191251
It("Should stop cron if DevWorkspaceOperatorConfig is deleted", func() {
192252
enabled := true
193253
schedule := "* * * * *"
@@ -223,6 +283,32 @@ var _ = Describe("BackupCronJobReconciler", func() {
223283
})
224284

225285
Context("executeBackupSync", func() {
286+
It("should fail if registry secret does not exist", func() {
287+
enabled := true
288+
schedule := "* * * * *"
289+
dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{
290+
ObjectMeta: metav1.ObjectMeta{Name: nameNamespace.Name, Namespace: nameNamespace.Namespace},
291+
Config: &controllerv1alpha1.OperatorConfiguration{
292+
Workspace: &controllerv1alpha1.WorkspaceConfig{
293+
BackupCronJob: &controllerv1alpha1.BackupCronJobConfig{
294+
Enable: &enabled,
295+
Schedule: schedule,
296+
Registry: &controllerv1alpha1.RegistryConfig{
297+
Path: "fake-registry",
298+
AuthSecret: "non-existent",
299+
},
300+
},
301+
},
302+
},
303+
}
304+
dw := createDevWorkspace("dw-recent", "ns-a", false, metav1.NewTime(time.Now().Add(-10*time.Minute)))
305+
dw.Status.Phase = dwv2.DevWorkspaceStatusStopped
306+
dw.Status.DevWorkspaceId = "id-recent"
307+
Expect(fakeClient.Create(ctx, dw)).To(Succeed())
308+
309+
Expect(reconciler.executeBackupSync(ctx, dwoc, log)).To(HaveOccurred())
310+
})
311+
226312
It("creates a Job for a DevWorkspace stopped with no previous backup", func() {
227313
enabled := true
228314
schedule := "* * * * *"
@@ -253,6 +339,25 @@ var _ = Describe("BackupCronJobReconciler", func() {
253339
jobList := &batchv1.JobList{}
254340
Expect(fakeClient.List(ctx, jobList, &client.ListOptions{Namespace: dw.Namespace})).To(Succeed())
255341
Expect(jobList.Items).To(HaveLen(1))
342+
job := jobList.Items[0]
343+
Expect(job.Labels[constants.DevWorkspaceIDLabel]).To(Equal("id-recent"))
344+
Expect(job.Spec.Template.Spec.ServiceAccountName).To(Equal("devworkspace-job-runner-id-recent"))
345+
container := job.Spec.Template.Spec.Containers[0]
346+
expectedEnvs := []corev1.EnvVar{
347+
{Name: "DEVWORKSPACE_NAME", Value: "dw-recent"},
348+
{Name: "DEVWORKSPACE_NAMESPACE", Value: "ns-a"},
349+
{Name: "WORKSPACE_ID", Value: "id-recent"},
350+
{Name: "BACKUP_SOURCE_PATH", Value: "/workspace/id-recent/projects"},
351+
{Name: "DEVWORKSPACE_BACKUP_REGISTRY", Value: "fake-registry"},
352+
{Name: "PODMAN_PUSH_OPTIONS", Value: "--tls-verify=false"},
353+
}
354+
Expect(container.Env).Should(ContainElements(expectedEnvs), "container env vars should include vars neeeded for backup")
355+
356+
expectedVolumeMounts := []corev1.VolumeMount{
357+
{MountPath: "/workspace", Name: "workspace-data"},
358+
{MountPath: "/var/lib/containers", Name: "build-storage"},
359+
}
360+
Expect(container.VolumeMounts).Should(ContainElements(expectedVolumeMounts), "container volume mounts should include mounts needed for backup")
256361
})
257362

258363
It("does not create a Job when the DevWorkspace was stopped beyond time range", func() {
@@ -357,6 +462,58 @@ var _ = Describe("BackupCronJobReconciler", func() {
357462
Expect(jobList.Items).To(HaveLen(1))
358463
})
359464
})
465+
Context("ensureJobRunnerRBAC", func() {
466+
It("creates ServiceAccount for Job runner", func() {
467+
dw := createDevWorkspace("dw-rbac", "ns-rbac", false, metav1.NewTime(time.Now().Add(-10*time.Minute)))
468+
dw.Status.DevWorkspaceId = "id-rbac"
469+
Expect(fakeClient.Create(ctx, dw)).To(Succeed())
470+
471+
err := reconciler.ensureJobRunnerRBAC(ctx, dw)
472+
Expect(err).ToNot(HaveOccurred())
473+
474+
sa := &corev1.ServiceAccount{}
475+
err = fakeClient.Get(ctx, types.NamespacedName{
476+
Name: "devworkspace-job-runner-id-rbac",
477+
Namespace: dw.Namespace,
478+
}, sa)
479+
Expect(err).ToNot(HaveOccurred())
480+
Expect(sa.Labels).To(HaveKeyWithValue(constants.DevWorkspaceIDLabel, "id-rbac"))
481+
Expect(sa.Labels).To(HaveKeyWithValue(constants.DevWorkspaceWatchSecretLabel, "true"))
482+
483+
// Calling again should be idempotent
484+
err = reconciler.ensureJobRunnerRBAC(ctx, dw)
485+
Expect(err).ToNot(HaveOccurred())
486+
})
487+
})
488+
Context("wasStoppedSinceLastBackup", func() {
489+
It("returns true if DevWorkspace was stopped since last backup", func() {
490+
lastBackupTime := metav1.NewTime(time.Now().Add(-30 * time.Minute))
491+
workspaceStoppedTime := metav1.NewTime(time.Now().Add(-20 * time.Minute))
492+
dw := createDevWorkspace("dw-test", "ns-test", false, workspaceStoppedTime)
493+
result := reconciler.wasStoppedSinceLastBackup(dw, &lastBackupTime, log)
494+
Expect(result).To(BeTrue())
495+
})
496+
497+
It("returns false if DevWorkspace was stopped before last backup", func() {
498+
lastBackupTime := metav1.NewTime(time.Now().Add(-5 * time.Minute))
499+
workspaceStoppedTime := metav1.NewTime(time.Now().Add(-10 * time.Minute))
500+
dw := createDevWorkspace("dw-test", "ns-test", false, workspaceStoppedTime)
501+
result := reconciler.wasStoppedSinceLastBackup(dw, &lastBackupTime, log)
502+
Expect(result).To(BeFalse())
503+
})
504+
It("returns true if there is no last backup time", func() {
505+
dw := createDevWorkspace("dw-test", "ns-test", false, metav1.NewTime(time.Now().Add(-10*time.Minute)))
506+
result := reconciler.wasStoppedSinceLastBackup(dw, nil, log)
507+
Expect(result).To(BeTrue())
508+
})
509+
It("returns false if DevWorkspace is running", func() {
510+
lastBackupTime := metav1.NewTime(time.Now().Add(-30 * time.Minute))
511+
workspaceStoppedTime := metav1.NewTime(time.Now().Add(-20 * time.Minute))
512+
dw := createDevWorkspace("dw-test", "ns-test", true, workspaceStoppedTime)
513+
result := reconciler.wasStoppedSinceLastBackup(dw, &lastBackupTime, log)
514+
Expect(result).To(BeFalse())
515+
})
516+
})
360517

361518
})
362519

@@ -385,6 +542,7 @@ func createDevWorkspace(name, namespace string, started bool, lastTransitionTime
385542
}
386543
if !started {
387544
condition.Status = corev1.ConditionFalse
545+
dw.Status.Phase = dwv2.DevWorkspaceStatusStopped
388546
}
389547
dw.Status.Conditions = append(dw.Status.Conditions, condition)
390548
}

0 commit comments

Comments
 (0)