![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/dev/tests/integration/framework/Magento/TestFramework/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\TestFramework; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\DeploymentConfig\Reader; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Autoload\AutoloaderInterface; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Filesystem\Glob; use Magento\Framework\Mail; use Magento\TestFramework; use Magento\TestFramework\Fixture\Data\ProcessorInterface; use Psr\Log\LoggerInterface; use DomainException; /** * Encapsulates application installation, initialization and uninstall. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ class Application { /** * Default application area. */ public const DEFAULT_APP_AREA = 'global'; /** * DB vendor adapter instance. * * @var TestFramework\Db\AbstractDb */ protected $_db; /** * Shell command executor. * * @var \Magento\Framework\Shell */ protected $_shell; /** * Configuration file that contains installation parameters. * * @var string */ private $installConfigFile; /** * Configuration file that contains array of post-installation commands to run through bin/magento CLI tool. * * @var string|null */ private $postInstallSetupCommandsFile; /** * The loaded installation parameters. * * @var array */ protected $installConfig; /** * The loaded post-installation commands. * * @var array */ private $postInstallSetupCommands; /** * Application *.xml configuration files. * * @var array */ protected $_globalConfigDir; /** * Installation destination directory. * * @var string */ protected $installDir; /** * Installation destination directory with configuration files. * * @var string */ protected $_configDir; /** * Application initialization parameters. * * @var array */ protected $_initParams = []; /** * Mode to run application. * * @var string */ protected $_appMode; /** * Application area. * * @var null */ protected $_appArea = null; /** * Primary DI Config. * * @var array */ protected $_primaryConfigData = []; /** * Object manager factory. * * @var TestFramework\ObjectManagerFactory */ protected $_factory; /** * Directory list. * * @var DirectoryList */ protected $dirList; /** * Config file for integration tests. * * @var string */ private $globalConfigFile; /** * Defines whether load test extension attributes or not. * * @var bool */ private $loadTestExtensionAttributes; /** * @var bool */ protected $dumpDb = true; /** * @var bool */ protected $canLoadArea = true; /** * @var bool */ protected $canInstallSequence = true; /** * Constructor. * * @param \Magento\Framework\Shell $shell * @param string $installDir * @param string $installConfigFile * @param string $globalConfigFile * @param string $globalConfigDir * @param string $appMode * @param AutoloaderInterface $autoloadWrapper * @param bool|null $loadTestExtensionAttributes * @param string|null $postInstallSetupCommandsFile */ public function __construct( \Magento\Framework\Shell $shell, $installDir, $installConfigFile, $globalConfigFile, $globalConfigDir, $appMode, AutoloaderInterface $autoloadWrapper, $loadTestExtensionAttributes = false, $postInstallSetupCommandsFile = null ) { if (getcwd() != BP . '/dev/tests/integration') { // phpcs:ignore Magento2.Functions.DiscouragedFunction chdir(BP . '/dev/tests/integration'); } $this->_shell = $shell; $this->installConfigFile = $installConfigFile; $this->postInstallSetupCommandsFile = $postInstallSetupCommandsFile; // phpcs:ignore Magento2.Functions.DiscouragedFunction $this->_globalConfigDir = realpath($globalConfigDir); $this->_appMode = $appMode; $this->installDir = $installDir; $this->loadTestExtensionAttributes = $loadTestExtensionAttributes; $customDirs = $this->getCustomDirs(); $this->dirList = new DirectoryList(BP, $customDirs); \Magento\Framework\Autoload\Populator::populateMappings( $autoloadWrapper, $this->dirList ); $this->_initParams = [ \Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS => $customDirs, \Magento\Framework\App\State::PARAM_MODE => $appMode ]; $driverPool = new \Magento\Framework\Filesystem\DriverPool(); $configFilePool = new \Magento\Framework\Config\File\ConfigFilePool(); $this->_factory = new TestFramework\ObjectManagerFactory($this->dirList, $driverPool, $configFilePool); $this->_configDir = $this->dirList->getPath(DirectoryList::CONFIG); $this->globalConfigFile = $globalConfigFile; } /** * Retrieve the database adapter instance. * * @return TestFramework\Db\AbstractDb */ public function getDbInstance() { if (null === $this->_db) { if ($this->isInstalled()) { $configPool = new \Magento\Framework\Config\File\ConfigFilePool(); $driverPool = new \Magento\Framework\Filesystem\DriverPool(); $reader = new Reader($this->dirList, $driverPool, $configPool); $deploymentConfig = new DeploymentConfig($reader, []); $host = $deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_HOST ); $user = $deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_USER ); $password = $deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_PASSWORD ); $dbName = $deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_NAME ); } else { $installConfig = $this->getInstallConfig(); $host = $installConfig['db-host']; $user = $installConfig['db-user']; $password = $installConfig['db-password']; $dbName = $installConfig['db-name']; } $this->_db = new Db\Mysql( $host, $user, $password, $dbName, $this->getTempDir(), $this->_shell ); } return $this->_db; } /** * Gets installation parameters. * * @return array */ protected function getInstallConfig() { if (null === $this->installConfig) { // phpcs:ignore Magento2.Security.IncludeFile $this->installConfig = include $this->installConfigFile; $this->installConfig['use-secure'] = '0'; $this->installConfig['use-secure-admin'] = '0'; } return $this->installConfig; } /** * Gets post-installation commands. * * @return array */ protected function getPostInstallSetupCommands() { if (null === $this->postInstallSetupCommandsFile) { $this->postInstallSetupCommands = []; } elseif (null === $this->postInstallSetupCommands) { // phpcs:ignore Magento2.Security.IncludeFile $this->postInstallSetupCommands = include $this->postInstallSetupCommandsFile; } return $this->postInstallSetupCommands; } /** * Gets deployment configuration path. * * @return string */ private function getLocalConfig() { return $this->_configDir . '/config.php'; } /** * Get path to temporary directory. * * @return string */ public function getTempDir() { return $this->installDir; } /** * Retrieve application initialization parameters. * * @return array */ public function getInitParams() { return $this->_initParams; } /** * Weather the application is installed or not. * * @return bool */ public function isInstalled() { // phpcs:ignore Magento2.Functions.DiscouragedFunction return is_file($this->getLocalConfig()); } /** * Create logger instance and rewrite already exist one in ObjectManager. * * @return \Psr\Log\LoggerInterface */ private function initLogger() { $objectManager = Helper\Bootstrap::getObjectManager(); /** @var \Psr\Log\LoggerInterface $logger */ $logger = $objectManager->create( TestFramework\ErrorLog\Logger::class, [ 'name' => 'integration-tests', 'handlers' => [ 'system' => $objectManager->create( \Magento\Framework\Logger\Handler\System::class, [ 'exceptionHandler' => $objectManager->create( \Magento\Framework\Logger\Handler\Exception::class, ['filePath' => $this->installDir] ), 'filePath' => $this->installDir ] ), 'debug' => $objectManager->create( \Magento\Framework\Logger\Handler\Debug::class, ['filePath' => $this->installDir] ), ] ] ); $objectManager->removeSharedInstance(LoggerInterface::class, true); $objectManager->addSharedInstance($logger, LoggerInterface::class, true); return $logger; } /** * Initialize application * * @param array $overriddenParams * @return void */ public function initialize($overriddenParams = []) { $overriddenParams[\Magento\Framework\App\State::PARAM_MODE] = $this->_appMode; $overriddenParams = $this->_customizeParams($overriddenParams); $directories = isset($overriddenParams[\Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS]) ? $overriddenParams[\Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] : []; $directoryList = new DirectoryList(BP, $directories); /** @var TestFramework\ObjectManager $objectManager */ $objectManager = Helper\Bootstrap::getObjectManager(); if (!$objectManager) { $objectManager = $this->_factory->create($overriddenParams); $objectManager->addSharedInstance( $directoryList, DirectoryList::class ); $objectManager->addSharedInstance( $directoryList, \Magento\Framework\Filesystem\DirectoryList::class ); } else { $objectManager = $this->_factory->restore($objectManager, $directoryList, $overriddenParams); } /** @var TestFramework\App\Filesystem $filesystem */ $filesystem = $objectManager->get(TestFramework\App\Filesystem::class); $objectManager->removeSharedInstance(\Magento\Framework\Filesystem::class); $objectManager->addSharedInstance($filesystem, \Magento\Framework\Filesystem::class); Helper\Bootstrap::setObjectManager($objectManager); $this->initLogger(); $sequenceBuilder = $objectManager->get(TestFramework\Db\Sequence\Builder::class); $objectManager->addSharedInstance($sequenceBuilder, \Magento\SalesSequence\Model\Builder::class); $objectManagerConfiguration = [ 'preferences' => [ \Magento\Framework\App\State::class => TestFramework\App\State::class, Mail\TransportInterface::class => TestFramework\Mail\TransportInterfaceMock::class, Mail\Template\TransportBuilder::class => TestFramework\Mail\Template\TransportBuilderMock::class, ProcessorInterface::class => \Magento\TestFramework\Fixture\Data\CompositeProcessor::class, ] ]; if ($this->loadTestExtensionAttributes) { $objectManagerConfiguration = array_merge( $objectManagerConfiguration, [ \Magento\Framework\Api\ExtensionAttribute\Config\Reader::class => [ 'arguments' => [ 'fileResolver' => [ 'instance' => TestFramework\Api\Config\Reader\FileResolver::class ], ], ], ] ); } $objectManager->configure($objectManagerConfiguration); /** Register event observer of Integration Framework */ /** @var \Magento\Framework\Event\Config\Data $eventConfigData */ $eventConfigData = $objectManager->get(\Magento\Framework\Event\Config\Data::class); $eventConfigData->merge( [ 'core_app_init_current_store_after' => [ 'integration_tests' => [ 'instance' => TestFramework\Event\Magento::class, 'name' => 'integration_tests' ] ] ] ); if ($this->canLoadArea) { $this->loadArea(TestFramework\Application::DEFAULT_APP_AREA); } TestFramework\Helper\Bootstrap::getObjectManager()->configure( $objectManager->get(\Magento\Framework\ObjectManager\DynamicConfigInterface::class)->getConfiguration() ); \Magento\Framework\Phrase::setRenderer( $objectManager->get(\Magento\Framework\Phrase\Renderer\Placeholder::class) ); if ($this->canInstallSequence) { /** @var TestFramework\Db\Sequence $sequence */ $sequence = $objectManager->get(\Magento\TestFramework\Db\Sequence::class); $sequence->generateSequences(); } $objectManager->create(\Magento\TestFramework\Config::class, ['configPath' => $this->globalConfigFile]) ->rewriteAdditionalConfig(); } /** * Reset and initialize again an already installed application * * @param array $overriddenParams * @return void */ public function reinitialize(array $overriddenParams = []) { $this->_resetApp(); $this->initialize($overriddenParams); } /** * Run application normally, but with encapsulated initialization options * * @return void */ public function run() { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var \Magento\Framework\App\Http $app */ $app = $objectManager->get(\Magento\Framework\App\Http::class); $response = $app->launch(); $response->sendResponse(); } /** * Create install dir for integration framework * * @return void */ public function createInstallDir() { $this->_ensureDirExists($this->installDir); $this->_ensureDirExists($this->_configDir); $this->copyAppConfigFiles(); } /** * Cleanup both the database and the file system * * @return void */ public function cleanup() { $this->createInstallDir(); /** * @see \Magento\Setup\Mvc\Bootstrap\InitParamListener::BOOTSTRAP_PARAM */ $this->_shell->execute( PHP_BINARY . ' -f %s setup:uninstall -vvv -n --magento-init-params=%s', [BP . '/bin/magento', $this->getInitParamsQuery()] ); } /** * Install an application * * @param bool $cleanup * @return void * @throws \Magento\Framework\Exception\LocalizedException */ public function install($cleanup) { $dirs = \Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS; $this->_ensureDirExists($this->installDir); $this->_ensureDirExists($this->_configDir); $this->_ensureDirExists($this->_initParams[$dirs][DirectoryList::PUB][DirectoryList::PATH]); $this->_ensureDirExists($this->_initParams[$dirs][DirectoryList::MEDIA][DirectoryList::PATH]); $this->_ensureDirExists($this->_initParams[$dirs][DirectoryList::STATIC_VIEW][DirectoryList::PATH]); $this->_ensureDirExists($this->_initParams[$dirs][DirectoryList::VAR_DIR][DirectoryList::PATH]); $this->copyAppConfigFiles(); $this->copyGlobalConfigFile(); $installParams = $this->getInstallCliParams(); // performance optimization: restore DB from last good dump to make installation on top of it (much faster) // do not restore from the database if the cleanup option is set to ensure we have a clean DB to test on $db = $this->getDbInstance(); if ($db->isDbDumpExists() && !$cleanup) { $db->restoreFromDbDump(); } // run install script $this->_shell->execute( PHP_BINARY . ' -f %s setup:install -vvv ' . implode(' ', array_keys($installParams)), array_merge([BP . '/bin/magento'], array_values($installParams)) ); $this->runPostInstallCommands(); // enable only specified list of caches $initParamsQuery = $this->getInitParamsQuery(); $this->_shell->execute( PHP_BINARY . ' -f %s cache:disable -vvv --bootstrap=%s', [BP . '/bin/magento', $initParamsQuery] ); $this->_shell->execute( PHP_BINARY . ' -f %s cache:enable -vvv %s %s %s %s --bootstrap=%s', [ BP . '/bin/magento', \Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER, \Magento\Framework\App\Cache\Type\Layout::TYPE_IDENTIFIER, \Magento\Framework\App\Cache\Type\Translate::TYPE_IDENTIFIER, \Magento\Eav\Model\Cache\Type::TYPE_IDENTIFIER, $initParamsQuery, ] ); // right after a clean installation, store DB dump for future reuse in tests or running the test suite again if (!$db->isDbDumpExists() && $this->dumpDb) { $this->getDbInstance()->storeDbDump(); } } /** * Run commands after installation configured in post-install-setup-command-config.php * * @throws \Magento\Framework\Exception\LocalizedException */ protected function runPostInstallCommands() { // run post-install setup commands $postInstallSetupCommands = $this->getPostInstallSetupCommands(); foreach ($postInstallSetupCommands as $postInstallSetupCommand) { if (!isset($postInstallSetupCommand['command'])) { throw new DomainException('"command" must be present in post install setup command arrays'); } $command = $postInstallSetupCommand['command']; $argumentsAndOptions = $postInstallSetupCommand['config']; $argumentsAndOptionsPlaceholders = []; foreach (array_keys($argumentsAndOptions) as $key) { $isArgument = is_numeric($key); if ($isArgument) { $argumentsAndOptionsPlaceholders[] = '%s'; } else { $argumentsAndOptionsPlaceholders[] = "$key=%s"; } } $argumentsAndOptionsPlaceholders[] = "--magento-init-params=%s"; $argumentsAndOptions[] = $this->getInitParamsQuery(); $this->_shell->execute( PHP_BINARY . ' -f %s %s -vvv ' . implode(' ', array_values($argumentsAndOptionsPlaceholders)), // phpcs:ignore Magento2.Performance.ForeachArrayMerge array_merge( [BP . '/bin/magento'], [$command], array_values($argumentsAndOptions) ), ); } } /** * Copies configuration files from the main code base, so the installation could proceed in the tests directory * * @return void */ private function copyAppConfigFiles() { $globalConfigFiles = Glob::glob( $this->_globalConfigDir . '/{di.xml,*/di.xml,db_schema.xml,vendor_path.php}', Glob::GLOB_BRACE ); foreach ($globalConfigFiles as $file) { $targetFile = $this->_configDir . str_replace($this->_globalConfigDir, '', $file); // phpcs:ignore Magento2.Functions.DiscouragedFunction $this->_ensureDirExists(dirname($targetFile)); if ($file !== $targetFile) { // phpcs:ignore Magento2.Functions.DiscouragedFunction copy($file, $targetFile); } } } /** * Copies global configuration file from the tests folder (see TESTS_GLOBAL_CONFIG_FILE) * * @return void */ private function copyGlobalConfigFile() { $targetFile = $this->_configDir . '/config.local.php'; // phpcs:ignore Magento2.Functions.DiscouragedFunction copy($this->globalConfigFile, $targetFile); } /** * Gets a list of CLI params for installation * * @return array */ private function getInstallCliParams() { $params = $this->getInstallConfig(); /** * Literal value is used instead of constant, because autoloader is not integrated with Magento Setup app * @see \Magento\Setup\Mvc\Bootstrap\InitParamListener::BOOTSTRAP_PARAM */ $params['magento-init-params'] = $this->getInitParamsQuery(); $result = []; foreach ($params as $key => $value) { if (isset($value)) { $result["--{$key}=%s"] = $value; } } return $result; } /** * Encodes init params into a query string * * @return string */ private function getInitParamsQuery() { return urldecode(http_build_query($this->_initParams)); } /** * Sub-routine for merging custom parameters with the ones defined in object state * * @param array $params * @return array */ public function _customizeParams($params) { return array_replace_recursive($this->_initParams, $params); } /** * Reset application global state */ protected function _resetApp() { /** @var $objectManager \Magento\TestFramework\ObjectManager */ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $objectManager->clearCache(); \Magento\Framework\Data\Form::setElementRenderer(null); \Magento\Framework\Data\Form::setFieldsetRenderer(null); \Magento\Framework\Data\Form::setFieldsetElementRenderer(null); $this->_appArea = null; } /** * Create a directory with write permissions or don't touch existing one * * @param string $dir * @return void * @throws \Magento\Framework\Exception\LocalizedException */ protected function _ensureDirExists($dir) { // phpcs:ignore Magento2.Functions.DiscouragedFunction if (!file_exists($dir)) { $old = umask(0); // phpcs:ignore Magento2.Functions.DiscouragedFunction mkdir($dir, 0777, true); umask($old); // phpcs:ignore Magento2.Functions.DiscouragedFunction } elseif (!is_dir($dir)) { throw new \Magento\Framework\Exception\LocalizedException(__("'%1' is not a directory.", $dir)); } } /** * Ge current application area * * @return string */ public function getArea() { return $this->_appArea; } /** * Load application area * * @param string $areaCode * @return void * @throws \Magento\Framework\Exception\LocalizedException */ public function loadArea($areaCode) { $this->_appArea = $areaCode; $scope = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\Config\Scope::class ); $scope->setCurrentScope($areaCode); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->configure( \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\App\ObjectManager\ConfigLoader::class )->load( $areaCode ) ); $app = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\AreaList::class); $areasForPartialLoading = [ \Magento\Framework\App\Area::AREA_GLOBAL, \Magento\Framework\App\Area::AREA_WEBAPI_REST, \Magento\Framework\App\Area::AREA_WEBAPI_SOAP, \Magento\Framework\App\Area::AREA_CRONTAB, \Magento\Framework\App\Area::AREA_GRAPHQL ]; if (in_array($areaCode, $areasForPartialLoading, true)) { $app->getArea($areaCode)->load(\Magento\Framework\App\Area::PART_CONFIG); } else { \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($areaCode); } } /** * Gets customized directory paths * * @return array */ protected function getCustomDirs() { $path = DirectoryList::PATH; $var = "{$this->installDir}/var"; $generated = "{$this->installDir}/generated"; $customDirs = [ DirectoryList::CONFIG => [$path => "{$this->installDir}/etc"], DirectoryList::VAR_DIR => [$path => $var], DirectoryList::VAR_EXPORT => [$path => "{$var}/export"], DirectoryList::MEDIA => [$path => "{$this->installDir}/pub/media"], DirectoryList::STATIC_VIEW => [$path => "{$this->installDir}/pub/static"], DirectoryList::TMP_MATERIALIZATION_DIR => [$path => "{$var}/view_preprocessed/pub/static"], DirectoryList::GENERATED_CODE => [$path => "{$generated}/code"], DirectoryList::CACHE => [$path => "{$var}/cache"], DirectoryList::LOG => [$path => "{$var}/log"], DirectoryList::SESSION => [$path => "{$var}/session"], DirectoryList::TMP => [$path => "{$var}/tmp"], DirectoryList::UPLOAD => [$path => "{$var}/upload"], DirectoryList::PUB => [$path => "{$this->installDir}/pub"], DirectoryList::VAR_IMPORT_EXPORT => [$path => "{$this->installDir}/var"], ]; return $customDirs; } }