From 0537b3d76525c8cd004d3d8c48d677ef3afd2d4d Mon Sep 17 00:00:00 2001 From: Hasan Turken Date: Wed, 26 Oct 2022 14:31:45 +0300 Subject: [PATCH] Add support for pre/post delete hooks Signed-off-by: Hasan Turken --- README.md | 6 +++++- internal/config/config.go | 4 ++++ internal/templates/01-delete.yaml.tmpl | 6 ++++++ internal/templates/renderer_test.go | 22 +++++++++++++--------- internal/tester.go | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5f064e9..d01d9e7 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ uptest e2e examples/user.yaml,examples/bucket.yaml --setup-script="test/hooks/se ### Hooks -There are 4 types of hooks that can be used to customize the test flow: +There are 6 types of hooks that can be used to customize the test flow: 1. `setup-script`: This hook will be executed before running the tests case. It is useful to set up the control plane before running the tests. For example, you can use it to create a provider config and your cloud credentials. This @@ -54,6 +54,10 @@ There are 4 types of hooks that can be used to customize the test flow: manifest file. 4. `post-assert-hook`: This hook will be executed after running the assertions. This can be configured via `uptest.upbound.io/post-assert-hook` annotation on the manifest as a relative path to the manifest file. +5. `pre-delete-hook`: This hook will be executed just before deleting the resource. This can be configured via + `uptest.upbound.io/pre-delete-hook` annotation on the manifest as a relative path to the manifest file. +6. `post-delete-hook`: This hook will be executed right after the resource is deleted. This can be configured via + `uptest.upbound.io/post-delete-hook` annotation on the manifest as a relative path to the manifest file. > All hooks need to be executables, please make sure to set the executable bit on your scripts, e.g. with `chmod +x`. diff --git a/internal/config/config.go b/internal/config/config.go index 1b8ce28..137b230 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,6 +7,8 @@ const ( AnnotationKeyConditions = "uptest.upbound.io/conditions" AnnotationKeyPreAssertHook = "uptest.upbound.io/pre-assert-hook" AnnotationKeyPostAssertHook = "uptest.upbound.io/post-assert-hook" + AnnotationKeyPreDeleteHook = "uptest.upbound.io/pre-delete-hook" + AnnotationKeyPostDeleteHook = "uptest.upbound.io/post-delete-hook" ) type AutomatedTest struct { @@ -44,4 +46,6 @@ type Resource struct { Conditions []string PreAssertScriptPath string PostAssertScriptPath string + PreDeleteScriptPath string + PostDeleteScriptPath string } diff --git a/internal/templates/01-delete.yaml.tmpl b/internal/templates/01-delete.yaml.tmpl index 7f25bf0..cf67e1c 100644 --- a/internal/templates/01-delete.yaml.tmpl +++ b/internal/templates/01-delete.yaml.tmpl @@ -2,9 +2,15 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: {{- range $resource := .Resources }} +{{- if $resource.PreDeleteScriptPath }} +- command: {{ $resource.PreDeleteScriptPath }} +{{- end }} {{- if $resource.Namespace }} - command: ${KUBECTL} delete {{ $resource.KindGroup }}/{{ $resource.Name }} --wait=false --namespace {{ $resource.Namespace }} --ignore-not-found {{- else }} - command: ${KUBECTL} delete {{ $resource.KindGroup }}/{{ $resource.Name }} --wait=false --ignore-not-found {{- end }} +{{- if $resource.PostDeleteScriptPath }} +- command: {{ $resource.PostDeleteScriptPath }} +{{- end }} {{- end }} diff --git a/internal/templates/renderer_test.go b/internal/templates/renderer_test.go index e1b0b68..314b370 100644 --- a/internal/templates/renderer_test.go +++ b/internal/templates/renderer_test.go @@ -5,7 +5,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/test" "github.com/google/go-cmp/cmp" - + "github.com/upbound/uptest/internal/config" ) @@ -71,7 +71,7 @@ commands: "01-delete.yaml": `apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: -- command: ${KUBECTL} delete s3.aws.upbound.io/example-bucket --wait=false +- command: ${KUBECTL} delete s3.aws.upbound.io/example-bucket --wait=false --ignore-not-found `, "01-assert.yaml": `apiVersion: kuttl.dev/v1beta1 kind: TestAssert @@ -92,11 +92,12 @@ commands: }, resources: []config.Resource{ { - YAML: bucketManifest, - Name: "example-bucket", - KindGroup: "s3.aws.upbound.io", - PreAssertScriptPath: "/tmp/bucket/pre-assert.sh", - Conditions: []string{"Test"}, + YAML: bucketManifest, + Name: "example-bucket", + KindGroup: "s3.aws.upbound.io", + PreAssertScriptPath: "/tmp/bucket/pre-assert.sh", + PostDeleteScriptPath: "/tmp/bucket/post-delete.sh", + Conditions: []string{"Test"}, }, { YAML: claimManifest, @@ -104,6 +105,7 @@ commands: KindGroup: "cluster.gcp.platformref.upbound.io", Namespace: "upbound-system", PostAssertScriptPath: "/tmp/claim/post-assert.sh", + PreDeleteScriptPath: "/tmp/claim/pre-delete.sh", Conditions: []string{"Ready", "Synced"}, }, }, @@ -129,8 +131,10 @@ commands: "01-delete.yaml": `apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: -- command: ${KUBECTL} delete s3.aws.upbound.io/example-bucket --wait=false -- command: ${KUBECTL} delete cluster.gcp.platformref.upbound.io/test-cluster-claim --wait=false --namespace upbound-system +- command: ${KUBECTL} delete s3.aws.upbound.io/example-bucket --wait=false --ignore-not-found +- command: /tmp/bucket/post-delete.sh +- command: /tmp/claim/pre-delete.sh +- command: ${KUBECTL} delete cluster.gcp.platformref.upbound.io/test-cluster-claim --wait=false --namespace upbound-system --ignore-not-found `, "01-assert.yaml": `apiVersion: kuttl.dev/v1beta1 kind: TestAssert diff --git a/internal/tester.go b/internal/tester.go index 3a03c5e..ff4e573 100644 --- a/internal/tester.go +++ b/internal/tester.go @@ -101,6 +101,20 @@ func (t *Tester) prepareConfig() (*config.TestCase, []config.Resource, error) { } } + if v, ok := annotations[config.AnnotationKeyPreDeleteHook]; ok { + example.PreDeleteScriptPath, err = filepath.Abs(filepath.Join(filepath.Dir(m.FilePath), filepath.Clean(v))) + if err != nil { + return nil, nil, errors.Wrap(err, "cannot find absolute path for pre delete hook") + } + } + + if v, ok := annotations[config.AnnotationKeyPostDeleteHook]; ok { + example.PostDeleteScriptPath, err = filepath.Abs(filepath.Join(filepath.Dir(m.FilePath), filepath.Clean(v))) + if err != nil { + return nil, nil, errors.Wrap(err, "cannot find absolute path for post delete hook") + } + } + examples = append(examples, example) }