diff --git a/src/Command/BuildCompose.php b/src/Command/BuildCompose.php index 407bac1b..093303c5 100644 --- a/src/Command/BuildCompose.php +++ b/src/Command/BuildCompose.php @@ -225,6 +225,11 @@ protected function configure(): void null, InputOption::VALUE_NONE, 'Add Selenium latest version' + )->addOption( + Source\CliSource::OPTION_WITH_TEST, + null, + InputOption::VALUE_NONE, + 'Add container for tests running' )->addOption( Source\CliSource::OPTION_NO_TMP_MOUNTS, null, diff --git a/src/Compose/ProductionBuilder.php b/src/Compose/ProductionBuilder.php index 31dbee32..3da2c796 100644 --- a/src/Compose/ProductionBuilder.php +++ b/src/Compose/ProductionBuilder.php @@ -140,8 +140,8 @@ public function build(Config $config): Manager $manager->addNetwork(self::NETWORK_MAGENTO_BUILD, ['driver' => 'bridge']); $mounts = $config->getMounts(); - $hasSelenium = $config->hasSelenium(); $hasTmpMounts = $config->hasTmpMounts(); + $hasTest = $config->hasServiceEnabled(ServiceInterface::SERVICE_TEST); $hasGenerated = !version_compare($config->getMagentoVersion(), '2.2.0', '<'); $volumes = []; @@ -163,13 +163,13 @@ public function build(Config $config): Manager )); $volumesRo = $this->volumeResolver->normalize(array_merge( $this->volumeResolver->getRootVolume(true), - $this->volumeResolver->getDevVolumes($hasSelenium), + $this->volumeResolver->getDevVolumes($hasTest), $this->volumeResolver->getMagentoVolumes($mounts, true, $hasGenerated), $this->volumeResolver->getMountVolumes($hasTmpMounts) )); $volumesRw = $this->volumeResolver->normalize(array_merge( $this->volumeResolver->getRootVolume(false), - $this->volumeResolver->getDevVolumes($hasSelenium), + $this->volumeResolver->getDevVolumes($hasTest), $this->volumeResolver->getMagentoVolumes($mounts, false, $hasGenerated), $this->volumeResolver->getMountVolumes($hasTmpMounts), $this->volumeResolver->getComposerVolumes() @@ -294,6 +294,9 @@ public function build(Config $config): Manager [self::NETWORK_MAGENTO], [self::SERVICE_WEB => []] ); + } + + if ($hasTest) { $manager->addService( self::SERVICE_TEST, $this->serviceFactory->create( diff --git a/src/Compose/ProductionBuilder/VolumeResolver.php b/src/Compose/ProductionBuilder/VolumeResolver.php index 5b4429d8..12084e16 100644 --- a/src/Compose/ProductionBuilder/VolumeResolver.php +++ b/src/Compose/ProductionBuilder/VolumeResolver.php @@ -28,12 +28,12 @@ public function getRootVolume(bool $isReadOnly): array } /** - * @param bool $hasSelenium + * @param bool $hasTest * @return array */ - public function getDevVolumes(bool $hasSelenium): array + public function getDevVolumes(bool $hasTest): array { - if ($hasSelenium) { + if ($hasTest) { return [ BuilderInterface::VOLUME_MAGENTO_DEV => [ 'path' => BuilderInterface::DIR_MAGENTO . '/dev', diff --git a/src/Config/Config.php b/src/Config/Config.php index 67cd0093..cba6a563 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -337,7 +337,7 @@ public function getVariables(): array { $config = $this->all(); - if ($this->hasSelenium()) { + if ($this->hasServiceEnabled(ServiceInterface::SERVICE_TEST)) { $config->set(SourceInterface::VARIABLES . '.' . 'MFTF_UTILS', 1); } diff --git a/src/Config/Source/CliSource.php b/src/Config/Source/CliSource.php index 7a0e049a..6224d412 100644 --- a/src/Config/Source/CliSource.php +++ b/src/Config/Source/CliSource.php @@ -48,6 +48,7 @@ class CliSource implements SourceInterface public const OPTION_WITH_CRON = 'with-cron'; public const OPTION_NO_VARNISH = 'no-varnish'; public const OPTION_WITH_SELENIUM = 'with-selenium'; + public const OPTION_WITH_TEST = 'with-test'; public const OPTION_NO_TMP_MOUNTS = 'no-tmp-mounts'; public const OPTION_SYNC_ENGINE = 'sync-engine'; public const OPTION_WITH_XDEBUG = 'with-xdebug'; @@ -189,6 +190,12 @@ public function read(): Repository ]); } + if ($this->input->getOption(self::OPTION_WITH_TEST)) { + $repository->set([ + self::SERVICES_TEST_ENABLED => true + ]); + } + if ($seleniumImage = $this->input->getOption(self::OPTION_SELENIUM_IMAGE)) { $repository->set([ self::SERVICES_SELENIUM_ENABLED => true, diff --git a/src/Config/Source/SourceInterface.php b/src/Config/Source/SourceInterface.php index 11faf693..c4488b81 100644 --- a/src/Config/Source/SourceInterface.php +++ b/src/Config/Source/SourceInterface.php @@ -29,9 +29,11 @@ interface SourceInterface * Selenium */ public const SERVICES_SELENIUM = self::SERVICES . '.' . ServiceInterface::SERVICE_SELENIUM; + public const SERVICES_TEST = self::SERVICES . '.' . ServiceInterface::SERVICE_TEST; public const SERVICES_SELENIUM_VERSION = self::SERVICES_SELENIUM . '.version'; public const SERVICES_SELENIUM_IMAGE = self::SERVICES_SELENIUM . '.image'; public const SERVICES_SELENIUM_ENABLED = self::SERVICES_SELENIUM . '.enabled'; + public const SERVICES_TEST_ENABLED = self::SERVICES_TEST . '.enabled'; /** * Varnish @@ -39,11 +41,6 @@ interface SourceInterface public const SERVICES_VARNISH = self::SERVICES . '.' . ServiceInterface::SERVICE_VARNISH; public const SERVICES_VARNISH_ENABLED = self::SERVICES_VARNISH . '.enabled'; - /** - * TLS - */ - public const SERVICES_TLS = self::SERVICES . '.' . ServiceInterface::SERVICE_TLS; - /** * DB */ diff --git a/src/Service/ServiceInterface.php b/src/Service/ServiceInterface.php index 724df8d6..b2f44984 100644 --- a/src/Service/ServiceInterface.php +++ b/src/Service/ServiceInterface.php @@ -28,6 +28,7 @@ interface ServiceInterface public const SERVICE_NODE = 'node'; public const SERVICE_VARNISH = 'varnish'; public const SERVICE_SELENIUM = 'selenium'; + public const SERVICE_TEST = 'test'; public const SERVICE_TLS = 'tls'; public const SERVICE_GENERIC = 'generic'; public const SERVICE_BLACKFIRE = 'blackfire'; diff --git a/src/Test/Integration/BuildComposeTest.php b/src/Test/Integration/BuildComposeTest.php index 81a14500..df35305c 100644 --- a/src/Test/Integration/BuildComposeTest.php +++ b/src/Test/Integration/BuildComposeTest.php @@ -84,6 +84,24 @@ public function buildDataProvider(): array [ [CliSource::OPTION_MODE, BuilderFactory::BUILDER_PRODUCTION], [CliSource::OPTION_WITH_SELENIUM, true], + [CliSource::OPTION_WITH_TEST, true], + [CliSource::OPTION_WITH_CRON, true], + [CliSource::OPTION_WITH_XDEBUG, true], + [CliSource::OPTION_ES, '5.2'], + [CliSource::OPTION_NO_ES, true], + [CliSource::OPTION_DB_INCREMENT_INCREMENT, 3], + [CliSource::OPTION_DB_INCREMENT_OFFSET, 2], + [CliSource::OPTION_WITH_ENTRYPOINT, true], + [CliSource::OPTION_WITH_MARIADB_CONF, true], + [CliSource::OPTION_TLS_PORT, '4443'], + [CliSource::OPTION_NO_MAILHOG, true] + ] + ], + 'cloud-base-test' => [ + __DIR__ . '/_files/cloud_base_test', + [ + [CliSource::OPTION_MODE, BuilderFactory::BUILDER_PRODUCTION], + [CliSource::OPTION_WITH_TEST, true], [CliSource::OPTION_WITH_CRON, true], [CliSource::OPTION_WITH_XDEBUG, true], [CliSource::OPTION_ES, '5.2'], diff --git a/src/Test/Integration/_files/cloud_base_test/.docker/.gitignore b/src/Test/Integration/_files/cloud_base_test/.docker/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/src/Test/Integration/_files/cloud_base_test/.docker/config.php.dist b/src/Test/Integration/_files/cloud_base_test/.docker/config.php.dist new file mode 100644 index 00000000..70d5fb5a --- /dev/null +++ b/src/Test/Integration/_files/cloud_base_test/.docker/config.php.dist @@ -0,0 +1,41 @@ + base64_encode(json_encode([ + 'database' => [ + [ + 'host' => 'db', + 'path' => 'magento2', + 'password' => 'magento2', + 'username' => 'magento2', + 'port' => '3306' + ] + ], + 'redis' => [ + [ + 'host' => 'redis', + 'port' => '6379' + ] + ] + ])), + 'MAGENTO_CLOUD_ROUTES' => base64_encode(json_encode([ + 'http://magento2.docker/' => [ + 'type' => 'upstream', + 'original_url' => 'http://{default}' + ], + 'https://magento2.docker/' => [ + 'type' => 'upstream', + 'original_url' => 'https://{default}' + ] + ])), + 'MAGENTO_CLOUD_VARIABLES' => base64_encode(json_encode([ + 'ADMIN_EMAIL' => 'admin@example.com', + 'ADMIN_PASSWORD' => '123123q', + 'ADMIN_URL' => 'admin' + ])), + 'MAGENTO_CLOUD_APPLICATION' => base64_encode(json_encode([ + 'hooks' => [ + + ] + ])), +]; diff --git a/src/Test/Integration/_files/cloud_base_test/.magento.app.yaml b/src/Test/Integration/_files/cloud_base_test/.magento.app.yaml new file mode 100644 index 00000000..aeaadbd0 --- /dev/null +++ b/src/Test/Integration/_files/cloud_base_test/.magento.app.yaml @@ -0,0 +1,29 @@ +name: mymagento + +type: php:7.3 +build: + flavor: composer + +runtime: + extensions: + - redis + - xsl + - json + - newrelic + - sodium + +relationships: + database: "mysql:mysql" + redis: "redis:redis" + elasticsearch: "elasticsearch:elasticsearch" + +mounts: + "var": "shared:files/var" + "app/etc": "shared:files/etc" + "pub/media": "shared:files/media" + "pub/static": "shared:files/static" + +crons: + cronrun: + spec: "* * * * *" + cmd: "php bin/magento cron:run" diff --git a/src/Test/Integration/_files/cloud_base_test/.magento/services.yaml b/src/Test/Integration/_files/cloud_base_test/.magento/services.yaml new file mode 100644 index 00000000..62bc6b64 --- /dev/null +++ b/src/Test/Integration/_files/cloud_base_test/.magento/services.yaml @@ -0,0 +1,10 @@ +mysql: + type: mysql:10.2 + disk: 2048 + +redis: + type: redis:5.0 + +elasticsearch: + type: elasticsearch:6.5 + disk: 1024 diff --git a/src/Test/Integration/_files/cloud_base_test/composer.json b/src/Test/Integration/_files/cloud_base_test/composer.json new file mode 100644 index 00000000..335d9b67 --- /dev/null +++ b/src/Test/Integration/_files/cloud_base_test/composer.json @@ -0,0 +1,6 @@ +{ + "name": "magento/project-enterprise-edition", + "description": "Composer file for integration tests", + "type": "project", + "version": "2.3.0" +} diff --git a/src/Test/Integration/_files/cloud_base_test/docker-compose.exp.yml b/src/Test/Integration/_files/cloud_base_test/docker-compose.exp.yml new file mode 100644 index 00000000..a3c5982c --- /dev/null +++ b/src/Test/Integration/_files/cloud_base_test/docker-compose.exp.yml @@ -0,0 +1,246 @@ +version: '2.1' +services: + db: + hostname: db.magento2.docker + image: 'mariadb:10.2' + environment: + - MYSQL_ROOT_PASSWORD=magento2 + - MYSQL_DATABASE=magento2 + - MYSQL_USER=magento2 + - MYSQL_PASSWORD=magento2 + ports: + - '3306' + volumes: + - '.docker/mnt:/mnt:rw,delegated' + - '.docker/mysql/mariadb.conf.d:/etc/mysql/mariadb.conf.d' + - 'mymagento-magento-db:/var/lib/mysql' + - '.docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d' + healthcheck: + test: 'mysqladmin ping -h localhost' + interval: 30s + timeout: 30s + retries: 3 + command: '--auto_increment_increment=3 --auto_increment_offset=2' + networks: + magento: + aliases: + - db.magento2.docker + redis: + hostname: redis.magento2.docker + image: 'redis:5.0' + volumes: + - /data + ports: + - 6379 + healthcheck: + test: 'redis-cli ping || exit 1' + interval: 30s + timeout: 30s + retries: 3 + networks: + magento: + aliases: + - redis.magento2.docker + fpm: + hostname: fpm.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-fpm-1.1' + extends: generic + volumes: + - '.:/app:ro,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:ro,delegated' + - 'magento-generated:/app/generated:ro,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + networks: + magento: + aliases: + - fpm.magento2.docker + depends_on: + db: + condition: service_healthy + web: + hostname: web.magento2.docker + image: 'magento/magento-cloud-docker-nginx:latest-1.1' + extends: generic + volumes: + - '.:/app:ro,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:ro,delegated' + - 'magento-generated:/app/generated:ro,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + environment: + - WITH_XDEBUG=1 + networks: + magento: + aliases: + - web.magento2.docker + depends_on: + fpm: + condition: service_started + varnish: + hostname: varnish.magento2.docker + image: 'magento/magento-cloud-docker-varnish:latest-1.1' + networks: + magento: + aliases: + - varnish.magento2.docker + depends_on: + web: + condition: service_started + tls: + hostname: tls.magento2.docker + image: 'magento/magento-cloud-docker-nginx:latest-1.1' + extends: generic + networks: + magento: + aliases: + - magento2.docker + environment: + UPSTREAM_HOST: varnish + ports: + - '80:80' + - '4443:443' + depends_on: + varnish: + condition: service_started + test: + hostname: test.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-cli-1.1' + extends: generic + volumes: + - '.:/app:rw,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:rw,delegated' + - 'magento-generated:/app/generated:rw,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + - '~/.composer/cache:/root/.composer/cache:rw,delegated' + networks: + magento: + aliases: + - test.magento2.docker + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + fpm_xdebug: + hostname: fpm_xdebug.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-fpm-1.1' + extends: generic + volumes: + - '.:/app:ro,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:ro,delegated' + - 'magento-generated:/app/generated:ro,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + environment: + - 'PHP_EXTENSIONS=bcmath bz2 calendar exif gd gettext intl mysqli pcntl pdo_mysql soap sockets sysvmsg sysvsem sysvshm opcache zip redis xsl sodium xdebug' + networks: + magento: + aliases: + - fpm_xdebug.magento2.docker + depends_on: + db: + condition: service_started + generic: + hostname: generic.magento2.docker + image: 'alpine:latest' + env_file: ./.docker/config.env + environment: + - 'PHP_EXTENSIONS=bcmath bz2 calendar exif gd gettext intl mysqli pcntl pdo_mysql soap sockets sysvmsg sysvsem sysvshm opcache zip redis xsl sodium' + build: + hostname: build.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-cli-1.1' + extends: generic + volumes: + - '.:/app:rw,delegated' + - 'magento-vendor:/app/vendor:rw,delegated' + - 'magento-generated:/app/generated:rw,delegated' + - '~/.composer/cache:/root/.composer/cache:rw,delegated' + networks: + magento-build: + aliases: + - build.magento2.docker + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + deploy: + hostname: deploy.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-cli-1.1' + extends: generic + volumes: + - '.:/app:ro,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:ro,delegated' + - 'magento-generated:/app/generated:ro,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + networks: + magento: + aliases: + - deploy.magento2.docker + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + cron: + hostname: cron.magento2.docker + image: 'magento/magento-cloud-docker-php:7.3-cli-1.1' + extends: generic + command: run-cron + environment: + CRONTAB: '* * * * * root cd /app && /usr/local/bin/php bin/magento cron:run >> /app/var/log/cron.log' + volumes: + - '.:/app:ro,delegated' + - './dev:/app/dev:rw,delegated' + - 'magento-vendor:/app/vendor:ro,delegated' + - 'magento-generated:/app/generated:ro,delegated' + - 'magento-var:/app/var:rw,delegated' + - 'magento-app-etc:/app/app/etc:rw,delegated' + - 'magento-pub-media:/app/pub/media:rw,delegated' + - 'magento-pub-static:/app/pub/static:rw,delegated' + - '.docker/mnt:/mnt:rw,delegated' + networks: + magento: + aliases: + - cron.magento2.docker + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy +volumes: + magento-vendor: { } + magento-generated: { } + magento-var: { } + magento-app-etc: { } + magento-pub-media: { } + magento-pub-static: { } + mymagento-magento-db: { } +networks: + magento: + driver: bridge + magento-build: + driver: bridge