@@ -83,6 +83,13 @@ func withDriftDetection(d bool) modifier {
8383 }
8484}
8585
86+ func withDeletionTimestamp () modifier {
87+ return func (r * v1alpha1.ServiceInstance ) {
88+ ts := metav1 .Now ()
89+ r .ObjectMeta .DeletionTimestamp = & ts
90+ }
91+ }
92+
8693func serviceInstance (typ string , m ... modifier ) * v1alpha1.ServiceInstance {
8794 r := & v1alpha1.ServiceInstance {
8895 ObjectMeta : metav1.ObjectMeta {
@@ -379,6 +386,153 @@ func TestObserve(t *testing.T) {
379386 return m
380387 },
381388 },
389+ "DeletionFastPath_Exists" : {
390+ args : args {
391+ mg : serviceInstance ("managed" ,
392+ withExternalName (guid ),
393+ withSpace (spaceGUID ),
394+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
395+ withDeletionTimestamp (), // mark as deleting
396+ ),
397+ },
398+ want : want {
399+ mg : serviceInstance ("managed" ,
400+ withExternalName (guid ),
401+ withSpace (spaceGUID ),
402+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
403+ withDeletionTimestamp (),
404+ ),
405+ obs : managed.ExternalObservation {ResourceExists : true , ResourceUpToDate : true },
406+ err : nil ,
407+ },
408+ service : func () * fake.MockServiceInstance {
409+ m := & fake.MockServiceInstance {}
410+ m .On ("Get" , guid ).Return (
411+ & fake .NewServiceInstance ("managed" ).
412+ SetName (name ).
413+ SetGUID (guid ).
414+ SetServicePlan (servicePlan ).
415+ SetLastOperation (v1alpha1 .LastOperationCreate , v1alpha1 .LastOperationSucceeded ).ServiceInstance ,
416+ nil ,
417+ )
418+ // Single() normally not called if Get by GUID succeeds; keep a safe default.
419+ m .On ("Single" ).Return (fake .ServiceInstanceNil , fake .ErrNoResultReturned )
420+ return m
421+ },
422+ },
423+ "DeletionFastPath_NotFound" : {
424+ args : args {
425+ mg : serviceInstance ("managed" ,
426+ withExternalName (guid ),
427+ withSpace (spaceGUID ),
428+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
429+ withDeletionTimestamp (),
430+ ),
431+ },
432+ want : want {
433+ mg : serviceInstance ("managed" ,
434+ withExternalName (guid ),
435+ withSpace (spaceGUID ),
436+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
437+ withDeletionTimestamp (),
438+ ),
439+ obs : managed.ExternalObservation {ResourceExists : false },
440+ err : nil ,
441+ },
442+ service : func () * fake.MockServiceInstance {
443+ m := & fake.MockServiceInstance {}
444+ m .On ("Get" , guid ).Return (
445+ fake .ServiceInstanceNil ,
446+ fake .ErrNoResultReturned ,
447+ )
448+ m .On ("Single" ).Return (
449+ fake .ServiceInstanceNil ,
450+ fake .ErrNoResultReturned ,
451+ )
452+ return m
453+ },
454+ },
455+ "DeletionFastPath_AdoptExternalName" : {
456+ args : args {
457+ mg : serviceInstance ("managed" ,
458+ withExternalName ("not-guid" ), // force mismatch
459+ withSpace (spaceGUID ),
460+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
461+ withDeletionTimestamp (), // trigger deletion fast-path
462+ ),
463+ },
464+ want : want {
465+ mg : serviceInstance ("managed" ,
466+ withExternalName (guid ), // updated annotation expected
467+ withSpace (spaceGUID ),
468+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
469+ withDeletionTimestamp (),
470+ ),
471+ obs : managed.ExternalObservation {ResourceExists : true , ResourceUpToDate : true },
472+ err : nil ,
473+ },
474+ service : func () * fake.MockServiceInstance {
475+ m := & fake.MockServiceInstance {}
476+ m .On ("Get" , "not-guid" ).Return (
477+ fake .ServiceInstanceNil ,
478+ fake .ErrNoResultReturned , // fall back to Single()
479+ )
480+ m .On ("Single" ).Return (
481+ & fake .NewServiceInstance ("managed" ).
482+ SetName (name ).
483+ SetGUID (guid ).
484+ SetServicePlan (servicePlan ).
485+ SetLastOperation (v1alpha1 .LastOperationCreate , v1alpha1 .LastOperationSucceeded ).
486+ ServiceInstance ,
487+ nil ,
488+ )
489+ return m
490+ },
491+ kube : & test.MockClient {
492+ MockUpdate : test .NewMockUpdateFn (nil ), // successful update
493+ },
494+ },
495+ "DeletionFastPath_AdoptExternalNameUpdateError" : {
496+ args : args {
497+ mg : serviceInstance ("managed" ,
498+ withExternalName ("not-guid" ),
499+ withSpace (spaceGUID ),
500+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
501+ withDeletionTimestamp (),
502+ ),
503+ },
504+ want : want {
505+ mg : serviceInstance ("managed" ,
506+ // meta.SetExternalName already applied in-memory even though Update fails
507+ withExternalName (guid ),
508+ withSpace (spaceGUID ),
509+ withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }),
510+ withDeletionTimestamp (),
511+ ),
512+ obs : managed.ExternalObservation {}, // aborted with error
513+ err : errors .Wrap (errBoom , errUpdateCR ), // wrapped update error
514+ },
515+ service : func () * fake.MockServiceInstance {
516+ m := & fake.MockServiceInstance {}
517+ m .On ("Get" , "not-guid" ).Return (
518+ fake .ServiceInstanceNil ,
519+ fake .ErrNoResultReturned ,
520+ )
521+ m .On ("Single" ).Return (
522+ & fake .NewServiceInstance ("managed" ).
523+ SetName (name ).
524+ SetGUID (guid ).
525+ SetServicePlan (servicePlan ).
526+ SetLastOperation (v1alpha1 .LastOperationCreate , v1alpha1 .LastOperationSucceeded ).
527+ ServiceInstance ,
528+ nil ,
529+ )
530+ return m
531+ },
532+ kube : & test.MockClient {
533+ MockUpdate : test .NewMockUpdateFn (errBoom ), // force failure -> cover error wrap
534+ },
535+ },
382536 "DriftDetectionLoop" : {
383537 args : args {
384538 mg : serviceInstance ("managed" , withExternalName (guid ), withSpace (spaceGUID ), withServicePlan (v1alpha1.ServicePlanParameters {ID : & servicePlan }), withParameters ("{\" foo\" :\" bar\" , \" baz\" : 1}" ), withDriftDetection (true )),
@@ -449,10 +603,15 @@ func TestObserve(t *testing.T) {
449603 for n , tc := range cases {
450604 t .Run (n , func (t * testing.T ) {
451605 t .Logf ("Testing: %s" , t .Name ())
452- c := & external {
453- kube : & test.MockClient {
606+
607+ kubeClient := tc .kube
608+ if kubeClient == nil {
609+ kubeClient = & test.MockClient {
454610 MockUpdate : test .NewMockUpdateFn (nil ),
455- },
611+ }
612+ }
613+ c := & external {
614+ kube : kubeClient ,
456615 serviceinstance : & serviceinstance.Client {
457616 ServiceInstance : tc .service (),
458617 Job : nil ,
0 commit comments