Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
20ecf1a
Refactor e2e tests for backup-info command.
woblerr Aug 17, 2025
3592a9e
Refactor e2e tests for report-info command.
woblerr Aug 26, 2025
c1e4d95
Merge branch 'master' into refactor_e2e_tests_p2
woblerr Aug 30, 2025
10135a0
Refactor e2e tests for backup-delete command.
woblerr Sep 1, 2025
98d36cd
Refactor e2e tests with unified architecture and common functions.
woblerr Sep 2, 2025
1c89eae
Remove unused files.
woblerr Sep 2, 2025
0e5b775
Refactor e2e tests for backup-clean command.
woblerr Sep 5, 2025
6a860ae
Add variable and function unification.
woblerr Sep 5, 2025
9cfb4ad
Refactor e2e tests for history-clean command.
woblerr Sep 10, 2025
817792e
Use common function and variable.
woblerr Sep 10, 2025
597ea2f
Refactor e2e tests for history-migrate command.
woblerr Sep 10, 2025
0d47e73
Fix e2e test for history-migrate.
woblerr Sep 10, 2025
a5cfda3
Refactor tests.
woblerr Sep 10, 2025
6b7f3cd
Remove unused code.
woblerr Sep 10, 2025
26ad1e2
Fix style and small bugs.
woblerr Sep 10, 2025
04fae8d
Use common function run_gpbackman.
woblerr Sep 10, 2025
447bf95
Run all e2e tests one by one.
woblerr Sep 11, 2025
a482d08
Add e2e tests execution on push to master.
woblerr Sep 12, 2025
05b426e
Run e2e tests only on pull requests to master.
woblerr Sep 12, 2025
f63cae9
Add docs for e2e tests.
woblerr Sep 12, 2025
6c482fe
Fix CI. Error like: repository does not exist or may require 'docker …
woblerr Sep 12, 2025
598f26e
Fix CI with e2e tests. Update README for e2e tests.
woblerr Sep 12, 2025
b62a5ba
Fix comments and remove trailing whitespaces.
woblerr Sep 13, 2025
90111bf
Fix folders in history-migrate tests.
woblerr Sep 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ jobs:
- name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}

# - name: Run end-to-end tests
# run: |
# make test-e2e
- name: Run end-to-end tests
if: github.event_name == 'pull_request' && github.base_ref == 'master'
run: |
make docker
make test-e2e

- name: Build image and push master tag to ghcr.io and Docker Hub
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
Expand Down
85 changes: 28 additions & 57 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,36 @@ ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
MUSL_CROSS := $(shell brew list| grep musl-cross)
UID := $(shell id -u)
GID := $(shell id -g)
GPDB_CONTAINER_NAME := greenplum
GPDB_USER := gpadmin
# List of all e2e test commands
E2E_COMMANDS := backup-info report-info backup-delete backup-clean history-clean history-migrate

.PHONY: test
test:
@echo "Run tests for $(APP_NAME)"
TZ="Etc/UTC" go test -mod=vendor -timeout=60s -count 1 ./...

.PHONY: test-e2e
test-e2e:
@echo "Run end-to-end tests for $(APP_NAME)"
@make docker
@make test-e2e_backup-clean
@make test-e2e_backup-delete
@make test-e2e_backup-info
@make test-e2e_history-clean
@make test-e2e_history-migrate
@make test-e2e_report-info

.PHONY: test-e2e_backup-info
test-e2e_backup-info:
@echo "Run end-to-end tests for $(APP_NAME) for backup-info command"
$(call down_docker_compose)
$(call run_docker_compose,backup-info)
$(call down_docker_compose)

.PHONY: test-e2e_backup-delete
test-e2e_backup-delete:
@echo "Run end-to-end tests for $(APP_NAME) for backup-delete command"
$(call down_docker_compose)
$(call run_docker_compose,backup-delete)
$(call down_docker_compose)

.PHONY: test-e2e_backup-clean
test-e2e_backup-clean:
@echo "Run end-to-end tests for $(APP_NAME) for backup-clean command"
$(call down_docker_compose)
$(call run_docker_compose,backup-clean)
$(call down_docker_compose)

.PHONY: test-e2e_history-clean
test-e2e_history-clean:
@echo "Run end-to-end tests for $(APP_NAME) for history-clean command"
$(call down_docker_compose)
$(call run_docker_compose,history-clean)
$(call down_docker_compose)
define define_e2e_test
.PHONY: test-e2e_$(1)
test-e2e_$(1):
@echo "Run end-to-end tests for $(APP_NAME) for $(1) command"
$$(call down_docker_compose)
$$(call run_docker_compose)
$$(call run_e2e_tests,$(1))
$$(call down_docker_compose)
endef

.PHONY: test-e2e_history-migrate
test-e2e_history-migrate:
@echo "Run end-to-end tests for $(APP_NAME) for history-migrate command"
$(call down_docker_compose)
$(call run_docker_compose,history-migrate)
$(call down_docker_compose)
# Generate e2e test targets for all commands
$(foreach cmd,$(E2E_COMMANDS),$(eval $(call define_e2e_test,$(cmd))))

.PHONY: test-e2e_report-info
test-e2e_report-info:
@echo "Run end-to-end tests for $(APP_NAME) for report-info command"
$(call down_docker_compose)
$(call run_docker_compose,report-info)
$(call down_docker_compose)
.PHONY: test-e2e
test-e2e:
@for cmd in $(E2E_COMMANDS); do \
echo "Running : $$cmd"; \
$(MAKE) test-e2e_$$cmd || { echo "$$cmd failed."; exit 1; }; \
echo "$$cmd passed"; \
done

.PHONY: test-e2e-down
test-e2e-down:
Expand Down Expand Up @@ -116,16 +88,15 @@ docker-alpine:
@echo "Version $(BRANCH)-$(GIT_REV)"
DOCKER_BUILDKIT=1 docker build --pull -f Dockerfile.alpine --build-arg REPO_BUILD_TAG=$(BRANCH)-$(GIT_REV) -t $(APP_NAME)-alpine .

define e2e_command
@echo "Run end-to-end tests for $(APP_NAME) for ${1} command"
docker run --rm -v $(ROOT_DIR)/e2e_tests/:/home/gpbackman/e2e_tests --name="$(APP_NAME)" "$(APP_NAME)" /home/gpbackman/e2e_tests/run_e2e_${1}.sh
endef

define run_docker_compose
GPBACKMAN_UID=$(UID) GPBACKMAN_GID=$(GID) docker compose -f e2e_tests/docker-compose.yml build --force-rm --parallel ${1}
GPBACKMAN_UID=$(UID) GPBACKMAN_GID=$(GID) docker compose -f e2e_tests/docker-compose.yml run --rm --name ${1} ${1}
docker compose -f e2e_tests/docker-compose.yml up -d
endef

define down_docker_compose
GPBACKMAN_UID=$(UID) GPBACKMAN_GID=$(GID) docker compose -f e2e_tests/docker-compose.yml down -v
docker compose -f e2e_tests/docker-compose.yml down -v
endef

define run_e2e_tests
docker exec "$(GPDB_CONTAINER_NAME)" su - ${GPDB_USER} -c "/home/$(GPDB_USER)/run_tests/run_test.sh $(1)"
endef
11 changes: 6 additions & 5 deletions e2e_tests/.env
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
IMAGE_GPBACKMAN=gpbackman
IMAGE_TAG_MINIO=RELEASE.2023-09-07T02-05-02Z
IMAGE_TAG_MINIO_MC=RELEASE.2023-09-07T22-48-55Z
# Don't upgade s3 plugin version until https://github.com/greenplum-db/gpbackup-s3-plugin/issues/61
# will be fixed.
S3_PLUGIN_VERSION=1.10.0

IMAGE_TAG_MINIO=RELEASE.2025-04-22T22-12-26Z
IMAGE_TAG_MINIO_MC=RELEASE.2025-04-16T18-13-26Z
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD=minioBackup
MINIO_SITE_REGION=us-west-1
Expand All @@ -12,3 +10,6 @@ S3_MINIO_BUCKET=backup
S3_MINIO_HOSTNAME=myminio
S3_MINIO_KEY=demo
S3_MINIO_KEY_SECRET=demoBackup

IMAGE_TAG_GREENPLUM=6.27.1
GREENPLUM_PASSWORD=gparray
47 changes: 47 additions & 0 deletions e2e_tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# End-to-end tests

The following architecture is used to run the tests:

* Separate containers for MinIO and nginx. Official images [minio/minio](https://hub.docker.com/r/minio/minio), [minio/mc](https://hub.docker.com/r/minio/mc) and [nginx](https://hub.docker.com/_/nginx) are used. It's necessary for S3 compatible storage for WAL archiving and backups.
- Separate container gpbackman-export: runs the gpbackman image and copies the binary to a shared Docker volume (gpbackman_bin) for use inside the Greenplum container.
* Separate container for Greenplum. The [docker-greenplum image](https://github.com/woblerr/docker-greenplum) is used to run a single-node Greenplum cluster.

## Running tests

Buld gpbackman image:
```bash
make docker
```

Run all tests (sequentially for all commands):

```bash
make test-e2e
```

Run tests for a single command:

```bash
make test-e2e_backup-info
make test-e2e_report-info
make test-e2e_backup-delete
make test-e2e_backup-clean
make test-e2e_history-clean
make test-e2e_history-migrate
```

Manually run a specific test (example for `backup-info`):

```bash
docker compose -f e2e_tests/docker-compose.yml up -d

docker exec greenplum bash -c 'su - gpadmin -c "/home/gpadmin/run_tests/run_test.sh backup-info"'

docker compose -f e2e_tests/docker-compose.yml down -v
```

If during manual execution the test fails, you should recreate containers.

## Notes
- Tests are executed as `gpadmin` inside the Greenplum container. The runner waits for the cluster to become ready and then prepares the backup set before executing checks.
- Scripts exit with a non-zero code on failure.
21 changes: 0 additions & 21 deletions e2e_tests/conf/Dockerfile.s3_plugin

This file was deleted.

2 changes: 1 addition & 1 deletion e2e_tests/conf/gpbackup_s3_plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
executablepath: /home/gpbackman/gpbackup_s3_plugin
executablepath: /usr/local/greenplum-db/bin/gpbackup_s3_plugin
options:
region: us-west-1
endpoint: minio:9000
Expand Down
122 changes: 24 additions & 98 deletions e2e_tests/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,123 +37,49 @@ services:
minio:
condition: service_healthy
volumes:
- "./scripts/prepare_minio.sh:/prepare_minio.sh"
- "./src_data:/tmp/src_data"
- "./scripts/prepare/prepare_minio.sh:/prepare_minio.sh"
entrypoint: /prepare_minio.sh
networks:
- e2e

################################################################
# Test backup-info command.
backup-info:
image: ${IMAGE_GPBACKMAN}
container_name: backup-info
hostname: backup-info
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_backup-info.sh:/home/gpbackman/run_backup-info.sh"
command: /home/gpbackman/run_backup-info.sh
networks:
- e2e

################################################################
# Test backup-delete command.
backup-delete:
build:
context: .
dockerfile: ./conf/Dockerfile.s3_plugin
args:
S3_PLUGIN_VERSION: ${S3_PLUGIN_VERSION}
image: backup-delete
container_name: backup-delete
hostname: backup-delete
depends_on:
minio:
condition: service_started
prepare_minio:
condition: service_completed_successfully
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_backup-delete.sh:/home/gpbackman/run_backup-delete.sh"
- "./conf/gpbackup_s3_plugin.yaml:/home/gpbackman/gpbackup_s3_plugin.yaml"
- "./conf/gpbackup_s3_plugin_invalid.yaml:/home/gpbackman/gpbackup_s3_plugin_invalid.yaml"
command: /home/gpbackman/run_backup-delete.sh
networks:
- e2e

################################################################
# Test history-clean command.
history-clean:
image: ${IMAGE_GPBACKMAN}
container_name: history-clean
hostname: history-clean
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_history-clean.sh:/home/gpbackman/run_history-clean.sh"
command: /home/gpbackman/run_history-clean.sh
networks:
- e2e

################################################################
# Test history-migrate command.
history-migrate:
# Export gpbackman binary to shared volume.
gpbackman-export:
image: ${IMAGE_GPBACKMAN}
container_name: history-migrate
hostname: history-migrate
container_name: gpbackman-export
hostname: gpbackman-export
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_history-migrate.sh:/home/gpbackman/run_history-migrate.sh"
command: /home/gpbackman/run_history-migrate.sh
- gpbackman_bin:/export
entrypoint: ["/bin/sh","-c","cp /usr/bin/gpbackman /export/gpbackman && chmod 755 /export/gpbackman && sleep infinity"]
networks:
- e2e

################################################################
# Test report-info command.
report-info:
build:
context: .
dockerfile: ./conf/Dockerfile.s3_plugin
args:
S3_PLUGIN_VERSION: ${S3_PLUGIN_VERSION}
image: report-info
container_name: report-info
hostname: report-info
greenplum:
image: woblerr/greenplum:${IMAGE_TAG_GREENPLUM}
container_name: greenplum
hostname: greenplum
depends_on:
minio:
condition: service_started
condition: service_healthy
prepare_minio:
condition: service_completed_successfully
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_report-info.sh:/home/gpbackman/run_report-info.sh"
- "./conf/gpbackup_s3_plugin.yaml:/home/gpbackman/gpbackup_s3_plugin.yaml"
command: /home/gpbackman/run_report-info.sh
networks:
- e2e

################################################################
# Test backup-clean command.
backup-clean:
build:
context: .
dockerfile: ./conf/Dockerfile.s3_plugin
args:
S3_PLUGIN_VERSION: ${S3_PLUGIN_VERSION}
image: backup-clean
container_name: backup-clean
hostname: backup-clean
depends_on:
minio:
gpbackman-export:
condition: service_started
prepare_minio:
condition: service_completed_successfully
environment:
- "GREENPLUM_PASSWORD"
volumes:
- "./src_data:/home/gpbackman/src_data"
- "./scripts/run_backup-clean.sh:/home/gpbackman/run_backup-clean.sh"
- "./conf/gpbackup_s3_plugin.yaml:/home/gpbackman/gpbackup_s3_plugin.yaml"
command: /home/gpbackman/run_backup-clean.sh
- ./conf/gpbackup_s3_plugin.yaml:/home/gpadmin/gpbackup_s3_plugin.yaml
- ./scripts/prepare/gpdb_init:/docker-entrypoint-initdb.d
- ./scripts/prepare/prepare_gpdb_backups.sh:/home/gpadmin/prepare_gpdb_backups.sh
- ./scripts/run_tests:/home/gpadmin/run_tests
- ./src_data:/home/gpadmin/src_data
- gpbackman_bin:/home/gpadmin/gpbackman
networks:
- e2e

networks:
e2e:

volumes:
gpbackman_bin:
16 changes: 16 additions & 0 deletions e2e_tests/scripts/prepare/gpdb_init/tables_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CREATE SCHEMA IF NOT EXISTS sch1;
CREATE SCHEMA IF NOT EXISTS sch2;

DROP TABLE IF EXISTS sch1.tbl_a;
DROP TABLE IF EXISTS sch1.tbl_b;
DROP TABLE IF EXISTS sch2.tbl_c;
DROP TABLE IF EXISTS sch2.tbl_d;

CREATE TABLE sch1.tbl_a AS SELECT i FROM generate_series(1,100000) AS i;
CREATE TABLE sch1.tbl_b AS SELECT i FROM generate_series(1,100000) AS i;

CREATE TABLE sch2.tbl_c (a int, b int) WITH (appendoptimized = true) DISTRIBUTED BY (a);
INSERT INTO sch2.tbl_c SELECT i, i FROM generate_series(1,100000) i;

CREATE TABLE sch2.tbl_d (a int, b int) WITH (appendoptimized = true, orientation = column) DISTRIBUTED BY (a);
INSERT INTO sch2.tbl_d SELECT i, i FROM generate_series(1,100000) i;
Loading
Loading