From 982f865434b11cc0bfe08d4b2361bd003d3e33df Mon Sep 17 00:00:00 2001 From: "Giau. Tran Minh" Date: Wed, 23 Oct 2024 23:51:36 +0700 Subject: [PATCH] test/e2e: added test for `concurrently` and `tx-mode` --- .../testscript/schema-plan-concurrently.txtar | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 test/e2e/testscript/schema-plan-concurrently.txtar diff --git a/test/e2e/testscript/schema-plan-concurrently.txtar b/test/e2e/testscript/schema-plan-concurrently.txtar new file mode 100644 index 0000000..32c3267 --- /dev/null +++ b/test/e2e/testscript/schema-plan-concurrently.txtar @@ -0,0 +1,217 @@ +env DB_URL=postgres://root:pass@postgres.${NAMESPACE}:5432/postgres?sslmode=disable +kubectl apply -f database.yaml +kubectl create secret generic db-creds --from-literal=url=${DB_URL} +# Wait for the DB ready before creating the schema +kubectl-wait-ready -l app=postgres pods + +# Create the secret to store ATLAS_TOKEN +kubectl create secret generic atlas-token --from-literal=ATLAS_TOKEN=${ATLAS_TOKEN} + +# Sync the $WORK directory to the controller pod +kubectl cp -n ${CONTROLLER_NS} ${WORK} ${CONTROLLER}:/tmp/${NAMESPACE}/ +env DEV_URL=postgres://root:pass@postgres.${NAMESPACE}:5433/postgres?sslmode=disable +# List all schema plans and remove them, it may come from previous failure runs +atlas schema plan list --format="{{range .}}{{println .URL}}{{end}}" --dev-url=${DEV_URL} --repo=atlas://atlas-operator --from=file:///tmp/${NAMESPACE}/schema-v1.hcl --to=file:///tmp/${NAMESPACE}/schema-v2.hcl +plans-rm stdout + +# Create the schema +kubectl apply -f schema.yaml +kubectl-wait-ready AtlasSchema/postgres + +# Inspect the schema to ensure it's correct +atlas schema inspect -u ${DB_URL} +cmp stdout schema-v1.hcl + +# Add a new index to the schema +kubectl patch -f schema.yaml --type merge --patch-file patch-index.yaml +kubectl wait --for=jsonpath='{.status.conditions[*].reason}'=ApprovalPending --timeout=120s AtlasSchemas/postgres + +# Get the plan URL from resource +kubectl get AtlasSchemas/postgres -o go-template --template='{{ .status.planURL }}' +envfile PLAN_URL=stdout +# atlas should generates the plan with `CONCURRENTLY` keyword +atlas schema plan pull --url=${PLAN_URL} +stdout 'plan "(\d+)" {' +stdout ' from = "lhl512tzvwQXJ9lroGuRNzGS6fiic8r9ohGMV\+/Ij0w="' +stdout ' to = "zDxiyrS84ByLVsf\+H96pd2XdDxDM7Ie2vSwHwIeo8b4="' +stdout ' migration = <<-SQL' +stdout ' -- Create index "idx" to table: "t1"' +stdout ' CREATE INDEX CONCURRENTLY "idx" ON "public"\."t1" \("c1"\);' +stdout ' SQL' +stdout '}' +# Approve the plan +atlas schema plan approve --url=${PLAN_URL} + +# The migration should be failed +kubectl wait --for=jsonpath='{.status.conditions[*].reason}'=ApplyingSchema --timeout=120s AtlasSchemas/postgres +# Check the error message +kubectl get AtlasSchemas/postgres -o jsonpath --template='{.status.conditions[*].message}' +stdout 'pq: CREATE INDEX CONCURRENTLY cannot run inside a transaction block' +# Change the transaction mode to `none` +kubectl patch -f schema.yaml --type merge --patch-file patch-tx-mode.yaml + +# The schema should be updated now +kubectl-wait-ready AtlasSchemas/postgres +atlas schema inspect -u ${DB_URL} +cmp stdout schema-v2.hcl + +# Cleanup schema plan for the next run +atlas schema plan rm --url=${PLAN_URL} +-- schema-v1.hcl -- +table "t1" { + schema = schema.public + column "id" { + null = false + type = integer + } + column "c1" { + null = true + type = integer + } + primary_key { + columns = [column.id] + } +} +schema "public" { + comment = "standard public schema" +} +-- schema-v2.hcl -- +table "t1" { + schema = schema.public + column "id" { + null = false + type = integer + } + column "c1" { + null = true + type = integer + } + primary_key { + columns = [column.id] + } + index "idx" { + columns = [column.c1] + } +} +schema "public" { + comment = "standard public schema" +} +-- patch-index.yaml -- +spec: + schema: + sql: | + create table t1 ( + id int not null, + c1 int, + primary key (id) + ); + create index idx ON t1 (c1); +-- patch-tx-mode.yaml -- +spec: + txMode: none +-- schema.yaml -- +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + name: postgres +spec: + urlFrom: + secretKeyRef: + name: db-creds + key: url + policy: + diff: + concurrent_index: + create: true + lint: + review: WARNING + cloud: + repo: atlas-operator + tokenFrom: + secretKeyRef: + name: atlas-token + key: ATLAS_TOKEN + schema: + sql: | + create table t1 ( + id int not null, + c1 int, + primary key (id) + ); +-- database.yaml -- +apiVersion: v1 +kind: Service +metadata: + name: postgres +spec: + selector: + app: postgres + ports: + - name: postgres + port: 5432 + targetPort: postgres + - name: postgres-dev + port: 5433 + targetPort: postgres-dev + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres +spec: + selector: + matchLabels: + app: postgres + replicas: 1 + template: + metadata: + labels: + app: postgres + spec: + securityContext: + runAsNonRoot: true + runAsUser: 999 + containers: + - name: postgres + image: postgres:15.4 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + env: + - name: POSTGRES_PASSWORD + value: pass + - name: POSTGRES_USER + value: root + ports: + - containerPort: 5432 + name: postgres + startupProbe: + exec: + command: [ "pg_isready" ] + failureThreshold: 30 + periodSeconds: 10 + - name: postgres-dev + image: postgres:15.4 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + env: + - name: POSTGRES_PASSWORD + value: pass + - name: POSTGRES_USER + value: root + - name: PGPORT + value: "5433" + ports: + - containerPort: 5433 + name: postgres-dev + startupProbe: + exec: + command: [ "pg_isready" ] + failureThreshold: 30 + periodSeconds: 10