Skip to content

Commit 2444ab0

Browse files
committed
feat: drop all connections before dropping db for postgres
1 parent f283835 commit 2444ab0

File tree

13 files changed

+298
-145
lines changed

13 files changed

+298
-145
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
jobs:
1010
tests:
11-
name: PHP ${{ matrix.php }}, SF ${{ matrix.symfony }} - ${{ matrix.deps }} ${{ matrix.use-orm == '1' && '- ORM' || '' }} ${{ matrix.use-odm == '1' && '- ODM' || '' }} ${{ matrix.use-dama == '1' && '- DAMA' || '' }}
11+
name: PHP ${{ matrix.php }}, SF ${{ matrix.symfony }} - ${{ matrix.deps }} ${{ matrix.use-orm == '1' && (matrix.orm-db == 'postgres' && '- ORM (postgres)' || '- ORM (mysql)') || '' }} ${{ matrix.use-odm == '1' && '- ODM' || '' }} ${{ matrix.use-dama == '1' && '- DAMA' || '' }}
1212
runs-on: ubuntu-latest
1313
strategy:
1414
fail-fast: false
@@ -19,20 +19,23 @@ jobs:
1919
use-orm: [1]
2020
use-odm: [1]
2121
use-dama: [1]
22+
orm-db: [ mysql ]
2223
exclude:
2324
- {use-orm: 0, use-odm: 0} # tested directly in a test case
2425
- {use-orm: 0, use-dama: 1} # cannot happen
2526
# conflicts
2627
- {php: 8.0, symfony: 6.2.*}
2728
- {php: 8.0, symfony: 6.3.*}
2829
include:
29-
- {php: 8.0, symfony: 5.4.*, use-orm: 1, use-odm: 0, use-dama: 0, deps: lowest}
30-
- {php: 8.0, symfony: 5.4.*, use-orm: 1, use-odm: 1, use-dama: 0, deps: lowest}
31-
- {php: 8.0, symfony: 5.4.*, use-orm: 0, use-odm: 1, use-dama: 0, deps: lowest}
32-
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 0, deps: highest}
33-
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 1, use-dama: 0, deps: highest}
34-
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 1, deps: highest}
35-
- {php: 8.2, symfony: 6.2.*, use-orm: 0, use-odm: 1, use-dama: 0, deps: highest}
30+
- {php: 8.0, symfony: 5.4.*, use-orm: 1, use-odm: 0, use-dama: 0, deps: lowest, orm-db: mysql}
31+
- {php: 8.0, symfony: 5.4.*, use-orm: 1, use-odm: 1, use-dama: 0, deps: lowest, orm-db: mysql}
32+
- {php: 8.0, symfony: 5.4.*, use-orm: 0, use-odm: 1, use-dama: 0, deps: lowest, orm-db: mysql}
33+
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 0, deps: highest, orm-db: mysql}
34+
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 1, use-dama: 0, deps: highest, orm-db: mysql}
35+
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 1, deps: highest, orm-db: mysql}
36+
- {php: 8.2, symfony: 6.2.*, use-orm: 0, use-odm: 1, use-dama: 0, deps: highest, orm-db: mysql}
37+
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 1, deps: highest, orm-db: postgres}
38+
- {php: 8.2, symfony: 6.2.*, use-orm: 1, use-odm: 0, use-dama: 0, deps: highest, orm-db: postgres}
3639

3740
services:
3841
mysql:
@@ -42,13 +45,25 @@ jobs:
4245
ports:
4346
- 3306:3306
4447
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
48+
49+
postgres:
50+
image: postgres:15
51+
env:
52+
POSTGRES_USER: postgres
53+
POSTGRES_DB: zenstruck_foundry_${{ matrix.use-dama }}_${{ matrix.orm-db }}
54+
POSTGRES_PASSWORD: 1234
55+
options: --health-cmd pg_isready --health-interval=10s --health-timeout=5s --health-retries=5
56+
ports:
57+
- 5432:5432
58+
4559
mongo:
4660
image: mongo:4
4761
ports:
4862
- 27017:27017
4963

5064
env:
51-
DATABASE_URL: mysql://root:1234@127.0.0.1:3306/zenstruck_foundry?serverVersion=5.7
65+
MYSQL_URL: mysql://root:1234@127.0.0.1:3306/zenstruck_foundry?serverVersion=5.7
66+
PGSQL_URL: postgresql://postgres:1234@127.0.0.1:5432/zenstruck_foundry_${{ matrix.use-dama }}_${{ matrix.orm-db }}?charset=utf8&serverVersion=15
5267
MONGO_URL: mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb
5368

5469
steps:
@@ -85,6 +100,7 @@ jobs:
85100
USE_ORM: ${{ matrix.use-orm }}
86101
USE_ODM: ${{ matrix.use-odm }}
87102
USE_FOUNDRY_BUNDLE: 1
103+
DATABASE_URL: ${{ matrix.orm-db == 'postgres' && env.PGSQL_URL || env.MYSQL_URL }}
88104

89105
code-coverage:
90106
name: Code Coverage

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
SHELL=/bin/bash
44

55
# DB variables
6-
MYSQL_URL="mysql://root:root@mysql:3306/zenstruck_foundry?charset=utf8"
6+
PGSQL_URL="postgresql://zenstruck:zenstruck@postgres:5432/zenstruck_foundry?serverVersion=15"
77
MONGO_URL="mongodb://mongo:mongo@mongo:27017/mongo?compressors=disabled&gssapiServiceName=mongodb&authSource=mongo"
88

99
# Default test context variables
@@ -47,10 +47,10 @@ endif
4747
# Create special context for CI
4848
INTERACTIVE:=$(shell [ -t 0 ] && echo 1)
4949
ifdef INTERACTIVE
50-
DC_EXEC=$(DOCKER_COMPOSE) exec -e USE_FOUNDRY_BUNDLE=${USE_FOUNDRY_BUNDLE} -e DATABASE_URL=${MYSQL_URL} -e MONGO_URL=${MONGO_URL}
50+
DC_EXEC=$(DOCKER_COMPOSE) exec -e USE_FOUNDRY_BUNDLE=${USE_FOUNDRY_BUNDLE} -e DATABASE_URL=${PGSQL_URL} -e MONGO_URL=${MONGO_URL}
5151
else
5252
# CI needs to be ran in no-tty mode
53-
DC_EXEC=$(DOCKER_COMPOSE) exec -e USE_FOUNDRY_BUNDLE=${USE_FOUNDRY_BUNDLE} -e DATABASE_URL=${MYSQL_URL} -e MONGO_URL=${MONGO_URL} -T
53+
DC_EXEC=$(DOCKER_COMPOSE) exec -e USE_FOUNDRY_BUNDLE=${USE_FOUNDRY_BUNDLE} -e DATABASE_URL=${PGSQL_URL} -e MONGO_URL=${MONGO_URL} -T
5454
endif
5555

5656
PHP=php${PHP_VERSION}
@@ -141,7 +141,7 @@ docker-build: ### Build and start containers
141141
.PHONY: docker-start
142142
docker-start: ### Start containers
143143
@echo -e "\nStarting containers. This could take up to one minute.\n"
144-
@$(DOCKER_COMPOSE) up --detach --no-build --remove-orphans mysql mongo "${PHP}";
144+
@$(DOCKER_COMPOSE) up --detach --no-build --remove-orphans postgres mongo "${PHP}";
145145

146146
.PHONY: docker-stop
147147
docker-stop: ### Stop containers

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ PREFER_LOWEST=1 # force composer to request lowest dependencies
8787

8888
You can also add these variables to the `.env` file to change the ports used by docker:
8989
```dotenv
90-
MYSQL_PORT=3307
91-
POSTGRES_PORT=5434
90+
PGSQL_PORT=5434
9291
MONGO_PORT=27018
9392
```
9493

docker-compose.yaml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ services:
55
container_name: foundry_php8.0
66
image: ghcr.io/zenstruck/foundry/php:8.0
77
depends_on:
8-
mysql:
8+
postgres:
99
condition: service_healthy
1010
mongo:
1111
condition: service_healthy
@@ -25,17 +25,19 @@ services:
2525
container_name: foundry_php8.2
2626
image: ghcr.io/zenstruck/foundry/php:8.2
2727

28-
mysql:
29-
container_name: foundry_mysql
30-
image: mysql
31-
command: --default-authentication-plugin=mysql_native_password
28+
postgres:
29+
container_name: foundry_postgres
30+
image: postgres:15
3231
environment:
33-
MYSQL_ROOT_PASSWORD: root
34-
MYSQL_DATABASE: zenstruck_foundry
32+
POSTGRES_DB: zenstruck_foundry
33+
POSTGRES_PASSWORD: zenstruck
34+
POSTGRES_USER: zenstruck
35+
volumes:
36+
- db-data:/var/lib/postgresql/data:rw
3537
ports:
36-
- ${MYSQL_PORT:-3306}:3306
38+
- ${PGSQL_PORT:-5432}:5432
3739
healthcheck:
38-
test: 'mysql -u root -proot -D zenstruck_foundry -e "SELECT 1"'
40+
test: 'pg_isready -d zenstruck_foundry'
3941
timeout: 120s
4042
retries: 60
4143
interval: 2s
@@ -59,3 +61,6 @@ services:
5961
test: echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet
6062
timeout: 10s
6163
retries: 10
64+
65+
volumes:
66+
db-data:

src/Test/AbstractSchemaResetter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ abstract class AbstractSchemaResetter
2222
{
2323
abstract public function resetSchema(): void;
2424

25-
protected function runCommand(Application $application, string $command, array $parameters = []): void
25+
protected function runCommand(Application $application, string $command, array $parameters = [], bool $canFail = false): void
2626
{
2727
$exit = $application->run(
2828
new ArrayInput(\array_merge(['command' => $command], $parameters)),
2929
$output = new BufferedOutput()
3030
);
3131

32-
if (0 !== $exit) {
32+
if (0 !== $exit && !$canFail) {
3333
throw new \RuntimeException(\sprintf('Error running "%s": %s', $command, $output->fetch()));
3434
}
3535
}

src/Test/ORMDatabaseResetter.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Zenstruck\Foundry\Test;
1313

14+
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
15+
use Doctrine\DBAL\Platforms\SqlitePlatform;
1416
use Doctrine\Persistence\ManagerRegistry;
1517
use Symfony\Bundle\FrameworkBundle\Console\Application;
1618

@@ -101,9 +103,24 @@ private function dropSchema(): void
101103
private function dropAndResetDatabase(): void
102104
{
103105
foreach ($this->connectionsToReset() as $connection) {
106+
$databasePlatform = $this->registry->getConnection($connection)->getDatabasePlatform();
107+
108+
if ($databasePlatform instanceof PostgreSQLPlatform) {
109+
// let's drop all connections to the database to be able to drop it
110+
$this->runCommand(
111+
$this->application,
112+
'doctrine:query:sql',
113+
[
114+
'--connection' => $connection,
115+
'sql' => 'SELECT pid, pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = current_database() AND pid <> pg_backend_pid()',
116+
],
117+
canFail: true,
118+
);
119+
}
120+
104121
$dropParams = ['--connection' => $connection, '--force' => true];
105122

106-
if ('sqlite' !== $this->registry->getConnection($connection)->getDatabasePlatform()->getName()) {
123+
if (!$databasePlatform instanceof SqlitePlatform) {
107124
// sqlite does not support "--if-exists" (ref: https://github.com/doctrine/dbal/pull/2402)
108125
$dropParams['--if-exists'] = true;
109126
}

tests/Fixtures/Migrations/Version20221204165429.php

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)