Skip to content

Commit

Permalink
[vax-230] Introduce Satellite E2E tests.
Browse files Browse the repository at this point in the history
Fix: github CI to use actual branch commit instead the merge on
top of main. (actions/checkout#881)

Fix: caching for docker and CI to make it more strict. We no longer
pick local-build image on CI for integration tests

Fix: migration tests that previously were skipped on CI

Fix: postgres manager is handling multiple requests originated from
the schema.

Fix: satellite protocol code would previously crash on start/stop/start
replication flow.
  • Loading branch information
define-null committed Nov 28, 2022
1 parent 67d0248 commit af94598
Show file tree
Hide file tree
Showing 35 changed files with 1,512 additions and 97 deletions.
102 changes: 74 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,59 +16,88 @@ jobs:
name: Get all the necessary dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: ls -lah
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "24.3"
elixir-version: "1.13"
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.KEY_TO_ACCESS_SATELLITE_JS_PROTO }}

- name: Try to reuse cached deps
id: cache-deps
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mixdeps-${{ hashFiles('**/mix.lock') }}

- run: make deps pretest_compile
- uses: actions/cache@v3

- name: Cache compiled code
id: cache-build
uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix
path: _build
key: ${{ runner.os }}-mixbuild-${{ env.GITHUB_SHA_SHORT }}

tests:
name: elixir tests and dialyzer
runs-on: ubuntu-latest
needs: deps
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "24.3"
elixir-version: "1.13"
- name: Prepare auxillary services
run: make start_dev_env
- uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix

- name: Try to reuse cached deps
id: cache-deps
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mixdeps-${{ hashFiles('**/mix.lock') }}

- name: Cache compiled code
id: cache-build
uses: actions/cache@v3
with:
path: _build
key: ${{ runner.os }}-mixbuild-${{ env.GITHUB_SHA_SHORT }}

- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.KEY_TO_ACCESS_SATELLITE_JS_PROTO }}

- run: make pretest_compile

- run: mix coveralls.lcov
env:
MIX_ENV: test

- name: Report code coverage
uses: zgosalvez/github-actions-report-lcov@v1
with:
coverage-files: cover/lcov.info
artifact-name: code-coverage-report
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Dialyzer
run: make dialyzer

- run: make check-format

e2e_tests:
Expand All @@ -78,7 +107,10 @@ jobs:
env:
VAXINE_IMAGE: europe-docker.pkg.dev/vaxine/vaxine-io/vaxine:latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4
- name: Log in to the Container registry
Expand All @@ -87,19 +119,30 @@ jobs:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix
- uses: erlef/setup-beam@v1
with:
otp-version: "24.3"
elixir-version: "1.13"

- name: Try to reuse cached deps
id: cache-deps
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mixdeps-${{ hashFiles('**/mix.lock') }}

- name: Cache compiled code
id: cache-build
uses: actions/cache@v3
with:
path: _build
key: ${{ runner.os }}-mixbuild-${{ env.GITHUB_SHA_SHORT }}

- run: make docker-build-ci
env:
ELECTRIC_IMAGE_NAME: ghcr.io/${{ github.repository }}/electric
ELECTRIC_IMAGE_TAG: ${{ env.GITHUB_HEAD_REF_SLUG || 'main' }}

ELECTRIC_IMAGE_TAG: ${{ env.GITHUB_SHA_SHORT || 'main' }}
- run: make pretest_compile
- run: make lux
working-directory: integration_tests

Expand All @@ -112,6 +155,9 @@ jobs:
- run: make test
id: tests
working-directory: integration_tests
env:
ELECTRIC_IMAGE_NAME: ghcr.io/${{ github.repository }}/electric
ELECTRIC_IMAGE_TAG: ${{ env.GITHUB_SHA_SHORT || 'main' }}

- name: Upload lux logs
uses: actions/upload-artifact@v3
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ COPY Makefile /app/
RUN make build_tools

COPY mix.* /app/
COPY deps /app/deps/
RUN ls -lah
RUN ls -lah deps
RUN make deps
COPY config /app/config/
COPY lib /app/lib/
Expand Down
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ docker-build:
docker build -t electric:local-build .

docker-build-ci:
docker pull ${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG} || true
docker pull ${ELECTRIC_IMAGE_NAME}:latest || true
docker build --cache-from ${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG} \
--cache-from ${ELECTRIC_IMAGE_NAME}:latest \
-t ${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG} \
docker build -t ${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG} \
-t electric:local-build .
docker push ${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG}

Expand Down
15 changes: 12 additions & 3 deletions integration_tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@ include common.mk

LUX_DIRS= \
single_dc \
multi_dc
multi_dc \
migrations

test: lux build pull
deps: lux
make -C satellite_client build

test: deps build pull
${LUX} ${LUX_DIRS}

build:
$(foreach dir, $(LUX_DIRS),make -C ${dir} build;)

pull:
docker-compose -f services_templates.yaml pull sysbench postgresql vaxine
docker-compose -f services_templates.yaml pull \
vaxine \
sysbench \
elixir_client \
postgresql \
satellite_client

clean:
$(foreach dir, $(LUX_DIRS),make -C ${dir} clean;)
Expand Down
38 changes: 29 additions & 9 deletions integration_tests/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ else
export SYSBENCH_IMAGE?=${DOCKER_REGISTRY}/sysbench:latest
endif

ifeq (${ELECTRIC_IMAGE_NAME}${ELECTRIC_IMAGE_TAG},)
export ELECTRIC_IMAGE=electric:local-build
else
export ELECTRIC_IMAGE=${ELECTRIC_IMAGE_NAME}:${ELECTRIC_IMAGE_TAG}
endif

lux: ${LUX}

${LUX}:
Expand All @@ -40,18 +46,20 @@ SYSBENCH_COMMIT:=df89d34c410a2277e19f77e47e535d0890b2029b
start_dev_env:
docker-compose -f ${DOCKER_COMPOSE_FILE} up -d pg_1 pg_2 pg_3

ifndef LUX_EXTRA_LOGS
export VAXINE_VOLUME=.
ifdef LUX_EXTRA_LOGS
export VAXINE_VOLUME=${LUX_EXTRA_LOGS}
export SATELLITE_DB_PATH=${LUX_EXTRA_LOGS}
else
export VAXINE_VOLUME:=${LUX_EXTRA_LOGS}
export SATELLITE_DB_PATH=.
export VAXINE_VOLUME=.
endif

start_vaxine_%:
mkdir -p ${VAXINE_VOLUME}/vaxine_$*
docker-compose -f ${DOCKER_COMPOSE_FILE} up --no-color --no-log-prefix vaxine_$*
docker-compose --verbose -f ${DOCKER_COMPOSE_FILE} up --no-color --no-log-prefix vaxine_$*

start_electric_%:
docker-compose -f ${DOCKER_COMPOSE_FILE} up --no-color --no-log-prefix electric_$*
docker-compose --verbose -f ${DOCKER_COMPOSE_FILE} up --no-color --no-log-prefix electric_$*

stop_dev_env:
docker-compose -f ${DOCKER_COMPOSE_FILE} down
Expand All @@ -66,7 +74,13 @@ start_elixir_test:
docker-compose -f ${DOCKER_COMPOSE_FILE} run \
--rm --entrypoint=/bin/bash \
--workdir=${PROJECT_ROOT} \
test_client
elixir_client_1

start_satellite_client_%:
docker-compose -f ${DOCKER_COMPOSE_FILE} run \
--rm --entrypoint=/bin/bash \
--workdir=${PROJECT_ROOT}/integration_tests/satellite_client \
satellite_client_$*

VAXINE_BRANCH?=main
vaxine:
Expand All @@ -93,11 +107,17 @@ docker-psql-%:
docker-attach-%:
docker-compose -f ${DOCKER_COMPOSE_FILE} exec $* bash

echo:
echo ${UID}:${GID}
DOCKER_WORKDIR?=${PROJECT_ROOT}

docker-start-clean-%:
docker-compose -f ${DOCKER_COMPOSE_FILE} run --rm --entrypoint=/bin/sh $*
docker-compose -f ${DOCKER_COMPOSE_FILE} run --rm --entrypoint=/bin/sh \
--workdir=${DOCKER_WORKDIR} \
$*

docker-make:
docker-compose -f ${DOCKER_COMPOSE_FILE} run --rm \
--workdir=${DOCKER_WORKDIR} ${MK_DOCKER} \
make ${MK_TARGET}

single_test:
${LUX} ${TEST}
5 changes: 5 additions & 0 deletions integration_tests/migrations/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
# @version 0.1
include ../common.mk

export MIGRATION_DIRS=${PROJECT_ROOT}/integration_tests/migrations/migrations

ELECTRIC_SQL_TAG=v0.0.1-initial
ELECTRIC_SQL_CLI_URL=https://github.com/electric-sql/cli/releases/download/${ELECTRIC_SQL_TAG}/electricsql_cli_${ELECTRIC_SQL_TAG}_linux

DOCKER_COMPOSE_FILE=compose.yaml

test:
Expand Down
24 changes: 16 additions & 8 deletions integration_tests/migrations/bidirectional.lux
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,54 @@
!curl http://localhost:5050/api/migrations/postgres_2
?{"applied_at":"[0-9-T:\.Z]{0,50}","hash":"initial","origin":"postgres_2","vsn":"1"}

[shell electric_migrate]
!curl -v -X PUT http://localhost:5050/api/migrations/postgres_1 \
-H 'Content-Type: application/json' -d '{"vsn":"1669232573_init"}'
?HTTP/1.1 200 OK
!curl -v -X PUT http://localhost:5050/api/migrations/postgres_2 \
-H 'Content-Type: application/json' -d '{"vsn":"1669232573_init"}'
?HTTP/1.1 200 OK

[shell pg_1]
[invoke log "Insert data into postgres_1"]
!INSERT INTO entries (id, content) VALUES ('${pg_id}', 'hello from pg_1');
!INSERT INTO public.items (id, content) VALUES ('${pg_id}', 'hello from pg_1');
?$psql

[shell pg_2]
[invoke log "Validate that postgresql_2 have received an update"]
[invoke wait-for "SELECT * FROM entries;" "hello from pg_1" 10 ${psql}]
[invoke wait-for "SELECT * FROM public.items;" "hello from pg_1" 10 ${psql}]


[shell electric_migrate]
[invoke log "Migrate postgres_1 instance 1 -> 2"]
!curl -v -X PUT http://localhost:5050/api/migrations/postgres_1 \
-H 'Content-Type: application/json' -d '{"vsn":"2"}'
-H 'Content-Type: application/json' -d '{"vsn":"1669232634_add_column"}'
?HTTP/1.1 200 OK

[shell pg_1]
[invoke log "Insert data that postgres_2 is not able to store"]
!UPDATE entries \
!UPDATE public.items \
SET content = 'hej pg_1 new data', \
added_column = 'new data added' \
WHERE id = '${pg_id}';
?$psql

[shell pg_2]
[invoke log "Validate that postgresql_2 have received an update"]
[invoke wait-for "SELECT * FROM entries;" "hej pg_1 new data" 10 ${psql}]
[invoke wait-for "SELECT * FROM public.items;" "hej pg_1 new data" 10 ${psql}]

[invoke log "Store data in old schema on postgresql_2"]
!UPDATE entries \
!UPDATE public.items \
SET content = 'hej pg_2 old data' \
WHERE id = '${pg_id}';
?$psql

[shell electric]
[shell electric_1]
?"content" => "hej pg_2 old data"

[shell pg_1]
[invoke log "Read data update"]
[invoke wait-for "SELECT * FROM entries;" "hej pg_2 old data" 10 ${psql}]
[invoke wait-for "SELECT * FROM public.items;" "hej pg_2 old data" 10 ${psql}]

[cleanup]
[invoke teardown]
Loading

0 comments on commit af94598

Please sign in to comment.