---
name: Test
on:
workflow_call:
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Format
run: cargo fmt --all -- --check
lint:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Clippy
run: cargo clippy --all-targets --all-features
check:
name: Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Check
run: cargo check
test:
name: Test
strategy:
matrix:
os:
- ubuntu-latest
- macOS-latest
rust:
- stable
runs-on: ${{ matrix.os }}
needs:
- format
- lint
- check
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: test
run: cargo test
integration-test:
name: Integration Tests
runs-on: ubuntu-latest
needs:
- format
- lint
- check
services:
postgres:
image: postgres:18
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
mariadb:
image: mariadb:12
env:
MARIADB_USER: dbpulse
MARIADB_PASSWORD: secret
MARIADB_ROOT_PASSWORD: secret
MARIADB_DATABASE: testdb
ports:
- 3306:3306
options: >-
--health-cmd "mariadb-admin ping -h localhost -u root -psecret"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Install database clients
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client mariadb-client
- name: Wait for databases
run: |
echo "Waiting for PostgreSQL..."
for i in {1..30}; do
if pg_isready -h localhost -p 5432 -U postgres; then
echo "PostgreSQL is ready!"
break
fi
echo "PostgreSQL not ready, waiting... ($i/30)"
sleep 2
done
echo "Waiting for MariaDB..."
for i in {1..30}; do
if mariadb -h 127.0.0.1 -u dbpulse -psecret -D testdb -e "SELECT 1" &>/dev/null; then
echo "MariaDB is ready!"
break
fi
echo "MariaDB not ready, waiting... ($i/30)"
sleep 2
done
- name: Run PostgreSQL integration tests
run: cargo test --test postgres_test -- --ignored --nocapture
env:
RUST_BACKTRACE: 1
- name: Run MariaDB integration tests
run: cargo test --test mariadb_test -- --ignored --nocapture
env:
RUST_BACKTRACE: 1
failover-transition-test:
name: Failover Transition Tests
runs-on: ubuntu-latest
needs:
- format
- lint
- check
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Install database clients
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client mariadb-client
- name: Start failover test databases
run: |
docker rm -f dbpulse-postgres dbpulse-mariadb 2>/dev/null || true
docker run -d --name dbpulse-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=testdb \
-p 5432:5432 postgres:18
docker run -d --name dbpulse-mariadb \
-e MARIADB_USER=dbpulse \
-e MARIADB_PASSWORD=secret \
-e MARIADB_ROOT_PASSWORD=secret \
-e MARIADB_DATABASE=testdb \
-p 3306:3306 mariadb:12
- name: Wait for failover test databases
run: |
echo "Waiting for PostgreSQL..."
for i in {1..30}; do
if docker exec dbpulse-postgres pg_isready -U postgres > /dev/null 2>&1; then
echo "PostgreSQL is ready!"
break
fi
if [ "$i" -eq 30 ]; then
echo "PostgreSQL did not become ready in time"
exit 1
fi
sleep 2
done
echo "Verifying PostgreSQL from host..."
for i in {1..30}; do
if PGPASSWORD=secret psql -h 127.0.0.1 -p 5432 -U postgres -d testdb -c "SELECT 1" > /dev/null 2>&1; then
echo "PostgreSQL host access is ready!"
break
fi
if [ "$i" -eq 30 ]; then
echo "PostgreSQL host access did not become ready in time"
exit 1
fi
sleep 1
done
echo "Waiting for MariaDB..."
for i in {1..30}; do
if docker exec dbpulse-mariadb mariadb -u dbpulse -psecret -D testdb -e "SELECT 1" > /dev/null 2>&1; then
echo "MariaDB is ready!"
break
fi
if [ "$i" -eq 30 ]; then
echo "MariaDB did not become ready in time"
exit 1
fi
sleep 2
done
- name: Run PostgreSQL failover transition test
run: cargo test --test postgres_test test_postgres_pulse_transition_stop_start
-- --ignored --nocapture --test-threads=1
env:
RUN_FAILOVER_TRANSITION_TESTS: '1'
RUST_BACKTRACE: 1
- name: Run MariaDB failover transition test
run: cargo test --test mariadb_test test_mariadb_pulse_transition_stop_start
-- --ignored --nocapture --test-threads=1
env:
RUN_FAILOVER_TRANSITION_TESTS: '1'
RUST_BACKTRACE: 1
- name: Show database logs on failure
if: failure()
run: |
echo "==> PostgreSQL logs:"
docker logs dbpulse-postgres || true
echo ""
echo "==> MariaDB logs:"
docker logs dbpulse-mariadb || true
- name: Cleanup failover test databases
if: always()
run: |
docker stop dbpulse-postgres dbpulse-mariadb || true
docker rm dbpulse-postgres dbpulse-mariadb || true
integration-test-tls:
name: Integration Tests with TLS
runs-on: ubuntu-latest
needs:
- format
- lint
- check
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client mariadb-client openssl
- name: Generate TLS certificates
run: |
./scripts/gen-certs.sh
# Make MariaDB key readable
chmod 644 .certs/mariadb/server.key
- name: Prepare PostgreSQL with TLS
run: |
# Create custom PostgreSQL image with certificates
cat > Dockerfile.postgres-tls <<EOF
FROM postgres:18-alpine
COPY .certs/postgres/server.crt /var/lib/postgresql/server.crt
COPY .certs/postgres/server.key /var/lib/postgresql/server.key
COPY .certs/postgres/ca.crt /var/lib/postgresql/ca.crt
RUN chown postgres:postgres /var/lib/postgresql/server.* /var/lib/postgresql/ca.crt && \
chmod 600 /var/lib/postgresql/server.key && \
chmod 644 /var/lib/postgresql/server.crt /var/lib/postgresql/ca.crt
EOF
docker build -t postgres-tls:test -f Dockerfile.postgres-tls .
- name: Start PostgreSQL with TLS
run: |
docker run -d \
--name postgres-tls \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=testdb \
-p 5432:5432 \
postgres-tls:test \
-c ssl=on \
-c ssl_cert_file=/var/lib/postgresql/server.crt \
-c ssl_key_file=/var/lib/postgresql/server.key \
-c ssl_ca_file=/var/lib/postgresql/ca.crt \
-c ssl_min_protocol_version=TLSv1.2
# Wait for PostgreSQL
for i in {1..30}; do
if docker exec postgres-tls pg_isready -U postgres 2>/dev/null; then
echo "PostgreSQL is ready!"
break
fi
echo "Waiting for PostgreSQL... ($i/30)"
sleep 2
done
- name: Start MariaDB with TLS
run: |
docker run -d \
--name mariadb-tls \
-e MARIADB_USER=dbpulse \
-e MARIADB_PASSWORD=secret \
-e MARIADB_ROOT_PASSWORD=secret \
-e MARIADB_DATABASE=testdb \
-p 3306:3306 \
-v $PWD/.certs/mariadb/server.crt:/etc/mysql/ssl/server.crt:ro \
-v $PWD/.certs/mariadb/server.key:/etc/mysql/ssl/server.key:ro \
-v $PWD/.certs/mariadb/ca.crt:/etc/mysql/ssl/ca.crt:ro \
mariadb:12 \
--ssl-cert=/etc/mysql/ssl/server.crt \
--ssl-key=/etc/mysql/ssl/server.key \
--ssl-ca=/etc/mysql/ssl/ca.crt \
--require-secure-transport=OFF \
--tls-version=TLSv1.2,TLSv1.3
# Wait for MariaDB
for i in {1..30}; do
if docker exec mariadb-tls mariadb -u dbpulse -psecret -D testdb -e "SELECT 1" &>/dev/null; then
echo "MariaDB is ready!"
break
fi
echo "Waiting for MariaDB... ($i/30)"
sleep 2
done
- name: Verify TLS is enabled (PostgreSQL)
run: |
docker exec postgres-tls psql -U postgres -d testdb -c "SHOW ssl;"
PGSSLMODE=require psql "postgresql://postgres:secret@localhost:5432/testdb" \
-c "SELECT ssl, version, cipher FROM pg_stat_ssl WHERE pid = pg_backend_pid();"
- name: Verify TLS is enabled (MariaDB)
run: |
docker exec mariadb-tls mariadb -u root -psecret -e "SHOW VARIABLES LIKE 'have_ssl';"
docker exec mariadb-tls mariadb -h 127.0.0.1 -u dbpulse -psecret -D testdb --ssl \
-e "SHOW STATUS LIKE 'Ssl_cipher';"
- name: Run PostgreSQL TLS tests
run: cargo test --test postgres_tls_test -- --ignored --nocapture
env:
POSTGRES_CA_CERT: ${{ github.workspace }}/.certs/postgres/ca.crt
RUST_BACKTRACE: 1
- name: Run MariaDB TLS tests
run: cargo test --test mariadb_tls_test -- --ignored --nocapture
env:
MARIADB_CA_CERT: ${{ github.workspace }}/.certs/mariadb/ca.crt
RUST_BACKTRACE: 1
- name: Show logs on failure
if: failure()
run: |
echo "==> PostgreSQL logs:"
docker logs postgres-tls || true
echo ""
echo "==> MariaDB logs:"
docker logs mariadb-tls || true
- name: Cleanup
if: always()
run: |-
docker stop postgres-tls mariadb-tls || true
docker rm postgres-tls mariadb-tls || true