diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 7a7b6968b2..8a568673ff 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -23,6 +23,7 @@ jobs:
composer config --unset repositories.repo.magento.com
composer remove --no-update magento/magento-cloud-components
composer remove --no-update magento/magento-cloud-docker
+ composer remove --no-update magento/quality-patches
composer remove --no-update magento/magento-cloud-patches
- name: Composer Update
run: composer update
diff --git a/.travis.yml b/.travis.yml
index aa9361e777..8aa596c185 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,7 +43,13 @@ jobs:
- php: '7.4'
env: TEST_SUITE=functional-ee
+before_install:
+# https://github.com/kylekatarnls/update-helper/issues/9
+ - if [ -n "${COMPOSER_VERSION}" ]; then travis_retry composer self-update ${COMPOSER_VERSION}; fi;
+
+
install:
+ - phpenv config-add travis.php.ini
- composer config http-basic.repo.magento.com ${REPO_USERNAME_CE} ${REPO_PASSWORD_CE}
- composer config github-oauth.github.com ${GITHUB_TOKEN}
- if [ -n "${MCC_VERSION}" ]; then composer config repositories.mcc git git@github.com:magento/magento-cloud-components.git && composer require "magento/magento-cloud-components:${MCC_VERSION}" --no-update; fi;
diff --git a/codeception.dist.yml b/codeception.dist.yml
index 2badeb2381..2549c69fb9 100644
--- a/codeception.dist.yml
+++ b/codeception.dist.yml
@@ -24,6 +24,7 @@ modules:
composer_magento_username: "%REPO_USERNAME%"
composer_magento_password: "%REPO_PASSWORD%"
composer_github_token: "%GITHUB_TOKEN%"
+ use_cached_workdir: true
printOutput: false
Magento\CloudDocker\Test\Functional\Codeception\Docker:
system_magento_dir: "%Magento.docker.settings.system.magento_dir%"
diff --git a/composer.json b/composer.json
index fd950ee5f0..aedd0cde83 100755
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"name": "magento/ece-tools",
"description": "Provides tools to build and deploy Magento 2 Enterprise Edition",
"type": "magento2-component",
- "version": "2002.1.2",
+ "version": "2002.1.3",
"license": "OSL-3.0",
"repositories": {
"repo.magento.com": {
@@ -24,6 +24,7 @@
"magento/magento-cloud-components": "^1.0.6",
"magento/magento-cloud-docker": "^1.0.0",
"magento/magento-cloud-patches": "^1.0.6",
+ "magento/quality-patches": "^1.0.3",
"monolog/monolog": "^1.16",
"nesbot/carbon": "^1.0||^2.0",
"psr/container": "^1.0",
diff --git a/config/schema.error.yaml b/config/schema.error.yaml
index 137685c180..af34cc9651 100644
--- a/config/schema.error.yaml
+++ b/config/schema.error.yaml
@@ -174,7 +174,7 @@
type: critical
!php/const Magento\MagentoCloud\App\Error::DEPLOY_REDIS_CACHE_CLEAN_FAILED:
title: 'Failed to clean the Redis cache'
- suggestion: 'Failed to clean the Redis cache. Check that the Redis cache configuration is correct and that the Redis service is available. See [Setup Redis service](https://devdocs.magento.com/cloud/project/project-conf-files_services-redis.html).'
+ suggestion: 'Failed to clean the Redis cache. Check that the Redis cache configuration is correct and that the Redis service is available. See [Setup Redis service](https://devdocs.magento.com/cloud/project/services-redis.html).'
step: 'pre-deploy: clean-redis-cache'
stage: deploy
type: critical
@@ -322,7 +322,7 @@
type: critical
!php/const Magento\MagentoCloud\App\Error::DEPLOY_ES_CANNOT_CONNECT:
title: 'Can not connect to the Elasticsearch service'
- suggestion: 'Check that credentials for elasticsearch are correct and service is running'
+ suggestion: 'Check for valid Elasticsearch credentials and verify that the service is running'
stage: deploy
type: critical
!php/const Magento\MagentoCloud\App\Error::DEPLOY_WRONG_BRAINTREE_VARIABLE:
@@ -331,12 +331,18 @@
suggestion: 'Support for the Braintree module is no longer included with Magento 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the .magento.app.yaml file. For Braintree support, use an official Braintree Payments extension from the Magento Marketplace instead.'
stage: deploy
type: critical
-!php/const Magento\MagentoCloud\App\Error::DEPLOY_WRONG_SEARCH_ENGINE:
+!php/const Magento\MagentoCloud\App\Error::DEPLOY_ES_SERVICE_NOT_INSTALLED:
step: validate-config
title: 'Magento 2.4.0 requires Elasticsearch service to be installed'
suggestion: 'Install Elasticsearch service'
stage: deploy
type: critical
+!php/const Magento\MagentoCloud\App\Error::DEPLOY_WRONG_SEARCH_ENGINE:
+ step: validate-config
+ title: 'The search engine must be set to Elasticsearch for Magento >= 2.4.0'
+ suggestion: 'Check the SEARCH_CONFIGURATION variable for the `engine` option. If it is configured, remove the option, or set the value to "elasticsearch".'
+ stage: deploy
+ type: critical
!php/const Magento\MagentoCloud\App\Error::PD_DEPLOY_IS_FAILED:
step: is-deploy-failed
title: 'Deploy stage failed'
@@ -577,6 +583,12 @@
suggestion: 'Check the `cloud.log` for more information.'
step: 'pre-deploy:restore-writable-dirs'
type: warning
+!php/const Magento\MagentoCloud\App\Error::WARN_NOT_SUPPORTED_MAGE_MODE:
+ title: 'Mode value for MAGE_MODE environment variable not supported'
+ stage: deploy
+ suggestion: 'Remove the MAGE_MODE environment variable, or change its value to "production". Magento Cloud supports "production" mode only.'
+ step: 'validate-config:mage-mode-variable'
+ type: warning
!php/const Magento\MagentoCloud\App\Error::WARN_DEBUG_LOG_ENABLED:
title: 'Debug logging is enabled in Magento'
suggestion: 'To save disk space, do not enable debug logging for your production environments.'
diff --git a/config/schema.yaml b/config/schema.yaml
index 5d2748b05c..2fd628c61e 100644
--- a/config/schema.yaml
+++ b/config/schema.yaml
@@ -176,6 +176,17 @@ variables:
- stage:
global:
SKIP_HTML_MINIFICATION: true
+ SKIP_COMPOSER_DUMP_AUTOLOAD:
+ description: Skip running compose dump-autoload command
+ type: boolean
+ stages:
+ - build
+ default:
+ build: false
+ examples:
+ - stage:
+ build:
+ SKIP_COMPOSER_DUMP_AUTOLOAD: true
SCD_ON_DEMAND:
description: Enable generation of static content when requested by a user.
Pre-loading the cache using the post_deploy hook reduces site downtime.
diff --git a/dist/error-codes.md b/dist/error-codes.md
index 46d3fbef4c..8477a4aa4e 100644
--- a/dist/error-codes.md
+++ b/dist/error-codes.md
@@ -46,7 +46,7 @@ Critical errors indicate a problem with the Magento Commerce Cloud project confi
| 104 | | Failed to parse the `.magento.env.yaml` file | Configuration is not defined in the `./vendor/magento/ece-tools/config/schema.yaml` file. Check that the config variable name is correct, and that it is defined. |
| 105 | | Unable to read the `.magento.env.yaml` file | Unable to read the `./.magento.env.yaml` file. Check file permissions. |
| 106 | | Unable to read the `.schema.yaml` file | |
-| 107 | pre-deploy: clean-redis-cache | Failed to clean the Redis cache | Failed to clean the Redis cache. Check that the Redis cache configuration is correct and that the Redis service is available. See [Setup Redis service](https://devdocs.magento.com/cloud/project/project-conf-files_services-redis.html). |
+| 107 | pre-deploy: clean-redis-cache | Failed to clean the Redis cache | Failed to clean the Redis cache. Check that the Redis cache configuration is correct and that the Redis service is available. See [Setup Redis service](https://devdocs.magento.com/cloud/project/services-redis.html). |
| 108 | pre-deploy: set-production-mode | Command `/bin/magento maintenance:enable` failed | Check the `cloud.log` for more information. For more detailed command output, add the `VERBOSE_COMMANDS: '-vvv'` option to the `.magento.env.yaml` file. |
| 109 | validate-config | Incorrect database configuration | Check that the the `DATABASE_CONFIGURATION` environment variable is configured correctly. |
| 110 | validate-config | Incorrect session configuration | Check that the `SESSION_CONFIGURATION` environment variable is configured correctly. The configuration must contain at least the `save` parameter. |
@@ -71,9 +71,10 @@ Critical errors indicate a problem with the Magento Commerce Cloud project confi
| 129 | install-update: reset-password | Unable to read reset password template | |
| 130 | install-update: cache_type | Command failed: `php ./bin/magento cache:enable` | Command `php ./bin/magento cache:enable` runs only when Magento was installed but `./app/etc/env.php` file was absent or empty at the beginning of the deployment. Check the `cloud.log` for more information. Add `VERBOSE_COMMANDS: '-vvv'` into `.magento.env.yaml` for more detailed command output. |
| 131 | install-update | The `crypt/key` key value does not exist in the `./app/etc/env.php` file or the `CRYPT_KEY` cloud environment variable | This error occurs if the `./app/etc/env.php` file is not present when Magento deployment begins, or if the `crypt/key` value is undefined. If you migrated the database from another environment, retrieve the crypt key value from that environment. Then, add the value to the [CRYPT_KEY](https://devdocs.magento.com/cloud/env/variables-deploy.html#crypt_key) cloud environment variable in your current environment. See [Add the Magento encryption key](https://devdocs.magento.com/cloud/setup/first-time-setup-import-import.html#encryption-key). If you accidentally removed the `./app/etc/env.php` file, use the following command to restore it from the backup files created from a previous deployment: `./vendor/bin/ece-tools backup:restore` CLI command ." |
-| 132 | | Can not connect to the Elasticsearch service | Check that credentials for elasticsearch are correct and service is running |
+| 132 | | Can not connect to the Elasticsearch service | Check for valid Elasticsearch credentials and verify that the service is running |
| 133 | validate-config | Remove Magento Braintree module configuration which is no longer supported in Magento 2.4 and later versions. | Support for the Braintree module is no longer included with Magento 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the .magento.app.yaml file. For Braintree support, use an official Braintree Payments extension from the Magento Marketplace instead. |
| 134 | validate-config | Magento 2.4.0 requires Elasticsearch service to be installed | Install Elasticsearch service |
+| 135 | validate-config | The search engine must be set to Elasticsearch for Magento >= 2.4.0 | Check the SEARCH_CONFIGURATION variable for the `engine` option. If it is configured, remove the option, or set the value to "elasticsearch". |
### Post-deploy stage
@@ -147,7 +148,8 @@ Warning errors indicate a problem with the Magento Commerce Cloud project config
| 2023 | install-update:split-db | Enabling a split database will be skipped. | |
| 2024 | install-update:split-db | The SPLIT_DB variable is missing the configuration for split connection types. | |
| 2025 | install-update:split-db | Slave connection not set. | |
-| 2026 | pre-deploy:restore-writable-dirs | Failed to restore some data generated data during the build phase to the mounted directories. | Check the `cloud.log` for more information. |
+| 2026 | pre-deploy:restore-writable-dirs | Failed to restore some data generated during the build phase to the mounted directories | Check the `cloud.log` for more information. |
+| 2027 | validate-config:mage-mode-variable | Mode value for MAGE_MODE environment variable not supported | Remove the MAGE_MODE environment variable, or change its value to "production". Magento Cloud supports "production" mode only. |
### Post-deploy stage
diff --git a/scenario/deploy.xml b/scenario/deploy.xml
index 5e9e719762..f4d990db8f 100644
--- a/scenario/deploy.xml
+++ b/scenario/deploy.xml
@@ -33,6 +33,7 @@
- Magento\MagentoCloud\Config\Validator\Deploy\ElasticSuiteIntegrity
-
+
- Magento\MagentoCloud\Config\Validator\Deploy\MageModeVariable
- Magento\MagentoCloud\Config\Validator\Deploy\DatabaseSplitConnection
- Magento\MagentoCloud\Config\Validator\Deploy\ReportDirNestingLevel
- Magento\MagentoCloud\Config\Validator\Deploy\AdminData
diff --git a/src/App/Error.php b/src/App/Error.php
index 7b478c942a..79d726fe4c 100644
--- a/src/App/Error.php
+++ b/src/App/Error.php
@@ -73,7 +73,8 @@ class Error
public const DEPLOY_CRYPT_KEY_IS_ABSENT = 131;
public const DEPLOY_ES_CANNOT_CONNECT = 132;
public const DEPLOY_WRONG_BRAINTREE_VARIABLE = 133;
- public const DEPLOY_WRONG_SEARCH_ENGINE = 134;
+ public const DEPLOY_ES_SERVICE_NOT_INSTALLED = 134;
+ public const DEPLOY_WRONG_SEARCH_ENGINE = 135;
public const PD_DEPLOY_IS_FAILED = 201;
public const PD_ENV_PHP_IS_NOT_WRITABLE = 202;
@@ -130,6 +131,7 @@ class Error
public const WARN_NOT_ENOUGH_DATA_SPLIT_DB_VAR = 2024;
public const WARN_SLAVE_CONNECTION_NOT_SET = 2025;
public const WARN_COPY_MOUNTED_DIRS_FAILED = 2026;
+ public const WARN_NOT_SUPPORTED_MAGE_MODE = 2027;
/**
* Post-deploy
diff --git a/src/Application.php b/src/Application.php
index ff0c510c9e..cda00402bc 100644
--- a/src/Application.php
+++ b/src/Application.php
@@ -75,6 +75,8 @@ protected function getDefaultCommands()
$this->container->create(Command\CronKill::class),
$this->container->create(Command\CronUnlock::class),
$this->container->create(Command\ConfigShow::class),
+ $this->container->create(Command\ConfigCreate::class),
+ $this->container->create(Command\ConfigUpdate::class),
$this->container->create(Command\RunCommand::class),
$this->container->create(Command\GenerateSchema::class),
$this->container->create(Command\ErrorShow::class)
diff --git a/src/Command/ApplyPatches.php b/src/Command/ApplyPatches.php
index d4c5c70539..f8802358c2 100644
--- a/src/Command/ApplyPatches.php
+++ b/src/Command/ApplyPatches.php
@@ -43,7 +43,7 @@ public function __construct(Manager $manager)
protected function configure(): void
{
$this->setName(self::NAME)
- ->setDescription('Applies custom patches');
+ ->setDescription('Applies custom patches.');
parent::configure();
}
diff --git a/src/Command/BackupList.php b/src/Command/BackupList.php
index 4ae77d40e6..efa4d9ffed 100644
--- a/src/Command/BackupList.php
+++ b/src/Command/BackupList.php
@@ -55,7 +55,7 @@ public function __construct(
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Shows the list of backup files');
+ ->setDescription('Shows the list of backup files.');
parent::configure();
}
diff --git a/src/Command/BackupRestore.php b/src/Command/BackupRestore.php
index 323b9399a3..53e3ada4fe 100644
--- a/src/Command/BackupRestore.php
+++ b/src/Command/BackupRestore.php
@@ -54,7 +54,9 @@ public function __construct(Restore $restore, LoggerInterface $logger)
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Restore important configuration files. Run backup:list to show the list of backup files');
+ ->setDescription(
+ 'Restore important configuration files. Run backup:list to show the list of backup files.'
+ );
$this->addOption(
'force',
'f',
diff --git a/src/Command/Build.php b/src/Command/Build.php
index 0c6cd4e3cf..445c05cc4c 100755
--- a/src/Command/Build.php
+++ b/src/Command/Build.php
@@ -28,7 +28,7 @@ class Build extends Command
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Builds application');
+ ->setDescription('Builds application.');
parent::configure();
}
diff --git a/src/Command/Build/Generate.php b/src/Command/Build/Generate.php
index 6a3bc8aca1..1b4634c401 100644
--- a/src/Command/Build/Generate.php
+++ b/src/Command/Build/Generate.php
@@ -44,7 +44,7 @@ public function __construct(Processor $processor)
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Generates all necessary files for build stage');
+ ->setDescription('Generates all necessary files for build stage.');
parent::configure();
}
diff --git a/src/Command/Build/Transfer.php b/src/Command/Build/Transfer.php
index 8ebb1ea955..bbdc7111a8 100644
--- a/src/Command/Build/Transfer.php
+++ b/src/Command/Build/Transfer.php
@@ -43,7 +43,7 @@ public function __construct(Processor $processor)
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Transfer generated files into init directory');
+ ->setDescription('Transfers generated files into init directory.');
parent::configure();
}
diff --git a/src/Command/ConfigCreate.php b/src/Command/ConfigCreate.php
new file mode 100644
index 0000000000..99e012a182
--- /dev/null
+++ b/src/Command/ConfigCreate.php
@@ -0,0 +1,88 @@
+configFileList = $configFileList;
+ $this->file = $file;
+
+ parent::__construct();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function configure()
+ {
+ $this->setName(static::NAME)
+ ->setDescription(
+ 'Creates a `.magento.env.yaml` file with the specified build, deploy, and post-deploy variable ' .
+ 'configuration. Overwrites any existing `.magento,.env.yaml` file.'
+ )
+ ->addArgument(
+ self::ARG_CONFIGURATION,
+ InputArgument::REQUIRED,
+ 'Configuration in JSON format'
+ );
+
+ parent::configure();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function execute(InputInterface $input, OutputInterface $output)
+ {
+ $configuration = $input->getArgument(self::ARG_CONFIGURATION);
+
+ $decodedConfig = json_decode($configuration, true);
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new \Exception('Wrong JSON format: ' . json_last_error_msg());
+ }
+
+ $yaml = Yaml::dump($decodedConfig, 10, 2);
+ $filePath = $this->configFileList->getEnvConfig();
+
+ $this->file->filePutContents($filePath, $yaml);
+
+ $output->writeln(sprintf("Config file %s was created", $filePath));
+ }
+}
diff --git a/src/Command/ConfigShow.php b/src/Command/ConfigShow.php
index 4e70711773..4fbb6d6f7b 100644
--- a/src/Command/ConfigShow.php
+++ b/src/Command/ConfigShow.php
@@ -66,7 +66,7 @@ public function __construct(
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Display encoded cloud configuration environment variables')
+ ->setDescription('Display encoded cloud configuration environment variables.')
->addArgument(
'variable',
InputArgument::IS_ARRAY,
diff --git a/src/Command/ConfigUpdate.php b/src/Command/ConfigUpdate.php
new file mode 100644
index 0000000000..0b69146684
--- /dev/null
+++ b/src/Command/ConfigUpdate.php
@@ -0,0 +1,98 @@
+configFileList = $configFileList;
+ $this->file = $file;
+ $this->reader = $reader;
+
+ parent::__construct();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function configure()
+ {
+ $this->setName(static::NAME)
+ ->setDescription(
+ 'Updates the existing `.magento.env.yaml` file with the specified configuration. ' .
+ 'Creates `.magento.env.yaml` file if it does not exist.'
+ )
+ ->addArgument(
+ self::ARG_CONFIGURATION,
+ InputArgument::REQUIRED,
+ 'Configuration in JSON format'
+ );
+
+ parent::configure();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function execute(InputInterface $input, OutputInterface $output)
+ {
+ $configuration = $input->getArgument(self::ARG_CONFIGURATION);
+
+ $decodedConfig = json_decode($configuration, true);
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new \Exception('Wrong JSON format: ' . json_last_error_msg());
+ }
+
+ $config = array_replace_recursive($this->reader->read(), $decodedConfig);
+
+ $yaml = Yaml::dump($config, 10, 2);
+ $filePath = $this->configFileList->getEnvConfig();
+
+ $this->file->filePutContents($filePath, $yaml);
+
+ $output->writeln(sprintf("Config file %s was updated", $filePath));
+ }
+}
diff --git a/src/Command/CronDisable.php b/src/Command/CronDisable.php
index b49be3e92a..470c4e8fec 100644
--- a/src/Command/CronDisable.php
+++ b/src/Command/CronDisable.php
@@ -60,7 +60,7 @@ public function __construct(
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Disable all Magento cron processes and kills currently running');
+ ->setDescription('Disable all Magento cron processes and terminates all running processes.');
parent::configure();
}
diff --git a/src/Command/CronEnable.php b/src/Command/CronEnable.php
index 501456efdd..4a321640d2 100644
--- a/src/Command/CronEnable.php
+++ b/src/Command/CronEnable.php
@@ -49,7 +49,7 @@ public function __construct(Switcher $cronSwitcher, LoggerInterface $logger)
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Enable Magento cron processes');
+ ->setDescription('Enables Magento cron processes.');
parent::configure();
}
diff --git a/src/Command/CronKill.php b/src/Command/CronKill.php
index 16277c344d..388e81a604 100644
--- a/src/Command/CronKill.php
+++ b/src/Command/CronKill.php
@@ -42,7 +42,7 @@ public function __construct(BackgroundProcess $backgroundProcess)
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Kill all Magento cron processes');
+ ->setDescription('Terminates all Magento cron processes.');
parent::configure();
}
diff --git a/src/Command/DbDump.php b/src/Command/DbDump.php
index e0baec754c..58b006132f 100644
--- a/src/Command/DbDump.php
+++ b/src/Command/DbDump.php
@@ -60,7 +60,7 @@ public function __construct(
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Creates backups of databases');
+ ->setDescription('Creates database backups.');
$this->addArgument(
self::ARGUMENT_DATABASES,
InputArgument::IS_ARRAY,
diff --git a/src/Command/Deploy.php b/src/Command/Deploy.php
index 6dc506afee..e6f6adf85e 100755
--- a/src/Command/Deploy.php
+++ b/src/Command/Deploy.php
@@ -52,7 +52,7 @@ public function __construct(Processor $processor, Manager $flagManager)
protected function configure()
{
$this->setName(static::NAME)
- ->setDescription('Deploys application');
+ ->setDescription('Deploys the application.');
parent::configure();
}
diff --git a/src/Command/Dev/GenerateSchemaError.php b/src/Command/Dev/GenerateSchemaError.php
index 6a38625677..22b7c15a66 100644
--- a/src/Command/Dev/GenerateSchemaError.php
+++ b/src/Command/Dev/GenerateSchemaError.php
@@ -51,6 +51,7 @@ class GenerateSchemaError extends Command
width: 200px;
}
+
EOT;
/**
@@ -72,7 +73,7 @@ public function __construct(File $file, FileList $fileList)
protected function configure(): void
{
$this->setName(static::NAME)
- ->setDescription('Generates dist/error-codes.md file from schema.error.yaml');
+ ->setDescription('Generates the dist/error-codes.md file from the schema.error.yaml file.');
parent::configure();
}
diff --git a/src/Command/ErrorShow.php b/src/Command/ErrorShow.php
index 54e2320068..d73ac1a5e0 100644
--- a/src/Command/ErrorShow.php
+++ b/src/Command/ErrorShow.php
@@ -53,7 +53,7 @@ public function __construct(ErrorInfo $errorInfo, ReaderInterface $reader)
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Display info about error by error id or info about all errors from the last deployment')
+ ->setDescription('Displays info about error by error id or info about all errors from the last deployment.')
->addArgument(
self::ARGUMENT_ERROR_CODE,
InputArgument::OPTIONAL,
diff --git a/src/Command/GenerateSchema.php b/src/Command/GenerateSchema.php
index b2c10013ed..9bfa53808a 100644
--- a/src/Command/GenerateSchema.php
+++ b/src/Command/GenerateSchema.php
@@ -68,7 +68,7 @@ public function __construct(
*/
protected function configure(): void
{
- $this->setDescription('Generate the schema dist file');
+ $this->setDescription('Generates the schema *.dist file.');
parent::configure();
}
diff --git a/src/Command/ModuleRefresh.php b/src/Command/ModuleRefresh.php
index 702e1f3282..3fabdbacbc 100644
--- a/src/Command/ModuleRefresh.php
+++ b/src/Command/ModuleRefresh.php
@@ -44,7 +44,7 @@ public function __construct(Module $module)
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Refresh config to enable newly added modules');
+ ->setDescription('Refreshes the configuration to enable newly added modules.');
}
/**
diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php
index 91046b5e22..b594ce9a52 100644
--- a/src/Command/RunCommand.php
+++ b/src/Command/RunCommand.php
@@ -44,7 +44,7 @@ public function __construct(Processor $processor)
*/
protected function configure()
{
- $this->setDescription('Execute scenario(s)')
+ $this->setDescription('Execute scenario(s).')
->addArgument(
self::ARG_SCENARIO,
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
diff --git a/src/Command/Wizard/IdealState.php b/src/Command/Wizard/IdealState.php
index 8ef2b2189e..a6e96271ac 100644
--- a/src/Command/Wizard/IdealState.php
+++ b/src/Command/Wizard/IdealState.php
@@ -52,7 +52,7 @@ public function __construct(OutputFormatter $outputFormatter, IdealStateValidato
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Verifies ideal state of configuration');
+ ->setDescription('Verifies ideal state of configuration.');
parent::configure();
}
diff --git a/src/Command/Wizard/MasterSlave.php b/src/Command/Wizard/MasterSlave.php
index 8239626040..8d9b9e5747 100644
--- a/src/Command/Wizard/MasterSlave.php
+++ b/src/Command/Wizard/MasterSlave.php
@@ -50,7 +50,7 @@ public function __construct(OutputFormatter $outputFormatter, DeployInterface $d
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Verifies master-slave configuration');
+ ->setDescription('Verifies master-slave configuration.');
}
/**
diff --git a/src/Command/Wizard/ScdOnBuild.php b/src/Command/Wizard/ScdOnBuild.php
index 4d4b1792d7..1cf3cf123d 100644
--- a/src/Command/Wizard/ScdOnBuild.php
+++ b/src/Command/Wizard/ScdOnBuild.php
@@ -53,7 +53,7 @@ public function __construct(
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Verifies SCD on build configuration');
+ ->setDescription('Verifies SCD on build configuration.');
parent::configure();
}
diff --git a/src/Command/Wizard/ScdOnDemand.php b/src/Command/Wizard/ScdOnDemand.php
index aac8982276..19ebbd9e63 100644
--- a/src/Command/Wizard/ScdOnDemand.php
+++ b/src/Command/Wizard/ScdOnDemand.php
@@ -50,7 +50,7 @@ public function __construct(OutputFormatter $outputFormatter, GlobalSection $glo
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Verifies SCD on demand configuration');
+ ->setDescription('Verifies SCD on demand configuration.');
parent::configure();
}
diff --git a/src/Command/Wizard/ScdOnDeploy.php b/src/Command/Wizard/ScdOnDeploy.php
index 6aa8b0d954..57afac01eb 100644
--- a/src/Command/Wizard/ScdOnDeploy.php
+++ b/src/Command/Wizard/ScdOnDeploy.php
@@ -51,7 +51,7 @@ public function __construct(OutputFormatter $outputFormatter, ScdOnDeployValidat
protected function configure()
{
$this->setName(self::NAME)
- ->setDescription('Verifies SCD on deploy configuration');
+ ->setDescription('Verifies SCD on deploy configuration.');
}
/**
diff --git a/src/Config/Environment.php b/src/Config/Environment.php
index 7634d136be..01cb62ac35 100755
--- a/src/Config/Environment.php
+++ b/src/Config/Environment.php
@@ -24,6 +24,8 @@ class Environment
public const VAL_DISABLED = 'disabled';
public const VARIABLE_CRYPT_KEY = 'CRYPT_KEY';
+ public const MOUNT_PUB_STATIC = 'pub/static';
+
/**
* The environment variable for controlling the directory nesting level for error reporting
*/
@@ -151,4 +153,23 @@ public function isMasterBranch(): bool
return !empty($branchName)
&& preg_match(self::GIT_MASTER_BRANCH_RE, $branchName);
}
+
+ /**
+ * Checks whether application has specific mount.
+ *
+ * The name of the mount may have slash in the beginning (env variable)
+ * or does not have it. Method checks both cases.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function hasMount(string $name): bool
+ {
+ $application = $this->getApplication();
+
+ $name = ltrim($name, '/');
+ $slashName = '/' . $name;
+
+ return isset($application['mounts'][$name]) || isset($application['mounts'][$slashName]);
+ }
}
diff --git a/src/Config/EnvironmentData.php b/src/Config/EnvironmentData.php
index ec40a4abfb..cdc2672cde 100644
--- a/src/Config/EnvironmentData.php
+++ b/src/Config/EnvironmentData.php
@@ -136,23 +136,48 @@ public function getApplication(): array
return $this->data['application'];
}
- $application = $this->getEnvVar(SystemConfigInterface::VAR_ENV_APPLICATION, []);
+ $applicationEnvConfig = $this->getEnvVar(SystemConfigInterface::VAR_ENV_APPLICATION, []);
+ $applicationFileConfig = $this->readApplicationConfig();
- if (!$application) {
+ if (!$applicationEnvConfig) {
+ return $this->data['application'] = $applicationFileConfig;
+ }
+
+ /**
+ * Temporary fix for the case when environment data does not accurately represent file configuration.
+ *
+ * @url https://github.com/magento/magento-cloud-docker/issues/292
+ */
+ if (!isset($applicationEnvConfig['mounts']) && isset($applicationFileConfig['mounts'])) {
+ $applicationEnvConfig['mounts'] = $applicationFileConfig['mounts'];
+ }
+
+ return $this->data['application'] = $applicationEnvConfig;
+ }
+
+ /**
+ * Read file config file if exists.
+ *
+ * @return array
+ */
+ private function readApplicationConfig(): array
+ {
+ $configFile = $this->fileList->getAppConfig();
+
+ if ($this->file->isExists($configFile)) {
try {
- $application = Yaml::parse(
- $this->file->fileGetContents($this->fileList->getAppConfig())
- );
- } catch (FileSystemException $e) {
+ return Yaml::parse($this->file->fileGetContents($configFile));
+ } catch (FileSystemException $exception) {
// Do nothing as $application needs to be empty
}
}
- return $this->data['application'] = $application;
+ return [];
}
/**
* Returns name of environment branch
+ *
* @return string
*
*/
@@ -160,6 +185,18 @@ public function getBranchName(): string
{
$envVarName = $this->systemConfig->get(SystemConfigInterface::VAR_ENV_ENVIRONMENT);
- return $this->getEnv($envVarName) ? (string) $this->getEnv($envVarName) : '';
+ return $this->getEnv($envVarName) ? (string)$this->getEnv($envVarName) : '';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getMageMode(): ?string
+ {
+ if (isset($this->data['mage-mode'])) {
+ return $this->data['mage-mode'];
+ }
+
+ return $this->data['mage-mode'] = $this->getEnv('MAGE_MODE') ?: null;
}
}
diff --git a/src/Config/EnvironmentDataInterface.php b/src/Config/EnvironmentDataInterface.php
index a41275c8cd..946656d34d 100644
--- a/src/Config/EnvironmentDataInterface.php
+++ b/src/Config/EnvironmentDataInterface.php
@@ -56,4 +56,11 @@ public function getApplication(): array;
* @return string
*/
public function getBranchName(): string;
+
+ /**
+ * Returns MAGE_MODE environment variable
+ *
+ * @return string|null
+ */
+ public function getMageMode(): ?string;
}
diff --git a/src/Config/Stage/BuildInterface.php b/src/Config/Stage/BuildInterface.php
index 6b8f852b00..f8919dccdd 100644
--- a/src/Config/Stage/BuildInterface.php
+++ b/src/Config/Stage/BuildInterface.php
@@ -30,4 +30,9 @@ interface BuildInterface extends StageConfigInterface
* Magento quality patches list
*/
public const VAR_QUALITY_PATCHES = 'QUALITY_PATCHES';
+
+ /**
+ * Skip composer dump-autoload
+ */
+ public const VAR_SKIP_COMPOSER_DUMP_AUTOLOAD = 'SKIP_COMPOSER_DUMP_AUTOLOAD';
}
diff --git a/src/Config/Validator/Deploy/DatabaseSplitConnection.php b/src/Config/Validator/Deploy/DatabaseSplitConnection.php
index e7ec38889e..94c75ec2ed 100644
--- a/src/Config/Validator/Deploy/DatabaseSplitConnection.php
+++ b/src/Config/Validator/Deploy/DatabaseSplitConnection.php
@@ -63,15 +63,21 @@ public function validate(): Validator\ResultInterface
return $this->resultFactory->success();
}
- return $this->resultFactory->error(sprintf(
- 'Split database configuration was detected in the property %s'
- . ' of the file .magento.env.yaml:' . PHP_EOL
- . '%s' . PHP_EOL
- . 'Magento Cloud does not support a custom split database configuration,'
- . ' such configurations will be ignored',
- DeployInterface::VAR_DATABASE_CONFIGURATION,
- implode(PHP_EOL, $messageItem),
+ return $this->resultFactory->error(
+ sprintf(
+ 'Detected split database configuration in the %s property of the file .magento.env.yaml:' . PHP_EOL
+ . '%s' . PHP_EOL
+ . 'Magento Cloud does not support custom connections in the split database configuration,'
+ . ' Custom connections will be ignored',
+ DeployInterface::VAR_DATABASE_CONFIGURATION,
+ implode(PHP_EOL, $messageItem)
+ ),
+ sprintf(
+ 'Update the %s variable in the \'.magento.env.yaml\' file to remove custom connections '
+ . 'for split databases.',
+ DeployInterface::VAR_DATABASE_CONFIGURATION
+ ),
Error::WARN_WRONG_SPLIT_DB_CONFIG
- ));
+ );
}
}
diff --git a/src/Config/Validator/Deploy/ElasticSearchIntegrity.php b/src/Config/Validator/Deploy/ElasticSearchIntegrity.php
index 67f0fe1cd4..6095a179da 100644
--- a/src/Config/Validator/Deploy/ElasticSearchIntegrity.php
+++ b/src/Config/Validator/Deploy/ElasticSearchIntegrity.php
@@ -60,7 +60,7 @@ public function validate(): Validator\ResultInterface
if ($this->magentoVersion->isGreaterOrEqual('2.4.0')
&& !$this->elasticsearch->isInstalled()
) {
- return $this->resultFactory->errorByCode(Error::DEPLOY_WRONG_SEARCH_ENGINE);
+ return $this->resultFactory->errorByCode(Error::DEPLOY_ES_SERVICE_NOT_INSTALLED);
}
} catch (UndefinedPackageException | FileSystemException $exception) {
throw new ValidatorException($exception->getMessage(), $exception->getCode(), $exception);
diff --git a/src/Config/Validator/Deploy/ElasticSearchVersion.php b/src/Config/Validator/Deploy/ElasticSearchVersion.php
index 941a0a09d6..1630b69ac8 100644
--- a/src/Config/Validator/Deploy/ElasticSearchVersion.php
+++ b/src/Config/Validator/Deploy/ElasticSearchVersion.php
@@ -78,19 +78,9 @@ class ElasticSearchVersion implements ValidatorInterface
'esVersionRaw' => '6.x',
],
[
- 'packageVersion' => '>=7.0 <7.2',
- 'esVersion' => '>=7.0 <7.2',
- 'esVersionRaw' => '>=7.0 <7.2',
- ],
- [
- 'packageVersion' => '>=7.2 <7.4',
- 'esVersion' => '>=7.2 <7.4',
- 'esVersionRaw' => '>=7.2 <7.4',
- ],
- [
- 'packageVersion' => '>=7.4',
- 'esVersion' => '>=7.4',
- 'esVersionRaw' => '>=7.4',
+ 'packageVersion' => '>=7.5',
+ 'esVersion' => '>=7.5',
+ 'esVersionRaw' => '>=7.5',
],
];
diff --git a/src/Config/Validator/Deploy/MageModeVariable.php b/src/Config/Validator/Deploy/MageModeVariable.php
new file mode 100644
index 0000000000..69feb6137a
--- /dev/null
+++ b/src/Config/Validator/Deploy/MageModeVariable.php
@@ -0,0 +1,59 @@
+envData = $envData;
+ $this->resultFactory = $resultFactory;
+ }
+
+ /**
+ * @return Validator\ResultInterface
+ * @throws FileSystemException
+ */
+ public function validate(): Validator\ResultInterface
+ {
+ $mageMode = $this->envData->getMageMode();
+ if (!$mageMode || $mageMode == self::PRODUCTION_MODE) {
+ return $this->resultFactory->success();
+ }
+
+ return $this->resultFactory->errorByCode(Error::WARN_NOT_SUPPORTED_MAGE_MODE);
+ }
+}
diff --git a/src/Config/Validator/Deploy/SearchConfiguration.php b/src/Config/Validator/Deploy/SearchConfiguration.php
index 0fe1509e9c..dd6dfd8507 100644
--- a/src/Config/Validator/Deploy/SearchConfiguration.php
+++ b/src/Config/Validator/Deploy/SearchConfiguration.php
@@ -8,11 +8,15 @@
namespace Magento\MagentoCloud\Config\Validator\Deploy;
use Magento\MagentoCloud\App\Error;
+use Magento\MagentoCloud\App\GenericException;
use Magento\MagentoCloud\Config\ConfigMerger;
use Magento\MagentoCloud\Config\Stage\DeployInterface;
use Magento\MagentoCloud\Config\Validator;
use Magento\MagentoCloud\Config\Validator\ResultFactory;
+use Magento\MagentoCloud\Config\ValidatorException;
use Magento\MagentoCloud\Config\ValidatorInterface;
+use Magento\MagentoCloud\Package\MagentoVersion;
+use Magento\MagentoCloud\Service\ElasticSearch;
/**
* Validates SEARCH_CONFIGURATION variable
@@ -34,39 +38,60 @@ class SearchConfiguration implements ValidatorInterface
*/
private $configMerger;
+ /**
+ * @var MagentoVersion
+ */
+ private $magentoVersion;
+
/**
* @param ResultFactory $resultFactory
* @param DeployInterface $stageConfig
* @param ConfigMerger $configMerger
+ * @param MagentoVersion $magentoVersion
*/
public function __construct(
ResultFactory $resultFactory,
DeployInterface $stageConfig,
- ConfigMerger $configMerger
+ ConfigMerger $configMerger,
+ MagentoVersion $magentoVersion
) {
$this->resultFactory = $resultFactory;
$this->stageConfig = $stageConfig;
$this->configMerger = $configMerger;
+ $this->magentoVersion = $magentoVersion;
}
/**
- * Checks that SEARCH_CONFIGURATION variable contains at least 'engine' option if _merge was not set
+ * Checks that SEARCH_CONFIGURATION variable contains at least 'engine' option if _merge was not set.
+ * Checks that search engine for Magento 2.4 is set to elasticsearch
*
- * @return Validator\ResultInterface
+ * {@inheritDoc}
*/
public function validate(): Validator\ResultInterface
{
- $searchConfig = $this->stageConfig->get(DeployInterface::VAR_SEARCH_CONFIGURATION);
- if ($this->configMerger->isEmpty($searchConfig) || $this->configMerger->isMergeRequired($searchConfig)) {
- return $this->resultFactory->success();
- }
+ try {
+ $searchConfig = $this->stageConfig->get(DeployInterface::VAR_SEARCH_CONFIGURATION);
+
+ if ($this->magentoVersion->isGreaterOrEqual('2.4.0')
+ && isset($searchConfig['engine'])
+ && $searchConfig['engine'] != ElasticSearch::ENGINE_NAME
+ ) {
+ return $this->resultFactory->errorByCode(Error::DEPLOY_WRONG_SEARCH_ENGINE);
+ }
+
+ if ($this->configMerger->isEmpty($searchConfig) || $this->configMerger->isMergeRequired($searchConfig)) {
+ return $this->resultFactory->success();
+ }
- if (!isset($searchConfig['engine'])) {
- return $this->resultFactory->error(
- sprintf('Variable %s is not configured properly', DeployInterface::VAR_SEARCH_CONFIGURATION),
- 'At least engine option must be configured',
- Error::DEPLOY_WRONG_CONFIGURATION_SEARCH
- );
+ if (!isset($searchConfig['engine'])) {
+ return $this->resultFactory->error(
+ sprintf('Variable %s is not configured properly', DeployInterface::VAR_SEARCH_CONFIGURATION),
+ 'At least engine option must be configured',
+ Error::DEPLOY_WRONG_CONFIGURATION_SEARCH
+ );
+ }
+ } catch (GenericException $exception) {
+ throw new ValidatorException($exception->getMessage(), $exception->getCode(), $exception);
}
return $this->resultFactory->success();
diff --git a/src/Config/Validator/Deploy/ServiceEol.php b/src/Config/Validator/Deploy/ServiceEol.php
index f1c270b739..96364ba500 100644
--- a/src/Config/Validator/Deploy/ServiceEol.php
+++ b/src/Config/Validator/Deploy/ServiceEol.php
@@ -8,11 +8,10 @@
namespace Magento\MagentoCloud\Config\Validator\Deploy;
use Magento\MagentoCloud\App\Error;
+use Magento\MagentoCloud\App\GenericException;
use Magento\MagentoCloud\Config\Validator;
-use Magento\MagentoCloud\Filesystem\FileSystemException;
use Magento\MagentoCloud\Service\EolValidator as EOLValidator;
use Magento\MagentoCloud\Config\ValidatorInterface;
-use Magento\MagentoCloud\Service\ServiceMismatchException;
/**
* Class to check if services approaching their EOLs.
@@ -52,8 +51,7 @@ public function __construct(
/**
* Get the defined services and versions and check for their EOLs by error level.
*
- * @return Validator\ResultInterface
- * @throws FileSystemException
+ * {@inheritDoc}
*/
public function validate(): Validator\ResultInterface
{
@@ -70,7 +68,7 @@ public function validate(): Validator\ResultInterface
$this->errorLevel == ValidatorInterface::LEVEL_WARNING ? Error::WARN_SERVICE_PASSED_EOL : null
);
}
- } catch (ServiceMismatchException $e) {
+ } catch (GenericException $e) {
return $this->resultFactory->error('Can\'t validate version of some services: ' . $e->getMessage());
}
diff --git a/src/Config/Validator/Deploy/ServiceVersion.php b/src/Config/Validator/Deploy/ServiceVersion.php
index 4170186b7b..2aca3e2e83 100644
--- a/src/Config/Validator/Deploy/ServiceVersion.php
+++ b/src/Config/Validator/Deploy/ServiceVersion.php
@@ -14,6 +14,7 @@
use Magento\MagentoCloud\Service\Validator as ServiceVersionValidator;
use Magento\MagentoCloud\Config\Validator;
use Magento\MagentoCloud\Config\ValidatorInterface;
+use Psr\Log\LoggerInterface;
/**
* Validates installed service versions according to version mapping.
@@ -36,19 +37,27 @@ class ServiceVersion implements ValidatorInterface
*/
private $serviceFactory;
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
/**
* @param Validator\ResultFactory $resultFactory
* @param ServiceVersionValidator $serviceVersionValidator
* @param ServiceFactory $serviceFactory
+ * @param LoggerInterface $logger
*/
public function __construct(
Validator\ResultFactory $resultFactory,
ServiceVersionValidator $serviceVersionValidator,
- ServiceFactory $serviceFactory
+ ServiceFactory $serviceFactory,
+ LoggerInterface $logger
) {
$this->resultFactory = $resultFactory;
$this->serviceVersionValidator = $serviceVersionValidator;
$this->serviceFactory = $serviceFactory;
+ $this->logger = $logger;
}
/**
@@ -62,13 +71,18 @@ public function validate(): Validator\ResultInterface
$services = [
ServiceInterface::NAME_RABBITMQ,
ServiceInterface::NAME_REDIS,
- ServiceInterface::NAME_DB
+ ServiceInterface::NAME_DB,
+ ServiceInterface::NAME_ELASTICSEARCH
];
$errors = [];
foreach ($services as $serviceName) {
$service = $this->serviceFactory->create($serviceName);
$serviceVersion = $service->getVersion();
+
+ $logMsq = $serviceVersion ? 'is ' . $serviceVersion : 'is not detected';
+ $this->logger->info(sprintf('Version of service \'%s\' %s', $serviceName, $logMsq));
+
if ($serviceVersion !== '0' &&
$error = $this->serviceVersionValidator->validateService($serviceName, $serviceVersion)
) {
diff --git a/src/DB/Data/ConnectionTypes.php b/src/DB/Data/ConnectionTypes.php
new file mode 100644
index 0000000000..02605986d6
--- /dev/null
+++ b/src/DB/Data/ConnectionTypes.php
@@ -0,0 +1,93 @@
+environment = $environment;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_KEY)[0] ?? [];
+ }
+
+ /**
+ * Returns service configuration for slave.
+ *
+ * @return array
+ */
+ public function getSlaveConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_SLAVE_KEY)[0] ?? [];
+ }
+
+ /**
+ * Returns configuration for quote service.
+ */
+ public function getQuoteConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_QUOTE_KEY)[0] ?? [];
+ }
+
+ /**
+ * Returns configuration for quote slave service.
+ *
+ * @return array
+ */
+ public function getQuoteSlaveConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_QUOTE_SLAVE_KEY)[0] ?? [];
+ }
+
+ /**
+ * Returns configuration for sales service.
+ */
+ public function getSalesConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_SALES_KEY)[0] ?? [];
+ }
+
+ /**
+ * Returns configuration for slave sales service.
+ *
+ * @return array
+ */
+ public function getSalesSlaveConfiguration(): array
+ {
+ return $this->environment->getRelationship(self::RELATIONSHIP_SALES_SLAVE_KEY)[0] ?? [];
+ }
+}
diff --git a/src/DB/Data/RelationshipConnectionFactory.php b/src/DB/Data/RelationshipConnectionFactory.php
index 4f1db41519..ced3a8f5b5 100644
--- a/src/DB/Data/RelationshipConnectionFactory.php
+++ b/src/DB/Data/RelationshipConnectionFactory.php
@@ -7,8 +7,6 @@
namespace Magento\MagentoCloud\DB\Data;
-use Magento\MagentoCloud\Service\Database;
-
/**
* Responsible for creating and configuring Magento\MagentoCloud\DB\Data\ConnectionInterface instances.
*/
@@ -24,16 +22,16 @@ class RelationshipConnectionFactory
const CONNECTION_SALES_SLAVE = 'sales-slave';
/**
- * @var Database
+ * @var ConnectionTypes
*/
- private $database;
+ private $connectionType;
/**
- * @param Database $database
+ * @param ConnectionTypes $connectionType
*/
- public function __construct(Database $database)
+ public function __construct(ConnectionTypes $connectionType)
{
- $this->database = $database;
+ $this->connectionType = $connectionType;
}
/**
@@ -47,22 +45,22 @@ public function create(string $connectionType): ConnectionInterface
{
switch ($connectionType) {
case self::CONNECTION_MAIN:
- $configuration = $this->database->getConfiguration();
+ $configuration = $this->connectionType->getConfiguration();
break;
case self::CONNECTION_SLAVE:
- $configuration = $this->database->getSlaveConfiguration();
+ $configuration = $this->connectionType->getSlaveConfiguration();
break;
case self::CONNECTION_QUOTE_MAIN:
- $configuration = $this->database->getQuoteConfiguration();
+ $configuration = $this->connectionType->getQuoteConfiguration();
break;
case self::CONNECTION_QUOTE_SLAVE:
- $configuration = $this->database->getQuoteSlaveConfiguration();
+ $configuration = $this->connectionType->getQuoteSlaveConfiguration();
break;
case self::CONNECTION_SALES_MAIN:
- $configuration = $this->database->getSalesConfiguration();
+ $configuration = $this->connectionType->getSalesConfiguration();
break;
case self::CONNECTION_SALES_SLAVE:
- $configuration = $this->database->getSalesSlaveConfiguration();
+ $configuration = $this->connectionType->getSalesSlaveConfiguration();
break;
default:
throw new \RuntimeException(
diff --git a/src/Service/Database.php b/src/Service/Database.php
index 6a0e3be181..3c6f37b00b 100644
--- a/src/Service/Database.php
+++ b/src/Service/Database.php
@@ -7,26 +7,23 @@
namespace Magento\MagentoCloud\Service;
-use Magento\MagentoCloud\Config\Environment;
+use Magento\MagentoCloud\DB\ConnectionInterface;
+use Magento\MagentoCloud\DB\Data\ConnectionTypes;
/**
- * Returns database service configurations.
+ * Returns main database service configurations.
*/
class Database implements ServiceInterface
{
- const RELATIONSHIP_KEY = 'database';
- const RELATIONSHIP_SLAVE_KEY = 'database-slave';
-
- const RELATIONSHIP_QUOTE_KEY = 'database-quote';
- const RELATIONSHIP_QUOTE_SLAVE_KEY = 'database-quote-slave';
-
- const RELATIONSHIP_SALES_KEY = 'database-sales';
- const RELATIONSHIP_SALES_SLAVE_KEY = 'database-sales-slave';
+ /**
+ * @var ConnectionTypes
+ */
+ private $connectionType;
/**
- * @var Environment
+ * @var ConnectionInterface
*/
- private $environment;
+ private $connection;
/**
* @var string
@@ -34,11 +31,15 @@ class Database implements ServiceInterface
private $version;
/**
- * @param Environment $environment
+ * @param ConnectionTypes $connectionType
+ * @param ConnectionInterface $connection
*/
- public function __construct(Environment $environment)
- {
- $this->environment = $environment;
+ public function __construct(
+ ConnectionTypes $connectionType,
+ ConnectionInterface $connection
+ ) {
+ $this->connectionType = $connectionType;
+ $this->connection = $connection;
}
/**
@@ -46,69 +47,33 @@ public function __construct(Environment $environment)
*/
public function getConfiguration(): array
{
- return $this->environment->getRelationship(self::RELATIONSHIP_KEY)[0] ?? [];
- }
-
- /**
- * Returns service configuration for slave.
- *
- * @return array
- */
- public function getSlaveConfiguration(): array
- {
- return $this->environment->getRelationship(self::RELATIONSHIP_SLAVE_KEY)[0] ?? [];
- }
-
- /**
- * Returns configuration for quote service.
- */
- public function getQuoteConfiguration(): array
- {
- return $this->environment->getRelationship(self::RELATIONSHIP_QUOTE_KEY)[0] ?? [];
- }
-
- /**
- * Returns configuration for quote slave service.
- *
- * @return array
- */
- public function getQuoteSlaveConfiguration(): array
- {
- return $this->environment->getRelationship(self::RELATIONSHIP_QUOTE_SLAVE_KEY)[0] ?? [];
+ return $this->connectionType->getConfiguration();
}
/**
- * Returns configuration for sales service.
- */
- public function getSalesConfiguration(): array
- {
- return $this->environment->getRelationship(self::RELATIONSHIP_SALES_KEY)[0] ?? [];
- }
-
- /**
- * Returns configuration for slave sales service.
- *
- * @return array
- */
- public function getSalesSlaveConfiguration(): array
- {
- return $this->environment->getRelationship(self::RELATIONSHIP_SALES_SLAVE_KEY)[0] ?? [];
- }
-
- /**
- * Returns version of the service.
+ * Retrieves MySQL service version whether from relationship configuration
+ * or using SQL query (for PRO environments)
*
- * @return string
+ * {@inheritDoc}
*/
public function getVersion(): string
{
if ($this->version === null) {
$this->version = '0';
- $databaseConfig = $this->getConfiguration();
+ try {
+ $databaseConfig = $this->getConfiguration();
+
+ if (isset($databaseConfig['type']) && strpos($databaseConfig['type'], ':') !== false) {
+ $this->version = explode(':', $databaseConfig['type'])[1];
+ } elseif (!empty($databaseConfig['host'])) {
+ $rawVersion = $this->connection->selectOne('SELECT VERSION() as version');
+ preg_match('/^\d+\.\d+/', $rawVersion['version'] ?? '', $matches);
- if (isset($databaseConfig['type']) && strpos($databaseConfig['type'], ':') !== false) {
- $this->version = explode(':', $databaseConfig['type'])[1];
+ $this->version = $matches[0] ?? '0';
+ }
+ } catch (\Exception $e) {
+ throw new ServiceException($e->getMessage());
}
}
diff --git a/src/Service/Php.php b/src/Service/Php.php
index e841a6c731..c3048efd70 100644
--- a/src/Service/Php.php
+++ b/src/Service/Php.php
@@ -12,11 +12,6 @@
*/
class Php implements ServiceInterface
{
- /**
- * @var string
- */
- private $version;
-
/**
* Get PHP configuration.
*
@@ -34,15 +29,6 @@ public function getConfiguration(): array
*/
public function getVersion(): string
{
- if ($this->version === null) {
- $this->version = '0';
-
- $phpConfigs = $this->getConfiguration();
- if (isset($phpConfigs['version'])) {
- $this->version = $phpConfigs['version'];
- }
- }
-
- return $this->version;
+ return $this->getConfiguration()['version'];
}
}
diff --git a/src/Service/RabbitMq.php b/src/Service/RabbitMq.php
index a9217321df..a7fad83d3c 100644
--- a/src/Service/RabbitMq.php
+++ b/src/Service/RabbitMq.php
@@ -8,6 +8,8 @@
namespace Magento\MagentoCloud\Service;
use Magento\MagentoCloud\Config\Environment;
+use Magento\MagentoCloud\Shell\ShellException;
+use Magento\MagentoCloud\Shell\ShellInterface;
/**
*
@@ -26,6 +28,11 @@ class RabbitMq implements ServiceInterface
*/
private $environment;
+ /**
+ * @var ShellInterface
+ */
+ private $shell;
+
/**
* @var string
*/
@@ -33,17 +40,21 @@ class RabbitMq implements ServiceInterface
/**
* @param Environment $environment
+ * @param ShellInterface $shell
*/
- public function __construct(Environment $environment)
- {
+ public function __construct(
+ Environment $environment,
+ ShellInterface $shell
+ ) {
$this->environment = $environment;
+ $this->shell = $shell;
}
/**
* Finds if configuration exists for one of possible amqp relationship names and return first match,
* amqp relationship can have different name on different environment.
*
- * {@inheritdoc}
+ * {@inheritDoc}
*/
public function getConfiguration(): array
{
@@ -58,7 +69,10 @@ public function getConfiguration(): array
}
/**
- * @inheritdoc
+ * Retrieve RabbitMQ service version whether from relationship configuration
+ * or using CLI command (for PRO environments)
+ *
+ * {@inheritDoc}
*/
public function getVersion(): string
{
@@ -69,6 +83,14 @@ public function getVersion(): string
if (isset($config['type']) && strpos($config['type'], ':') !== false) {
$this->version = explode(':', $config['type'])[1];
+ } elseif (isset($config['host']) && isset($config['port'])) {
+ try {
+ $process = $this->shell->execute('dpkg -s rabbitmq-server | grep Version');
+ preg_match('/^(?:Version:(?:\s)?)(\d+\.\d+)/', $process->getOutput(), $matches);
+ $this->version = $matches[1] ?? '0';
+ } catch (ShellException $exception) {
+ throw new ServiceException($exception->getMessage());
+ }
}
}
diff --git a/src/Service/Redis.php b/src/Service/Redis.php
index b468f3c1d9..7a8d50d885 100644
--- a/src/Service/Redis.php
+++ b/src/Service/Redis.php
@@ -8,6 +8,8 @@
namespace Magento\MagentoCloud\Service;
use Magento\MagentoCloud\Config\Environment;
+use Magento\MagentoCloud\Shell\ShellException;
+use Magento\MagentoCloud\Shell\ShellInterface;
/**
* Returns Redis service configurations.
@@ -22,6 +24,11 @@ class Redis implements ServiceInterface
*/
private $environment;
+ /**
+ * @var ShellInterface
+ */
+ private $shell;
+
/**
* @var string
*/
@@ -29,10 +36,14 @@ class Redis implements ServiceInterface
/**
* @param Environment $environment
+ * @param ShellInterface $shell
*/
- public function __construct(Environment $environment)
- {
+ public function __construct(
+ Environment $environment,
+ ShellInterface $shell
+ ) {
$this->environment = $environment;
+ $this->shell = $shell;
}
/**
@@ -54,19 +65,35 @@ public function getSlaveConfiguration(): array
}
/**
- * Returns version of the service.
+ * Retrieves Redis service version whether from relationship configuration
+ * or using CLI command (for PRO environments)
*
- * @return string
+ * {@inheritDoc}
*/
public function getVersion(): string
{
if ($this->version === null) {
$this->version = '0';
-
$redisConfig = $this->getConfiguration();
+ //on integration environments
if (isset($redisConfig['type']) && strpos($redisConfig['type'], ':') !== false) {
$this->version = explode(':', $redisConfig['type'])[1];
+ } elseif (isset($redisConfig['host']) && isset($redisConfig['port'])) {
+ //on dedicated environments
+ try {
+ $process = $this->shell->execute(
+ sprintf(
+ 'redis-cli -p %s -h %s info | grep redis_version',
+ $redisConfig['port'],
+ $redisConfig['host']
+ )
+ );
+ preg_match('/^(?:redis_version:)(\d+\.\d+)/', $process->getOutput(), $matches);
+ $this->version = $matches[1] ?? '0';
+ } catch (ShellException $exception) {
+ throw new ServiceException($exception->getMessage());
+ }
}
}
diff --git a/src/Service/Validator.php b/src/Service/Validator.php
index 5a9fed8f88..66f6c174c5 100644
--- a/src/Service/Validator.php
+++ b/src/Service/Validator.php
@@ -43,14 +43,17 @@ class Validator
'>=2.3.3' => '^4.0 || ^5.0 || ^6.2',
],
ServiceInterface::NAME_REDIS => [
- '*' => '~3.2.0 || ~4.0.0 || ~5.0.0',
+ '*' => '~3.2.0 || ~4.0.0 || ~5.0.0 || ~6.0.0',
],
ServiceInterface::NAME_ELASTICSEARCH => [
'<2.2.0' => '~1.7.0 || ~2.4.0',
'>=2.2.0 <2.2.8 || 2.3.0' => '~1.7.0 || ~2.4.0 || ~5.2.0',
'>=2.2.8 <2.3.0 || >=2.3.1 <2.3.5' => '~1.7.0 || ~2.4.0 || ~5.2.0 || ~6.5.0',
- '>=2.3.5 <2.4.0' => '~1.7.0 || ~2.4.0 || ~5.2.0 || ~6.5.0 || ~6.8.0 || ~7.5.0 || ~7.6.0 || ~7.7.0',
- '>=2.4.0' => '~7.5.0 || ~7.6.0 || ~7.7.0',
+ '>=2.3.5 <2.3.7' => '~1.7.0 || ~2.4.0 || ~5.2.0 || ~6.5.0 || ~6.8.0 || ~7.5.0 || ~7.6.0 || ~7.7.0',
+ '>=2.3.7 <2.4.0' => '~1.7.0 || ~2.4.0 || ~5.2.0 || ~6.5.0 || ~6.8.0 || ~7.5.0 || ~7.6.0 || ~7.7.0' .
+ ' || ~7.9.0',
+ '>=2.4.0 <2.4.2' => '~7.5.0 || ~7.6.0 || ~7.7.0',
+ '>=2.4.2' => '~7.5.0 || ~7.6.0 || ~7.7.0 || ~7.9.0',
],
ServiceInterface::NAME_RABBITMQ => [
'<2.3.0' => '~3.5.0',
diff --git a/src/Step/Build/BackupData/StaticContent.php b/src/Step/Build/BackupData/StaticContent.php
index 502d649882..8f2eedd42e 100644
--- a/src/Step/Build/BackupData/StaticContent.php
+++ b/src/Step/Build/BackupData/StaticContent.php
@@ -9,10 +9,12 @@
use Magento\MagentoCloud\App\Error;
use Magento\MagentoCloud\App\GenericException;
+use Magento\MagentoCloud\Config\Environment;
use Magento\MagentoCloud\Filesystem\DirectoryList;
use Magento\MagentoCloud\Filesystem\Driver\File;
use Magento\MagentoCloud\Filesystem\FileSystemException;
use Magento\MagentoCloud\Filesystem\Flag\Manager as FlagManager;
+use Magento\MagentoCloud\Package\UndefinedPackageException;
use Magento\MagentoCloud\Step\StepException;
use Magento\MagentoCloud\Step\StepInterface;
use Psr\Log\LoggerInterface;
@@ -42,28 +44,36 @@ class StaticContent implements StepInterface
*/
private $flagManager;
+ /**
+ * @var Environment
+ */
+ private $environment;
+
/**
* @param File $file
* @param LoggerInterface $logger
* @param DirectoryList $directoryList
* @param FlagManager $flagManager
+ * @param Environment $environmentData
*/
public function __construct(
File $file,
LoggerInterface $logger,
DirectoryList $directoryList,
- FlagManager $flagManager
+ FlagManager $flagManager,
+ Environment $environmentData
) {
$this->file = $file;
$this->logger = $logger;
$this->directoryList = $directoryList;
$this->flagManager = $flagManager;
+ $this->environment = $environmentData;
}
/**
* @inheritdoc
*/
- public function execute()
+ public function execute(): void
{
try {
$this->flagManager->delete(FlagManager::FLAG_REGENERATE);
@@ -73,17 +83,25 @@ public function execute()
return;
}
+ } catch (GenericException $e) {
+ throw new StepException($e->getMessage(), $e->getCode(), $e);
+ }
+
+ if (!$this->environment->hasMount(Environment::MOUNT_PUB_STATIC)) {
+ $this->logger->info('Static content was not moved to ./init directory');
+ return;
+ }
+
+ try {
$initPubStatic = $this->directoryList->getPath(DirectoryList::DIR_INIT) . '/pub/static';
$originalPubStatic = $this->directoryList->getPath(DirectoryList::DIR_STATIC);
-
- $this->cleanInitPubStatic($initPubStatic);
- $this->moveStaticContent($originalPubStatic, $initPubStatic);
- } catch (StepException $e) {
- throw $e;
- } catch (GenericException $e) {
- throw new StepException($e->getMessage(), $e->getCode(), $e);
+ } catch (UndefinedPackageException $exception) {
+ throw new StepException($exception->getMessage(), $exception->getCode(), $exception);
}
+
+ $this->cleanInitPubStatic($initPubStatic);
+ $this->moveStaticContent($originalPubStatic, $initPubStatic);
}
/**
diff --git a/src/Step/Build/ComposerDumpAutoload.php b/src/Step/Build/ComposerDumpAutoload.php
index 015f655c99..65a0c89fc6 100644
--- a/src/Step/Build/ComposerDumpAutoload.php
+++ b/src/Step/Build/ComposerDumpAutoload.php
@@ -8,10 +8,13 @@
namespace Magento\MagentoCloud\Step\Build;
use Magento\MagentoCloud\App\Error;
+use Magento\MagentoCloud\Config\ConfigException;
use Magento\MagentoCloud\Step\StepException;
use Magento\MagentoCloud\Step\StepInterface;
use Magento\MagentoCloud\Shell\ShellException;
use Magento\MagentoCloud\Shell\ShellInterface;
+use Magento\MagentoCloud\Config\Stage\BuildInterface;
+use Psr\Log\LoggerInterface;
/**
* @inheritdoc
@@ -23,12 +26,25 @@ class ComposerDumpAutoload implements StepInterface
*/
private $shell;
+ /**
+ * @var BuildInterface
+ */
+ private $stageConfig;
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
/**
* @param ShellInterface $shell
+ * @param BuildInterface $stageConfig
+ * @param LoggerInterface $logger
*/
- public function __construct(ShellInterface $shell)
+ public function __construct(ShellInterface $shell, BuildInterface $stageConfig, LoggerInterface $logger)
{
$this->shell = $shell;
+ $this->stageConfig = $stageConfig;
+ $this->logger = $logger;
}
/**
@@ -37,7 +53,17 @@ public function __construct(ShellInterface $shell)
public function execute()
{
try {
+ if ($this->stageConfig->get(BuildInterface::VAR_SKIP_COMPOSER_DUMP_AUTOLOAD)) {
+ $this->logger->info(sprintf(
+ 'The composer dump-autoload command was skipped as %s variable is set to true',
+ BuildInterface::VAR_SKIP_COMPOSER_DUMP_AUTOLOAD
+ ));
+
+ return;
+ }
$this->shell->execute('composer dump-autoload -o --ansi --no-interaction');
+ } catch (ConfigException $e) {
+ throw new StepException($e->getMessage(), $e->getCode(), $e);
} catch (ShellException $e) {
throw new StepException($e->getMessage(), Error::BUILD_COMPOSER_DUMP_AUTOLOAD_FAILED, $e);
}
diff --git a/src/Step/Deploy/PreDeploy/CleanStaticContent.php b/src/Step/Deploy/PreDeploy/CleanStaticContent.php
index 2199d03b52..d1bd0c0f02 100644
--- a/src/Step/Deploy/PreDeploy/CleanStaticContent.php
+++ b/src/Step/Deploy/PreDeploy/CleanStaticContent.php
@@ -27,7 +27,7 @@ class CleanStaticContent implements StepInterface
/**
* @var Environment
*/
- private $env;
+ private $environment;
/**
* @var LoggerInterface
@@ -56,7 +56,7 @@ class CleanStaticContent implements StepInterface
/**
* @param LoggerInterface $logger
- * @param Environment $env
+ * @param Environment $environment
* @param File $file
* @param DirectoryList $directoryList
* @param FlagManager $flagManager
@@ -64,14 +64,14 @@ class CleanStaticContent implements StepInterface
*/
public function __construct(
LoggerInterface $logger,
- Environment $env,
+ Environment $environment,
File $file,
DirectoryList $directoryList,
FlagManager $flagManager,
DeployInterface $stageConfig
) {
$this->logger = $logger;
- $this->env = $env;
+ $this->environment = $environment;
$this->file = $file;
$this->directoryList = $directoryList;
$this->flagManager = $flagManager;
@@ -83,11 +83,13 @@ public function __construct(
*
* {@inheritdoc}
*/
- public function execute()
+ public function execute(): void
{
try {
if (!$this->flagManager->exists(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
- || !$this->stageConfig->get(DeployInterface::VAR_CLEAN_STATIC_FILES)) {
+ || !$this->stageConfig->get(DeployInterface::VAR_CLEAN_STATIC_FILES)
+ || !$this->environment->hasMount(Environment::MOUNT_PUB_STATIC)
+ ) {
return;
}
diff --git a/src/Step/PostDeploy/WarmUp.php b/src/Step/PostDeploy/WarmUp.php
index 968e9b97c7..a76bcd1620 100644
--- a/src/Step/PostDeploy/WarmUp.php
+++ b/src/Step/PostDeploy/WarmUp.php
@@ -67,9 +67,21 @@ public function __construct(
public function execute()
{
try {
- $this->logger->info('Starting page warming up');
+ $this->logger->info('Starting page warmup');
$config = [];
+ $concurrency = $this->postDeploy->get(PostDeployInterface::VAR_WARM_UP_CONCURRENCY);
+ if ($concurrency) {
+ $config['concurrency'] = $concurrency;
+ $this->logger->info(
+ sprintf(
+ 'Warmup concurrency set to %s as specified by the %s configuration',
+ $concurrency,
+ PostDeployInterface::VAR_WARM_UP_CONCURRENCY
+ )
+ );
+ }
+
$urls = $this->urls->getAll();
$config['fulfilled'] = function ($response, $index) use ($urls) {
@@ -95,11 +107,6 @@ public function execute()
$this->logger->error('Warming up failed: ' . $urls[$index], $context);
};
- $concurrency = $this->postDeploy->get(PostDeployInterface::VAR_WARM_UP_CONCURRENCY);
- if ($concurrency) {
- $config['concurrency'] = $concurrency;
- }
-
$pool = $this->poolFactory->create($urls, $config);
/** @var PromiseInterface $promise */
diff --git a/src/Test/Functional/Acceptance/AbstractCest.php b/src/Test/Functional/Acceptance/AbstractCest.php
index 2ff196e6be..a78cf452c8 100644
--- a/src/Test/Functional/Acceptance/AbstractCest.php
+++ b/src/Test/Functional/Acceptance/AbstractCest.php
@@ -61,6 +61,14 @@ protected function convertEnvFromArrayToJson(array $data): string
protected function prepareWorkplace(\CliTester $I, string $templateVersion): void
{
$I->cleanupWorkDir();
+
+ if ($I->isCacheWorkDirExists($templateVersion)) {
+ $I->restoreWorkDirFromCache($templateVersion);
+ $this->removeESIfExists($I, $templateVersion);
+
+ return;
+ }
+
$I->cloneTemplateToWorkDir($templateVersion);
$I->createAuthJson();
$I->createArtifactsDir();
@@ -90,6 +98,7 @@ protected function prepareWorkplace(\CliTester $I, string $templateVersion): voi
if ($this->runComposerUpdate) {
$I->composerUpdate();
+ $I->cacheWorkDir($templateVersion);
}
$this->removeESIfExists($I, $templateVersion);
diff --git a/src/Test/Functional/Acceptance/AcceptanceCe71Cest.php b/src/Test/Functional/Acceptance/AcceptanceCe71Cest.php
index e04a446664..9f04040dfa 100644
--- a/src/Test/Functional/Acceptance/AcceptanceCe71Cest.php
+++ b/src/Test/Functional/Acceptance/AcceptanceCe71Cest.php
@@ -22,5 +22,5 @@ class AcceptanceCe71Cest extends AcceptanceCeCest
/**
* @var string
*/
- protected $magentoCloudTemplate = '2.1.17';
+ protected $magentoCloudTemplate = '2.1.18';
}
diff --git a/src/Test/Functional/Acceptance/AdminCredential21Cest.php b/src/Test/Functional/Acceptance/AdminCredential21Cest.php
index 8ea34c9f69..3ff42875fe 100644
--- a/src/Test/Functional/Acceptance/AdminCredential21Cest.php
+++ b/src/Test/Functional/Acceptance/AdminCredential21Cest.php
@@ -15,5 +15,5 @@ class AdminCredential21Cest extends AdminCredentialCest
/**
* @var string
*/
- protected $magentoCloudTemplate = '2.1.17';
+ protected $magentoCloudTemplate = '2.1.18';
}
diff --git a/src/Test/Functional/Acceptance/Cron21Cest.php b/src/Test/Functional/Acceptance/Cron21Cest.php
index 25c1c561a1..5a8c18d279 100644
--- a/src/Test/Functional/Acceptance/Cron21Cest.php
+++ b/src/Test/Functional/Acceptance/Cron21Cest.php
@@ -19,7 +19,7 @@ protected function cronDataProvider(): array
{
return [
[
- 'version' => '2.1.17',
+ 'version' => '2.1.18',
'variables' => [
'MAGENTO_CLOUD_VARIABLES' => [
'ADMIN_EMAIL' => 'admin@example.com',
diff --git a/src/Test/Integration/Command/ConfigCreateTest.php b/src/Test/Integration/Command/ConfigCreateTest.php
new file mode 100644
index 0000000000..42af74fcde
--- /dev/null
+++ b/src/Test/Integration/Command/ConfigCreateTest.php
@@ -0,0 +1,110 @@
+baseDir);
+
+ $this->command = new ConfigCreate(
+ $container->get(ConfigFileList::class),
+ $container->get(File::class)
+ );
+ }
+
+ /**
+ * @param array $inputConfiguration
+ * @param string $expectedFile
+ * @throws \ReflectionException
+ * @dataProvider executeDataProvider
+ */
+ public function testExecute(array $inputConfiguration, string $expectedFile)
+ {
+ $inputMock = $this->getMockForAbstractClass(InputInterface::class);
+ $outputMock = $this->getMockForAbstractClass(OutputInterface::class);
+
+ $inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with(ConfigCreate::ARG_CONFIGURATION)
+ ->willReturn(json_encode($inputConfiguration));
+
+ $this->command->execute($inputMock, $outputMock);
+
+ $this->assertEquals(
+ file_get_contents($this->baseDir . '/' . $expectedFile),
+ file_get_contents($this->baseDir . '/.magento.env.yaml')
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function executeDataProvider(): array
+ {
+ return [
+ [
+ ['stage' => ['build' => ['SCD_THREADS' => 3]]],
+ '.magento.env.scd.yaml'
+ ],
+ [
+ [
+ 'stage' => [
+ 'build' => [
+ BuildInterface::VAR_SCD_THREADS => 3,
+ BuildInterface::VAR_ERROR_REPORT_DIR_NESTING_LEVEL => 10,
+ ],
+ 'deploy' => [
+ DeployInterface::VAR_DATABASE_CONFIGURATION => [
+ '_merge' => true,
+ 'connection' => [
+ 'default' => [
+ 'host' => 'localhost',
+ 'port' => '3307',
+ 'password' => '1234',
+ 'user' => 'localuser'
+ ]
+ ]
+ ],
+ DeployInterface::VAR_LOCK_PROVIDER => 'db',
+ ],
+ ]
+ ],
+ '.magento.env.dbconfiguration.yaml'
+ ],
+ ];
+ }
+}
diff --git a/src/Test/Integration/Command/ConfigUpdateTest.php b/src/Test/Integration/Command/ConfigUpdateTest.php
new file mode 100644
index 0000000000..191396207b
--- /dev/null
+++ b/src/Test/Integration/Command/ConfigUpdateTest.php
@@ -0,0 +1,110 @@
+get(ConfigFileList::class),
+ $container->get(File::class),
+ $container->get(ReaderInterface::class)
+ );
+
+ $inputMock = $this->getMockForAbstractClass(InputInterface::class);
+ $outputMock = $this->getMockForAbstractClass(OutputInterface::class);
+
+ $inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with(ConfigUpdate::ARG_CONFIGURATION)
+ ->willReturn(json_encode($inputConfiguration));
+
+ $command->execute($inputMock, $outputMock);
+
+ $this->assertEquals(
+ file_get_contents($baseDir . '/.magento.env_exp.yaml'),
+ file_get_contents($baseDir . '/.magento.env.yaml')
+ );
+
+ file_put_contents($baseDir . '/.magento.env.yaml', $tmpMagentoEnvYaml);
+ }
+
+ /**
+ * @return array
+ */
+ public function executeDataProvider(): array
+ {
+ return [
+ [
+ [
+ 'stage' => [
+ 'build' => [
+ BuildInterface::VAR_SCD_THREADS => 6,
+ BuildInterface::VAR_ERROR_REPORT_DIR_NESTING_LEVEL => 12,
+ ],
+ ],
+ ],
+ $this->baseDir . '/scdupdate'
+ ],
+ [
+ [
+ 'stage' => [
+ 'deploy' => [
+ DeployInterface::VAR_DATABASE_CONFIGURATION => [
+ '_merge' => true,
+ 'connection' => [
+ 'default' => [
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ 'password' => 'newpassword',
+ 'user' => 'newuser'
+ ]
+ ]
+ ],
+ DeployInterface::VAR_LOCK_PROVIDER => 'redis',
+ ],
+ ]
+ ],
+ $this->baseDir . '/dbconfiguration'
+ ],
+ ];
+ }
+}
diff --git a/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.dbconfiguration.yaml b/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.dbconfiguration.yaml
new file mode 100644
index 0000000000..ba4ac3f5c7
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.dbconfiguration.yaml
@@ -0,0 +1,14 @@
+stage:
+ build:
+ SCD_THREADS: 3
+ ERROR_REPORT_DIR_NESTING_LEVEL: 10
+ deploy:
+ DATABASE_CONFIGURATION:
+ _merge: true
+ connection:
+ default:
+ host: localhost
+ port: '3307'
+ password: '1234'
+ user: localuser
+ LOCK_PROVIDER: db
diff --git a/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.scd.yaml b/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.scd.yaml
new file mode 100644
index 0000000000..ea43b54751
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigCreate/.magento.env.scd.yaml
@@ -0,0 +1,3 @@
+stage:
+ build:
+ SCD_THREADS: 3
diff --git a/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env.yaml b/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env.yaml
new file mode 100644
index 0000000000..2698b46cc0
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env.yaml
@@ -0,0 +1,11 @@
+stage:
+ deploy:
+ DATABASE_CONFIGURATION:
+ _merge: true
+ connection:
+ default:
+ host: localhost
+ port: '3307'
+ password: 1234
+ user: user
+ LOCK_PROVIDER: db
diff --git a/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env_exp.yaml b/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env_exp.yaml
new file mode 100644
index 0000000000..c2bd8064ea
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigUpdate/dbconfiguration/.magento.env_exp.yaml
@@ -0,0 +1,11 @@
+stage:
+ deploy:
+ DATABASE_CONFIGURATION:
+ _merge: true
+ connection:
+ default:
+ host: 127.0.0.1
+ port: '3306'
+ password: newpassword
+ user: newuser
+ LOCK_PROVIDER: redis
diff --git a/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env.yaml b/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env.yaml
new file mode 100644
index 0000000000..3eed606289
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env.yaml
@@ -0,0 +1,4 @@
+stage:
+ build:
+ SCD_THREADS: 3
+ ERROR_REPORT_DIR_NESTING_LEVEL: 10
diff --git a/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env_exp.yaml b/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env_exp.yaml
new file mode 100644
index 0000000000..d5cfebcbda
--- /dev/null
+++ b/src/Test/Integration/Command/_files/ConfigUpdate/scdupdate/.magento.env_exp.yaml
@@ -0,0 +1,4 @@
+stage:
+ build:
+ SCD_THREADS: 6
+ ERROR_REPORT_DIR_NESTING_LEVEL: 12
diff --git a/src/Test/Unit/ApplicationTest.php b/src/Test/Unit/ApplicationTest.php
index bdc2a95577..9de9861c43 100644
--- a/src/Test/Unit/ApplicationTest.php
+++ b/src/Test/Unit/ApplicationTest.php
@@ -80,6 +80,8 @@ class ApplicationTest extends TestCase
Command\CronEnable::NAME => Command\CronEnable::class,
Command\CronDisable::NAME => Command\CronDisable::class,
Command\ConfigShow::NAME => Command\ConfigShow::class,
+ Command\ConfigCreate::NAME => Command\ConfigCreate::class,
+ Command\ConfigUpdate::NAME => Command\ConfigUpdate::class,
Command\RunCommand::NAME => Command\RunCommand::class,
Command\GenerateSchema::NAME => Command\GenerateSchema::class,
Command\ErrorShow::NAME => Command\ErrorShow::class,
diff --git a/src/Test/Unit/Command/ConfigCreateTest.php b/src/Test/Unit/Command/ConfigCreateTest.php
new file mode 100644
index 0000000000..d693e35f13
--- /dev/null
+++ b/src/Test/Unit/Command/ConfigCreateTest.php
@@ -0,0 +1,121 @@
+configFileListMock = $this->createMock(ConfigFileList::class);
+ $this->fileMock = $this->createMock(File::class);
+ $this->inputMock = $this->getMockForAbstractClass(InputInterface::class);
+ $this->outputMock = $this->getMockForAbstractClass(OutputInterface::class);
+
+ $this->command = new ConfigCreate(
+ $this->configFileListMock,
+ $this->fileMock
+ );
+ }
+
+ /**
+ * @dataProvider executeDataProvider
+ * @param string $configuration
+ * @param string $expected
+ */
+ public function testExecute(string $configuration, string $expected)
+ {
+ $this->inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with('configuration')
+ ->willReturn($configuration);
+ $this->configFileListMock->expects($this->once())
+ ->method('getEnvConfig')
+ ->willReturn('/path/to/.magento.env.yaml');
+ $this->fileMock->expects($this->once())
+ ->method('filePutContents')
+ ->with('/path/to/.magento.env.yaml', $expected);
+
+ $this->command->execute($this->inputMock, $this->outputMock);
+ }
+
+ public function executeDataProvider(): array
+ {
+ return [
+ [
+ '{"stage":{"build":{"SKIP_COMPOSER_DUMP_AUTOLOAD":false}}}',
+ 'stage:
+ build:
+ SKIP_COMPOSER_DUMP_AUTOLOAD: false
+'
+ ],
+ [
+ '{"stage":{"deploy":{"DATABASE_CONFIGURATION":{"password":"test", "_merge":true}}}}',
+ 'stage:
+ deploy:
+ DATABASE_CONFIGURATION:
+ password: test
+ _merge: true
+'
+ ],
+ ];
+ }
+
+ public function testExecuteWithWrongArgument()
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessageRegExp('/Wrong JSON format.*/');
+
+ $this->inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with('configuration')
+ ->willReturn('wrong-json');
+ $this->outputMock->expects($this->never())
+ ->method('writeln');
+
+ $this->command->execute($this->inputMock, $this->outputMock);
+ }
+}
diff --git a/src/Test/Unit/Command/ConfigUpdateTest.php b/src/Test/Unit/Command/ConfigUpdateTest.php
new file mode 100644
index 0000000000..743c68a189
--- /dev/null
+++ b/src/Test/Unit/Command/ConfigUpdateTest.php
@@ -0,0 +1,156 @@
+configFileListMock = $this->createMock(ConfigFileList::class);
+ $this->fileMock = $this->createMock(File::class);
+ $this->readerMock = $this->getMockForAbstractClass(ReaderInterface::class);
+ $this->inputMock = $this->getMockForAbstractClass(InputInterface::class);
+ $this->outputMock = $this->getMockForAbstractClass(OutputInterface::class);
+
+ $this->command = new ConfigUpdate(
+ $this->configFileListMock,
+ $this->fileMock,
+ $this->readerMock
+ );
+ }
+
+ /**
+ * @dataProvider executeDataProvider
+ * @param string $configuration
+ * @param array $currentConfig
+ * @param string $expected
+ */
+ public function testExecute(string $configuration, array $currentConfig, string $expected)
+ {
+ $this->inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with('configuration')
+ ->willReturn($configuration);
+ $this->readerMock->expects($this->once())
+ ->method('read')
+ ->willReturn($currentConfig);
+ $this->configFileListMock->expects($this->once())
+ ->method('getEnvConfig')
+ ->willReturn('/path/to/.magento.env.yaml');
+ $this->fileMock->expects($this->once())
+ ->method('filePutContents')
+ ->with('/path/to/.magento.env.yaml', $expected);
+
+ $this->command->execute($this->inputMock, $this->outputMock);
+ }
+
+ public function executeDataProvider(): array
+ {
+ return [
+ [
+ '{"stage":{"build":{"SKIP_COMPOSER_DUMP_AUTOLOAD":false},"deploy":{"SCD_THREADS":6}}}',
+ [
+ 'stage' => [
+ 'build' => [
+ 'SCD_THREADS' => 5,
+ ],
+ 'deploy' => [
+ 'SCD_THREADS' => 4,
+ ],
+ ],
+ ],
+ 'stage:
+ build:
+ SCD_THREADS: 5
+ SKIP_COMPOSER_DUMP_AUTOLOAD: false
+ deploy:
+ SCD_THREADS: 6
+'
+ ],
+ [
+ '{"stage":{"deploy":{"DATABASE_CONFIGURATION":{"password":"test test", "_merge":true}}}}',
+ [
+ 'stage' => [
+ 'deploy' => [
+ 'DATABASE_CONFIGURATION' => [
+ 'host' => 'localhost',
+ 'password' => 'test'
+ ]
+ ]
+ ]
+ ],
+ 'stage:
+ deploy:
+ DATABASE_CONFIGURATION:
+ host: localhost
+ password: \'test test\'
+ _merge: true
+'
+ ],
+ ];
+ }
+
+ public function testExecuteWithWrongArgument()
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessageRegExp('/Wrong JSON format.*/');
+
+ $this->inputMock->expects($this->once())
+ ->method('getArgument')
+ ->with('configuration')
+ ->willReturn('wrong-json');
+ $this->outputMock->expects($this->never())
+ ->method('writeln');
+
+ $this->command->execute($this->inputMock, $this->outputMock);
+ }
+}
diff --git a/src/Test/Unit/Config/EnvironmentDataTest.php b/src/Test/Unit/Config/EnvironmentDataTest.php
index 45086999d3..6bc0e0498d 100644
--- a/src/Test/Unit/Config/EnvironmentDataTest.php
+++ b/src/Test/Unit/Config/EnvironmentDataTest.php
@@ -153,6 +153,9 @@ public function testGetApplicationWithNoSystemVariablesFileExists(): void
{
$_ENV = null;
+ $this->fileMock->expects($this->once())
+ ->method('isExists')
+ ->willReturn(true);
$this->fileMock->expects($this->once())
->method('fileGetContents')
->willReturn('[]');
@@ -165,10 +168,26 @@ public function testGetApplicationWithNoSystemVariablesFileNotExists(): void
$_ENV = null;
$exception = new FilesystemException('.magento.app.yaml not exist');
+ $this->fileMock->expects($this->once())
+ ->method('isExists')
+ ->willReturn(true);
$this->fileMock->expects($this->once())
->method('fileGetContents')
->willThrowException($exception);
$this->assertEquals([], $this->environmentData->getApplication());
}
+
+ public function testGetMageMode(): void
+ {
+ $this->assertNull($this->environmentData->getMageMode());
+
+ $mode = 'some_mode';
+ $_ENV['MAGE_MODE'] = $mode;
+ $this->assertEquals($mode, $this->environmentData->getMageMode());
+
+ //check that value was taken from cache
+ $_ENV['MAGE_MODE'] = 'new value';
+ $this->assertEquals($mode, $this->environmentData->getMageMode());
+ }
}
diff --git a/src/Test/Unit/Config/EnvironmentTest.php b/src/Test/Unit/Config/EnvironmentTest.php
index 0d08d36067..69dec9e4dc 100644
--- a/src/Test/Unit/Config/EnvironmentTest.php
+++ b/src/Test/Unit/Config/EnvironmentTest.php
@@ -148,4 +148,22 @@ public function testGetEnvVarMageErrorReportDirNestingLevel(): void
$this->assertSame(1, $this->environment->getEnvVarMageErrorReportDirNestingLevel());
}
+
+ public function testHasMount(): void
+ {
+ $this->environmentDataMock->method('getApplication')
+ ->willReturn([
+ 'mounts' => [
+ 'test' => [],
+ '/test_with_slash' => []
+ ]
+ ]);
+
+ self::assertTrue($this->environment->hasMount('test'));
+ self::assertTrue($this->environment->hasMount('/test'));
+ self::assertTrue($this->environment->hasMount('test_with_slash'));
+ self::assertTrue($this->environment->hasMount('/test_with_slash'));
+ self::assertFalse($this->environment->hasMount('/unknown'));
+ self::assertFalse($this->environment->hasMount('unknown'));
+ }
}
diff --git a/src/Test/Unit/Config/SchemaTest.php b/src/Test/Unit/Config/SchemaTest.php
index fba9691931..2adc45778c 100644
--- a/src/Test/Unit/Config/SchemaTest.php
+++ b/src/Test/Unit/Config/SchemaTest.php
@@ -77,7 +77,8 @@ public function testGetDefaultsForBuild(): void
BuildInterface::VAR_SCD_MAX_EXEC_TIME => null,
BuildInterface::VAR_ERROR_REPORT_DIR_NESTING_LEVEL => 1,
BuildInterface::VAR_SCD_USE_BALER => false,
- BuildInterface::VAR_QUALITY_PATCHES => []
+ BuildInterface::VAR_QUALITY_PATCHES => [],
+ BuildInterface::VAR_SKIP_COMPOSER_DUMP_AUTOLOAD => false,
],
$this->schema->getDefaults(StageConfigInterface::STAGE_BUILD)
);
diff --git a/src/Test/Unit/Config/Validator/Deploy/DatabaseSplitConnectionTest.php b/src/Test/Unit/Config/Validator/Deploy/DatabaseSplitConnectionTest.php
index 25575488a7..c6965cf47f 100644
--- a/src/Test/Unit/Config/Validator/Deploy/DatabaseSplitConnectionTest.php
+++ b/src/Test/Unit/Config/Validator/Deploy/DatabaseSplitConnectionTest.php
@@ -7,6 +7,7 @@
namespace Magento\MagentoCloud\Test\Unit\Config\Validator\Deploy;
+use Magento\MagentoCloud\App\Error as ApplicationError;
use Magento\MagentoCloud\Config\ConfigException;
use Magento\MagentoCloud\Config\Stage\DeployInterface;
use Magento\MagentoCloud\Config\Validator\Deploy\DatabaseSplitConnection;
@@ -78,14 +79,19 @@ public function testMessageValidate()
->willReturn($dbConfiguration);
$this->resultFactoryMock->expects($this->once())
->method('error')
- ->with('Split database configuration was detected in the property DATABASE_CONFIGURATION of the'
- . ' file .magento.env.yaml:' . PHP_EOL
- . '- connection: checkout' . PHP_EOL
- . '- connection: sales' . PHP_EOL
- . '- slave_connection: checkout' . PHP_EOL
- . '- slave_connection: sales' . PHP_EOL
- . 'Magento Cloud does not support a custom split database configuration,'
- . ' such configurations will be ignored');
+ ->with(
+ 'Detected split database configuration in the DATABASE_CONFIGURATION property of the'
+ . ' file .magento.env.yaml:' . PHP_EOL
+ . '- connection: checkout' . PHP_EOL
+ . '- connection: sales' . PHP_EOL
+ . '- slave_connection: checkout' . PHP_EOL
+ . '- slave_connection: sales' . PHP_EOL
+ . 'Magento Cloud does not support custom connections in the split database configuration,'
+ . ' Custom connections will be ignored',
+ 'Update the DATABASE_CONFIGURATION variable in the \'.magento.env.yaml\' file to remove '
+ . 'custom connections for split databases.',
+ ApplicationError::WARN_WRONG_SPLIT_DB_CONFIG
+ );
$this->assertInstanceOf(Error::class, $this->validator->validate());
}
diff --git a/src/Test/Unit/Config/Validator/Deploy/ElasticSearchVersionTest.php b/src/Test/Unit/Config/Validator/Deploy/ElasticSearchVersionTest.php
index 5ff69f9ea7..3f4ce2baa5 100644
--- a/src/Test/Unit/Config/Validator/Deploy/ElasticSearchVersionTest.php
+++ b/src/Test/Unit/Config/Validator/Deploy/ElasticSearchVersionTest.php
@@ -239,11 +239,13 @@ public function validateDataProvider(): array
['7.1', '7.0', Success::class],
['7.2', '7.3', Success::class],
['7.3', '7.2', Success::class],
- ['7.4', '7.6', Success::class],
['7.6', '7.4', Success::class],
- ['7.4', '7.5', Success::class],
['7.5', '7.4', Success::class],
- ['7.4', '7.2', Error::class],
+ ['7.4', '7.2', Success::class],
+ ['7.7', '7.8', Success::class],
+ ['7.6', '7.7', Success::class],
+ ['7.4', '7.6', Error::class],
+ ['7.4', '7.5', Error::class],
['6.1', '2.0', Error::class],
[
'6.2',
diff --git a/src/Test/Unit/Config/Validator/Deploy/ElasticsearchIntegrityTest.php b/src/Test/Unit/Config/Validator/Deploy/ElasticsearchIntegrityTest.php
index 3effc2fce5..717f44b946 100644
--- a/src/Test/Unit/Config/Validator/Deploy/ElasticsearchIntegrityTest.php
+++ b/src/Test/Unit/Config/Validator/Deploy/ElasticsearchIntegrityTest.php
@@ -86,7 +86,7 @@ public function testValidateNoElasticSearch(): void
->willReturn(false);
$this->resultFactoryMock->expects($this->once())
->method('errorByCode')
- ->with(Error::DEPLOY_WRONG_SEARCH_ENGINE);
+ ->with(Error::DEPLOY_ES_SERVICE_NOT_INSTALLED);
$this->validator->validate();
}
diff --git a/src/Test/Unit/Config/Validator/Deploy/MageModeVariableTest.php b/src/Test/Unit/Config/Validator/Deploy/MageModeVariableTest.php
new file mode 100644
index 0000000000..070644a039
--- /dev/null
+++ b/src/Test/Unit/Config/Validator/Deploy/MageModeVariableTest.php
@@ -0,0 +1,113 @@
+envDataMock = $this->createMock(EnvironmentDataInterface::class);
+ $this->resultFactoryMock = $this->createMock(ResultFactory::class);
+
+ $this->validator = new MageModeVariable(
+ $this->envDataMock,
+ $this->resultFactoryMock
+ );
+ }
+
+ /**
+ * @param $mageMode string|null
+ * @throws FileSystemException
+ * @dataProvider validateSuccessDataProvider
+ */
+ public function testValidateSuccess($mageMode)
+ {
+ $this->envDataMock->expects($this->once())
+ ->method('getMageMode')
+ ->willReturn($mageMode);
+ $this->resultFactoryMock->expects($this->once())
+ ->method('success');
+ $this->resultFactoryMock->expects($this->never())
+ ->method('errorByCode');
+
+ $this->validator->validate();
+ }
+
+ /**
+ * Data provider for testValidateSuccess
+ * @return array
+ */
+ public function validateSuccessDataProvider()
+ {
+ return [
+ [null],
+ [''],
+ [MageModeVariable::PRODUCTION_MODE],
+ ];
+ }
+
+ /**
+ * @param $mageMode string
+ * @throws FileSystemException
+ * @dataProvider validateErrorDataProvider
+ */
+ public function testValidateError($mageMode)
+ {
+ $this->envDataMock->expects($this->once())
+ ->method('getMageMode')
+ ->willReturn($mageMode);
+ $this->resultFactoryMock->expects($this->never())
+ ->method('success');
+ $this->resultFactoryMock->expects($this->once())
+ ->method('errorByCode');
+
+ $this->validator->validate();
+ }
+
+ /**
+ * Data provider for testValidateError
+ * @return array
+ */
+ public function validateErrorDataProvider()
+ {
+ return [
+ ['developer'],
+ ['default'],
+ ['maintenance'],
+ ];
+ }
+}
diff --git a/src/Test/Unit/Config/Validator/Deploy/SearchConfigurationTest.php b/src/Test/Unit/Config/Validator/Deploy/SearchConfigurationTest.php
index 9d47b4a486..29001079f2 100644
--- a/src/Test/Unit/Config/Validator/Deploy/SearchConfigurationTest.php
+++ b/src/Test/Unit/Config/Validator/Deploy/SearchConfigurationTest.php
@@ -14,6 +14,9 @@
use Magento\MagentoCloud\Config\Validator\Result\Error;
use Magento\MagentoCloud\Config\Validator\Result\Success;
use Magento\MagentoCloud\Config\Validator\ResultFactory;
+use Magento\MagentoCloud\Config\ValidatorException;
+use Magento\MagentoCloud\Package\MagentoVersion;
+use Magento\MagentoCloud\Package\UndefinedPackageException;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -37,6 +40,11 @@ class SearchConfigurationTest extends TestCase
*/
private $stageConfigMock;
+ /**
+ * @var MagentoVersion|MockObject
+ */
+ private $magentoVersionMock;
+
/**
* @inheritdoc
*/
@@ -47,11 +55,13 @@ protected function setUp()
'error' => $this->createMock(Error::class)
]);
$this->stageConfigMock = $this->getMockForAbstractClass(DeployInterface::class);
+ $this->magentoVersionMock = $this->createMock(MagentoVersion::class);
$this->validator = new SearchConfiguration(
$this->resultFactoryMock,
$this->stageConfigMock,
- new ConfigMerger()
+ new ConfigMerger(),
+ $this->magentoVersionMock
);
}
@@ -75,10 +85,16 @@ public function testErrorCode()
/**
* @param array $searchConfiguration
* @param string $expectedResultClass
+ * @param bool $isMagento24plus
* @dataProvider validateDataProvider
+ * @throws ValidatorException
*/
- public function testValidate(array $searchConfiguration, string $expectedResultClass)
+ public function testValidate(array $searchConfiguration, string $expectedResultClass, bool $isMagento24plus = false)
{
+ $this->magentoVersionMock->expects($this->once())
+ ->method('isGreaterOrEqual')
+ ->with('2.4.0')
+ ->willReturn($isMagento24plus);
$this->stageConfigMock->expects($this->once())
->method('get')
->with(DeployInterface::VAR_SEARCH_CONFIGURATION)
@@ -125,13 +141,58 @@ public function validateDataProvider(): array
Success::class,
],
[
-
[
'engine' => 'mysql',
'_merge' => true,
],
Success::class,
],
+ [
+ [],
+ Success::class,
+ true
+ ],
+ [
+ [
+ 'engine' => 'mysql',
+ '_merge' => true,
+ ],
+ Error::class,
+ true
+ ],
+ [
+ [
+ 'engine' => 'mysql',
+ ],
+ Error::class,
+ true
+ ],
+ [
+ [
+ 'engine' => 'elasticsearch',
+ ],
+ Success::class,
+ true
+ ],
];
}
+
+ /**
+ * @throws ValidatorException
+ */
+ public function testValidateWithException()
+ {
+ $this->expectException(ValidatorException::class);
+ $this->expectExceptionMessage('some error');
+
+ $this->stageConfigMock->expects($this->once())
+ ->method('get')
+ ->with(DeployInterface::VAR_SEARCH_CONFIGURATION)
+ ->willReturn(['engine' => 'elasticsearch']);
+ $this->magentoVersionMock->expects($this->once())
+ ->method('isGreaterOrEqual')
+ ->willThrowException(new UndefinedPackageException('some error'));
+
+ $this->validator->validate();
+ }
}
diff --git a/src/Test/Unit/Config/Validator/Deploy/ServiceVersionTest.php b/src/Test/Unit/Config/Validator/Deploy/ServiceVersionTest.php
index 8ee187bc5c..08b23ce581 100644
--- a/src/Test/Unit/Config/Validator/Deploy/ServiceVersionTest.php
+++ b/src/Test/Unit/Config/Validator/Deploy/ServiceVersionTest.php
@@ -17,6 +17,7 @@
use Magento\MagentoCloud\Config\Validator\ResultFactory;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
/**
* @inheritdoc
@@ -38,6 +39,11 @@ class ServiceVersionTest extends TestCase
*/
private $serviceVersionValidatorMock;
+ /**
+ * @var LoggerInterface|MockObject
+ */
+ private $loggerMock;
+
/**
* @var ServiceFactory|MockObject
*/
@@ -54,36 +60,51 @@ protected function setUp()
]);
$this->serviceVersionValidatorMock = $this->createMock(ServiceVersionValidator::class);
$this->serviceFactory = $this->createMock(ServiceFactory::class);
+ $this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
$this->validator = new ServiceVersion(
$this->resultFactoryMock,
$this->serviceVersionValidatorMock,
- $this->serviceFactory
+ $this->serviceFactory,
+ $this->loggerMock
);
}
- public function testValidate()
+ public function testValidate(): void
{
- $service1 = $this->createMock(ServiceInterface::class);
- $service1->expects($this->once())
+ $serviceRmq = $this->createMock(ServiceInterface::class);
+ $serviceRmq->expects($this->once())
->method('getVersion')
->willReturn('0');
- $service2 = $this->createMock(ServiceInterface::class);
- $service2->expects($this->once())
+ $serviceRedis = $this->createMock(ServiceInterface::class);
+ $serviceRedis->expects($this->once())
->method('getVersion')
->willReturn('3.2');
- $service3 = $this->createMock(ServiceInterface::class);
- $service3->expects($this->once())
+ $serviceDB = $this->createMock(ServiceInterface::class);
+ $serviceDB->expects($this->once())
->method('getVersion')
->willReturn('10.2');
- $this->serviceFactory->expects($this->exactly(3))
+ $serviceES = $this->createMock(ServiceInterface::class);
+ $serviceES->expects($this->once())
+ ->method('getVersion')
+ ->willReturn('7.7');
+ $this->serviceFactory->expects($this->exactly(4))
->method('create')
- ->willReturnOnConsecutiveCalls($service1, $service2, $service3);
- $this->serviceVersionValidatorMock->expects($this->exactly(2))
+ ->willReturnOnConsecutiveCalls($serviceRmq, $serviceRedis, $serviceDB, $serviceES);
+ $this->loggerMock->expects($this->exactly(4))
+ ->method('info')
+ ->withConsecutive(
+ ['Version of service \'rabbitmq\' is not detected', []],
+ ['Version of service \'redis\' is 3.2', []],
+ ['Version of service \'mysql\' is 10.2', []],
+ ['Version of service \'elasticsearch\' is 7.7', []]
+ );
+ $this->serviceVersionValidatorMock->expects($this->exactly(3))
->method('validateService')
->withConsecutive(
[ServiceInterface::NAME_REDIS, '3.2'],
- [ServiceInterface::NAME_DB, '10.2']
+ [ServiceInterface::NAME_DB, '10.2'],
+ [ServiceInterface::NAME_ELASTICSEARCH, '7.7']
)
->willReturn('');
$this->resultFactoryMock->expects($this->once())
@@ -92,9 +113,9 @@ public function testValidate()
$this->validator->validate();
}
- public function testValidateWithErrors()
+ public function testValidateWithErrors(): void
{
- $errorMessages = ['error message 1', 'error message 2', 'error message 3'];
+ $errorMessages = ['error message 1', 'error message 2', 'error message 3', 'error message 4'];
$service1 = $this->createMock(ServiceInterface::class);
$service1->expects($this->once())
->method('getVersion')
@@ -107,15 +128,20 @@ public function testValidateWithErrors()
$service3->expects($this->once())
->method('getVersion')
->willReturn('5.7');
- $this->serviceFactory->expects($this->exactly(3))
+ $service4 = $this->createMock(ServiceInterface::class);
+ $service4->expects($this->once())
+ ->method('getVersion')
+ ->willReturn('7.7');
+ $this->serviceFactory->expects($this->exactly(4))
->method('create')
- ->willReturnOnConsecutiveCalls($service1, $service2, $service3);
- $this->serviceVersionValidatorMock->expects($this->exactly(3))
+ ->willReturnOnConsecutiveCalls($service1, $service2, $service3, $service4);
+ $this->serviceVersionValidatorMock->expects($this->exactly(4))
->method('validateService')
->withConsecutive(
[ServiceInterface::NAME_RABBITMQ, '1.5'],
[ServiceInterface::NAME_REDIS, '2.2'],
- [ServiceInterface::NAME_DB, '5.7']
+ [ServiceInterface::NAME_DB, '5.7'],
+ [ServiceInterface::NAME_ELASTICSEARCH, '7.7']
)
->willReturnOnConsecutiveCalls(...$errorMessages);
$this->resultFactoryMock->expects($this->once())
@@ -125,7 +151,7 @@ public function testValidateWithErrors()
$this->validator->validate();
}
- public function testValidateWithException()
+ public function testValidateWithException(): void
{
$this->serviceFactory->expects($this->any())
->method('create')
diff --git a/src/Test/Unit/DB/Data/ConnectionTypesTest.php b/src/Test/Unit/DB/Data/ConnectionTypesTest.php
new file mode 100644
index 0000000000..562f637dd3
--- /dev/null
+++ b/src/Test/Unit/DB/Data/ConnectionTypesTest.php
@@ -0,0 +1,169 @@
+environmentMock = $this->createMock(Environment::class);
+
+ $this->connectionType = new ConnectionTypes(
+ $this->environmentMock
+ );
+ }
+
+ public function testGetConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ ],
+ $this->connectionType->getConfiguration()
+ );
+ }
+
+ public function testGetSlaveConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_SLAVE_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3304',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3304',
+ ],
+ $this->connectionType->getSlaveConfiguration()
+ );
+ }
+
+ public function testGetQuoteConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_QUOTE_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3307',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3307',
+ ],
+ $this->connectionType->getQuoteConfiguration()
+ );
+ }
+
+ public function testGetQuoteSlaveConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_QUOTE_SLAVE_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3308',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3308',
+ ],
+ $this->connectionType->getQuoteSlaveConfiguration()
+ );
+ }
+
+ public function testGetSalesConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_SALES_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3309',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3309',
+ ],
+ $this->connectionType->getSalesConfiguration()
+ );
+ }
+
+ public function testGetSaleSlaveConfiguration(): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(ConnectionTypes::RELATIONSHIP_SALES_SLAVE_KEY)
+ ->willReturn([
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3310',
+ ]
+ ]);
+
+ $this->assertSame(
+ [
+ 'host' => '127.0.0.1',
+ 'port' => '3310',
+ ],
+ $this->connectionType->getSalesSlaveConfiguration()
+ );
+ }
+}
diff --git a/src/Test/Unit/DB/Data/RelationshipConnectionFactoryTest.php b/src/Test/Unit/DB/Data/RelationshipConnectionFactoryTest.php
index cbf96ac53d..046723ec6b 100644
--- a/src/Test/Unit/DB/Data/RelationshipConnectionFactoryTest.php
+++ b/src/Test/Unit/DB/Data/RelationshipConnectionFactoryTest.php
@@ -7,9 +7,9 @@
namespace Magento\MagentoCloud\Test\Unit\DB\Data;
+use Magento\MagentoCloud\DB\Data\ConnectionTypes;
use Magento\MagentoCloud\DB\Data\RelationshipConnection;
use Magento\MagentoCloud\DB\Data\RelationshipConnectionFactory;
-use Magento\MagentoCloud\Service\Database;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -24,19 +24,19 @@ class RelationshipConnectionFactoryTest extends TestCase
private $factory;
/**
- * @var Database|MockObject
+ * @var ConnectionTypes|MockObject
*/
- private $databaseMock;
+ private $connectionTypeMock;
/**
* @inheritdoc
*/
protected function setUp()
{
- $this->databaseMock = $this->createMock(Database::class);
+ $this->connectionTypeMock = $this->createMock(ConnectionTypes::class);
$this->factory = new RelationshipConnectionFactory(
- $this->databaseMock
+ $this->connectionTypeMock
);
}
@@ -47,7 +47,7 @@ protected function setUp()
*/
public function testCreate(string $method, string $connectionType)
{
- $this->databaseMock->expects($this->once())
+ $this->connectionTypeMock->expects($this->once())
->method($method)
->willReturn([]);
diff --git a/src/Test/Unit/Service/DatabaseTest.php b/src/Test/Unit/Service/DatabaseTest.php
index 1c44a13b2a..8d5b4a9116 100644
--- a/src/Test/Unit/Service/DatabaseTest.php
+++ b/src/Test/Unit/Service/DatabaseTest.php
@@ -7,7 +7,8 @@
namespace Magento\MagentoCloud\Test\Unit\Service;
-use Magento\MagentoCloud\Config\Environment;
+use Magento\MagentoCloud\DB\ConnectionInterface;
+use Magento\MagentoCloud\DB\Data\ConnectionTypes;
use Magento\MagentoCloud\Service\Database;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -19,176 +20,129 @@ class DatabaseTest extends TestCase
{
/**
- * @var Database|MockObject
+ * @var Database
*/
private $database;
/**
- * @var Environment|MockObject
+ * @var ConnectionTypes|MockObject
*/
- private $environmentMock;
+ private $connectionTypeMock;
+
+ /**
+ * @var ConnectionInterface|MockObject
+ */
+ private $connectionMock;
/**
* @inheritdoc
*/
public function setUp()
{
- $this->environmentMock = $this->createMock(Environment::class);
+ $this->connectionTypeMock = $this->createMock(ConnectionTypes::class);
+ $this->connectionMock = $this->getMockForAbstractClass(ConnectionInterface::class);
$this->database = new Database(
- $this->environmentMock
+ $this->connectionTypeMock,
+ $this->connectionMock
);
}
- public function testGetConfiguration()
+ public function testGetConfiguration(): void
{
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_KEY)
- ->willReturn([
- [
- 'host' => '127.0.0.1',
- 'port' => '3306',
- ]
- ]);
+ $connection = [
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ ];
- $this->assertSame(
- [
- 'host' => '127.0.0.1',
- 'port' => '3306',
- ],
- $this->database->getConfiguration()
- );
- }
-
- public function testGetSlaveConfiguration()
- {
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_SLAVE_KEY)
- ->willReturn([
- [
- 'host' => '127.0.0.1',
- 'port' => '3307',
- ]
- ]);
+ $this->connectionTypeMock->expects($this->once())
+ ->method('getConfiguration')
+ ->willReturn($connection);
$this->assertSame(
- [
- 'host' => '127.0.0.1',
- 'port' => '3307',
- ],
- $this->database->getSlaveConfiguration()
+ $connection,
+ $this->database->getConfiguration()
);
}
- public function testGetQuoteConfiguration()
+ /**
+ * @param array $config
+ * @param string $expectedVersion
+ *
+ * @dataProvider getVersionFromConfigDataProvider
+ */
+ public function testGetVersionFromConfig(array $config, string $expectedVersion): void
{
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_QUOTE_KEY)
- ->willReturn([
- [
- 'host' => '127.0.0.1',
- 'port' => '3308',
- ]
- ]);
+ $this->connectionTypeMock->expects($this->once())
+ ->method('getConfiguration')
+ ->willReturn($config);
+ $this->connectionMock->expects($this->never())
+ ->method('selectOne');
- $this->assertSame(
- [
- 'host' => '127.0.0.1',
- 'port' => '3308',
- ],
- $this->database->getQuoteConfiguration()
- );
+ $this->assertEquals($expectedVersion, $this->database->getVersion());
}
- public function testGetQuoteSlaveConfiguration()
+ /**
+ * Data provider for testGetVersionFromConfig
+ * @return array
+ */
+ public function getVersionFromConfigDataProvider(): array
{
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_QUOTE_SLAVE_KEY)
- ->willReturn([
- [
- 'host' => '127.0.0.1',
- 'port' => '3309',
- ]
- ]);
-
- $this->assertSame(
+ return [
[
- 'host' => '127.0.0.1',
- 'port' => '3309',
- ],
- $this->database->getQuoteSlaveConfiguration()
- );
- }
-
- public function testGetSalesConfiguration()
- {
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_SALES_KEY)
- ->willReturn([
[
'host' => '127.0.0.1',
- 'port' => '3308',
- ]
- ]);
-
- $this->assertSame(
- [
- 'host' => '127.0.0.1',
- 'port' => '3308',
+ 'port' => '3306',
+ 'type' => 'mysql:10.2',
+ ],
+ '10.2'
],
- $this->database->getSalesConfiguration()
- );
- }
-
- public function testGetSaleSlaveConfiguration()
- {
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_SALES_SLAVE_KEY)
- ->willReturn([
- [
- 'host' => '127.0.0.1',
- 'port' => '3309',
- ]
- ]);
-
- $this->assertSame(
[
- 'host' => '127.0.0.1',
- 'port' => '3309',
- ],
- $this->database->getSalesSlaveConfiguration()
- );
+ ['host' => ''],
+ '0'
+ ]
+ ];
}
- public function testGetVersion()
+ /**
+ * @param array $version
+ * @param string $expectedResult
+ * @throws \Magento\MagentoCloud\Service\ServiceException
+ *
+ * @dataProvider getVersionDataProvider
+ */
+ public function testGetVersion(array $version, string $expectedResult): void
{
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_KEY)
- ->willReturn([
+ $this->connectionTypeMock->expects($this->once())
+ ->method('getConfiguration')
+ ->willReturn(
[
'host' => '127.0.0.1',
'port' => '3306',
- 'type' => 'mysql:10.2',
]
- ]);
+ );
- $this->assertEquals('10.2', $this->database->getVersion());
+ $this->connectionMock->expects($this->once())
+ ->method('selectOne')
+ ->with('SELECT VERSION() as version')
+ ->willReturn($version);
+
+ $this->assertEquals($expectedResult, $this->database->getVersion());
}
- public function testGetVersionNotConfigured()
+ /**
+ * Data provider for testGetVersion
+ * @return array
+ */
+ public function getVersionDataProvider(): array
{
- $this->environmentMock->expects($this->once())
- ->method('getRelationship')
- ->with(Database::RELATIONSHIP_KEY)
- ->willReturn([]);
-
- $this->assertEquals('0', $this->database->getVersion());
+ return [
+ [['version' => '10.2.33-MariaDB-10.2.33+maria~stretch-lo'], '10.2'],
+ [['version' => '10.3.20-MariaDB-1:10.3.20+maria~jessie'], '10.3'],
+ [['version' => 's10.3.20-MariaDB-1:10.3.20+maria~jessie'], '0'],
+ [['version' => ''], '0'],
+ [['version' => '10.version'], '0'],
+ [[], '0'],
+ ];
}
}
diff --git a/src/Test/Unit/Service/RabbitMqTest.php b/src/Test/Unit/Service/RabbitMqTest.php
index a2eeb32e34..1cf9cfe097 100644
--- a/src/Test/Unit/Service/RabbitMqTest.php
+++ b/src/Test/Unit/Service/RabbitMqTest.php
@@ -9,6 +9,10 @@
use Magento\MagentoCloud\Config\Environment;
use Magento\MagentoCloud\Service\RabbitMq;
+use Magento\MagentoCloud\Service\ServiceException;
+use Magento\MagentoCloud\Shell\ProcessInterface;
+use Magento\MagentoCloud\Shell\ShellException;
+use Magento\MagentoCloud\Shell\ShellInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -28,19 +32,26 @@ class RabbitMqTest extends TestCase
*/
private $environmentMock;
+ /**
+ * @var ShellInterface|MockObject
+ */
+ private $shellMock;
+
/**
* @inheritdoc
*/
public function setUp()
{
$this->environmentMock = $this->createMock(Environment::class);
+ $this->shellMock = $this->getMockForAbstractClass(ShellInterface::class);
$this->rabbitMq = new RabbitMq(
- $this->environmentMock
+ $this->environmentMock,
+ $this->shellMock
);
}
- public function testGetConfiguration()
+ public function testGetConfiguration(): void
{
$this->environmentMock->expects($this->exactly(3))
->method('getRelationship')
@@ -65,7 +76,7 @@ public function testGetConfiguration()
);
}
- public function testGetVersion()
+ public function testGetVersion(): void
{
$this->environmentMock->expects($this->exactly(3))
->method('getRelationship')
@@ -82,15 +93,94 @@ public function testGetVersion()
]
);
+ $this->shellMock->expects($this->never())
+ ->method('execute');
$this->assertEquals('3.7', $this->rabbitMq->getVersion());
}
- public function testGetVersionNotConfigured()
+ /**
+ * @throws ServiceException
+ */
+ public function testGetVersionNotInstalled(): void
{
$this->environmentMock->expects($this->exactly(3))
->method('getRelationship')
- ->willReturn([]);
+ ->withConsecutive(['rabbitmq'], ['mq'], ['amqp'])
+ ->willReturnOnConsecutiveCalls(
+ [],
+ [],
+ []
+ );
+ $this->shellMock->expects($this->never())
+ ->method('execute');
$this->assertEquals('0', $this->rabbitMq->getVersion());
}
+
+ /**
+ * @param string $version
+ * @param string $expectedResult
+ * @throws ServiceException
+ *
+ * @dataProvider getVersionFromCliDataProvider
+ */
+ public function testGetVersionFromCli(string $version, string $expectedResult): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with('rabbitmq')
+ ->willReturn([[
+ 'host' => '127.0.0.1',
+ 'port' => '5672',
+ ]]);
+
+ $processMock = $this->getMockForAbstractClass(ProcessInterface::class);
+ $processMock->expects($this->once())
+ ->method('getOutput')
+ ->willReturn($version);
+ $this->shellMock->expects($this->once())
+ ->method('execute')
+ ->with('dpkg -s rabbitmq-server | grep Version')
+ ->willReturn($processMock);
+
+ $this->assertEquals($expectedResult, $this->rabbitMq->getVersion());
+ }
+
+ /**
+ * Data provider for testGetVersionFromCli
+ * @return array
+ */
+ public function getVersionFromCliDataProvider(): array
+ {
+ return [
+ ['Version: 3.8.5', '3.8'],
+ ['Version:3.8.5', '3.8'],
+ ['Version: 111.222.333', '111.222'],
+ ['Version: some version', '0'],
+ ['redis_version:abc', '0'],
+ ['redis:5.3.6', '0'],
+ ['', '0'],
+ ['error', '0'],
+ ];
+ }
+
+ public function testGetVersionWithException(): void
+ {
+ $exceptionMessage = 'Some shell exception';
+ $this->expectException(ServiceException::class);
+ $this->expectExceptionMessage($exceptionMessage);
+
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with('rabbitmq')
+ ->willReturn([[
+ 'host' => '127.0.0.1',
+ 'port' => '5672',
+ ]]);
+
+ $this->shellMock->expects($this->once())
+ ->method('execute')
+ ->willThrowException(new ShellException($exceptionMessage));
+ $this->rabbitMq->getVersion();
+ }
}
diff --git a/src/Test/Unit/Service/RedisTest.php b/src/Test/Unit/Service/RedisTest.php
index ba93f0daf0..7d27c4f2ec 100644
--- a/src/Test/Unit/Service/RedisTest.php
+++ b/src/Test/Unit/Service/RedisTest.php
@@ -9,6 +9,10 @@
use Magento\MagentoCloud\Config\Environment;
use Magento\MagentoCloud\Service\Redis;
+use Magento\MagentoCloud\Service\ServiceException;
+use Magento\MagentoCloud\Shell\ProcessInterface;
+use Magento\MagentoCloud\Shell\ShellException;
+use Magento\MagentoCloud\Shell\ShellInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -19,7 +23,7 @@ class RedisTest extends TestCase
{
/**
- * @var Redis|MockObject
+ * @var Redis
*/
private $redis;
@@ -28,19 +32,26 @@ class RedisTest extends TestCase
*/
private $environmentMock;
+ /**
+ * @var ShellInterface|MockObject
+ */
+ private $shellMock;
+
/**
* @inheritdoc
*/
public function setUp()
{
$this->environmentMock = $this->createMock(Environment::class);
+ $this->shellMock = $this->getMockForAbstractClass(ShellInterface::class);
$this->redis = new Redis(
- $this->environmentMock
+ $this->environmentMock,
+ $this->shellMock
);
}
- public function testGetConfiguration()
+ public function testGetConfiguration(): void
{
$this->environmentMock->expects($this->once())
->method('getRelationship')
@@ -61,7 +72,7 @@ public function testGetConfiguration()
);
}
- public function testGetSlaveConfiguration()
+ public function testGetSlaveConfiguration(): void
{
$this->environmentMock->expects($this->once())
->method('getRelationship')
@@ -82,29 +93,118 @@ public function testGetSlaveConfiguration()
);
}
- public function testGetVersion()
+ /**
+ * @param array $config
+ * @param string $expectedResult
+ * @throws \Magento\MagentoCloud\Service\ServiceException
+ * @throws \ReflectionException
+ *
+ * @dataProvider getVersionFromConfigDataProvider
+ */
+ public function testGetVersionFromConfig(array $config, string $expectedResult): void
{
$this->environmentMock->expects($this->once())
->method('getRelationship')
->with(Redis::RELATIONSHIP_KEY)
- ->willReturn([
- [
+ ->willReturn($config);
+
+ $this->shellMock->expects($this->never())
+ ->method('execute');
+
+ $this->assertEquals($expectedResult, $this->redis->getVersion());
+ }
+
+ /**
+ * Data provider for testGetVersionFromConfig
+ * @return array
+ */
+ public function getVersionFromConfigDataProvider(): array
+ {
+ return [
+ [
+ [[
'host' => '127.0.0.1',
'port' => '3306',
- 'type' => 'mysql:10.2',
- ]
- ]);
+ 'type' => 'redis:10.2'
+ ]],
+ '10.2'
+ ],
+ [
+ [[
+ 'type' => 'redis:10.2.5'
+ ]],
+ '10.2.5'
+ ],
+ [
+ [],
+ '0'
+ ],
+ ];
+ }
+
+ /**
+ * @param string $version
+ * @param string $expectedResult
+ * @throws \Magento\MagentoCloud\Service\ServiceException
+ * @throws \ReflectionException
+ *
+ * @dataProvider getVersionFromCliDataProvider
+ */
+ public function testGetVersionFromCli(string $version, string $expectedResult): void
+ {
+ $this->environmentMock->expects($this->once())
+ ->method('getRelationship')
+ ->with(Redis::RELATIONSHIP_KEY)
+ ->willReturn([[
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ ]]);
+
+ $processMock = $this->getMockForAbstractClass(ProcessInterface::class);
+ $processMock->expects($this->once())
+ ->method('getOutput')
+ ->willReturn($version);
+ $this->shellMock->expects($this->once())
+ ->method('execute')
+ ->with('redis-cli -p 3306 -h 127.0.0.1 info | grep redis_version')
+ ->willReturn($processMock);
- $this->assertEquals('10.2', $this->redis->getVersion());
+ $this->assertEquals($expectedResult, $this->redis->getVersion());
+ }
+
+ /**
+ * Data provider for testGetVersionFromCli
+ * @return array
+ */
+ public function getVersionFromCliDataProvider(): array
+ {
+ return [
+ ['redis_version:5.3.6', '5.3'],
+ ['redis_version:1.2.3.4.5', '1.2'],
+ ['redis_version:abc', '0'],
+ ['redis:5.3.6', '0'],
+ ['', '0'],
+ ['error', '0'],
+ ];
}
- public function testGetVersionNotConfigured()
+ public function testGetVersionWithException()
{
+ $exceptionMessage = 'Some shell exception';
+ $this->expectException(ServiceException::class);
+ $this->expectExceptionMessage($exceptionMessage);
+
$this->environmentMock->expects($this->once())
->method('getRelationship')
->with(Redis::RELATIONSHIP_KEY)
- ->willReturn([]);
+ ->willReturn([[
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ ]]);
- $this->assertEquals('0', $this->redis->getVersion());
+ $this->shellMock->expects($this->once())
+ ->method('execute')
+ ->willThrowException(new ShellException($exceptionMessage));
+ $this->redis->getVersion();
}
}
diff --git a/src/Test/Unit/Service/ValidatorTest.php b/src/Test/Unit/Service/ValidatorTest.php
index fa42ad192c..b46745b890 100644
--- a/src/Test/Unit/Service/ValidatorTest.php
+++ b/src/Test/Unit/Service/ValidatorTest.php
@@ -107,6 +107,8 @@ public function testValidateNonexistentService()
/**
* @return array
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function validateVersionsDataProvider(): array
{
@@ -180,6 +182,51 @@ public function validateVersionsDataProvider(): array
],
0
],
+ [
+ '2.4.1',
+ [
+ ServiceInterface::NAME_PHP => '7.4',
+ ServiceInterface::NAME_DB => '10.4',
+ ServiceInterface::NAME_NGINX => '1.9',
+ ServiceInterface::NAME_VARNISH => '6.2',
+ ServiceInterface::NAME_REDIS => '5.0',
+ ServiceInterface::NAME_ELASTICSEARCH => '7.9', // wrong
+ ServiceInterface::NAME_RABBITMQ => '3.8'
+ ],
+ 1
+ ],
+ [
+ '2.4.2',
+ [
+ ServiceInterface::NAME_PHP => '7.4',
+ ServiceInterface::NAME_DB => '10.4',
+ ServiceInterface::NAME_NGINX => '1.9',
+ ServiceInterface::NAME_VARNISH => '6.2',
+ ServiceInterface::NAME_REDIS => '5.0',
+ ServiceInterface::NAME_ELASTICSEARCH => '7.9',
+ ServiceInterface::NAME_RABBITMQ => '3.8'
+ ],
+ 0
+ ],
+ [
+ '2.3.6',
+ [
+ ServiceInterface::NAME_PHP => '7.4', // wrong
+ ServiceInterface::NAME_DB => '10.2',
+ ServiceInterface::NAME_NGINX => '1.19',
+ ServiceInterface::NAME_VARNISH => '6.2',
+ ServiceInterface::NAME_REDIS => '5.0',
+ ServiceInterface::NAME_ELASTICSEARCH => '7.9', //wrong
+ ],
+ 2
+ ],
+ [
+ '2.3.7',
+ [
+ ServiceInterface::NAME_ELASTICSEARCH => '7.9',
+ ],
+ 0
+ ],
[
'2.1.4',
[ServiceInterface::NAME_PHP => '5.6'],
diff --git a/src/Test/Unit/Step/Build/BackupData/StaticContentTest.php b/src/Test/Unit/Step/Build/BackupData/StaticContentTest.php
index 371b1068c1..582daec21f 100644
--- a/src/Test/Unit/Step/Build/BackupData/StaticContentTest.php
+++ b/src/Test/Unit/Step/Build/BackupData/StaticContentTest.php
@@ -8,6 +8,7 @@
namespace Magento\MagentoCloud\Test\Unit\Step\Build\BackupData;
use Magento\MagentoCloud\App\Error;
+use Magento\MagentoCloud\Config\Environment;
use Magento\MagentoCloud\Step\StepException;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -48,6 +49,11 @@ class StaticContentTest extends TestCase
*/
private $flagManagerMock;
+ /**
+ * @var Environment|MockObject
+ */
+ private $environment;
+
/**
* @var string
*/
@@ -74,6 +80,7 @@ protected function setUp(): void
->getMockForAbstractClass();
$this->directoryListMock = $this->createMock(DirectoryList::class);
$this->flagManagerMock = $this->createMock(FlagManager::class);
+ $this->environment = $this->createMock(Environment::class);
$this->flagManagerMock->expects($this->once())
->method('delete')
@@ -83,7 +90,8 @@ protected function setUp(): void
$this->fileMock,
$this->loggerMock,
$this->directoryListMock,
- $this->flagManagerMock
+ $this->flagManagerMock,
+ $this->environment
);
}
@@ -125,6 +133,10 @@ public function testExecuteFlagSCDInBuildExistsAndInitPubStaticExists(): void
->with($this->originalPubStaticPath, $this->initPubStaticPath);
$this->fileMock->expects($this->never())
->method('copyDirectory');
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -171,6 +183,10 @@ public function testExecuteFlagSCDInBuildExistsAndInitPubStaticDoesNotExist(): v
->with($this->originalPubStaticPath, $this->initPubStaticPath);
$this->fileMock->expects($this->never())
->method('copyDirectory');
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -216,6 +232,10 @@ public function testExecuteSCDInAndInitPubStaticDoesNotExistAndRecreatePubStatic
->with($this->originalPubStaticPath, $this->initPubStaticPath);
$this->fileMock->expects($this->never())
->method('copyDirectory');
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -273,6 +293,10 @@ public function testCopyingWithException(): void
$this->expectException(StepException::class);
$this->expectExceptionMessage('some error');
$this->expectExceptionCode(Error::BUILD_SCD_COPYING_FAILED);
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -313,12 +337,16 @@ public function prepareCopying(): void
->method('rename')
->with($this->originalPubStaticPath, $this->initPubStaticPath)
->willThrowException(new FileSystemException('Some error'));
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
}
/**
* @throws StepException
*/
- public function testClearingDirectoryWithFileSystemException()
+ public function testClearingDirectoryWithFileSystemException(): void
{
$this->expectException(StepException::class);
$this->expectExceptionMessage('some error');
@@ -341,6 +369,29 @@ public function testClearingDirectoryWithFileSystemException()
->method('backgroundClearDirectory')
->with($this->initPubStaticPath)
->willThrowException(new FileSystemException('some error'));
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
+
+ $this->step->execute();
+ }
+
+ public function testExecuteScdOnBuildAndReadonly(): void
+ {
+ $this->flagManagerMock->expects(self::once())
+ ->method('exists')
+ ->with(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
+ ->willReturn(true);
+ $this->loggerMock->expects(self::once())
+ ->method('info')
+ ->withConsecutive(
+ ['Static content was not moved to ./init directory']
+ );
+ $this->environment->expects($this->once())
+ ->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(false);
$this->step->execute();
}
diff --git a/src/Test/Unit/Step/Build/ComposerDumpAutoloadTest.php b/src/Test/Unit/Step/Build/ComposerDumpAutoloadTest.php
index 6d151f5d2a..04fab70783 100644
--- a/src/Test/Unit/Step/Build/ComposerDumpAutoloadTest.php
+++ b/src/Test/Unit/Step/Build/ComposerDumpAutoloadTest.php
@@ -8,12 +8,15 @@
namespace Magento\MagentoCloud\Test\Unit\Step\Build;
use Magento\MagentoCloud\App\Error;
+use Magento\MagentoCloud\Config\ConfigException;
+use Magento\MagentoCloud\Config\Stage\BuildInterface;
use Magento\MagentoCloud\Step\Build\ComposerDumpAutoload;
use Magento\MagentoCloud\Shell\ShellException;
use Magento\MagentoCloud\Shell\ShellInterface;
use Magento\MagentoCloud\Step\StepException;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
/**
* @inheritdoc
@@ -28,18 +31,31 @@ class ComposerDumpAutoloadTest extends TestCase
/**
* @var ShellInterface|MockObject
*/
- private $shell;
+ private $shellMock;
+
+ /**
+ * @var BuildInterface|MockObject
+ */
+ private $stageConfigMock;
+
+ /**
+ * @var LoggerInterface|MockObject
+ */
+ private $loggerMock;
/**
* @inheritdoc
*/
protected function setUp(): void
{
- $this->shell = $this->getMockBuilder(ShellInterface::class)
- ->getMockForAbstractClass();
+ $this->shellMock = $this->getMockForAbstractClass(ShellInterface::class);
+ $this->stageConfigMock = $this->getMockForAbstractClass(BuildInterface::class);
+ $this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
$this->step = new ComposerDumpAutoload(
- $this->shell
+ $this->shellMock,
+ $this->stageConfigMock,
+ $this->loggerMock
);
}
@@ -48,13 +64,37 @@ protected function setUp(): void
*/
public function testExecute(): void
{
- $this->shell->expects($this->once())
+ $this->stageConfigMock->expects($this->once())
+ ->method('get')
+ ->with(BuildInterface::VAR_SKIP_COMPOSER_DUMP_AUTOLOAD)
+ ->willReturn(false);
+ $this->shellMock->expects($this->once())
->method('execute')
->with('composer dump-autoload -o --ansi --no-interaction');
$this->step->execute();
}
+ /**
+ * @throws StepException
+ */
+ public function testExecuteDumpSkipped(): void
+ {
+ $this->stageConfigMock->expects($this->once())
+ ->method('get')
+ ->with(BuildInterface::VAR_SKIP_COMPOSER_DUMP_AUTOLOAD)
+ ->willReturn(true);
+ $this->loggerMock->expects($this->once())
+ ->method('info')
+ ->with(
+ 'The composer dump-autoload command was skipped as SKIP_COMPOSER_DUMP_AUTOLOAD variable is set to true'
+ );
+ $this->shellMock->expects($this->never())
+ ->method('execute');
+
+ $this->step->execute();
+ }
+
/**
* @throws StepException
*/
@@ -64,11 +104,29 @@ public function testExecuteWithException(): void
$this->expectExceptionMessage('something went wrong');
$this->expectExceptionCode(Error::BUILD_COMPOSER_DUMP_AUTOLOAD_FAILED);
- $this->shell->expects($this->once())
+ $this->shellMock->expects($this->once())
->method('execute')
->with('composer dump-autoload -o --ansi --no-interaction')
->willThrowException(new ShellException('something went wrong'));
$this->step->execute();
}
+
+ /**
+ * @throws StepException
+ */
+ public function testExecuteWithConfigException(): void
+ {
+ $this->expectException(StepException::class);
+ $this->expectExceptionMessage('something went wrong');
+ $this->expectExceptionCode(10);
+
+ $this->stageConfigMock->expects($this->once())
+ ->method('get')
+ ->willThrowException(new ConfigException('something went wrong', 10));
+ $this->shellMock->expects($this->never())
+ ->method('execute');
+
+ $this->step->execute();
+ }
}
diff --git a/src/Test/Unit/Step/Deploy/PreDeploy/CleanStaticContentTest.php b/src/Test/Unit/Step/Deploy/PreDeploy/CleanStaticContentTest.php
index c3de3e1dca..4946d218b3 100644
--- a/src/Test/Unit/Step/Deploy/PreDeploy/CleanStaticContentTest.php
+++ b/src/Test/Unit/Step/Deploy/PreDeploy/CleanStaticContentTest.php
@@ -93,10 +93,10 @@ public function testExecute(): void
->method('exists')
->with(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
->willReturn(true);
- $this->stageConfigMock->expects($this->once())
- ->method('get')
- ->with(DeployInterface::VAR_CLEAN_STATIC_FILES)
- ->willReturn(true);
+ $this->stageConfigMock->method('get')
+ ->willReturnMap([
+ [DeployInterface::VAR_CLEAN_STATIC_FILES, true]
+ ]);
$this->directoryListMock->expects($this->once())
->method('getMagentoRoot')
->willReturn('magento_root');
@@ -109,6 +109,9 @@ public function testExecute(): void
['Static content deployment was performed during build hook, cleaning old content.'],
['Clearing pub/static']
);
+ $this->environmentMock->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -143,16 +146,19 @@ public function testExecuteWithDeployInBuildNoClean(): void
->method('exists')
->with(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
->willReturn(true);
- $this->stageConfigMock->expects($this->once())
- ->method('get')
- ->with(DeployInterface::VAR_CLEAN_STATIC_FILES)
- ->willReturn(false);
+ $this->stageConfigMock->method('get')
+ ->willReturnMap([
+ [DeployInterface::VAR_CLEAN_STATIC_FILES, false]
+ ]);
$this->directoryListMock->expects($this->never())
->method('getMagentoRoot')
->willReturn('magento_root');
$this->fileMock->expects($this->never())
->method('backgroundClearDirectory')
->with('magento_root/pub/static');
+ $this->environmentMock->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -160,7 +166,7 @@ public function testExecuteWithDeployInBuildNoClean(): void
/**
* @throws StepException
*/
- public function testExecuteWithFileSystemException()
+ public function testExecuteWithFileSystemException(): void
{
$this->expectExceptionCode(Error::DEPLOY_SCD_CLEAN_FAILED);
$this->expectException(StepException::class);
@@ -170,13 +176,16 @@ public function testExecuteWithFileSystemException()
->method('exists')
->with(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
->willReturn(true);
- $this->stageConfigMock->expects($this->once())
- ->method('get')
- ->with(DeployInterface::VAR_CLEAN_STATIC_FILES)
- ->willReturn(true);
+ $this->stageConfigMock->method('get')
+ ->willReturnMap([
+ [DeployInterface::VAR_CLEAN_STATIC_FILES, true]
+ ]);
$this->fileMock->expects($this->once())
->method('backgroundClearDirectory')
->willThrowException(new FileSystemException('some error'));
+ $this->environmentMock->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(true);
$this->step->execute();
}
@@ -184,7 +193,7 @@ public function testExecuteWithFileSystemException()
/**
* @throws StepException
*/
- public function testExecuteWithGenericException()
+ public function testExecuteWithGenericException(): void
{
$this->expectExceptionCode(10);
$this->expectException(StepException::class);
@@ -200,4 +209,27 @@ public function testExecuteWithGenericException()
$this->step->execute();
}
+
+ public function testExecuteWithDeployInBuildCleanNoMoveScd(): void
+ {
+ $this->flagManagerMock->expects(self::once())
+ ->method('exists')
+ ->with(FlagManager::FLAG_STATIC_CONTENT_DEPLOY_IN_BUILD)
+ ->willReturn(true);
+ $this->stageConfigMock->method('get')
+ ->willReturnMap([
+ [DeployInterface::VAR_CLEAN_STATIC_FILES, true]
+ ]);
+ $this->directoryListMock->expects(self::never())
+ ->method('getMagentoRoot')
+ ->willReturn('magento_root');
+ $this->fileMock->expects(self::never())
+ ->method('backgroundClearDirectory')
+ ->with('magento_root/pub/static');
+ $this->environmentMock->method('hasMount')
+ ->with(Environment::MOUNT_PUB_STATIC)
+ ->willReturn(false);
+
+ $this->step->execute();
+ }
}
diff --git a/src/Test/Unit/Step/PostDeploy/WarmUpTest.php b/src/Test/Unit/Step/PostDeploy/WarmUpTest.php
index bd15ecbb2c..b2250529cc 100644
--- a/src/Test/Unit/Step/PostDeploy/WarmUpTest.php
+++ b/src/Test/Unit/Step/PostDeploy/WarmUpTest.php
@@ -185,6 +185,14 @@ public function testExecuteWithConcurrency()
];
$concurrency = 2;
+ $this->loggerMock->expects($this->any())
+ ->method('info')
+ ->withConsecutive(
+ ['Starting page warmup'],
+ ['Warmup concurrency set to ' . $concurrency . ' as specified by the '
+ . PostDeployInterface::VAR_WARM_UP_CONCURRENCY . ' configuration']
+ );
+
$this->urlsMock->method('getAll')
->willReturn($urls);
$this->postDeployMock->method('get')
diff --git a/src/Util/BuildDirCopier.php b/src/Util/BuildDirCopier.php
index 839d7b8ea4..64a0a26477 100644
--- a/src/Util/BuildDirCopier.php
+++ b/src/Util/BuildDirCopier.php
@@ -56,7 +56,7 @@ public function __construct(
*
* @throws UndefinedPackageException
*/
- public function copy(string $dir, string $strategyName)
+ public function copy(string $dir, string $strategyName): void
{
try {
$magentoRoot = $this->directoryList->getMagentoRoot();
diff --git a/tests/travis/prepare_functional_parallel.sh b/tests/travis/prepare_functional_parallel.sh
index a99f80e5b2..ba44c3b9e5 100755
--- a/tests/travis/prepare_functional_parallel.sh
+++ b/tests/travis/prepare_functional_parallel.sh
@@ -8,15 +8,9 @@ trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit
php_version="${TRAVIS_PHP_VERSION//./}"
-readarray -t test_set_list <<< "$(grep -Rl php${php_version} --exclude='*AcceptanceCest.php' --exclude='*AcceptanceCeCest.php' --exclude='*AcceptanceCe71Cest.php' --exclude='*AcceptanceCe72Cest.php' --exclude='*AcceptanceCe73Cest.php' --exclude='*AbstractCest.php' src/Test/Functional/Acceptance | sort)"
+test_set_list=($(grep -Rl php${php_version} --exclude='*AcceptanceCest.php' --exclude='*AcceptanceCeCest.php' --exclude='*AcceptanceCe71Cest.php' --exclude='*AcceptanceCe72Cest.php' --exclude='*AcceptanceCe73Cest.php' --exclude='*AbstractCest.php' src/Test/Functional/Acceptance | sort))
group_count=6
-if [ $(( ${#test_set_list[@]} % group_count )) -eq 0 ]; then
- element_in_group=$(printf "%.0f" "$(echo "scale=2;(${#test_set_list[@]})/${group_count}" | bc)")
-else
- element_in_group=$(printf "%.0f" "$(echo "scale=2;(${#test_set_list[@]} + ${group_count} - 1)/${group_count}" | bc)")
-fi
-
cp codeception.dist.yml codeception.yml
echo "groups:" >> codeception.yml
echo " parallel_${php_version}_*: tests/functional/_data/parallel_${php_version}_*" >> codeception.yml
@@ -30,15 +24,11 @@ else
start_group_id=1
fi
-for((i=0, group_id=start_group_id; i < ${#test_set_list[@]}; i+=element_in_group, group_id++))
+for((i=0, group_id=start_group_id; i < ${#test_set_list[@]}; i+=1, group_id++))
do
- test_file_group=( "${test_set_list[@]:i:element_in_group}" )
- echo "Batch #${group_id} = ${#test_file_group[@]}"
-
+ if [ $group_id -gt $group_count ]; then
+ group_id=$start_group_id
+ fi
group_file="tests/functional/_data/parallel_${php_version}_$group_id.yml"
-
- for test_file in "${test_file_group[@]}"
- do
- echo "$test_file" >> "$group_file"
- done
+ echo "${test_set_list[i]}" >> "$group_file"
done
diff --git a/travis.php.ini b/travis.php.ini
new file mode 100644
index 0000000000..0b1342670d
--- /dev/null
+++ b/travis.php.ini
@@ -0,0 +1 @@
+memory_limit = 4G