Skip to content

Commit

Permalink
EZP-31246: Refactored Test setup to stop relying on Database Handler (#…
Browse files Browse the repository at this point in the history
…14)

* Dropped eZ\Publish\Core\Persistence\Doctrine\Tests

* Changed format of integration tests data fixtures into Yaml

* Refactored integration tests data import to stop relying on DB Handler

* Implemented database fixtures importer

* Refactored Legacy Storage Setup Factory to use FixtureImporter

* Updated test data LSE FullText index

* Refactored unit tests setups to use FixtureImporter

* Refactored TestCase::assertQueryResult accept QueryBuilder

* Changed Core\Persistence TestCase::getDatabaseConnection to fail
instead of throwing exception (makes no sense for test case
to report it thrown and then report it for every test using that
method as thrown as well).

* Refactored unit tests to rely on Doctrine QueryBuilder

* [Unit Tests] Replaced DatabaseHandler usages with Doctrine\DBAL

* Refactored remaining unit tests to stop relying on test_data.php

* Dropped test_data.php in favor of test_data.yaml

  The new data fixture file is located at: eZ/Publish/API/Repository/Tests/_fixtures/Legacy/data/test_data.yaml
  • Loading branch information
alongosz authored Mar 31, 2020
1 parent 3ef5eda commit 6da412b
Show file tree
Hide file tree
Showing 41 changed files with 2,147 additions and 11,906 deletions.
144 changes: 35 additions & 109 deletions eZ/Publish/API/Repository/Tests/SetupFactory/Legacy.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
namespace eZ\Publish\API\Repository\Tests\SetupFactory;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\PDOException;
use Doctrine\DBAL\Schema\Schema;
use eZ\Publish\API\Repository\Tests\LegacySchemaImporter;
use eZ\Publish\Core\Base\ServiceContainer;
use eZ\Publish\SPI\Tests\Persistence\Fixture;
use eZ\Publish\SPI\Tests\Persistence\FixtureImporter;
use eZ\Publish\SPI\Tests\Persistence\YamlFixture;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use eZ\Publish\API\Repository\Tests\SetupFactory;
use eZ\Publish\API\Repository\Tests\IdManager;
Expand Down Expand Up @@ -66,14 +66,24 @@ class Legacy extends SetupFactory
protected static $schemaInitialized = false;

/**
* Initial database data.
* Cached in-memory initial database data fixture.
*
* @var array
* @var \eZ\Publish\SPI\Tests\Persistence\Fixture
*/
protected static $initialData;
private static $initialDataFixture;

/**
* Cached in-memory post insert SQL statements.
*
* @var string[]
*/
private static $postInsertStatements;

protected $repositoryReference = 'ezpublish.api.repository';

/** @var \Doctrine\DBAL\Connection */
private $connection;

/**
* Creates a new setup factory.
*/
Expand Down Expand Up @@ -178,66 +188,16 @@ public function getIdManager()

/**
* Insert the database data.
*
* @throws \Doctrine\DBAL\DBALException
*/
public function insertData()
public function insertData(): void
{
$data = $this->getInitialData();
$handler = $this->getDatabaseHandler();
$connection = $handler->getConnection();
$dbPlatform = $connection->getDatabasePlatform();
$connection = $this->getDatabaseConnection();
$this->cleanupVarDir($this->getInitialVarDir());

foreach (array_reverse(array_keys($data)) as $table) {
try {
// Cleanup before inserting (using TRUNCATE for speed, however not possible to rollback)
$connection->executeUpdate($dbPlatform->getTruncateTableSql($handler->quoteIdentifier($table)));
} catch (DBALException | PDOException $e) {
// Fallback to DELETE if TRUNCATE failed (because of FKs for instance)
$connection->createQueryBuilder()->delete($table)->execute();
}
}

foreach ($data as $table => $rows) {
// Check that at least one row exists
if (!isset($rows[0])) {
continue;
}

$q = $handler->createInsertQuery();
$q->insertInto($handler->quoteIdentifier($table));

// Contains the bound parameters
$values = [];

// Binding the parameters
foreach ($rows[0] as $col => $val) {
$q->set(
$handler->quoteIdentifier($col),
$q->bindParam($values[$col])
);
}

$stmt = $q->prepare();

foreach ($rows as $row) {
try {
// This CANNOT be replaced by:
// $values = $row
// each $values[$col] is a PHP reference which should be
// kept for parameters binding to work
foreach ($row as $col => $val) {
$values[$col] = $val;
}

$stmt->execute();
} catch (Exception $e) {
echo "$table ( ", implode(', ', $row), " )\n";
throw $e;
}
}
}

$this->applyStatements($this->getPostInsertStatements());
$fixtureImporter = new FixtureImporter($connection);
$fixtureImporter->import($this->getInitialDataFixture());
}

protected function getInitialVarDir()
Expand Down Expand Up @@ -282,33 +242,19 @@ protected function clearInternalCaches()
}

/**
* Returns statements to be executed after data insert.
*
* @return string[]
*/
protected function getPostInsertStatements()
{
if (self::$db === 'pgsql') {
$setvalPath = __DIR__ . '/../../../../Core/Persistence/Legacy/Tests/_fixtures/setval.pgsql.sql';

return array_filter(preg_split('(;\\s*$)m', file_get_contents($setvalPath)));
}

return [];
}

/**
* Returns the initial database data.
* Returns the initial database data fixture.
*
* @return array
* @return \eZ\Publish\SPI\Tests\Persistence\Fixture
*/
protected function getInitialData()
protected function getInitialDataFixture(): Fixture
{
if (!isset(self::$initialData)) {
self::$initialData = include __DIR__ . '/../../../../Core/Repository/Tests/Service/Integration/Legacy/_fixtures/test_data.php';
if (!isset(self::$initialDataFixture)) {
self::$initialDataFixture = new YamlFixture(
__DIR__ . '/../_fixtures/Legacy/data/test_data.yaml'
);
}

return self::$initialData;
return self::$initialDataFixture;
}

/**
Expand All @@ -329,38 +275,18 @@ protected function initializeSchema(): void
}
}

/**
* Applies the given SQL $statements to the database in use.
*
* @param array $statements
*/
protected function applyStatements(array $statements)
{
foreach ($statements as $statement) {
$this->getDatabaseHandler()->exec($statement);
}
}

// ************* Setup copied and refactored from common.php ************

/**
* Returns the database handler from the service container.
*
* @return \eZ\Publish\Core\Persistence\Doctrine\ConnectionHandler
*/
protected function getDatabaseHandler()
{
return $this->getServiceContainer()->get('ezpublish.api.storage_engine.legacy.dbhandler');
}

/**
* Returns the raw database connection from the service container.
*
* @return \Doctrine\DBAL\Connection
*/
private function getDatabaseConnection(): Connection
{
return $this->getServiceContainer()->get('ezpublish.persistence.connection');
if (null === $this->connection) {
$this->connection = $this->getServiceContainer()->get('ezpublish.persistence.connection');
}

return $this->connection;
}

/**
Expand Down
Loading

0 comments on commit 6da412b

Please sign in to comment.