From f2f1c00ea03412d96e8f2a748e1e17fea6571ee0 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 4 May 2020 17:20:16 +0200 Subject: [PATCH] [znapzend] Add more unit tests --- znapzend/templates/job.yaml | 4 +- znapzend/test/configmap_test.go | 130 ++++++++++++++++++++++++++ znapzend/test/job_test.go | 71 ++++++++++++++ znapzend/test/main_test.go | 29 ++++++ znapzend/test/statefulset_test.go | 19 +--- znapzend/test/values/configmap_1.yaml | 4 + znapzend/test/values/configmap_2.yaml | 7 ++ znapzend/test/values/configmap_3.yaml | 12 +++ znapzend/test/values/job_1.yaml | 8 ++ znapzend/test/values/job_2.yaml | 13 +++ 10 files changed, 278 insertions(+), 19 deletions(-) create mode 100644 znapzend/test/configmap_test.go create mode 100644 znapzend/test/job_test.go create mode 100644 znapzend/test/values/configmap_1.yaml create mode 100644 znapzend/test/values/configmap_2.yaml create mode 100644 znapzend/test/values/configmap_3.yaml create mode 100644 znapzend/test/values/job_1.yaml create mode 100644 znapzend/test/values/job_2.yaml diff --git a/znapzend/templates/job.yaml b/znapzend/templates/job.yaml index e9a4e33..3e7a34d 100644 --- a/znapzend/templates/job.yaml +++ b/znapzend/templates/job.yaml @@ -7,7 +7,7 @@ metadata: helm.sh/hook: post-install,post-upgrade spec: backoffLimit: 2 - ttlSecondsAfterFinished: 172800 # After 2 days, nobody cares about the logs of the job anymore. + ttlSecondsAfterFinished: 172800 # 2 days template: spec: serviceAccountName: {{ include "znapzend.serviceAccountName" . }} @@ -43,7 +43,7 @@ spec: mountPath: /etc/znapzend - name: success mountPath: /tmp/znapzend - {{- if .Values.znapzend.reloadPlans -}} + {{- if .Values.znapzend.reloadPlans }} - name: reload-znapzend image: "docker.io/bitnami/kubectl:1.17" imagePullPolicy: {{ .Values.image.pullPolicy }} diff --git a/znapzend/test/configmap_test.go b/znapzend/test/configmap_test.go new file mode 100644 index 0000000..1a4d3b2 --- /dev/null +++ b/znapzend/test/configmap_test.go @@ -0,0 +1,130 @@ +package test + +import ( + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "testing" +) + +var tplConfigMap = []string{"templates/configmap.yaml"} + +func Test_ConfigMap_GivenBackupPlans_WhenCustomField_ThenRenderCustomFile(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/configmap_1.yaml"}, + } + + expectedContent := "mycustomcontent=invalid-znapzend-config" + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplConfigMap) + + var configmap v1.ConfigMap + helm.UnmarshalK8SYaml(t, output, &configmap) + + assert.Equal(t, expectedContent, configmap.Data["plan0"]) + +} + +func Test_ConfigMap_GivenPlanField_WhenMinimalConfig_ThenRenderPlanWithDefaults(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/configmap_2.yaml"}, + SetValues: map[string]string{ + "metrics.enabled": "false", + }, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplConfigMap) + + var configmap v1.ConfigMap + helm.UnmarshalK8SYaml(t, output, &configmap) + + plan := configmap.Data["plan0"] + expectedPlan := `enabled=on +src_plan=1days=>2hours,2weeks=>1days,6months=>1weeks +recursive=off +tsformat=%Y-%m-%d-%H%M%S +mbuffer_size=1G +mbuffer=off +zend_delay=0` + + assert.Equal(t, expectedPlan, plan) +} + +func Test_ConfigMap_GivenPlanField_WhenMetricsEnabled_ThenRenderSourceWithReset(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/configmap_2.yaml"}, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplConfigMap) + + var configmap v1.ConfigMap + helm.UnmarshalK8SYaml(t, output, &configmap) + + plan := configmap.Data["plan0"] + expectedPlan := `enabled=on +src_plan=1days=>2hours,2weeks=>1days,6months=>1weeks +pre_znap_cmd=/usr/bin/curl -sS localhost:8080/presnap/tank/test/dataset +post_znap_cmd=/usr/bin/curl -sS localhost:8080/postsnap/tank/test/dataset?SelfResetAfter=5m +recursive=off +tsformat=%Y-%m-%d-%H%M%S +mbuffer_size=1G +mbuffer=off +zend_delay=0` + + assert.Equal(t, expectedPlan, plan) +} + +func Test_ConfigMap_GivenPlanField_WhenTargetsGiven_ThenRenderTargets(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/configmap_3.yaml"}, + SetValues: map[string]string{ + "metrics.enabled": "false", + }, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplConfigMap) + + var configmap v1.ConfigMap + helm.UnmarshalK8SYaml(t, output, &configmap) + + plan := configmap.Data["plan0"] + expectedPlan := `enabled=on +src_plan=1days=>2hours,2weeks=>1days,6months=>1weeks +dst_0=target.host:backup/target +dst_0_plan=1days=>2hours +recursive=on +tsformat=%Y-%m-%d-%H%M%S +mbuffer_size=1G +mbuffer=off +zend_delay=600` + + assert.Equal(t, expectedPlan, plan) +} + +func Test_ConfigMap_GivenPlanField_WhenTargetsAndMetricsGiven_ThenRenderTargetsWithMetrics(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/configmap_3.yaml"}, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplConfigMap) + + var configmap v1.ConfigMap + helm.UnmarshalK8SYaml(t, output, &configmap) + + plan := configmap.Data["plan0"] + expectedPlan := `enabled=on +src_plan=1days=>2hours,2weeks=>1days,6months=>1weeks +dst_0=target.host:backup/target +dst_0_plan=1days=>2hours +dst_0_precmd=/usr/bin/curl -sS localhost:8080/presend/tank/test/dataset +dst_0_pstcmd=/usr/bin/curl -sS localhost:8080/postsend/tank/test/dataset?SelfResetAfter=1h +pre_znap_cmd=/usr/bin/curl -sS localhost:8080/presnap/tank/test/dataset +post_znap_cmd=/usr/bin/curl -sS localhost:8080/postsnap/tank/test/dataset +recursive=on +tsformat=%Y-%m-%d-%H%M%S +mbuffer_size=1G +mbuffer=off +zend_delay=600` + + assert.Equal(t, expectedPlan, plan) +} diff --git a/znapzend/test/job_test.go b/znapzend/test/job_test.go new file mode 100644 index 0000000..45d705c --- /dev/null +++ b/znapzend/test/job_test.go @@ -0,0 +1,71 @@ +package test + +import ( + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + batchv1 "k8s.io/api/batch/v1" + v1 "k8s.io/api/core/v1" + "testing" +) + +var tplJob = []string{"templates/job.yaml"} + +func Test_Job_GivenBackupPlans_WhenEnabled_ThenRenderEnvironmentVariables(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/job_1.yaml"}, + } + + expectedKeys := []string{"KEY1", "ANOTHER_KEY"} + expectedValues := []string{"value", "another value"} + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplJob) + + var job batchv1.Job + helm.UnmarshalK8SYaml(t, output, &job) + + envs := job.Spec.Template.Spec.Containers[0].Env + for i, _ := range envs { + require.Contains(t, envs, v1.EnvVar{ + Name: expectedKeys[i], + Value: expectedValues[i], + }) + } +} + +func Test_Job_GivenBackupPlans_WhenSshIdentitiesProvided_ThenRenderVolumes(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/job_2.yaml"}, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplJob) + + var job batchv1.Job + helm.UnmarshalK8SYaml(t, output, &job) + + volumeMounts := job.Spec.Template.Spec.Containers[0].VolumeMounts + assertSshVolumeMounts(t, volumeMounts) + + volumes := job.Spec.Template.Spec.Volumes + assertSshVolume(t, volumes) +} + +func Test_Job_GivenBackupPlans_WhenMultiplePlans_ThenRenderCommandArgs(t *testing.T) { + options := &helm.Options{ + ValuesFiles: []string{"values/job_2.yaml"}, + } + + output := helm.RenderTemplate(t, options, helmChartPath, releaseName, tplJob) + + var job batchv1.Job + helm.UnmarshalK8SYaml(t, output, &job) + + args := job.Spec.Template.Spec.Containers[0].Args + expectedArgs := `set -e && +znapzendzetup import --write pool/dataset1 /etc/znapzend/plan0 && +znapzendzetup import --write pool/dataset2 /etc/znapzend/plan1 && +echo "$?" > /tmp/znapzend/success +` + + assert.Equal(t, args[0], expectedArgs) +} diff --git a/znapzend/test/main_test.go b/znapzend/test/main_test.go index 37f207b..736c145 100644 --- a/znapzend/test/main_test.go +++ b/znapzend/test/main_test.go @@ -1,6 +1,35 @@ package test +import ( + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + "testing" +) + var ( helmChartPath = ".." releaseName = "test-release" ) + +func assertSshVolume(t *testing.T, volumes []v1.Volume) { + require.Contains(t, volumes, v1.Volume{ + Name: "ssh", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: releaseName + "-znapzend", + DefaultMode: getIntPointer(0600), + }, + }, + }) +} + +func assertSshVolumeMounts(t *testing.T, volumeMounts []v1.VolumeMount) { + require.Contains(t, volumeMounts, v1.VolumeMount{ + Name: "zfs", + MountPath: "/dev/zfs", + }) + require.Contains(t, volumeMounts, v1.VolumeMount{ + Name: "ssh", + MountPath: "/root/.ssh", + }) +} diff --git a/znapzend/test/statefulset_test.go b/znapzend/test/statefulset_test.go index 9739882..3620200 100644 --- a/znapzend/test/statefulset_test.go +++ b/znapzend/test/statefulset_test.go @@ -45,25 +45,10 @@ func Test_StatefulSet_ShouldRender_SshVolumes_IfEnabled(t *testing.T) { helm.UnmarshalK8SYaml(t, output, &statefulset) volumeMounts := statefulset.Spec.Template.Spec.Containers[0].VolumeMounts - require.Contains(t, volumeMounts, v1.VolumeMount{ - Name: "zfs", - MountPath: "/dev/zfs", - }) - require.Contains(t, volumeMounts, v1.VolumeMount{ - Name: "ssh", - MountPath: "/root/.ssh", - }) + assertSshVolumeMounts(t, volumeMounts) volumes := statefulset.Spec.Template.Spec.Volumes - require.Contains(t, volumes, v1.Volume{ - Name: "ssh", - VolumeSource: v1.VolumeSource{ - Secret: &v1.SecretVolumeSource{ - SecretName: releaseName + "-znapzend", - DefaultMode: getIntPointer(0600), - }, - }, - }) + assertSshVolume(t, volumes) } func getIntPointer(mode int) *int32 { diff --git a/znapzend/test/values/configmap_1.yaml b/znapzend/test/values/configmap_1.yaml new file mode 100644 index 0000000..89c7ade --- /dev/null +++ b/znapzend/test/values/configmap_1.yaml @@ -0,0 +1,4 @@ +znapzend: + backupPlans: + - custom: | + mycustomcontent=invalid-znapzend-config diff --git a/znapzend/test/values/configmap_2.yaml b/znapzend/test/values/configmap_2.yaml new file mode 100644 index 0000000..51f43f5 --- /dev/null +++ b/znapzend/test/values/configmap_2.yaml @@ -0,0 +1,7 @@ +znapzend: + backupPlans: + - dataset: tank/test/dataset + plan: + source: + retention: 1days=>2hours,2weeks=>1days,6months=>1weeks + selfResetAfter: 5m diff --git a/znapzend/test/values/configmap_3.yaml b/znapzend/test/values/configmap_3.yaml new file mode 100644 index 0000000..75c4114 --- /dev/null +++ b/znapzend/test/values/configmap_3.yaml @@ -0,0 +1,12 @@ +znapzend: + backupPlans: + - dataset: tank/test/dataset + plan: + source: + retention: 1days=>2hours,2weeks=>1days,6months=>1weeks + recursive: true + targets: + - host: target.host + retention: 1days=>2hours + dataset: backup/target + delaySeconds: 600 diff --git a/znapzend/test/values/job_1.yaml b/znapzend/test/values/job_1.yaml new file mode 100644 index 0000000..dcd8b0c --- /dev/null +++ b/znapzend/test/values/job_1.yaml @@ -0,0 +1,8 @@ +env: + KEY1: value + ANOTHER_KEY: another value +znapzend: + backupPlans: + - dataset: pool/dataset + custom: | + a plan diff --git a/znapzend/test/values/job_2.yaml b/znapzend/test/values/job_2.yaml new file mode 100644 index 0000000..321e305 --- /dev/null +++ b/znapzend/test/values/job_2.yaml @@ -0,0 +1,13 @@ +ssh: + identities: + id_rsa: | + ----BEGIN---- + ----END---- +znapzend: + backupPlans: + - dataset: pool/dataset1 + custom: | + a plan + - dataset: pool/dataset2 + custom: | + a plan