diff --git a/e2e-tests/run-minikube.csv b/e2e-tests/run-minikube.csv index 46cbda5633..76e65b1b42 100644 --- a/e2e-tests/run-minikube.csv +++ b/e2e-tests/run-minikube.csv @@ -1,11 +1,13 @@ custom-extensions demand-backup init-deploy +one-pod operator-self-healing scaling scheduled-backup self-healing start-from-backup telemetry-transfer +upgrade-consistency upgrade-minor users diff --git a/e2e-tests/run-pr.csv b/e2e-tests/run-pr.csv index c39ab41ce7..f296dc48ea 100644 --- a/e2e-tests/run-pr.csv +++ b/e2e-tests/run-pr.csv @@ -2,13 +2,15 @@ custom-extensions demand-backup init-deploy monitoring +one-pod operator-self-healing +pitr scaling scheduled-backup self-healing start-from-backup tablespaces telemetry-transfer +upgrade-consistency upgrade-minor users -pitr \ No newline at end of file diff --git a/e2e-tests/run-release.csv b/e2e-tests/run-release.csv index f6d6cac4f8..b2ad42a583 100644 --- a/e2e-tests/run-release.csv +++ b/e2e-tests/run-release.csv @@ -3,13 +3,15 @@ demand-backup init-deploy migration-backup-s3 monitoring +one-pod operator-self-healing +pitr scaling scheduled-backup self-healing start-from-backup tablespaces telemetry-transfer +upgrade-consistency upgrade-minor users -pitr \ No newline at end of file diff --git a/e2e-tests/tests/one-pod/00-assert.yaml b/e2e-tests/tests/one-pod/00-assert.yaml new file mode 100644 index 0000000000..ae5a062d84 --- /dev/null +++ b/e2e-tests/tests/one-pod/00-assert.yaml @@ -0,0 +1,24 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 120 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: perconapgclusters.pgv2.percona.com +spec: + group: pgv2.percona.com + names: + kind: PerconaPGCluster + listKind: PerconaPGClusterList + plural: perconapgclusters + singular: perconapgcluster + scope: Namespaced +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +metadata: + name: check-operator-deploy-status +timeout: 120 +commands: + - script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1 diff --git a/e2e-tests/tests/one-pod/00-deploy-operator.yaml b/e2e-tests/tests/one-pod/00-deploy-operator.yaml new file mode 100644 index 0000000000..7faf4da852 --- /dev/null +++ b/e2e-tests/tests/one-pod/00-deploy-operator.yaml @@ -0,0 +1,14 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 10 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + init_temp_dir # do this only in the first TestStep + + deploy_operator + deploy_client + deploy_s3_secrets diff --git a/e2e-tests/tests/one-pod/01-assert.yaml b/e2e-tests/tests/one-pod/01-assert.yaml new file mode 100644 index 0000000000..73369dfe4c --- /dev/null +++ b/e2e-tests/tests/one-pod/01-assert.yaml @@ -0,0 +1,108 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 120 +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + labels: + postgres-operator.crunchydata.com/cluster: one-pod + postgres-operator.crunchydata.com/data: postgres + postgres-operator.crunchydata.com/instance-set: instance1 + ownerReferences: + - apiVersion: postgres-operator.crunchydata.com/v1beta1 + kind: PostgresCluster + name: one-pod + controller: true + blockOwnerDeletion: true +status: + observedGeneration: 1 + replicas: 1 + readyReplicas: 1 + currentReplicas: 1 + updatedReplicas: 1 + collisionCount: 0 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: one-pod-pgbouncer + labels: + postgres-operator.crunchydata.com/cluster: one-pod + postgres-operator.crunchydata.com/role: pgbouncer + annotations: + deployment.kubernetes.io/revision: '1' + ownerReferences: + - apiVersion: postgres-operator.crunchydata.com/v1beta1 + kind: PostgresCluster + name: one-pod + controller: true + blockOwnerDeletion: true +status: + observedGeneration: 1 + replicas: 1 + updatedReplicas: 1 + readyReplicas: 1 +--- +kind: Job +apiVersion: batch/v1 +metadata: + labels: + postgres-operator.crunchydata.com/cluster: one-pod + postgres-operator.crunchydata.com/pgbackrest: '' + postgres-operator.crunchydata.com/pgbackrest-backup: replica-create + postgres-operator.crunchydata.com/pgbackrest-repo: repo1 + annotations: + postgres-operator.crunchydata.com/pgbackrest-config: pgbackrest + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGBackup + controller: true + blockOwnerDeletion: true +status: + succeeded: 1 +--- +apiVersion: postgres-operator.crunchydata.com/v1beta1 +kind: PostgresCluster +metadata: + name: one-pod + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGCluster + name: one-pod + controller: true + blockOwnerDeletion: true + finalizers: + - postgres-operator.crunchydata.com/finalizer +status: + instances: + - name: instance1 + readyReplicas: 1 + replicas: 1 + updatedReplicas: 1 + observedGeneration: 1 + pgbackrest: + repos: + - name: repo1 + stanzaCreated: true + proxy: + pgBouncer: + readyReplicas: 1 + replicas: 1 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGCluster +metadata: + name: one-pod +status: + pgbouncer: + ready: 1 + size: 1 + postgres: + instances: + - name: instance1 + ready: 1 + size: 1 + ready: 1 + size: 1 + state: ready diff --git a/e2e-tests/tests/one-pod/01-create-cluster.yaml b/e2e-tests/tests/one-pod/01-create-cluster.yaml new file mode 100644 index 0000000000..b60717231a --- /dev/null +++ b/e2e-tests/tests/one-pod/01-create-cluster.yaml @@ -0,0 +1,15 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 10 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + get_cr \ + | yq eval ' + .spec.proxy.pgBouncer.replicas=1 | + .spec.instances[].replicas=1' - \ + | kubectl -n "${NAMESPACE}" apply -f - diff --git a/e2e-tests/tests/one-pod/02-write-data.yaml b/e2e-tests/tests/one-pod/02-write-data.yaml new file mode 100644 index 0000000000..70b9f424e5 --- /dev/null +++ b/e2e-tests/tests/one-pod/02-write-data.yaml @@ -0,0 +1,16 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + run_psql_local \ + 'CREATE DATABASE myapp; \c myapp \\\ CREATE TABLE IF NOT EXISTS myApp (id int PRIMARY KEY);' \ + "postgres:$(get_psql_user_pass one-pod-pguser-postgres)@$(get_psql_user_host one-pod-pguser-postgres)" + + run_psql_local \ + '\c myapp \\\ INSERT INTO myApp (id) VALUES (100500)' \ + "postgres:$(get_psql_user_pass one-pod-pguser-postgres)@$(get_psql_user_host one-pod-pguser-postgres)" diff --git a/e2e-tests/tests/one-pod/03-assert.yaml b/e2e-tests/tests/one-pod/03-assert.yaml new file mode 100644 index 0000000000..6848a5b79a --- /dev/null +++ b/e2e-tests/tests/one-pod/03-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 30 +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: 03-read-from-primary +data: + data: ' 100500' diff --git a/e2e-tests/tests/one-pod/03-read-from-primary.yaml b/e2e-tests/tests/one-pod/03-read-from-primary.yaml new file mode 100644 index 0000000000..6d0c0a7a2c --- /dev/null +++ b/e2e-tests/tests/one-pod/03-read-from-primary.yaml @@ -0,0 +1,13 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 30 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + data=$(run_psql_local '\c myapp \\\ SELECT * from myApp;' "postgres:$(get_psql_user_pass one-pod-pguser-postgres)@$(get_psql_user_host one-pod-pguser-postgres)") + + kubectl create configmap -n "${NAMESPACE}" 03-read-from-primary --from-literal=data="${data}" diff --git a/e2e-tests/tests/one-pod/04-assert.yaml b/e2e-tests/tests/one-pod/04-assert.yaml new file mode 100644 index 0000000000..c2284872f7 --- /dev/null +++ b/e2e-tests/tests/one-pod/04-assert.yaml @@ -0,0 +1,31 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 560 +--- +kind: Job +apiVersion: batch/v1 +metadata: + annotations: + postgres-operator.crunchydata.com/pgbackrest-backup: one-pod-full + labels: + postgres-operator.crunchydata.com/pgbackrest-backup: manual + postgres-operator.crunchydata.com/pgbackrest-repo: repo1 + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGBackup + controller: true + blockOwnerDeletion: true +status: + succeeded: 1 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGBackup +metadata: + name: one-pod-full +spec: + pgCluster: one-pod + repoName: repo1 + options: + - --type=full +status: + state: Succeeded diff --git a/e2e-tests/tests/one-pod/04-create-backup.yaml b/e2e-tests/tests/one-pod/04-create-backup.yaml new file mode 100644 index 0000000000..c08219927f --- /dev/null +++ b/e2e-tests/tests/one-pod/04-create-backup.yaml @@ -0,0 +1,9 @@ +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGBackup +metadata: + name: one-pod-full +spec: + pgCluster: one-pod + repoName: repo1 + options: + - --type=full diff --git a/e2e-tests/tests/one-pod/05-check-pgbackrest-info.yaml b/e2e-tests/tests/one-pod/05-check-pgbackrest-info.yaml new file mode 100644 index 0000000000..b409a0928d --- /dev/null +++ b/e2e-tests/tests/one-pod/05-check-pgbackrest-info.yaml @@ -0,0 +1,43 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + instance=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/instance-set=instance1 -o 'jsonpath={.items[].metadata.name}') + + pgbackrest_info_backups=$(kubectl exec -n "${NAMESPACE}" "$instance" -c database -- pgbackrest info --output json | jq '.[0].backup.[]') + + check_backup() { + local backup_name=$1 + local pgbackrest_annotation=$2 + local pgbackrest_annotation_value=$3 + + status_backup_name=$(kubectl get -n "${NAMESPACE}" pg-backup "$backup_name" -o jsonpath='{.status.backupName}') + if [[ -z $status_backup_name ]]; then + echo ".status.backupName is empty in $backup_name" + exit 1 + fi + + backup_info=$(echo "$pgbackrest_info_backups" | jq "select(.annotation.\"$pgbackrest_annotation\" == \"$pgbackrest_annotation_value\")") + if [[ $status_backup_name != $(echo "$backup_info" | jq ".label" --raw-output) ]]; then + echo ".status.backupName doesn't equal to label in pgbackrest info" + exit 1 + fi + + backup_job_name=$(kubectl get -n "${NAMESPACE}" pg-backup "$backup_name" -o jsonpath='{.status.jobName}') + backup_job_annotation=$(echo "$backup_info" | jq '.annotation."percona.com/backup-job-name"' --raw-output) + if [[ $backup_job_name != "$backup_job_annotation" ]]; then + echo "Failed to get job name annotation from pgbackrest" + exit 1 + fi + } + + manual_backup_name="one-pod-full" + check_backup "$manual_backup_name" "percona.com/backup-name" "$manual_backup_name" + + replica_backup_name=$(kubectl get -n "${NAMESPACE}" pg-backup -o jsonpath='{.items[?(@.metadata.annotations.pgv2\.percona\.com/pgbackrest-backup-job-type=="replica-create")].metadata.name}') + check_backup "$replica_backup_name" "percona.com/backup-job-type" "replica-create" diff --git a/e2e-tests/tests/one-pod/06-delete-data.yaml b/e2e-tests/tests/one-pod/06-delete-data.yaml new file mode 100644 index 0000000000..64fcec0287 --- /dev/null +++ b/e2e-tests/tests/one-pod/06-delete-data.yaml @@ -0,0 +1,12 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + run_psql_local \ + '\c myapp \\\ TRUNCATE TABLE myApp' \ + "postgres:$(get_psql_user_pass one-pod-pguser-postgres)@$(get_psql_user_host one-pod-pguser-postgres)" diff --git a/e2e-tests/tests/one-pod/07-assert.yaml b/e2e-tests/tests/one-pod/07-assert.yaml new file mode 100644 index 0000000000..01410f5aa0 --- /dev/null +++ b/e2e-tests/tests/one-pod/07-assert.yaml @@ -0,0 +1,49 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 180 +--- +apiVersion: postgres-operator.crunchydata.com/v1beta1 +kind: PostgresCluster +metadata: + name: one-pod + generation: 4 + annotations: + postgres-operator.crunchydata.com/pgbackrest-restore: one-pod-restore + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGCluster + name: one-pod + controller: true + blockOwnerDeletion: true + finalizers: + - postgres-operator.crunchydata.com/finalizer +status: + instances: + - name: instance1 + readyReplicas: 1 + replicas: 1 + updatedReplicas: 1 + observedGeneration: 4 + pgbackrest: + repos: + - name: repo1 + replicaCreateBackupComplete: true + stanzaCreated: true + restore: + finished: true + id: one-pod-restore + succeeded: 1 + proxy: + pgBouncer: + readyReplicas: 1 + replicas: 1 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGRestore +metadata: + name: one-pod-restore +spec: + pgCluster: one-pod + repoName: repo1 +status: + state: Succeeded diff --git a/e2e-tests/tests/one-pod/07-create-restore.yaml b/e2e-tests/tests/one-pod/07-create-restore.yaml new file mode 100644 index 0000000000..241ce566be --- /dev/null +++ b/e2e-tests/tests/one-pod/07-create-restore.yaml @@ -0,0 +1,24 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + primary=$(get_pod_by_role one-pod master name) + latest_full_backup=$(kubectl -n ${NAMESPACE} exec ${primary} -- pgbackrest info --output json | jq '[.[] | .backup[] | select(.type == "full")][-1].label') + + cat <