@@ -46,15 +46,15 @@ func newTestSyncCtx(getResourceFunc *func(ctx context.Context, config *rest.Conf
46
46
& metav1.APIResourceList {
47
47
GroupVersion : "v1" ,
48
48
APIResources : []metav1.APIResource {
49
- {Kind : "Pod" , Group : "" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
50
- {Kind : "Service" , Group : "" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
51
- {Kind : "Namespace" , Group : "" , Version : "v1" , Namespaced : false , Verbs : standardVerbs },
49
+ {Name : "pods" , Kind : "Pod" , Group : "" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
50
+ {Name : "services" , Kind : "Service" , Group : "" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
51
+ {Name : "namespaces" , Kind : "Namespace" , Group : "" , Version : "v1" , Namespaced : false , Verbs : standardVerbs },
52
52
},
53
53
},
54
54
& metav1.APIResourceList {
55
55
GroupVersion : "apps/v1" ,
56
56
APIResources : []metav1.APIResource {
57
- {Kind : "Deployment" , Group : "apps" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
57
+ {Name : "deployments" , Kind : "Deployment" , Group : "apps" , Version : "v1" , Namespaced : true , Verbs : standardVerbs },
58
58
},
59
59
})
60
60
sc := syncContext {
@@ -854,6 +854,39 @@ func withReplaceAndServerSideApplyAnnotations(un *unstructured.Unstructured) *un
854
854
return un
855
855
}
856
856
857
+ func TestSync_HookWithReplaceAndBeforeHookCreation_AlreadyDeleted (t * testing.T ) {
858
+ // This test a race condition when Delete is called on an already deleted object
859
+ // LiveObj is set, but then the resource is deleted asynchronously in kubernetes
860
+ syncCtx := newTestSyncCtx (nil )
861
+
862
+ target := withReplaceAnnotation (testingutils .NewPod ())
863
+ target .SetNamespace (testingutils .FakeArgoCDNamespace )
864
+ target = testingutils .Annotate (target , synccommon .AnnotationKeyHookDeletePolicy , string (synccommon .HookDeletePolicyBeforeHookCreation ))
865
+ target = testingutils .Annotate (target , synccommon .AnnotationKeyHook , string (synccommon .SyncPhasePreSync ))
866
+ live := target .DeepCopy ()
867
+
868
+ syncCtx .resources = groupResources (ReconciliationResult {
869
+ Live : []* unstructured.Unstructured {live },
870
+ Target : []* unstructured.Unstructured {target },
871
+ })
872
+ syncCtx .hooks = []* unstructured.Unstructured {live }
873
+
874
+ client := fake .NewSimpleDynamicClient (runtime .NewScheme ())
875
+ deleted := false
876
+ client .PrependReactor ("delete" , "pods" , func (_ testcore.Action ) (bool , runtime.Object , error ) {
877
+ deleted = true
878
+ // simulate the race conditions where liveObj was not null, but is now deleted in k8s
879
+ return true , nil , apierrors .NewNotFound (corev1 .Resource ("pods" ), live .GetName ())
880
+ })
881
+ syncCtx .dynamicIf = client
882
+
883
+ syncCtx .Sync ()
884
+
885
+ resourceOps , _ := syncCtx .resourceOps .(* kubetest.MockResourceOps )
886
+ assert .Equal (t , "create" , resourceOps .GetLastResourceCommand (kube .GetResourceKey (target )))
887
+ assert .True (t , deleted )
888
+ }
889
+
857
890
func TestSync_ServerSideApply (t * testing.T ) {
858
891
testCases := []struct {
859
892
name string
0 commit comments