Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
  • Loading branch information
alexmt committed Dec 16, 2023
1 parent 7a9bb3b commit 0e74e77
Showing 1 changed file with 151 additions and 0 deletions.
151 changes: 151 additions & 0 deletions controller/appcontroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/client-go/rest"

Expand Down Expand Up @@ -64,6 +65,12 @@ type MockKubectl struct {
kube.Kubectl

DeletedResources []kube.ResourceKey
CreatedResources []*unstructured.Unstructured
}

func (m *MockKubectl) CreateResource(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, obj *unstructured.Unstructured, createOptions metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
m.CreatedResources = append(m.CreatedResources, obj)
return m.Kubectl.CreateResource(ctx, config, gvk, name, namespace, obj, createOptions, subresources...)
}

func (m *MockKubectl) DeleteResource(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, deleteOptions metav1.DeleteOptions) error {
Expand Down Expand Up @@ -349,6 +356,38 @@ metadata:
data:
`

var fakePostDeleteHook = `
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "post-delete-hook",
"namespace": "default",
"labels": {
"app.kubernetes.io/instance": "my-app"
},
"annotations": {
"argocd.argoproj.io/hook": "PostDelete",
"argocd.argoproj.io/hook-delete-policy": "HookSucceeded"
}
},
"spec": {
"containers": [
{
"name": "post-delete-hook",
"image": "busybox",
"restartPolicy": "Never",
"command": [
"/bin/sh",
"-c",
"sleep 5 && echo hello from the post-delete-hook pod"
]
}
]
}
}
`

func newFakeApp() *v1alpha1.Application {
return createFakeApp(fakeApp)
}
Expand Down Expand Up @@ -383,6 +422,15 @@ func newFakeCM() map[string]interface{} {
return cm
}

func newFakePostDeleteHook() map[string]interface{} {
var cm map[string]interface{}
err := yaml.Unmarshal([]byte(fakePostDeleteHook), &cm)
if err != nil {
panic(err)
}
return cm
}

func TestAutoSync(t *testing.T) {
app := newFakeApp()
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil)
Expand Down Expand Up @@ -782,6 +830,109 @@ func TestFinalizeAppDeletion(t *testing.T) {

})

t.Run("PostDelete_HookIsCreated", func(t *testing.T) {
app := newFakeApp()
app.SetPostDeleteFinalizer()
app.Spec.Destination.Namespace = test.FakeArgoCDNamespace
ctrl := newFakeController(&fakeData{
manifestResponses: []*apiclient.ManifestResponse{{
Manifests: []string{fakePostDeleteHook},
}},
apps: []runtime.Object{app, &defaultProj},
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}}, nil)

patched := false
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
defaultReactor := fakeAppCs.ReactionChain[0]
fakeAppCs.ReactionChain = nil
fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
return defaultReactor.React(action)
})
fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
patched = true
return true, &v1alpha1.Application{}, nil
})
err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) {
return []*v1alpha1.Cluster{}, nil
})
assert.NoError(t, err)
// finalizer is not deleted
assert.False(t, patched)
// post-delete hook is created
require.Len(t, ctrl.kubectl.(*MockKubectl).CreatedResources, 1)
require.Equal(t, "post-delete-hook", ctrl.kubectl.(*MockKubectl).CreatedResources[0].GetName())
})

t.Run("PostDelete_HookIsExecuted", func(t *testing.T) {
app := newFakeApp()
app.SetPostDeleteFinalizer()
app.Spec.Destination.Namespace = test.FakeArgoCDNamespace
liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()}
require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase"))
ctrl := newFakeController(&fakeData{
manifestResponses: []*apiclient.ManifestResponse{{
Manifests: []string{fakePostDeleteHook},
}},
apps: []runtime.Object{app, &defaultProj},
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
kube.GetResourceKey(liveHook): liveHook,
}}, nil)

patched := false
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
defaultReactor := fakeAppCs.ReactionChain[0]
fakeAppCs.ReactionChain = nil
fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
return defaultReactor.React(action)
})
fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
patched = true
return true, &v1alpha1.Application{}, nil
})
err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) {
return []*v1alpha1.Cluster{}, nil
})
assert.NoError(t, err)
// finalizer is removed
assert.True(t, patched)
})

t.Run("PostDelete_HookIsDeleted", func(t *testing.T) {
app := newFakeApp()
app.SetPostDeleteFinalizer("cleanup")
app.Spec.Destination.Namespace = test.FakeArgoCDNamespace
liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()}
require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase"))
ctrl := newFakeController(&fakeData{
manifestResponses: []*apiclient.ManifestResponse{{
Manifests: []string{fakePostDeleteHook},
}},
apps: []runtime.Object{app, &defaultProj},
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
kube.GetResourceKey(liveHook): liveHook,
}}, nil)

patched := false
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
defaultReactor := fakeAppCs.ReactionChain[0]
fakeAppCs.ReactionChain = nil
fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
return defaultReactor.React(action)
})
fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
patched = true
return true, &v1alpha1.Application{}, nil
})
err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) {
return []*v1alpha1.Cluster{}, nil
})
assert.NoError(t, err)
// post-delete hook is deleted
require.Len(t, ctrl.kubectl.(*MockKubectl).DeletedResources, 1)
require.Equal(t, "post-delete-hook", ctrl.kubectl.(*MockKubectl).DeletedResources[0].Name)
// finalizer is not removed
assert.False(t, patched)
})
}

// TestNormalizeApplication verifies we normalize an application during reconciliation
Expand Down

0 comments on commit 0e74e77

Please sign in to comment.