From 000c280aa512eaca4233517d6eebc59cc5a99bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergen=20Yal=C3=A7=C4=B1n?= Date: Fri, 15 Dec 2023 14:03:50 +0300 Subject: [PATCH 1/4] Add disable options for Update and Import steps Add defer statment to remove all test directory before completing the cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sergen Yalçın --- internal/config/config.go | 5 +++++ internal/runner.go | 9 +++++++++ internal/templates/01-assert.yaml.tmpl | 3 --- internal/templates/01-update.yaml.tmpl | 3 --- internal/templates/renderer.go | 8 ++++++++ internal/tester.go | 6 ++++++ 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 77101b2..3a28234 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -41,6 +41,9 @@ const ( // AnnotationKeyExampleID is id of example that populated from example // manifest. This information will be used for determining the root resource AnnotationKeyExampleID = "meta.upbound.io/example-id" + // AnnotationKeyDisableImport defines that determines whether the Import + // step of the resource to be tested will be executed or not. + AnnotationKeyDisableImport = "uptest.upbound.io/disable-import" ) // AutomatedTest represents an automated test of resource example @@ -72,6 +75,8 @@ type TestCase struct { Timeout int SetupScriptPath string TeardownScriptPath string + SkipUpdate bool + SkipImport bool } // Resource represents a Kubernetes object to be tested and asserted diff --git a/internal/runner.go b/internal/runner.go index 8304fe5..38fe5b5 100644 --- a/internal/runner.go +++ b/internal/runner.go @@ -15,6 +15,9 @@ package internal import ( + "fmt" + "os" + "github.com/crossplane/crossplane-runtime/pkg/errors" "github.com/upbound/uptest/internal/config" @@ -22,6 +25,12 @@ import ( // RunTest runs the specified automated test func RunTest(o *config.AutomatedTest) error { + defer func() { + if err := os.RemoveAll(o.Directory); err != nil { + fmt.Println(fmt.Sprint(err, "cannot clean the test directory")) + } + }() + // Read examples and inject data source values to manifests manifests, err := newPreparer(o.ManifestPaths, withDataSource(o.DataSourcePath), withTestDirectory(o.Directory)).prepareManifests() if err != nil { diff --git a/internal/templates/01-assert.yaml.tmpl b/internal/templates/01-assert.yaml.tmpl index a4dc2c5..c8a83a3 100644 --- a/internal/templates/01-assert.yaml.tmpl +++ b/internal/templates/01-assert.yaml.tmpl @@ -5,9 +5,6 @@ timeout: {{ .TestCase.Timeout }} commands: - script: echo "Dump MR manifests for the update assertion step:"; ${KUBECTL} get managed -o yaml {{- range $resource := .Resources }} -{{- if eq $resource.UpdateParameter "" -}} - {{continue}} -{{- end -}} {{- if eq $resource.KindGroup "secret." -}} {{continue}} {{- end -}} diff --git a/internal/templates/01-update.yaml.tmpl b/internal/templates/01-update.yaml.tmpl index 77a6280..621e97d 100644 --- a/internal/templates/01-update.yaml.tmpl +++ b/internal/templates/01-update.yaml.tmpl @@ -3,9 +3,6 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: {{- range $resource := .Resources }} -{{- if eq $resource.UpdateParameter "" -}} - {{continue}} -{{- end -}} {{- if eq $resource.KindGroup "secret." -}} {{continue}} {{- end -}} diff --git a/internal/templates/renderer.go b/internal/templates/renderer.go index 7333dc4..dc0ac6c 100644 --- a/internal/templates/renderer.go +++ b/internal/templates/renderer.go @@ -49,6 +49,14 @@ func Render(tc *config.TestCase, resources []config.Resource, skipDelete bool) ( res := make(map[string]string, len(fileTemplates)) for name, tmpl := range fileTemplates { + // Skip templates with names starting with "01-" if skipUpdate is true + if tc.SkipUpdate && strings.HasPrefix(name, "01-") { + continue + } + // Skip templates with names starting with "02-" if skipImport is true + if tc.SkipImport && strings.HasPrefix(name, "02-") { + continue + } // Skip templates with names starting with "03-" if skipDelete is true if skipDelete && strings.HasPrefix(name, "03-") { continue diff --git a/internal/tester.go b/internal/tester.go index b8e5c9a..e2af0b8 100644 --- a/internal/tester.go +++ b/internal/tester.go @@ -138,10 +138,16 @@ func (t *tester) prepareConfig() (*config.TestCase, []config.Resource, error) { return nil, nil, errors.Wrapf(err, "cannot unmarshal JSON object: %s", updateParameter) } example.UpdateAssertKey, example.UpdateAssertValue = convertToJSONPath(data, "") + } else { + tc.SkipUpdate = true } if exampleID, ok := annotations[config.AnnotationKeyExampleID]; ok { if exampleID == strings.ToLower(fmt.Sprintf("%s/%s/%s", strings.Split(groupVersionKind.Group, ".")[0], groupVersionKind.Version, groupVersionKind.Kind)) { + disableImport, ok := annotations[config.AnnotationKeyDisableImport] + if ok && disableImport == "true" { + tc.SkipImport = true + } example.Root = true } } From 49ac2469498da83d48ed8ca6221e26c0b8c96740 Mon Sep 17 00:00:00 2001 From: Matt Bush Date: Sun, 31 Dec 2023 17:58:47 -0800 Subject: [PATCH 2/4] Allow annotation to skip same-id import check on a per-resource basis --- internal/config/config.go | 2 + internal/templates/02-assert.yaml.tmpl | 2 +- internal/templates/renderer_test.go | 90 ++++++++++++++++++++++++++ internal/tester.go | 8 ++- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 3a28234..0292ea6 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -98,5 +98,7 @@ type Resource struct { UpdateAssertKey string UpdateAssertValue string + SkipImport bool + Root bool } diff --git a/internal/templates/02-assert.yaml.tmpl b/internal/templates/02-assert.yaml.tmpl index f851203..ac67afe 100644 --- a/internal/templates/02-assert.yaml.tmpl +++ b/internal/templates/02-assert.yaml.tmpl @@ -13,7 +13,7 @@ commands: - command: ${KUBECTL} wait {{ $resource.KindGroup }}/{{ $resource.Name }} --for=condition={{ $condition }} --timeout 10s {{- end }} {{- end }} -{{- if not $resource.Namespace }} +{{- if not (or $resource.Namespace $resource.SkipImport) }} - script: new_id="$(${KUBECTL} get {{ $resource.KindGroup }}/{{ $resource.Name }} -o=jsonpath='{.status.atProvider.id}')" && old_id="$(${KUBECTL} get {{ $resource.KindGroup }}/{{ $resource.Name }} -o=jsonpath='{.metadata.annotations.uptest-old-id}')" && [ "$new_id" = "$old_id" ] {{- end }} {{- end }} diff --git a/internal/templates/renderer_test.go b/internal/templates/renderer_test.go index 6878aeb..81f63b5 100644 --- a/internal/templates/renderer_test.go +++ b/internal/templates/renderer_test.go @@ -343,6 +343,96 @@ commands: - script: ${KUBECTL} annotate s3.aws.upbound.io/example-bucket uptest-old-id=$(${KUBECTL} get s3.aws.upbound.io/example-bucket -o=jsonpath='{.status.atProvider.id}') --overwrite - command: ${KUBECTL} scale deployment crossplane -n upbound-system --replicas=1 - script: ${KUBECTL} -n upbound-system get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n upbound-system scale deploy --replicas=1 +`, + }, + }, + }, + "SkipImport": { + args: args{ + tc: &config.TestCase{ + Timeout: 10, + SetupScriptPath: "/tmp/setup.sh", + TeardownScriptPath: "/tmp/teardown.sh", + }, + resources: []config.Resource{ + { + YAML: bucketManifest, + Name: "example-bucket", + KindGroup: "s3.aws.upbound.io", + PreAssertScriptPath: "/tmp/bucket/pre-assert.sh", + PostDeleteScriptPath: "/tmp/bucket/post-delete.sh", + SkipImport: true, + Conditions: []string{"Test"}, + }, + { + YAML: claimManifest, + Name: "test-cluster-claim", + 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"}, + }, + { + YAML: secretManifest, + Name: "test-secret", + KindGroup: "secret.", + Namespace: "upbound-system", + }, + }, + }, + want: want{ + out: map[string]string{ + "00-apply.yaml": `# This file belongs to the resource apply step. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- command: /tmp/setup.sh +` + "---\n" + bucketManifest + "---\n" + claimManifest + "---\n" + secretManifest, + "00-assert.yaml": `# This assert file belongs to the resource apply step. +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 10 +commands: +- command: ${KUBECTL} annotate managed --all upjet.upbound.io/test=true --overwrite +- script: echo "Dump MR manifests for the apply assertion step:"; ${KUBECTL} get managed -o yaml +- script: echo "Dump Claim manifests for the apply assertion step:" || ${KUBECTL} get claim --all-namespaces -o yaml +- command: /tmp/bucket/pre-assert.sh +- command: ${KUBECTL} wait s3.aws.upbound.io/example-bucket --for=condition=Test --timeout 10s +- command: ${KUBECTL} wait cluster.gcp.platformref.upbound.io/test-cluster-claim --for=condition=Ready --timeout 10s --namespace upbound-system +- command: ${KUBECTL} wait cluster.gcp.platformref.upbound.io/test-cluster-claim --for=condition=Synced --timeout 10s --namespace upbound-system +- command: /tmp/claim/post-assert.sh +`, + "01-update.yaml": `# This file belongs to the resource update step. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +`, + "01-assert.yaml": `# This assert file belongs to the resource update step. +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 10 +commands: +- script: echo "Dump MR manifests for the update assertion step:"; ${KUBECTL} get managed -o yaml +`, + "02-assert.yaml": `# This assert file belongs to the resource import step. +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 10 +commands: +- script: echo "Dump MR manifests for the import assertion step:"; ${KUBECTL} get managed -o yaml +- command: ${KUBECTL} wait s3.aws.upbound.io/example-bucket --for=condition=Test --timeout 10s +`, + "02-import.yaml": `# This file belongs to the resource import step. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- command: ${KUBECTL} scale deployment crossplane -n upbound-system --replicas=0 +- script: ${KUBECTL} -n upbound-system get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n upbound-system scale deploy --replicas=0 +- command: ${KUBECTL} --subresource=status patch s3.aws.upbound.io/example-bucket --type=merge -p '{"status":{"conditions":[]}}' +- script: ${KUBECTL} annotate s3.aws.upbound.io/example-bucket uptest-old-id=$(${KUBECTL} get s3.aws.upbound.io/example-bucket -o=jsonpath='{.status.atProvider.id}') --overwrite +- command: ${KUBECTL} scale deployment crossplane -n upbound-system --replicas=1 +- script: ${KUBECTL} -n upbound-system get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n upbound-system scale deploy --replicas=1 `, }, }, diff --git a/internal/tester.go b/internal/tester.go index e2af0b8..1723176 100644 --- a/internal/tester.go +++ b/internal/tester.go @@ -141,14 +141,18 @@ func (t *tester) prepareConfig() (*config.TestCase, []config.Resource, error) { } else { tc.SkipUpdate = true } + disableImport, ok := annotations[config.AnnotationKeyDisableImport] + if ok && disableImport == "true" { + example.SkipImport = true + } if exampleID, ok := annotations[config.AnnotationKeyExampleID]; ok { if exampleID == strings.ToLower(fmt.Sprintf("%s/%s/%s", strings.Split(groupVersionKind.Group, ".")[0], groupVersionKind.Version, groupVersionKind.Kind)) { - disableImport, ok := annotations[config.AnnotationKeyDisableImport] - if ok && disableImport == "true" { + if disableImport == "true" { tc.SkipImport = true } example.Root = true + } } From 604fedeba6d3bbff8fa296e31c0ce415210add62 Mon Sep 17 00:00:00 2001 From: Matt Bush Date: Tue, 9 Jan 2024 18:41:58 -0800 Subject: [PATCH 3/4] fix typo --- internal/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/config/config.go b/internal/config/config.go index 0b05f5c..5423f65 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -41,7 +41,7 @@ const ( // AnnotationKeyExampleID is id of example that populated from example // manifest. This information will be used for determining the root resource AnnotationKeyExampleID = "meta.upbound.io/example-id" - // AnnotationKeyDisableImport defines that determines whether the Import + // AnnotationKeyDisableImport determines whether the Import // step of the resource to be tested will be executed or not. AnnotationKeyDisableImport = "uptest.upbound.io/disable-import" ) From 3b51371a15adfd8771dc99e86dc1a783bc435496 Mon Sep 17 00:00:00 2001 From: Matt Bush Date: Tue, 9 Jan 2024 18:47:14 -0800 Subject: [PATCH 4/4] update test --- internal/templates/renderer_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/templates/renderer_test.go b/internal/templates/renderer_test.go index 6d18dc4..755e332 100644 --- a/internal/templates/renderer_test.go +++ b/internal/templates/renderer_test.go @@ -427,12 +427,12 @@ commands: apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: -- command: ${KUBECTL} scale deployment crossplane -n upbound-system --replicas=0 -- script: ${KUBECTL} -n upbound-system get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n upbound-system scale deploy --replicas=0 +- command: ${KUBECTL} scale deployment crossplane -n ${CROSSPLANE_NAMESPACE} --replicas=0 +- script: ${KUBECTL} -n ${CROSSPLANE_NAMESPACE} get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n ${CROSSPLANE_NAMESPACE} scale deploy --replicas=0 - command: ${KUBECTL} --subresource=status patch s3.aws.upbound.io/example-bucket --type=merge -p '{"status":{"conditions":[]}}' - script: ${KUBECTL} annotate s3.aws.upbound.io/example-bucket uptest-old-id=$(${KUBECTL} get s3.aws.upbound.io/example-bucket -o=jsonpath='{.status.atProvider.id}') --overwrite -- command: ${KUBECTL} scale deployment crossplane -n upbound-system --replicas=1 -- script: ${KUBECTL} -n upbound-system get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n upbound-system scale deploy --replicas=1 +- command: ${KUBECTL} scale deployment crossplane -n ${CROSSPLANE_NAMESPACE} --replicas=1 +- script: ${KUBECTL} -n ${CROSSPLANE_NAMESPACE} get deploy --no-headers -o custom-columns=":metadata.name" | grep "provider-" | xargs ${KUBECTL} -n ${CROSSPLANE_NAMESPACE} scale deploy --replicas=1 `, }, },