diff --git a/tests/docker/Dockerfile b/tests/docker/Dockerfile deleted file mode 100644 index edd5914c2..000000000 --- a/tests/docker/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -FROM php:7.3-cli-alpine AS composer -RUN apk add wget -COPY ./scripts/install-composer.sh /tmp/install-composer.sh -RUN sh /tmp/install-composer.sh - - - - - -FROM php:7.3-cli-alpine AS deployer -RUN apk add \ - git \ - openssh-client \ - rsync - -RUN ssh-keygen \ - -q \ - -b 2048 \ - -t rsa \ - -f ~/.ssh/id_rsa - -RUN git config --global user.email "e2e@deployer.test" \ - && git config --global user.name "E2E Deployer" - -ARG XDEBUG_VERSION=2.9.8 -RUN set -eux; \ - apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ - pecl install xdebug-$XDEBUG_VERSION; \ - docker-php-ext-enable xdebug; \ - apk del .build-deps - -COPY scripts/php-code-coverage/coverage-start-wrapper.php /usr/local/etc/php/php-code-coverage/ -COPY conf/10-coverage.ini /usr/local/etc/php/conf.d/ - -COPY --from=composer /tmp/composer /bin/composer -VOLUME [ "/project" ] -WORKDIR /project - - - - - -FROM php:7.3-apache AS server -RUN apt-get update && apt-get install -y \ - acl \ - git \ - openssh-server \ - sudo \ - && rm -rf /var/lib/apt/lists/* - -# SSH login fix. Otherwise user is kicked off after login -RUN mkdir /run/sshd \ - && sed -i 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshd - -# Configure Apache to expose healthcheck & configure site to use /var/www/html/current ad document root -COPY conf/healthcheck.conf /etc/apache2/sites-available/healthcheck.conf -COPY ./initial-site /var/www/html/initial-site - -ENV APACHE_DOCUMENT_ROOT /var/www/html/current/public -RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/000-default.conf \ - && sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \ - && ln -s /var/www/html/initial-site /var/www/html/current \ - && chown -R www-data:www-data /var/www/html \ - && echo "Listen 81" >> /etc/apache2/ports.conf \ - && a2enmod rewrite \ - && a2ensite healthcheck - -RUN useradd \ - --create-home \ - deployer \ - && echo 'deployer:deployer' | chpasswd \ - && echo 'deployer ALL=(ALL) ALL' >> /etc/sudoers \ - && mkdir ~deployer/.ssh \ - && touch ~deployer/.ssh/authorized_keys \ - && chown -R deployer:deployer ~deployer/.ssh \ - && chmod 700 ~deployer/.ssh \ - && chmod 600 ~deployer/.ssh/authorized_keys \ - && usermod -a -G www-data deployer - -RUN useradd \ - --create-home \ - git \ - && mkdir ~git/.ssh \ - && touch ~git/.ssh/authorized_keys \ - && chown -R git:git ~git/.ssh \ - && chmod 700 ~git/.ssh \ - && chmod 700 ~git/.ssh/authorized_keys \ - && mkdir ~git/repository \ - && git init --bare ~git/repository \ - && chown -R git:git ~git/repository - -COPY scripts/start-servers.sh /usr/local/bin/start-servers -COPY --from=composer /tmp/composer /usr/local/bin/composer -COPY --from=deployer /root/.ssh/id_rsa.pub /tmp/root_rsa.pub - -RUN chmod a+x /usr/local/bin/start-servers \ - && cat /tmp/root_rsa.pub >> ~deployer/.ssh/authorized_keys \ - && cat /tmp/root_rsa.pub >> ~git/.ssh/authorized_keys \ - && rm -rf /tmp/root_rsa.pub - -EXPOSE 22 80 81 -CMD [ "start-servers" ] diff --git a/tests/docker/README.md b/tests/docker/README.md deleted file mode 100644 index eb7ef2342..000000000 --- a/tests/docker/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Deployer E2E testing environment - -This directory contains an end-to-end testing environment for Deployer. - -All commands mentioned in this readme, should be executed in the `docker` directory. - -## Requirements - -* Docker -* docker-compose - -## Running tests - -The E2E are started when running the `docker-compose up` command. -This will start the `server` container that has the Apache, OpenSSH & PHP 7.3 enabled. - -Once the `server` is up and running, the `deployer` container will be started and alongside it -the tests will be ran. - -## Adding new E2E tests - -The E2E test should be a part of the `e2e` test suite. -Each `e2e` test class should inherit from `AbstractE2ETest` class. - -Note: E2E tests will only run in an environment where env variable `E2E_ENV` has been set and has a truthy value. - -## Manually accessing the `deployer` container. - -The container can be accessed by running: - -``` -docker-compose run deployer sh -``` - -This command will spawn a `sh` shell inside the `deployer` container. - -## About containers - -### `deployer` container - -The `deployer` container contains: - -* git -* PHP 7.3 with XDebug enabled -* rsync -* SSH client - -It is possible to access the `server` container via ssh by running: - -``` -ssh deployer@server -``` - -`root`'s public key has been added to authorized keys for `deployer` user. - -#### Enabling XDebug - -To enable XDebug create a `docker-compose.override.yml` file with following content: - -```dockerfile -services: - deployer: - environment: - # See https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host - # See https://github.com/docker/for-linux/issues/264 - # The `remote_host` below may optionally be replaced with `remote_connect_back=1` - XDEBUG_CONFIG: >- - remote_enable=1 - remote_host=${XDEBUG_HOST:-host.docker.internal} - remote_autostart=1 - remote_port=9000 - idekey=PHPSTORM - # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` - # Then PHPStorm will use the corresponding path mappings - PHP_IDE_CONFIG: serverName=deployer-e2e -``` - -Note: you may want to set the `XDEBUG_HOST` env variable to point to your IP address when running tests in Linux. - -### `server` container - -The `server` container contains: - -* Apache (with the `DocumentRoot` set to `/var/www/html/current`) -* git -* PHP 7.3 -* SSH server with -* sudo (user `deployer` can use `sudo` after providing a password: `deployer`) diff --git a/tests/docker/conf/10-coverage.ini b/tests/docker/conf/10-coverage.ini deleted file mode 100644 index 038ce7c9e..000000000 --- a/tests/docker/conf/10-coverage.ini +++ /dev/null @@ -1,2 +0,0 @@ -auto_prepend_file = /usr/local/etc/php/php-code-coverage/coverage-start-wrapper.php -auto_append_file = /usr/local/etc/php/php-code-coverage/coverage-start-wrapper.php \ No newline at end of file diff --git a/tests/docker/conf/healthcheck.conf b/tests/docker/conf/healthcheck.conf deleted file mode 100644 index f51410f86..000000000 --- a/tests/docker/conf/healthcheck.conf +++ /dev/null @@ -1,32 +0,0 @@ - - # The ServerName directive sets the request scheme, hostname and port that - # the server uses to identify itself. This is used when creating - # redirection URLs. In the context of virtual hosts, the ServerName - # specifies what hostname must appear in the request's Host: header to - # match this virtual host. For the default virtual host (this file) this - # value is not decisive as it is used as a last resort host regardless. - # However, you must set it for any further virtual host explicitly. - #ServerName www.example.com - - ServerAdmin webmaster@localhost - DocumentRoot /var/www/html - - # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, - # error, crit, alert, emerg. - # It is also possible to configure the loglevel for particular - # modules, e.g. - #LogLevel info ssl:warn - - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - - RewriteEngine on - RedirectMatch 204 /health_check - - # For most configuration files from conf-available/, which are - # enabled or disabled at a global level, it is possible to - # include a line for only one particular virtual host. For example the - # following line enables the CGI configuration for this host only - # after it has been globally disabled with "a2disconf". - #Include conf-available/serve-cgi-bin.conf - diff --git a/tests/docker/docker-compose.yml b/tests/docker/docker-compose.yml deleted file mode 100644 index 7b0d16c6e..000000000 --- a/tests/docker/docker-compose.yml +++ /dev/null @@ -1,46 +0,0 @@ -services: - deployer: - build: - context: "" - target: deployer - depends_on: - server: - condition: service_healthy - volumes: - - ./../../:/project - command: "sh /project/tests/e2e/coverage/start-e2e-test.sh" - networks: - - e2e - environment: - PHP_CCOV_START_FILE: '/project/tests/e2e/coverage/coverage-start.php' - PHP_CCOV_OUTPUT_FILE: '/project/tests/e2e/report/clover.xml' -# # See https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host -# # See https://github.com/docker/for-linux/issues/264 -# # The `remote_host` below may optionally be replaced with `remote_connect_back=1` -# XDEBUG_CONFIG: >- -# remote_enable=1 -# remote_host=${XDEBUG_RHOST:-host.docker.internal} -# remote_autostart=1 -# remote_port=9000 -# idekey=PHPSTORM -# # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` -# # Then PHPStorm will use the corresponding path mappings -# PHP_IDE_CONFIG: serverName=deployer-e2e - - server: - build: - context: "" - target: server - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:81/health_check"] - interval: 5s - timeout: 2s - retries: 3 - start_period: 2s - networks: - e2e: - aliases: - - server.test - -networks: - e2e: diff --git a/tests/docker/initial-site/public/index.html b/tests/docker/initial-site/public/index.html deleted file mode 100644 index 5016ba876..000000000 --- a/tests/docker/initial-site/public/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - Hello World! - - \ No newline at end of file diff --git a/tests/docker/scripts/install-composer.sh b/tests/docker/scripts/install-composer.sh deleted file mode 100644 index e2ac87df5..000000000 --- a/tests/docker/scripts/install-composer.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -EXPECTED_CHECKSUM="$(wget -q -O - https://composer.github.io/installer.sig)" -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" - -if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ] -then - >&2 echo 'ERROR: Invalid installer checksum' - rm composer-setup.php - exit 1 -fi - -php composer-setup.php --quiet --install-dir=/tmp --filename=composer -RESULT=$? -rm composer-setup.php -chmod a+x /tmp/composer -exit $RESULT \ No newline at end of file diff --git a/tests/docker/scripts/php-code-coverage/coverage-start-wrapper.php b/tests/docker/scripts/php-code-coverage/coverage-start-wrapper.php deleted file mode 100644 index 5a3f7bc55..000000000 --- a/tests/docker/scripts/php-code-coverage/coverage-start-wrapper.php +++ /dev/null @@ -1,5 +0,0 @@ -tester = new ConsoleApplicationTester(__DIR__ . '/../../bin/dep', __DIR__); - } -} diff --git a/tests/e2e/ConsoleApplicationTester.php b/tests/e2e/ConsoleApplicationTester.php deleted file mode 100644 index 0e06b37e7..000000000 --- a/tests/e2e/ConsoleApplicationTester.php +++ /dev/null @@ -1,148 +0,0 @@ -binaryPath ], $arguments); - - $outputArgs = []; - foreach ($arguments as $key => $value) { - if (!is_numeric($key)) { - $outputArgs[] = $key; - } - - $outputArgs[] = $value; - } - - return $outputArgs; - } - - private function prepareProcess(array $arguments): Process - { - $commandLine = $this->generateCommand($arguments); - - $process = new Process($commandLine); - $process->setTimeout($this->timeout); - - if (!empty($this->inputs)) { - $inputs = self::createInputsStream($this->inputs); - $process->setInput($inputs); - } - - if (!empty($this->cwd)) { - $process->setWorkingDirectory($this->cwd); - } - - return $process; - } - - public function __construct(string $binaryPath, string $cwd = '') - { - $this->binaryPath = $binaryPath; - $this->cwd = $cwd; - } - - public function __destruct() - { - if ($this->process && $this->process->isRunning()) { - $this->process->stop(0); - } - } - - /** - * @param int $timeout timout in seconds after which process will be stopped - * @return $this - */ - public function setTimeout(int $timeout): self - { - $this->timeout = $timeout; - return $this; - } - - public function setInputs(array $inputs): self - { - $this->inputs = $inputs; - return $this; - } - - public function run(array $arguments): self - { - if ($this->process && $this->process->isRunning()) { - throw new \RuntimeException('Previous process did not end yet'); - } - - $this->process = $this->prepareProcess($arguments); - $this->process->run(); - - return $this; - } - - public function getDisplay(bool $normalize = false): string - { - if ($this->process === null) { - throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?'); - } - - $display = $this->process->getOutput(); - if ($normalize) { - $display = str_replace(\PHP_EOL, "\n", $display); - } - - return $display; - } - - public function getErrors(bool $normalize = false): string - { - if ($this->process === null) { - throw new \RuntimeException('Error output not initialized, did you execute the command before requesting the display?'); - } - - $display = $this->process->getErrorOutput(); - if ($normalize) { - $display = str_replace(\PHP_EOL, "\n", $display); - } - - return $display; - } - - public function getStatusCode() - { - if ($this->process === null) { - throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the display?'); - } - - return $this->process->getExitCode(); - } -} diff --git a/tests/e2e/FunctionsE2ETest.php b/tests/e2e/FunctionsE2ETest.php deleted file mode 100644 index f537f91ce..000000000 --- a/tests/e2e/FunctionsE2ETest.php +++ /dev/null @@ -1,27 +0,0 @@ -tester->run([ - '-f' => self::RECIPE, - 'test:functions:run-with-placeholders', - 'all', - ]); - - $display = trim($this->tester->getDisplay()); - - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('placeholder {{bar}} xyz%', $display); - } -} diff --git a/tests/e2e/LaravelBoilerplateE2ETest.php b/tests/e2e/LaravelBoilerplateE2ETest.php deleted file mode 100644 index 33e97467f..000000000 --- a/tests/e2e/LaravelBoilerplateE2ETest.php +++ /dev/null @@ -1,40 +0,0 @@ -tester->setTimeout(180) - ->run([ - '-f' => self::RECIPE, - 'deploy', - 'all', - ]); - - $display = trim($this->tester->getDisplay()); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - - $siteContent = file_get_contents('http://server.test'); - $expectedSiteContent = "Build v8."; - self::assertStringContainsString($expectedSiteContent, $siteContent); - } - - protected function tearDown(): void - { - parent::tearDown(); - - if ($this->tester) { - $this->tester->run([ - '-f' => self::RECIPE, - 'deploy:unlock', - 'all', - ]); - } - } -} diff --git a/tests/e2e/MiscE2ETest.php b/tests/e2e/MiscE2ETest.php deleted file mode 100644 index 7b97334fe..000000000 --- a/tests/e2e/MiscE2ETest.php +++ /dev/null @@ -1,48 +0,0 @@ -tester->setInputs(['deployer']); - - $this->tester->run([ - '-f' => self::RECIPE, - 'test:misc:sudo-write-user', - 'all', - ]); - - $display = trim($this->tester->getDisplay()); - - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('Current user is: root', $display); - } - - /** - * @group e2e - */ - public function testSudoWithPasswordProvidedViaArgument(): void - { - $this->tester->run([ - '-f' => self::RECIPE, - 'test:misc:sudo-write-user', - '-o' => 'sudo_pass=deployer', - 'all', - ]); - - $display = trim($this->tester->getDisplay()); - - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('Current user is: root', $display); - } -} diff --git a/tests/e2e/SymfonyBoilerplateE2ETest.php b/tests/e2e/SymfonyBoilerplateE2ETest.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/e2e/TimeoutsE2ETest.php b/tests/e2e/TimeoutsE2ETest.php deleted file mode 100644 index 292f9c74d..000000000 --- a/tests/e2e/TimeoutsE2ETest.php +++ /dev/null @@ -1,28 +0,0 @@ -tester->run([ - '-f' => self::RECIPE, - 'test:timeouts', - 'all', - '-v', - ]); - - $display = trim($this->tester->getDisplay()); - - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('+timeout', $display); - } -} diff --git a/tests/e2e/bootstrap.php b/tests/e2e/bootstrap.php deleted file mode 100644 index 3b6098044..000000000 --- a/tests/e2e/bootstrap.php +++ /dev/null @@ -1,15 +0,0 @@ -includeDirectory('/project'); -$filter->excludeDirectory('/project/vendor'); -$filter->excludeDirectory('/project/tests'); - -$outputCoverage = new CodeCoverage( - (new Selector())->forLineCoverage($filter), - $filter, -); - -$coverageReports = glob("/tmp/ccov/*.php"); -foreach ($coverageReports as $reportPath) { - /** @var CodeCoverage $partialCoverage */ - $partialCoverage = include $reportPath; - if (!$partialCoverage) { - throw new \Exception("Failed to load coverage report from file '{$reportPath}'"); - } - $outputCoverage->merge($partialCoverage); -} - -$cloverReport = new Clover(); -$cloverReport->process($outputCoverage, $outputFile); - -echo "Clover report file written to {$outputFile}\n"; diff --git a/tests/e2e/coverage/coverage-start.php b/tests/e2e/coverage/coverage-start.php deleted file mode 100644 index 98448acfb..000000000 --- a/tests/e2e/coverage/coverage-start.php +++ /dev/null @@ -1,62 +0,0 @@ -includeDirectory('/project'); -$filter->excludeDirectory('/project/vendor'); -$filter->excludeDirectory('/project/tests'); -$report = new PHPReport(); - -$coverage = new CodeCoverage( - (new Selector())->forLineCoverage($filter), - $filter, -); - -$outputDir = '/tmp/ccov'; -if (!is_dir($outputDir)) { - mkdir($outputDir); -} - -// use anonymous class as we don't really want to pollute class space with this stuff -(new class ($coverage, $report, $outputDir) { - /** @var CodeCoverage */ - private $coverage; - /** @var PHPReport */ - private $report; - /** @var string */ - private $outputDir; - /** @var string|null */ - private $coverageName; - - public function __construct(CodeCoverage $coverage, PHPReport $report, string $outputDir) - { - $this->coverage = $coverage; - $this->report = $report; - $this->outputDir = $outputDir; - } - - public function start(): void - { - register_shutdown_function([$this, 'stop']); - - $coverageName = uniqid('coverage_'); - $this->coverageName = $coverageName; - $this->coverage->start($this->coverageName); - } - - public function stop(): void - { - $this->coverage->stop(); - - $outputFile = $this->outputDir . "/{$this->coverageName}.php"; - $this->report->process($this->coverage, $outputFile); - } -})->start(); diff --git a/tests/e2e/coverage/start-e2e-test.sh b/tests/e2e/coverage/start-e2e-test.sh deleted file mode 100644 index ba82ffe23..000000000 --- a/tests/e2e/coverage/start-e2e-test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -ROOTDIR=$(readlink -f "$(dirname "$0")/../../..") - -# Run E2E tests and grab exit code of the process -php "$ROOTDIR/vendor/bin/pest" --config "$ROOTDIR/tests/e2e/phpunit-e2e.xml" -E2E_EXIT_CODE=$? - -# Generate coverage report file -php "$ROOTDIR/tests/e2e/coverage/coverage-report.php" - -return $E2E_EXIT_CODE \ No newline at end of file diff --git a/tests/e2e/phpunit-e2e.xml b/tests/e2e/phpunit-e2e.xml deleted file mode 100644 index aac4227af..000000000 --- a/tests/e2e/phpunit-e2e.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - . - - - diff --git a/tests/e2e/recipe/functions.php b/tests/e2e/recipe/functions.php deleted file mode 100644 index 642690b6a..000000000 --- a/tests/e2e/recipe/functions.php +++ /dev/null @@ -1,16 +0,0 @@ - '{{bar}}', 'baz' => 'xyz%']; - - $output = run($cmd, ['env' => $env]); - output()->writeln($output); // we use this to skip \Deployer\parse() being called in normal \Deployer\writeln() -}); diff --git a/tests/e2e/recipe/hosts.php b/tests/e2e/recipe/hosts.php deleted file mode 100644 index e145a084c..000000000 --- a/tests/e2e/recipe/hosts.php +++ /dev/null @@ -1,16 +0,0 @@ -setDeployPath('/var/www/html') - ->set('bin/php', '/usr/local/bin/php') - ->setTag('e2e') - ->setRemoteUser('deployer') - ->set('timeout', 600) - ->setSshArguments([ - '-o UserKnownHostsFile=/dev/null', - '-o StrictHostKeyChecking=no', - ]); diff --git a/tests/e2e/recipe/laravel-boilerplate.php b/tests/e2e/recipe/laravel-boilerplate.php deleted file mode 100644 index 050e1a68d..000000000 --- a/tests/e2e/recipe/laravel-boilerplate.php +++ /dev/null @@ -1,32 +0,0 @@ -disable(); - -before('deploy:shared', 'laravel:setup-env'); -before('artisan:storage:link', 'artisan:key:generate'); diff --git a/tests/e2e/recipe/misc.php b/tests/e2e/recipe/misc.php deleted file mode 100644 index e22aef0ae..000000000 --- a/tests/e2e/recipe/misc.php +++ /dev/null @@ -1,14 +0,0 @@ - 1 ]); - } catch (TimeoutException $e) { - $ps = run("if ps aux | grep '[p]hp -r while(true){}'; then echo still running; else echo +timeout; fi"); - if ($ps != '+timeout') { - throw new \Exception('Process still running.'); - } - } -});