magento2-docker/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php

493 lines
16 KiB
PHP
Executable File

<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Setup;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Setup\Declaration\Schema\Diff\SchemaDiff;
use Magento\Framework\Setup\Declaration\Schema\SchemaConfigInterface;
use Magento\Framework\Setup\Declaration\Schema\Sharding;
use Magento\TestFramework\Deploy\CliCommand;
use Magento\TestFramework\Deploy\DescribeTable;
use Magento\TestFramework\Deploy\TestModuleManager;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\SetupTestCase;
/**
* The purpose of this test is verifying declarative installation works.
*/
class DeclarativeInstallerTest extends SetupTestCase
{
/**
* @var TestModuleManager
*/
private $moduleManager;
/**
* @var CliCommand
*/
private $cliCommand;
/**
* @var SchemaDiff
*/
private $schemaDiff;
/**
* @var SchemaConfigInterface
*/
private $schemaConfig;
/**
* @var ResourceConnection
*/
private $resourceConnection;
/**
* @var DescribeTable
*/
private $describeTable;
/**
* @inheritdoc
*/
protected function setUp(): void
{
$objectManager = Bootstrap::getObjectManager();
$this->moduleManager = $objectManager->get(TestModuleManager::class);
$this->cliCommand = $objectManager->get(CliCommand::class);
$this->describeTable = $objectManager->get(DescribeTable::class);
$this->schemaDiff = $objectManager->get(SchemaDiff::class);
$this->schemaConfig = $objectManager->get(SchemaConfigInterface::class);
$this->resourceConnection = $objectManager->get(ResourceConnection::class);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php
*/
public function testInstallation()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
//Second time installation should not find anything as we do not change anything
self::assertNull($diff->getAll());
$this->compareStructures();
}
/**
* Compare structure of DB and declared structure.
*/
private function compareStructures()
{
$shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION);
foreach ($this->getTrimmedData() as $tableName => $sql) {
$this->assertArrayHasKey($tableName, $shardData);
/**
* MySQL 8.0 and above does not provide information about the ON DELETE instruction
* if ON DELETE NO ACTION
*/
if (preg_match('#ON DELETE\s+NO ACTION#i', $shardData[$tableName] === 1)) {
preg_replace('#ON DELETE\s+NO ACTION#i', '', $sql);
self::assertEquals($sql, $shardData[$tableName]);
}
}
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php
* @throws \Exception
*/
public function testInstallationWithColumnsModification()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
//Move InstallSchema file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'column_modifications',
'db_schema.xml',
'etc'
);
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
self::assertNull($diff->getAll());
$this->compareStructures();
}
/**
* Updates revision for db_schema and db_schema_whitelist files
*
* @param string $revisionName
*/
private function updateDbSchemaRevision($revisionName)
{
//Move InstallSchema file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
$revisionName,
'db_schema.xml',
'etc'
);
//Move InstallSchema file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
$revisionName,
'db_schema_whitelist.json',
'etc'
);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php
* @throws \Exception
*/
public function testInstallationWithColumnsRemoval()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$this->updateDbSchemaRevision('column_removals');
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
self::assertNull($diff->getAll());
$this->compareStructures();
}
/**
* As sometimes we want to ignore spaces and other special characters,
* we need to trim data before compare it
*
* @return array
*/
private function getTrimmedData()
{
$data = [];
foreach ($this->getData() as $key => $createTable) {
$data[$key] = preg_replace('/(\s)\n/', '$1', $createTable);
}
return $data;
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php
* @throws \Exception
*/
public function testInstallationWithConstraintsModification()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$this->updateDbSchemaRevision('constraint_modifications');
$this->cliCommand->upgrade();
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
self::assertNull($diff->getAll());
$shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION);
$this->assertTableCreationStatements($this->getTrimmedData(), $shardData);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php
* @throws \Exception
*/
public function testInstallationWithDroppingTables()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
//Move db_schema.xml file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'drop_table',
'db_schema.xml',
'etc'
);
$this->cliCommand->upgrade();
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
self::assertNull($diff->getAll());
$shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION);
$this->assertTableCreationStatements($this->getData(), $shardData);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @moduleName Magento_TestSetupDeclarationModule3
*/
public function testInstallationWithDroppingTablesFromSecondaryModule()
{
$modules = [
'Magento_TestSetupDeclarationModule1',
'Magento_TestSetupDeclarationModule3',
];
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule3',
'drop_table_with_external_dependency',
'db_schema.xml',
'etc'
);
foreach ($modules as $moduleName) {
$this->moduleManager->updateRevision(
$moduleName,
'without_setup_version',
'module.xml',
'etc'
);
}
try {
$this->cliCommand->install($modules);
} catch (\Exception $e) {
$installException = $e->getPrevious();
self::assertSame(1, $installException->getCode());
self::assertStringContainsString(
'The reference table named "reference_table" is disabled',
$installException->getMessage()
);
}
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php
* @throws \Exception
*/
public function testInstallWithCodeBaseRollback()
{
//Move db_schema.xml file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'before_rollback',
'db_schema.xml',
'etc'
);
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
if ($this->isUsingAuroraDb()) {
$this->markTestSkipped('Test skipped in AWS Aurora');
}
$beforeRollback = $this->describeTable->describeShard('default');
self::assertEquals($this->getTrimmedData()['before'], $beforeRollback);
//Move db_schema.xml file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'after_rollback',
'db_schema.xml',
'etc'
);
$this->cliCommand->upgrade();
$afterRollback = $this->describeTable->describeShard('default');
self::assertEquals($this->getData()['after'], $afterRollback);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @dataProviderFromFile Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.php
* @throws \Exception
*/
public function testTableRename()
{
$dataToMigrate = ['some_column' => 'Some Value'];
//Move db_schema.xml file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'table_rename',
'db_schema.xml',
'etc'
);
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1']
);
$before = $this->describeTable->describeShard('default');
$adapter = $this->resourceConnection->getConnection('default');
$adapter->insert(
$this->resourceConnection->getTableName('some_table'),
$dataToMigrate
);
$this->isUsingAuroraDb() ?
$this->assertStringContainsString($before['some_table'], $this->getTrimmedData()['before']) :
$this->assertEquals($this->getData()['before'], $before['some_table']);
//Move db_schema.xml file and tried to install
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'table_rename_after',
'db_schema.xml',
'etc'
);
$this->cliCommand->upgrade();
$after = $this->describeTable->describeShard('default');
$this->isUsingAuroraDb() ?
$this->assertStringContainsString($after['some_table_renamed'], $this->getTrimmedData()['after']) :
$this->assertEquals($this->getData()['after'], $after['some_table_renamed']);
$select = $adapter->select()
->from($this->resourceConnection->getTableName('some_table_renamed'));
self::assertEquals([$dataToMigrate], $adapter->fetchAll($select));
}
/**
* @moduleName Magento_TestSetupDeclarationModule8
* @throws \Exception
*/
public function testForeignKeyReferenceId()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule8']
);
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule8',
'unpatterned_fk_name',
'db_schema.xml',
'etc'
);
$this->cliCommand->upgrade();
$tableStatements = $this->describeTable->describeShard('default');
$tableSql = $tableStatements['dependent'];
$this->assertMatchesRegularExpression('/CONSTRAINT\s`DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID`/', $tableSql);
$this->assertMatchesRegularExpression(
'/CONSTRAINT\s`DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID`/',
$tableSql
);
}
/**
* @moduleName Magento_TestSetupDeclarationModule1
* @moduleName Magento_TestSetupDeclarationModule8
* @throws \Exception
*/
public function testDisableIndexByExternalModule()
{
$this->cliCommand->install(
['Magento_TestSetupDeclarationModule1', 'Magento_TestSetupDeclarationModule8']
);
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule1',
'index_to_disable',
'db_schema.xml',
'etc'
);
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule8',
'disable_index_by_external_module',
'db_schema.xml',
'etc'
);
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule8',
'disable_index_by_external_module',
'db_schema_whitelist.json',
'etc'
);
$this->moduleManager->updateRevision(
'Magento_TestSetupDeclarationModule8',
'disable_index_by_external_module',
'module.xml',
'etc'
);
$this->cliCommand->upgrade();
$tableStatements = $this->describeTable->describeShard('default');
$tableSql = $tableStatements['test_table'];
$this->assertDoesNotMatchRegularExpression(
'/KEY\s+`TEST_TABLE_VARCHAR`\s+\(`varchar`\)/',
$tableSql,
'Index is not being disabled by external module'
);
}
/**
* @moduleName Magento_TestSetupDeclarationModule8
* @moduleName Magento_TestSetupDeclarationModule9
* @dataProviderFromFile Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.php
* @throws \Exception
*/
public function testInstallationWithDisablingTables()
{
$modules = [
'Magento_TestSetupDeclarationModule8',
'Magento_TestSetupDeclarationModule9',
];
foreach ($modules as $moduleName) {
$this->moduleManager->updateRevision(
$moduleName,
'disabling_tables',
'db_schema.xml',
'etc'
);
}
$this->cliCommand->install($modules);
$diff = $this->schemaDiff->diff(
$this->schemaConfig->getDeclarationConfig(),
$this->schemaConfig->getDbConfig()
);
self::assertNull($diff->getAll());
$shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION);
$this->assertTableCreationStatements($this->getData(), $shardData);
}
/**
* Assert table creation statements
*
* @param array $expectedData
* @param array $actualData
*/
private function assertTableCreationStatements(array $expectedData, array $actualData): void
{
if (!$this->isUsingAuroraDb()) {
$this->assertEquals($expectedData, $actualData);
} else {
ksort($expectedData);
ksort($actualData);
$this->assertSameSize($expectedData, $actualData);
foreach ($expectedData as $key => $value) {
$this->assertStringContainsString($actualData[$key], $value);
}
}
}
}