Skip to content

Commit d808fd4

Browse files
authored
test: isolate local database runs and preserve user configuration (#68)
1 parent e81c1d1 commit d808fd4

2 files changed

Lines changed: 91 additions & 30 deletions

File tree

‎test.sh‎

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,64 @@
1-
#!/bin/sh
2-
docker compose -f tests/docker-compose.yml run -it -p 5432:5432 --name postgres_16 postgres_16
3-
DATABASE_URL="postgres://postgres@localhost:5432/sqlx?sslmode=verify-ca&sslrootcert=./tests/certs/ca.crt&sslcert=./tests/certs/client.crt&sslkey=./tests/keys/client.key" cargo test --features any,postgres,macros,all-types,rustls --
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
44

5-
docker compose -f tests/docker-compose.yml run -it -p 1433:1433 --rm --name mssql_2022 mssql_2022
6-
DATABASE_URL='mssql://sa:Password123!@localhost/sqlx' cargo test --features any,mssql,macros,all-types,rustls --
5+
backend=${1:-all}
6+
if [[ $backend == all ]]; then
7+
for backend in postgres mssql mysql sqlite odbc; do
8+
bash ./test.sh "$backend"
9+
done
10+
exit 0
11+
fi
712

8-
docker compose -f tests/docker-compose.yml run -it -p 3306:3306 --name mysql_8 mysql_8
9-
DATABASE_URL='mysql://root:password@localhost/sqlx' cargo test --features any,mysql,macros,all-types,rustls --
13+
features="any,macros,all-types,rustls"
14+
case "$backend" in
15+
sqlite)
16+
sqlite_dir=$(mktemp -d "${TMPDIR:-/tmp}/sqlx-local-sqlite.XXXXXX")
17+
trap 'rm -rf -- "$sqlite_dir"' EXIT
18+
cp tests/sqlite/sqlite.db "$sqlite_dir/sqlite.db"
19+
export DATABASE_URL="sqlite://$sqlite_dir/sqlite.db"
20+
cargo test --locked --no-default-features --features "$features,sqlite,migrate"
21+
exit
22+
;;
23+
postgres) service=postgres_14; port=5432 ;;
24+
mysql) service=mysql_8; port=3306 ;;
25+
mssql) service=mssql_2022; port=1433 ;;
26+
odbc) service=postgres_16_no_ssl; port=5432 ;;
27+
*)
28+
echo "Usage: $0 [all|sqlite|postgres|mysql|mssql|odbc]" >&2
29+
exit 2
30+
;;
31+
esac
1032

11-
DATABASE_URL='sqlite://./tests/sqlite/sqlite.db' cargo test --features any,sqlite,macros,all-types,rustls --
33+
project="sqlx-local-test-$$-$RANDOM"
34+
unset SQLX_POSTGRES_PORT SQLX_MYSQL_PORT SQLX_MSSQL_PORT
35+
cleanup() {
36+
status=$?
37+
docker compose -p "$project" -f tests/docker-compose.yml \
38+
down --volumes --remove-orphans >/dev/null 2>&1 || true
39+
exit "$status"
40+
}
41+
trap cleanup EXIT
1242

43+
# Each invocation owns one disposable container and a random loopback-only port.
44+
docker compose -p "$project" -f tests/docker-compose.yml \
45+
up --wait --wait-timeout 120 "$service"
46+
address=$(docker compose -p "$project" -f tests/docker-compose.yml port "$service" "$port")
47+
host_port=${address##*:}
48+
if [[ ! $host_port =~ ^[0-9]+$ ]]; then
49+
echo "Could not determine the database's published port: $address" >&2
50+
exit 1
51+
fi
1352

14-
# Copy odbc config from tests/odbc.ini to ~/.odbc.ini and run ODBC tests against Postgres
15-
cp tests/odbc.ini ~/.odbc.ini
16-
docker compose -f tests/docker-compose.yml run -p 5432:5432 --name postgres_16_no_ssl -it postgres_16_no_ssl
17-
DATABASE_URL='DSN=SNOWFLAKE' cargo test --no-default-features --features any,odbc,all-types,macros,rustls
53+
case "$backend" in
54+
postgres) DATABASE_URL="postgres://postgres:password@127.0.0.1:$host_port/sqlx" ;;
55+
mysql) DATABASE_URL="mysql://root:password@127.0.0.1:$host_port/sqlx" ;;
56+
mssql) DATABASE_URL="mssql://sa:Password123!@127.0.0.1:$host_port/sqlx" ;;
57+
odbc)
58+
# Use only the container we started; do not overwrite ~/.odbc.ini or use a saved DSN.
59+
DATABASE_URL="Driver={PostgreSQL Unicode};Servername=127.0.0.1;Port=$host_port;Database=sqlx;Uid=postgres;Pwd=password"
60+
;;
61+
esac
62+
export DATABASE_URL
63+
if [[ $backend != odbc ]]; then features+=",migrate"; fi
64+
cargo test --locked --no-default-features --features "$features,$backend"

‎tests/README.md‎

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
1-
2-
3-
### Running Tests
4-
SQLx uses docker to run many compatible database systems for integration testing. You'll need to [install docker](https://docs.docker.com/engine/) to run the full suite. You can validate your docker installation with:
5-
6-
$ docker run hello-world
7-
8-
Start the databases with `docker-compose` before running tests:
9-
10-
$ docker-compose up
11-
12-
Run all tests against all supported databases using:
13-
14-
$ ./x.py
15-
16-
If you see test failures, or want to run a more specific set of tests against a specific database, you can specify both the features to be tests and the DATABASE_URL. e.g.
17-
18-
$ DATABASE_URL=mysql://root:password@127.0.0.1:49183/sqlx cargo test --no-default-features --features macros,offline,any,all-types,mysql,native-tls
1+
# Running tests
2+
3+
Install Rust through rustup and [Docker Compose](https://docs.docker.com/compose/install/).
4+
Run the local test script from any directory:
5+
6+
```sh
7+
./test.sh # all backends, stopping at the first failure
8+
./test.sh sqlite # SQLite only; no Docker needed
9+
./test.sh postgres # PostgreSQL 14
10+
./test.sh mysql # MySQL 8
11+
./test.sh mssql # SQL Server 2022
12+
./test.sh odbc # ODBC against local PostgreSQL 16
13+
```
14+
15+
Each database run starts a disposable container, waits for its test schema, and
16+
publishes a randomly assigned port on loopback. The script uses that container's
17+
connection string and removes it when the test command exits, including failures.
18+
SQLite runs against a temporary copy of its fixture database.
19+
The script does not use an existing `DATABASE_URL`, a saved ODBC DSN, or modify `~/.odbc.ini`.
20+
The ODBC run requires unixODBC and the **PostgreSQL Unicode** driver on the host.
21+
22+
The PostgreSQL client-certificate authentication configuration is tested separately
23+
by the **Postgres with SSL client cert** CI job.
24+
25+
For custom databases, set `DATABASE_URL` explicitly when invoking Cargo. These tests
26+
create and modify database objects: use a disposable test database.
27+
28+
```sh
29+
DATABASE_URL=mysql://root:password@127.0.0.1:3306/sqlx \
30+
cargo test --locked --no-default-features \
31+
--features macros,offline,any,all-types,mysql,native-tls
32+
```

0 commit comments

Comments
 (0)