Skip to content

Commit d8b429d

Browse files
Merge pull request #316 from alexislefebvre/chore-restore-backup-3.x
[3.x] Revert "chore: remove backup"
2 parents 203df64 + cf1244f commit d8b429d

34 files changed

+1382
-86
lines changed

.github/workflows/tests.yml

+19-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on: [push, pull_request]
44

55
jobs:
66
tests:
7-
name: Symfony ${{ matrix.symfony-version }} - PHP ${{ matrix.php-version }} - flags ${{ matrix.composer-flags }}
7+
name: Symfony ${{ matrix.symfony-version }} - PHP ${{ matrix.php-version }} - flags ${{ matrix.composer-flags }} - mysqldump ${{ matrix.mysql-client }}
88
runs-on: ubuntu-latest
99

1010
strategy:
@@ -14,6 +14,7 @@ jobs:
1414
php-version: ['8.2']
1515
composer-flags: ['']
1616
symfony-version: ['^6.4']
17+
mysql-client: [ "default-mysql-client" ]
1718
include:
1819
- php-version: 8.1
1920
# Use "update" instead of "install" since it allows using the "--prefer-lowest" option
@@ -24,6 +25,10 @@ jobs:
2425
# `theofidry/alice-data-fixtures:1.6.0` and `doctrine/dbal:^4.0` cause issues:
2526
# Error: Call to undefined method Doctrine\DBAL\Connection::exec()
2627
composer-flags: "require doctrine/dbal:^3.0"
28+
- php-version: 8.2
29+
symfony-version: "^6.4"
30+
# add a specific job to test mysqldump from MariaDB
31+
mysql-client: "mariadb-client"
2732
- php-version: 8.2
2833
symfony-version: "^7.0"
2934
- php-version: 8.3
@@ -57,6 +62,18 @@ jobs:
5762
- 27017:27017
5863

5964
steps:
65+
- name: Install mysqldump
66+
run: |
67+
sudo apt update
68+
sudo apt install -y -q ${{ matrix.mysql-client }}
69+
mysqldump --version
70+
71+
- name: Install mongodb database tools
72+
run: |
73+
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian92-x86_64-100.3.1.deb
74+
sudo apt install ./mongodb-database-tools-*.deb
75+
rm -f mongodb-database-tools-*.deb
76+
6077
- name: Checkout
6178
uses: actions/checkout@v4
6279

@@ -99,7 +116,7 @@ jobs:
99116
run: echo '127.0.0.1 mariadb postgres mongodb' | sudo tee -a /etc/hosts
100117

101118
- name: Run tests
102-
# Run tests twice to ensure that tests are idempotent
119+
# Run tests twice to ensure that tests are idempotent even if database caching is enabled
103120
run: |
104121
php ./vendor/bin/phpunit --testdox --process-isolation
105122
php ./vendor/bin/phpunit --testdox --process-isolation

doc/configuration.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ Here is the full configuration with default values:
77
liip_test_fixtures:
88
keep_database_and_schema: false
99
cache_metadata: true
10+
cache_db: ~
1011
```
1112
1213
- `keep_database_and_schema`: pass it to `true` to avoid deleting and creating the database and schema before each test, you'll have to create the database schema before running your tests:
1314
1. create database with `bin/console --env=test doctrine:database:create`:
1415
2. create schema with `bin/console --env=test doctrine:schema:update --force` or `bin/console --env=test doctrine:migrations:migrate --no-interaction`
1516
- `cache_metadata`: using the cache slightly improve the performance
17+
- `cache_db`: an array with a storage as key and a service as value, examples :
18+
- `sqlite: 'Liip\TestFixturesBundle\Services\DatabaseBackup\SqliteDatabaseBackup'`
19+
- `mysql: 'Liip\TestFixturesBundle\Services\DatabaseBackup\MysqlDatabaseBackup'`
20+
- `mongodb: 'Liip\TestFixturesBundle\Services\DatabaseBackup\MongodbDatabaseBackup'`
1621
1722
« [Installation](./installation.md) • [Database](./database.md) »

doc/database.md

+37
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ Methods
7979

8080
It also give access to other helpers:
8181

82+
- `setDatabaseCacheEnabled()` accept `true` or `false` to disable the cache
83+
- you can call `$this->databaseTool->withDatabaseCacheEnabled(false)->loadFixtures(…)` to disable the cache on-demand
84+
8285
- `setPurgeMode()` accept `true` or `false` to disable purging the database
8386
- you can call `$this->databaseTool->withPurgeMode(false)->loadFixtures(…)` to disable the purging on-demand
8487

@@ -106,6 +109,40 @@ Tips for Fixture Loading Tests
106109

107110
NB: If you have an existing Doctrine configuration which uses slaves be sure to separate out the configuration for the slaves. Further detail is provided at the bottom of this README.
108111

112+
2. In order to run your tests even faster, use LiipFunctionalBundle cached database.
113+
This will create backups of the initial databases (with all fixtures loaded)
114+
and re-load them when required.
115+
116+
**Attention: you need Doctrine >= 2.2 to use this feature.**
117+
118+
```yaml
119+
# sf4: config/packages/test/framework.yaml
120+
liip_test_fixtures:
121+
cache_db:
122+
sqlite: 'Liip\TestFixturesBundle\Services\DatabaseBackup\SqliteDatabaseBackup'
123+
```
124+
125+
### Custom database cache services ([↑](#methods))
126+
127+
To create custom database cache service:
128+
129+
Create cache class, implement `\Liip\TestFixturesBundle\Services\DatabaseBackup\DatabaseBackupInterface` and add it to config
130+
131+
For example:
132+
```yaml
133+
# app/config/config_test.yml
134+
liip_test_fixtures:
135+
cache_db:
136+
mysql: 'Liip\TestFixturesBundle\Services\DatabaseBackup\MysqlDatabaseBackup'
137+
mongodb: 'Liip\TestFixturesBundle\Services\DatabaseBackup\MongodbDatabaseBackup'
138+
db2: ...
139+
[Other \Doctrine\DBAL\Platforms\AbstractPlatform name]: ...
140+
```
141+
142+
**Attention: `Liip\TestFixturesBundle\Services\DatabaseBackup\MysqlDatabaseBackup` requires `mysql-client` installed on server.**
143+
144+
**Attention: `Liip\TestFixturesBundle\Services\DatabaseBackup\MongodbDatabaseBackup` requires `mongodb-clients` installed on server.**
145+
109146
### Load fixtures ([↑](#methods))
110147

111148
Load your Doctrine fixtures in your tests:

doc/events.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
Available events:
44

5+
- `LiipTestFixturesEvents::PRE_FIXTURE_BACKUP_RESTORE`: triggered before restoring the backup
6+
- `LiipTestFixturesEvents::POST_FIXTURE_BACKUP_RESTORE`: triggered after the backup has been restored
57
- `LiipTestFixturesEvents::POST_FIXTURE_SETUP`: triggered before purging the database
8+
- `LiipTestFixturesEvents::PRE_REFERENCE_SAVE`: triggered before saving the backup of fixtures
9+
- `LiipTestFixturesEvents::POST_REFERENCE_SAVE`: triggered before the backup of fixtures has been saved
610

711
## Registering events
812

@@ -15,6 +19,7 @@ declare(strict_types=1);
1519

1620
namespace Liip\Acme\Tests\AppConfigEvents\EventListener;
1721

22+
use Liip\TestFixturesBundle\Event\PreFixtureBackupRestoreEvent;
1823
use Liip\TestFixturesBundle\LiipTestFixturesEvents;
1924
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
2025

@@ -23,12 +28,16 @@ class FixturesSubscriber implements EventSubscriberInterface
2328
public static function getSubscribedEvents(): array
2429
{
2530
return [
26-
LiipTestFixturesEvents::POST_FIXTURE_SETUP => 'postFixtureSetup',
31+
LiipTestFixturesEvents::PRE_FIXTURE_BACKUP_RESTORE => 'preFixtureBackupRestore',
2732
];
2833
}
2934

30-
public function postFixtureSetup(FixtureEvent $fixtureEvent): void
35+
public function preFixtureBackupRestore(PreFixtureBackupRestoreEvent $preFixtureBackupRestoreEvent): void
3136
{
37+
$manager = $preFixtureBackupRestoreEvent->getManager();
38+
$repository = $preFixtureBackupRestoreEvent->getRepository();
39+
$backupFilePath = $preFixtureBackupRestoreEvent->getBackupFilePath();
40+
3241
// your code
3342
}
3443
}

src/DependencyInjection/Configuration.php

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ public function getConfigTreeBuilder(): TreeBuilder
2828

2929
$rootNode
3030
->children()
31+
->arrayNode('cache_db')
32+
->addDefaultsIfNotSet()
33+
->ignoreExtraKeys(false)
34+
->children()
35+
->scalarNode('sqlite')
36+
->defaultNull()
37+
->end()
38+
->end()
39+
->end()
3140
->booleanNode('keep_database_and_schema')->defaultFalse()->end()
3241
->booleanNode('cache_metadata')->defaultTrue()->end()
3342
;

src/DependencyInjection/LiipTestFixturesExtension.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,20 @@ public function load(array $configs, ContainerBuilder $container): void
3131
$loader->load('database_tools.xml');
3232

3333
foreach ($config as $key => $value) {
34-
$container->setParameter($this->getAlias().'.'.$key, $value);
34+
// If the node is an array,
35+
// e.g. "liip_test_fixtures.cache_db.mysql",
36+
// set the value as
37+
// "liip_test_fixtures.cache_db.mysql"
38+
// instead of an array "liip_test_fixtures.cache_db"
39+
// with a "mysql" key.
40+
if (\is_array($value)) {
41+
foreach ($value as $key2 => $value2) {
42+
$container->setParameter($this->getAlias().'.'.$key.
43+
'.'.$key2, $value2);
44+
}
45+
} else {
46+
$container->setParameter($this->getAlias().'.'.$key, $value);
47+
}
3548
}
3649
}
3750
}

src/Event/FixtureEvent.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@
1313

1414
namespace Liip\TestFixturesBundle\Event;
1515

16+
// Compatibility layer to use Contract if Symfony\Contracts\EventDispatcher\Event is not available
1617
use Symfony\Contracts\EventDispatcher\Event;
1718

18-
class FixtureEvent extends Event
19-
{
19+
if (class_exists('\Symfony\Component\EventDispatcher\Event')) {
20+
// Symfony < 5.0
21+
class FixtureEvent extends \Symfony\Component\EventDispatcher\Event
22+
{
23+
}
24+
} else {
25+
class FixtureEvent extends Event
26+
{
27+
}
2028
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <[email protected]>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\TestFixturesBundle\Event;
15+
16+
class PostFixtureBackupRestoreEvent extends FixtureEvent
17+
{
18+
private $backupFilePath;
19+
20+
public function __construct(string $backupFilePath)
21+
{
22+
$this->backupFilePath = $backupFilePath;
23+
}
24+
25+
public function getBackupFilePath(): string
26+
{
27+
return $this->backupFilePath;
28+
}
29+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <[email protected]>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\TestFixturesBundle\Event;
15+
16+
use Doctrine\Common\DataFixtures\ReferenceRepository;
17+
use Doctrine\Persistence\ObjectManager;
18+
19+
class PreFixtureBackupRestoreEvent extends FixtureEvent
20+
{
21+
private $manager;
22+
private $repository;
23+
private $backupFilePath;
24+
25+
public function __construct(
26+
ObjectManager $manager,
27+
ReferenceRepository $executor,
28+
string $backupFilePath
29+
) {
30+
$this->manager = $manager;
31+
$this->repository = $executor;
32+
$this->backupFilePath = $backupFilePath;
33+
}
34+
35+
public function getManager(): ObjectManager
36+
{
37+
return $this->manager;
38+
}
39+
40+
public function getRepository(): ReferenceRepository
41+
{
42+
return $this->repository;
43+
}
44+
45+
public function getBackupFilePath(): string
46+
{
47+
return $this->backupFilePath;
48+
}
49+
}

src/Event/ReferenceSaveEvent.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <[email protected]>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\TestFixturesBundle\Event;
15+
16+
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor;
17+
use Doctrine\Persistence\ObjectManager;
18+
19+
class ReferenceSaveEvent extends FixtureEvent
20+
{
21+
private $manager;
22+
private $executor;
23+
private $backupFilePath;
24+
25+
public function __construct(
26+
ObjectManager $manager,
27+
AbstractExecutor $executor,
28+
string $backupFilePath
29+
) {
30+
$this->manager = $manager;
31+
$this->executor = $executor;
32+
$this->backupFilePath = $backupFilePath;
33+
}
34+
35+
public function getManager(): ObjectManager
36+
{
37+
return $this->manager;
38+
}
39+
40+
public function getExecutor(): AbstractExecutor
41+
{
42+
return $this->executor;
43+
}
44+
45+
public function getBackupFilePath(): string
46+
{
47+
return $this->backupFilePath;
48+
}
49+
}

src/LiipTestFixturesEvents.php

+15
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,24 @@
1414
namespace Liip\TestFixturesBundle;
1515

1616
use Liip\TestFixturesBundle\Event\FixtureEvent;
17+
use Liip\TestFixturesBundle\Event\PostFixtureBackupRestoreEvent;
18+
use Liip\TestFixturesBundle\Event\PreFixtureBackupRestoreEvent;
19+
use Liip\TestFixturesBundle\Event\ReferenceSaveEvent;
1720

1821
final class LiipTestFixturesEvents
1922
{
23+
/** @see PreFixtureBackupRestoreEvent */
24+
public const PRE_FIXTURE_BACKUP_RESTORE = 'liip_test_fixtures.pre_fixture_backup_restore';
25+
2026
/** @see FixtureEvent */
2127
public const POST_FIXTURE_SETUP = 'liip_test_fixtures.post_fixture_setup';
28+
29+
/** @see PostFixtureBackupRestoreEvent */
30+
public const POST_FIXTURE_BACKUP_RESTORE = 'liip_test_fixtures.post_fixture_backup_restore';
31+
32+
/** @see ReferenceSaveEvent */
33+
public const PRE_REFERENCE_SAVE = 'liip_test_fixtures.pre_reference_save';
34+
35+
/** @see ReferenceSaveEvent */
36+
public const POST_REFERENCE_SAVE = 'liip_test_fixtures.post_reference_save';
2237
}

src/Resources/config/database_tools.xml

+15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414
<argument type="service" id="doctrine_mongodb.odm.symfony.fixtures.loader" on-invalid="null"/>
1515
</service>
1616

17+
<service id="Liip\TestFixturesBundle\Services\DatabaseBackup\SqliteDatabaseBackup" public="true">
18+
<argument type="service" id="service_container" />
19+
<argument type="service" id="Liip\TestFixturesBundle\Services\FixturesLoaderFactory" />
20+
</service>
21+
22+
<service id="Liip\TestFixturesBundle\Services\DatabaseBackup\MysqlDatabaseBackup" public="true">
23+
<argument type="service" id="service_container" />
24+
<argument type="service" id="Liip\TestFixturesBundle\Services\FixturesLoaderFactory" />
25+
</service>
26+
27+
<service id="Liip\TestFixturesBundle\Services\DatabaseBackup\MongodbDatabaseBackup" public="true">
28+
<argument type="service" id="service_container" />
29+
<argument type="service" id="Liip\TestFixturesBundle\Services\MongoDBFixturesLoaderFactory" />
30+
</service>
31+
1732
<service id="Liip\TestFixturesBundle\Services\DatabaseTools\ORMDatabaseTool" public="false">
1833
<argument type="service" id="service_container" />
1934
<argument type="service" id="Liip\TestFixturesBundle\Services\FixturesLoaderFactory" />

0 commit comments

Comments
 (0)