Skip to content

Commit

Permalink
ci: Add Docker for test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelespinoza committed Apr 24, 2021
1 parent c0524c4 commit b01af18
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .ci/client_base.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM golang:alpine
WORKDIR /src
RUN apk update && apk --no-cache add gcc g++ git make
COPY go.mod /src
RUN go mod download && go mod verify
COPY . /src
8 changes: 8 additions & 0 deletions .ci/mysql/client.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM godfish_test/client_base:latest
LABEL driver=mysql role=client
WORKDIR /src
RUN apk update && apk --no-cache add mysql-client
RUN go build -v ./drivers/mysql/godfish && \
go test -c . && go test -c ./drivers/mysql
COPY .ci/mysql/client.sh /
ENTRYPOINT /client.sh
30 changes: 30 additions & 0 deletions .ci/mysql/client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env sh

set -eu

dbhost="${1:?missing dbhost}"
dbuser='godfish'

echo "building binary"
make mysql
echo "testing godfish"
make test ARGS='-v -count=1'

# Wait for db server to be ready, with some limits.

num_attempts=0

until mysqladmin --host="${dbhost}" --user="${dbuser}" --password="${MYSQL_PASSWORD}" ping; do
num_attempts=$((num_attempts+1))
if [ $num_attempts -gt 10 ]; then
>&2 echo "ERROR: max attempts exceeded"
exit 1
fi

>&2 echo "db is unavailable now, sleeping"
sleep 1
done
>&2 echo "db is up"

echo "testing godfish against live db"
make mysql-test ARGS='-v -count=1'
31 changes: 31 additions & 0 deletions .ci/mysql/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: "3.9"

services:
client:
image: godfish_test/mysql/client:latest
container_name: godfish_ci_mysql_client
depends_on:
- server
entrypoint: /client.sh server
env_file: env
environment:
CGO_ENABLED: 0
# Seems like existing env vars can't be used to create new env vars.
# The schema for a connection string is roughly:
# "$db_user:$db_password@tcp($db_host)/$db_name"
DB_DSN: "godfish:password@tcp(server)/godfish_test"
tty: true
server:
image: godfish_test/mysql/server:latest
container_name: godfish_ci_mysql_server
env_file: env
expose:
- 3306
volumes:
-
type: volume
source: server
target: /var/lib/mysql

volumes:
server:
4 changes: 4 additions & 0 deletions .ci/mysql/env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MYSQL_DATABASE=godfish_test
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=root_password
MYSQL_USER=godfish
3 changes: 3 additions & 0 deletions .ci/mysql/server.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM mariadb:10.4
LABEL driver=mysql role=server
EXPOSE 3306
8 changes: 8 additions & 0 deletions .ci/postgres/client.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM godfish_test/client_base:latest
LABEL driver=postgres role=client
WORKDIR /src
RUN apk --no-cache add postgresql-client
RUN go build -v ./drivers/postgres/godfish && \
go test -c . && go test -c ./drivers/postgres
COPY .ci/postgres/client.sh /
ENTRYPOINT /client.sh
30 changes: 30 additions & 0 deletions .ci/postgres/client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env sh

set -eu

dbhost="${1:?missing dbhost}"
dbname='godfish_test'
dbuser='godfish'

echo "building binary"
make postgres
echo "testing godfish"
make test ARGS='-v -count=1'

# Wait for db server to be ready, with some limits.

num_attempts=0
until PGPASSWORD="${POSTGRES_PASSWORD}" psql -h "${dbhost}" -U "${dbuser}" "${dbname}" -c '\q'; do
num_attempts=$((num_attempts+1))
if [ $num_attempts -gt 10 ]; then
>&2 echo "ERROR: max attempts exceeded"
exit 1
fi

>&2 echo "db is unavailable now, sleeping"
sleep 1
done
>&2 echo "db is up"

echo "testing godfish against live db"
make postgres-test ARGS='-v -count=1'
30 changes: 30 additions & 0 deletions .ci/postgres/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
version: "3.9"

services:
client:
image: godfish_test/postgres/client:latest
container_name: godfish_ci_postgres_client
depends_on:
- server
entrypoint: /client.sh server
env_file:
- env
environment:
CGO_ENABLED: 0
DB_DSN: "postgresql://godfish:password@server:5432/godfish_test?sslmode=disable"
tty: true
server:
image: godfish_test/postgres/server:latest
container_name: godfish_ci_postgres_server
env_file:
- env
expose:
- 5432
volumes:
-
type: volume
source: server
target: /var/lib/postgresql/data

volumes:
server:
3 changes: 3 additions & 0 deletions .ci/postgres/env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POSTGRES_DB=godfish_test
POSTGRES_PASSWORD=password
POSTGRES_USER=godfish
6 changes: 6 additions & 0 deletions .ci/postgres/server.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM postgres:12.6-alpine
LABEL driver=postgres role=server
WORKDIR /var/lib/postgresql
COPY .ci/postgres/server.sh scripts/
RUN scripts/server.sh
EXPOSE 5432
21 changes: 21 additions & 0 deletions .ci/postgres/server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env sh

set -eu

datadir='/var/lib/postgresql/data'
dbname='godfish_test'
dbuser='godfish'

if ! su - postgres -c "pg_ctl init -D ${datadir}"; then
echo "seems like cluster is already initialized at ${datadir}"
fi

if ! su - postgres -c "pg_isready"; then
su - postgres -c "pg_ctl start -D ${datadir} -l logfile"
fi

su - postgres -c "psql -v ON_ERROR_STOP=1" <<-SQL
CREATE USER ${dbuser};
CREATE DATABASE ${dbname} WITH ENCODING utf8 OWNER ${dbuser};
GRANT ALL PRIVILEGES ON DATABASE ${dbname} TO ${dbuser};
SQL
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env*
.git
.scratch
12 changes: 12 additions & 0 deletions .github/workflows/mysql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: mysql
on: [push, pull_request]
jobs:
all:
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@v1
- name: Build environment and run tests
run: make -f Makefile.docker ci-mysql-up
- name: Teardown
run: make -f Makefile.docker ci-mysql-down
12 changes: 12 additions & 0 deletions .github/workflows/postgres.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: postgres
on: [push, pull_request]
jobs:
all:
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@v1
- name: Build environment and run tests
run: make -f Makefile.docker ci-postgres-up
- name: Teardown
run: make -f Makefile.docker ci-postgres-down
10 changes: 0 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ postgres:
./drivers/postgres/godfish
postgres-test:
$(GO) test $(ARGS) ./drivers/postgres
postgres-test-teardown:
dropdb --if-exists $(TEST_DB_NAME)
postgres-test-setup:
createdb -E utf8 $(TEST_DB_NAME)

mysql:
$(GO) build -o $(BIN) -v \
Expand All @@ -39,9 +35,3 @@ mysql:
./drivers/mysql/godfish
mysql-test:
$(GO) test $(ARGS) ./drivers/mysql
mysql-test-teardown:
mysql -u $(DB_USER) -h $(DB_HOST) \
-e "DROP DATABASE IF EXISTS ${TEST_DB_NAME}"
mysql-test-setup:
mysql -u $(DB_USER) -h $(DB_HOST) \
-e "CREATE DATABASE IF NOT EXISTS ${TEST_DB_NAME}"
51 changes: 51 additions & 0 deletions Makefile.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
BASENAME=godfish_test
CI_DIR=./.ci

#
# Build CI environment, run test suite against a live DB.
# NOTE: The client entrypoints require the other Makefile.
#
ci-mysql-up: build-mysql
docker-compose -f $(CI_DIR)/mysql/docker-compose.yml -- up --exit-code-from client
ci-postgres-up: build-postgres
docker-compose -f $(CI_DIR)/postgres/docker-compose.yml -- up --exit-code-from client
ci-mysql-down:
docker-compose -f $(CI_DIR)/mysql/docker-compose.yml -- down --rmi all --volumes
ci-postgres-down:
docker-compose -f $(CI_DIR)/postgres/docker-compose.yml -- down --rmi all --volumes

#
# Build and tag images.
#
# Create a temporary directory, save the name to a variable.
build-base: $(eval BUILD_DIR=$(shell mktemp -d -p /tmp $(BASENAME)_XXXXXX))
build-base:
git clone --depth=1 file://$(PWD) $(BUILD_DIR)
docker image build -f $(CI_DIR)/client_base.Dockerfile -t $(BASENAME)/client_base $(BUILD_DIR)
build-mysql: build-base
docker image build -f $(CI_DIR)/mysql/client.Dockerfile -t $(BASENAME)/mysql/client $(BUILD_DIR)
docker image build -f $(CI_DIR)/mysql/server.Dockerfile -t $(BASENAME)/mysql/server $(BUILD_DIR)
rm -rf $(BUILD_DIR)
build-postgres: build-base
docker image build -f $(CI_DIR)/postgres/client.Dockerfile -t $(BASENAME)/postgres/client $(BUILD_DIR)
docker image build -f $(CI_DIR)/postgres/server.Dockerfile -t $(BASENAME)/postgres/server $(BUILD_DIR)
rm -rf $(BUILD_DIR)

#
# More cleanup stuff.
#
rm-mysql:
docker container rm $(shell docker container ls -aq --filter ancestor=$(BASENAME)/mysql/client)
docker container rm $(shell docker container ls -aq --filter ancestor=$(BASENAME)/mysql/server)
rm-postgres:
docker container rm $(shell docker container ls -aq --filter ancestor=$(BASENAME)/postgres/client)
docker container rm $(shell docker container ls -aq --filter ancestor=$(BASENAME)/postgres/server)

rmi-mysql:
docker image rmi $(shell docker image ls -aq $(BASENAME)/mysql/client)
docker image rmi $(shell docker image ls -aq $(BASENAME)/mysql/server)
rmi-postgres:
docker image rmi $(shell docker image ls -aq $(BASENAME)/postgres/client)
docker image rmi $(shell docker image ls -aq $(BASENAME)/postgres/server)
rmi-base:
docker image rmi $(shell docker image ls -aq $(BASENAME)/client_base)
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

[![Go Reference](https://pkg.go.dev/badge/github.com/rafaelespinoza/godfish.svg)](https://pkg.go.dev/github.com/rafaelespinoza/godfish)

[![mysql](https://github.com/rafaelespinoza/godfish/actions/workflows/mysql.yml/badge.svg)](https://github.com/rafaelespinoza/godfish/actions/workflows/mysql.yml)
[![postgres](https://github.com/rafaelespinoza/godfish/actions/workflows/postgres.yml/badge.svg)](https://github.com/rafaelespinoza/godfish/actions/workflows/postgres.yml)

`godfish` is a relational database migration manager, similar to the very
good [`dogfish`](https://github.com/dwb/dogfish), but written in golang.

Expand Down Expand Up @@ -137,3 +140,19 @@ Comments line lengths should be limited to 80 characters wide. Try not to make
source code lines too long. More lines is fine with the exception of
declarations of exported identifiers; they should be on one line, otherwise the
generated godoc looks weird. There are also tests, those should pass.

## tests

Docker and docker-compose are used to create environments and run the tests
against a live database. Each database has a separate configuration. All of this
lives in `Makefile.docker` and the `.ci/` directory.

```sh
# Build environments and run tests
make -f Makefile.docker ci-mysql-up
make -f Makefile.docker ci-postgres-up

# Teardown
make -f Makefile.docker ci-mysql-down
make -f Makefile.docker ci-postgres-down
```

0 comments on commit b01af18

Please sign in to comment.