Skip to content

Commit ccd52dc

Browse files
test: add NotFound/helm-delete path tests for DataProcess status han… (#6068)
* test: add NotFound/helm-delete path tests for DataProcess status handlers Add unit tests covering the job/CronJob NotFound code path in all three DataProcess status handlers: - TestOnceGetOperationStatusJobNotFound: Job not found triggers helm release deletion and returns unchanged status (no error) - TestOnEventGetOperationStatusJobNotFound: same for OnEventStatusHandler - TestCronGetOperationStatusCronJobNotFound: CronJob not found triggers helm release deletion and returns unchanged status Uses gomonkey.ApplyFunc to patch helm.DeleteReleaseIfExists so the tests do not require the ddc-helm binary (which is not available in unit test environments). This was promised as a follow-up to PR #5969 (review comment by cheyang). Closes #6066 Signed-off-by: Aditya Upasani <adityaupasani29@gmail.com> * test: fix staticcheck SA5011 and strengthen assertions in NotFound tests - Replace t.Error with t.Fatal for nil opStatus checks to prevent nil pointer dereference (SA5011 staticcheck finding that was blocking lint/staticcheck CI) - Add called bool + name/namespace capture to verify helm.DeleteReleaseIfExists is actually invoked with the correct release name and namespace, so a future removal of the delete call would fail the test - Fix CronStatusHandler test: set ctx.Namespace to "default" so it matches the namespace passed to helm.DeleteReleaseIfExists in production code (ctx.Namespace), making the assertion meaningful Addresses cheyang and Gemini review comments on #6068 Signed-off-by: Aditya Upasani <adityaupasani29@gmail.com> --------- Signed-off-by: Aditya Upasani <adityaupasani29@gmail.com>
1 parent bf04633 commit ccd52dc

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

pkg/controllers/v1alpha1/dataprocess/status_handler_test.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/fluid-cloudnative/fluid/pkg/utils"
2828
"github.com/fluid-cloudnative/fluid/pkg/utils/compatibility"
2929
"github.com/fluid-cloudnative/fluid/pkg/utils/fake"
30+
"github.com/fluid-cloudnative/fluid/pkg/utils/helm"
3031
batchv1 "k8s.io/api/batch/v1"
3132
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3233
"k8s.io/apimachinery/pkg/runtime"
@@ -425,3 +426,171 @@ func TestCronGetOperationStatusNotScheduledYet(t *testing.T) {
425426
t.Error("expected non-nil opStatus")
426427
}
427428
}
429+
430+
func TestOnceGetOperationStatusJobNotFound(t *testing.T) {
431+
testScheme := runtime.NewScheme()
432+
_ = v1alpha1.AddToScheme(testScheme)
433+
_ = batchv1.AddToScheme(testScheme)
434+
435+
var helmCalled bool
436+
var helmCalledName, helmCalledNamespace string
437+
helmPatch := gomonkey.ApplyFunc(helm.DeleteReleaseIfExists, func(name, namespace string) error {
438+
helmCalled = true
439+
helmCalledName = name
440+
helmCalledNamespace = namespace
441+
return nil
442+
})
443+
defer helmPatch.Reset()
444+
445+
mockDataProcess := v1alpha1.DataProcess{
446+
ObjectMeta: v1.ObjectMeta{
447+
Name: "test",
448+
Namespace: "default",
449+
},
450+
Spec: v1alpha1.DataProcessSpec{
451+
Policy: v1alpha1.Once,
452+
},
453+
Status: v1alpha1.OperationStatus{
454+
Phase: common.PhasePending,
455+
},
456+
}
457+
458+
client := fake.NewFakeClientWithScheme(testScheme, &mockDataProcess)
459+
handler := &OnceStatusHandler{Client: client, dataProcess: &mockDataProcess}
460+
ctx := cruntime.ReconcileRequestContext{
461+
NamespacedName: types.NamespacedName{Namespace: "default", Name: ""},
462+
Log: fake.NullLogger(),
463+
}
464+
465+
opStatus, err := handler.GetOperationStatus(ctx, &mockDataProcess.Status)
466+
if err != nil {
467+
t.Fatalf("unexpected error on NotFound path: %v", err)
468+
}
469+
if opStatus == nil {
470+
t.Fatal("expected non-nil opStatus")
471+
}
472+
if opStatus.Phase != common.PhasePending {
473+
t.Errorf("expected phase %s, got %s", common.PhasePending, opStatus.Phase)
474+
}
475+
if !helmCalled {
476+
t.Error("expected helm.DeleteReleaseIfExists to be called")
477+
}
478+
expectedReleaseName := utils.GetDataProcessReleaseName(mockDataProcess.GetName())
479+
if helmCalledName != expectedReleaseName || helmCalledNamespace != "default" {
480+
t.Errorf("expected helm.DeleteReleaseIfExists(%s, %s), got (%s, %s)", expectedReleaseName, "default", helmCalledName, helmCalledNamespace)
481+
}
482+
}
483+
484+
func TestOnEventGetOperationStatusJobNotFound(t *testing.T) {
485+
testScheme := runtime.NewScheme()
486+
_ = v1alpha1.AddToScheme(testScheme)
487+
_ = batchv1.AddToScheme(testScheme)
488+
489+
var helmCalled bool
490+
var helmCalledName, helmCalledNamespace string
491+
helmPatch := gomonkey.ApplyFunc(helm.DeleteReleaseIfExists, func(name, namespace string) error {
492+
helmCalled = true
493+
helmCalledName = name
494+
helmCalledNamespace = namespace
495+
return nil
496+
})
497+
defer helmPatch.Reset()
498+
499+
mockDataProcess := v1alpha1.DataProcess{
500+
ObjectMeta: v1.ObjectMeta{
501+
Name: "test",
502+
Namespace: "default",
503+
},
504+
Spec: v1alpha1.DataProcessSpec{
505+
Policy: v1alpha1.OnEvent,
506+
},
507+
Status: v1alpha1.OperationStatus{
508+
Phase: common.PhasePending,
509+
},
510+
}
511+
512+
client := fake.NewFakeClientWithScheme(testScheme, &mockDataProcess)
513+
handler := &OnEventStatusHandler{Client: client, dataProcess: &mockDataProcess}
514+
ctx := cruntime.ReconcileRequestContext{
515+
NamespacedName: types.NamespacedName{Namespace: "default", Name: ""},
516+
Log: fake.NullLogger(),
517+
}
518+
519+
opStatus, err := handler.GetOperationStatus(ctx, &mockDataProcess.Status)
520+
if err != nil {
521+
t.Fatalf("unexpected error on NotFound path: %v", err)
522+
}
523+
if opStatus == nil {
524+
t.Fatal("expected non-nil opStatus")
525+
}
526+
if opStatus.Phase != common.PhasePending {
527+
t.Errorf("expected phase %s, got %s", common.PhasePending, opStatus.Phase)
528+
}
529+
if !helmCalled {
530+
t.Error("expected helm.DeleteReleaseIfExists to be called")
531+
}
532+
expectedReleaseName := utils.GetDataProcessReleaseName(mockDataProcess.GetName())
533+
if helmCalledName != expectedReleaseName || helmCalledNamespace != "default" {
534+
t.Errorf("expected helm.DeleteReleaseIfExists(%s, %s), got (%s, %s)", expectedReleaseName, "default", helmCalledName, helmCalledNamespace)
535+
}
536+
}
537+
538+
func TestCronGetOperationStatusCronJobNotFound(t *testing.T) {
539+
testScheme := runtime.NewScheme()
540+
_ = v1alpha1.AddToScheme(testScheme)
541+
_ = batchv1.AddToScheme(testScheme)
542+
543+
patch := gomonkey.ApplyFunc(compatibility.IsBatchV1CronJobSupported, func() bool {
544+
return true
545+
})
546+
defer patch.Reset()
547+
548+
var helmCalled bool
549+
var helmCalledName, helmCalledNamespace string
550+
helmPatch := gomonkey.ApplyFunc(helm.DeleteReleaseIfExists, func(name, namespace string) error {
551+
helmCalled = true
552+
helmCalledName = name
553+
helmCalledNamespace = namespace
554+
return nil
555+
})
556+
defer helmPatch.Reset()
557+
558+
mockDataProcess := v1alpha1.DataProcess{
559+
ObjectMeta: v1.ObjectMeta{
560+
Name: "test",
561+
Namespace: "default",
562+
},
563+
Spec: v1alpha1.DataProcessSpec{
564+
Policy: v1alpha1.Cron,
565+
Schedule: "* * * * *",
566+
},
567+
Status: v1alpha1.OperationStatus{
568+
Phase: common.PhasePending,
569+
},
570+
}
571+
572+
client := fake.NewFakeClientWithScheme(testScheme, &mockDataProcess)
573+
handler := &CronStatusHandler{Client: client, dataProcess: &mockDataProcess}
574+
ctx := cruntime.ReconcileRequestContext{
575+
NamespacedName: types.NamespacedName{Namespace: "default", Name: ""},
576+
Log: fake.NullLogger(),
577+
}
578+
579+
opStatus, err := handler.GetOperationStatus(ctx, &mockDataProcess.Status)
580+
if err != nil {
581+
t.Fatalf("unexpected error on NotFound path: %v", err)
582+
}
583+
if opStatus == nil {
584+
t.Fatal("expected non-nil opStatus")
585+
}
586+
if opStatus.Phase != common.PhasePending {
587+
t.Errorf("expected phase %s, got %s", common.PhasePending, opStatus.Phase)
588+
}
589+
if !helmCalled {
590+
t.Error("expected helm.DeleteReleaseIfExists to be called")
591+
}
592+
expectedReleaseName := utils.GetDataProcessReleaseName(mockDataProcess.GetName())
593+
if helmCalledName != expectedReleaseName || helmCalledNamespace != "default" {
594+
t.Errorf("expected helm.DeleteReleaseIfExists(%s, %s), got (%s, %s)", expectedReleaseName, "default", helmCalledName, helmCalledNamespace)
595+
}
596+
}

0 commit comments

Comments
 (0)