From: gggeek Date: Fri, 11 Dec 2020 17:21:28 +0000 (+0000) Subject: Merge branch 'master' into docker_tests X-Git-Tag: plcapi-7.1-0~3^2~145 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=8da25b8f417af37d783289c118c798f034c9f9fb;hp=ae5a8552a784500adbacfdbd9e0b08970a83a9fa;p=plcapi.git Merge branch 'master' into docker_tests --- diff --git a/.travis.yml b/.travis.yml index c270357..365eb35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ dist: xenial env: global: - - LOCALSERVER=localhost + - HTTPSERVER=localhost - URI=/demo/server/server.php - HTTPSSERVER=localhost - HTTPSURI=/demo/server/server.php @@ -38,6 +38,7 @@ before_install: - sudo apt-get install -y privoxy # Disable xdebug for speed (executing composer), but allow us to re-enable it later + # @todo move to setup_php - export XDEBUG_INI=`php -i | grep xdebug.ini | grep home/travis | grep -v '=>' | head -1` - export XDEBUG_INI=${XDEBUG_INI/,/} - if [ "$XDEBUG_INI" != "" ]; then mv "$XDEBUG_INI" "$XDEBUG_INI.bak"; fi @@ -51,15 +52,15 @@ install: before_script: # Set up Apache and Privoxy instances inside the Travis VM and use them for testing against - - ./tests/ci/travis/setup_php_fpm.sh - - ./tests/ci/travis/setup_apache.sh - - ./tests/ci/travis/setup_privoxy.sh + - sudo ./tests/ci/setup/setup_apache.sh + - sudo ./tests/ci/setup/setup_php.sh + - sudo ./tests/ci/setup/setup_privoxy.sh # output what version of phpunit we got going - vendor/bin/phpunit --version script: - vendor/bin/phpunit $COVERAGE_OPTS tests + ./vendor/bin/phpunit $COVERAGE_OPTS tests after_failure: # Save as much info as we can to help developers diff --git a/demo/client/_bootstrap.php b/demo/client/_bootstrap.php index d705d64..0645d3a 100644 --- a/demo/client/_bootstrap.php +++ b/demo/client/_bootstrap.php @@ -3,23 +3,23 @@ * Hackish code used to make the demos both viewable as source, runnable, and viewable as html */ -// Make errors visible -ini_set('display_errors', true); -error_reporting(E_ALL); - if (isset($_GET['showSource']) && $_GET['showSource']) { $file = debug_backtrace()[0]['file']; highlight_file($file); die(); } +// Make errors visible +ini_set('display_errors', true); +error_reporting(E_ALL); + // Use the custom class autoloader. These two lines not needed when the phpxmlrpc library is installed using Composer include_once __DIR__ . '/../../src/Autoloader.php'; PhpXmlRpc\Autoloader::register(); // Let unit tests run against localhost, 'plain' demos against a known public server -if (isset($_SERVER['LOCALSERVER'])) { - define('XMLRPCSERVER', 'http://'.$_SERVER['LOCALSERVER'].'/demo/server/server.php'); +if (isset($_SERVER['HTTPSERVER'])) { + define('XMLRPCSERVER', 'http://'.$_SERVER['HTTPSERVER'].'/demo/server/server.php'); } else { define('XMLRPCSERVER', 'http://phpxmlrpc.sourceforge.net/server.php'); } diff --git a/tests/2InvalidHostTest.php b/tests/2InvalidHostTest.php index 0607c51..18c8f6c 100644 --- a/tests/2InvalidHostTest.php +++ b/tests/2InvalidHostTest.php @@ -19,7 +19,7 @@ class InvalidHostTest extends PhpXmlRpc_PolyfillTestCase { $this->args = argParser::getArgs(); - $this->client = new xmlrpc_client('/NOTEXIST.php', $this->args['LOCALSERVER'], 80); + $this->client = new xmlrpc_client('/NOTEXIST.php', $this->args['HTTPSERVER'], 80); $this->client->setDebug($this->args['DEBUG']); if ($this->args['DEBUG'] == 1) @@ -81,12 +81,12 @@ class InvalidHostTest extends PhpXmlRpc_PolyfillTestCase $this->assertTrue($r->faultCode() === 8 || $r->faultCode() == 5); // now test a successful connection - $server = explode(':', $this->args['LOCALSERVER']); + $server = explode(':', $this->args['HTTPSERVER']); if (count($server) > 1) { $this->client->port = $server[1]; } $this->client->server = $server[0]; - $this->client->path = $this->args['URI']; + $this->client->path = $this->args['HTTPURI']; $r = $this->client->send($m, 5, 'http11'); $this->assertEquals(0, $r->faultCode()); diff --git a/tests/3LocalhostTest.php b/tests/3LocalhostTest.php index 9cbd1fd..439b635 100644 --- a/tests/3LocalhostTest.php +++ b/tests/3LocalhostTest.php @@ -87,18 +87,18 @@ class LocalhostTest extends PhpXmlRpc_PolyfillTestCase { $this->args = argParser::getArgs(); - $server = explode(':', $this->args['LOCALSERVER']); + $server = explode(':', $this->args['HTTPSERVER']); if (count($server) > 1) { - $this->client = new xmlrpc_client($this->args['URI'], $server[0], $server[1]); + $this->client = new xmlrpc_client($this->args['HTTPURI'], $server[0], $server[1]); } else { - $this->client = new xmlrpc_client($this->args['URI'], $this->args['LOCALSERVER']); + $this->client = new xmlrpc_client($this->args['HTTPURI'], $this->args['HTTPSERVER']); } $this->client->setDebug($this->args['DEBUG']); $this->client->request_compression = $this->request_compression; $this->client->accepted_compression = $this->accepted_compression; - $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] ); + $this->coverageScriptUrl = 'http://' . $this->args['HTTPSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['HTTPURI'] ); if ($this->args['DEBUG'] == 1) ob_start(); diff --git a/tests/5DemofilesTest.php b/tests/5DemofilesTest.php index e064add..583be3f 100644 --- a/tests/5DemofilesTest.php +++ b/tests/5DemofilesTest.php @@ -11,9 +11,9 @@ class DemoFilesTest extends PhpXmlRpc_LocalFileTestCase { $this->args = argParser::getArgs(); - $this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/demo/', $this->args['URI'] ); + $this->baseUrl = $this->args['HTTPSERVER'] . str_replace( '/demo/server/server.php', '/demo/', $this->args['HTTPURI'] ); - $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] ); + $this->coverageScriptUrl = 'http://' . $this->args['HTTPSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['HTTPURI'] ); } public function testAgeSort() diff --git a/tests/6DebuggerTest.php b/tests/6DebuggerTest.php index eaacd43..b0e7948 100644 --- a/tests/6DebuggerTest.php +++ b/tests/6DebuggerTest.php @@ -8,9 +8,9 @@ class DebuggerTest extends PhpXmlRpc_LocalFileTestCase { $this->args = argParser::getArgs(); - $this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/debugger/', $this->args['URI'] ); + $this->baseUrl = $this->args['HTTPSERVER'] . str_replace( '/demo/server/server.php', '/debugger/', $this->args['HTTPURI'] ); - $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] ); + $this->coverageScriptUrl = 'http://' . $this->args['HTTPSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['HTTPURI'] ); } public function testIndex() diff --git a/tests/7ExtraTest.php b/tests/7ExtraTest.php index de7d48f..5770eca 100644 --- a/tests/7ExtraTest.php +++ b/tests/7ExtraTest.php @@ -11,9 +11,9 @@ class ExtraTest extends PhpXmlRpc_LocalFileTestCase { $this->args = argParser::getArgs(); - $this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/tests/', $this->args['URI'] ); + $this->baseUrl = $this->args['HTTPSERVER'] . str_replace( '/demo/server/server.php', '/tests/', $this->args['HTTPURI'] ); - $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] ); + $this->coverageScriptUrl = 'http://' . $this->args['HTTPSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['HTTPURI'] ); } public function testVerifyCompat() diff --git a/tests/benchmark.php b/tests/benchmark.php index 3f0a470..8ef4587 100644 --- a/tests/benchmark.php +++ b/tests/benchmark.php @@ -206,13 +206,13 @@ if (!$xd) { for ($i = 0; $i < 25; $i++) { $reqs[] = $req; } - $server = explode(':', $args['LOCALSERVER']); + $server = explode(':', $args['HTTPSERVER']); if (count($server) > 1) { - $srv = $server[1] . '://' . $server[0] . $args['URI']; - $c = new Client($args['URI'], $server[0], $server[1]); + $srv = $server[1] . '://' . $server[0] . $args['HTTPURI']; + $c = new Client($args['HTTPURI'], $server[0], $server[1]); } else { - $srv = $args['LOCALSERVER'] . $args['URI']; - $c = new Client($args['URI'], $args['LOCALSERVER']); + $srv = $args['HTTPSERVER'] . $args['HTTPURI']; + $c = new Client($args['HTTPURI'], $args['HTTPSERVER']); } // do not interfere with http compression $c->accepted_compression = array(); diff --git a/tests/ci/Dockerfile b/tests/ci/Dockerfile new file mode 100644 index 0000000..7fb27de --- /dev/null +++ b/tests/ci/Dockerfile @@ -0,0 +1,28 @@ +ARG UBUNTU_VERSION=xenial + +FROM ubuntu:${UBUNTU_VERSION} + +ARG PHP_VERSION=default + +COPY setup/*.sh /root/setup/ +COPY config/* /root/config/ + +RUN mkdir -p /usr/share/man/man1 && \ + apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y upgrade && \ + chmod 755 /root/setup/*.sh && \ + cd /root/setup && \ + ./install_packages.sh && \ + ./create_user.sh && \ + ./setup_apache.sh && \ + ./setup_privoxy.sh && \ + ./setup_php.sh "${PHP_VERSION}" && \ + ./setup_composer.sh + +COPY docker/entrypoint.sh /root/entrypoint.sh +RUN chmod 755 /root/entrypoint.sh + +EXPOSE 80 443 8080 + +WORKDIR /home/test + +ENTRYPOINT ["/root/entrypoint.sh"] diff --git a/tests/ci/config/apache_phpfpm_fastcgi b/tests/ci/config/apache_phpfpm_fastcgi new file mode 100644 index 0000000..4c64b5c --- /dev/null +++ b/tests/ci/config/apache_phpfpm_fastcgi @@ -0,0 +1,12 @@ +# @todo check: is this limited to php5 only? + +# Wire up Apache to use php-fpm via mod_fastcgi. + + AddHandler php5-fcgi .php + Action php5-fcgi /php5-fcgi + Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi + FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization + + Require all granted + + diff --git a/tests/ci/config/apache_phpfpm_fcgid b/tests/ci/config/apache_phpfpm_fcgid new file mode 100644 index 0000000..e69de29 diff --git a/tests/ci/config/apache_phpfpm_proxyfccgi b/tests/ci/config/apache_phpfpm_proxyfccgi new file mode 100644 index 0000000..bac168d --- /dev/null +++ b/tests/ci/config/apache_phpfpm_proxyfccgi @@ -0,0 +1,25 @@ +# @todo check: templatize this, to make it work with any php version + +# Redirect to local php-fpm if mod_php is not available + + + # Enable http authorization headers + + SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1 + + + + SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost" + + + # Deny access to raw php sources by default + # To re-enable it's recommended to enable access to the files + # only in specific virtual host or directory + Require all denied + + # Deny access to files without filename (e.g. '.php') + + Require all denied + + + diff --git a/tests/ci/config/apache_vhost b/tests/ci/config/apache_vhost new file mode 100644 index 0000000..bf7db16 --- /dev/null +++ b/tests/ci/config/apache_vhost @@ -0,0 +1,69 @@ +# Uses env vars: +# HTTPSERVER +# TESTS_ROOT_DIR + + + + DocumentRoot ${TESTS_ROOT_DIR} + + ErrorLog "${TESTS_ROOT_DIR}/apache_error.log" + CustomLog "${TESTS_ROOT_DIR}/apache_access.log" combined + + # Env vars used by the test code, which we get from the environment + SetEnv HTTPSERVER ${HTTPSERVER} + + + Options FollowSymLinks MultiViews + AllowOverride All + + Require all granted + + # needed for basic auth (PHP_AUTH_USER and PHP_AUTH_PW) + RewriteEngine on + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] + + + + + + + + + DocumentRoot ${TESTS_ROOT_DIR} + + ErrorLog "${TESTS_ROOT_DIR}/apache_error.log" + CustomLog "${TESTS_ROOT_DIR}/apache_access.log" combined + + # Env vars used by the test code, which we get from the environment + SetEnv HTTPSERVER ${HTTPSERVER} + + + Options FollowSymLinks MultiViews + AllowOverride All + + Require all granted + + # needed for basic auth (PHP_AUTH_USER and PHP_AUTH_PW) + RewriteEngine on + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] + + + SSLEngine on + # This cert is bundled by default in Ubuntu + SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem + SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key + + + SSLOptions +StdEnvVars + + + BrowserMatch "MSIE [2-6]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown + + + + diff --git a/tests/ci/travis/privoxy b/tests/ci/config/privoxy similarity index 100% rename from tests/ci/travis/privoxy rename to tests/ci/config/privoxy diff --git a/tests/ci/docker/entrypoint.sh b/tests/ci/docker/entrypoint.sh new file mode 100644 index 0000000..658d8e3 --- /dev/null +++ b/tests/ci/docker/entrypoint.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# @todo make username flexible + +USERNAME=test + +echo "[$(date)] Bootstrapping the Test container..." + +clean_up() { + # Perform program exit housekeeping + + echo "[$(date)] Stopping the Web server" + service apache2 stop + + echo "[$(date)] Stopping Privoxy" + service privoxy stop + + echo "[$(date)] Stopping FPM" + service php-fpm stop + + echo "[$(date)] Exiting" + exit +} + +# Fix UID & GID for user + +echo "[$(date)] Fixing filesystem permissions..." + +ORIGPASSWD=$(cat /etc/passwd | grep "^${USERNAME}:") +ORIG_UID=$(echo "$ORIGPASSWD" | cut -f3 -d:) +ORIG_GID=$(echo "$ORIGPASSWD" | cut -f4 -d:) +CONTAINER_USER_HOME=$(echo "$ORIGPASSWD" | cut -f6 -d:) +CONTAINER_USER_UID=${CONTAINER_USER_UID:=$ORIG_UID} +CONTAINER_USER_GID=${CONTAINER_USER_GID:=$ORIG_GID} + +if [ "$CONTAINER_USER_UID" != "$ORIG_UID" -o "$CONTAINER_USER_GID" != "$ORIG_GID" ]; then + groupmod -g "$CONTAINER_USER_GID" "${USERNAME}" + usermod -u "$CONTAINER_USER_UID" -g "$CONTAINER_USER_GID" "${USERNAME}" +fi +if [ $(stat -c '%u' "${CONTAINER_USER_HOME}") != "${CONTAINER_USER_UID}" -o $(stat -c '%g' "${CONTAINER_USER_HOME}") != "${CONTAINER_USER_GID}" ]; then + chown "${CONTAINER_USER_UID}":"${CONTAINER_USER_GID}" "${CONTAINER_USER_HOME}" + chown -R "${CONTAINER_USER_UID}":"${CONTAINER_USER_GID}" "${CONTAINER_USER_HOME}"/.* +fi + +echo "[$(date)] Fixing apache configuration..." + +sed -e "s?^export TESTS_ROOT_DIR=.*?export TESTS_ROOT_DIR=${TESTS_ROOT_DIR}?g" --in-place /etc/apache2/envvars + +# @todo set as well php-fpm user/group ? + +echo "[$(date)] Running Composer..." + +sudo test -c "cd /home/test && composer install" + +trap clean_up TERM + +echo "[$(date)] Starting FPM..." +service php-fpm start + +echo "[$(date)] Starting the Web server..." +service apache2 start + +echo "[$(date)] Starting Privoxy..." +service privoxy start + +tail -f /dev/null & +child=$! +wait "$child" diff --git a/tests/ci/setup/create_user.sh b/tests/ci/setup/create_user.sh new file mode 100644 index 0000000..67adae5 --- /dev/null +++ b/tests/ci/setup/create_user.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# @todo set up the same user for running tests as on travis (ie. 'travis'), or maybe user 'user' ? +# @todo make the GID & UID of the user variable + +set -e + +USERNAME="${1:-test}" + +addgroup --gid 1013 "${USERNAME}" +adduser --system --uid=1013 --gid=1013 --home "/home/${USERNAME}" --shell /bin/bash "${USERNAME}" +adduser "${USERNAME}" "${USERNAME}" + +mkdir -p "/home/${USERNAME}/.ssh" +cp /etc/skel/.[!.]* "/home/${USERNAME}" + +chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}" + +if [ -f /etc/sudoers ]; then + adduser "${USERNAME}" sudo + sed -i "\$ a ${USERNAME} ALL=\(ALL:ALL\) NOPASSWD: ALL" /etc/sudoers +fi diff --git a/tests/ci/setup/install_packages.sh b/tests/ci/setup/install_packages.sh new file mode 100644 index 0000000..c760675 --- /dev/null +++ b/tests/ci/setup/install_packages.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +DEBIAN_FRONTEND=noninteractive apt-get install -y \ + lsb-release sudo unzip wget zip diff --git a/tests/ci/setup/setup_apache.sh b/tests/ci/setup/setup_apache.sh new file mode 100644 index 0000000..781f203 --- /dev/null +++ b/tests/ci/setup/setup_apache.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +# @todo make this work across all apache versions (precise to focal) + +SCRIPT_DIR="$(dirname -- "$(readlink -f "$0")")" + +# install and configure apache2 + +DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 + +# set up Apache for php-fpm +# @see https://github.com/travis-ci/travis-ci.github.com/blob/master/docs/user/languages/php.md#apache--php + +a2enmod rewrite proxy_fcgi setenvif ssl + +# configure apache virtual hosts + +cp -f "$SCRIPT_DIR/../config/apache_vhost" /etc/apache2/sites-available/000-default.conf + +if [ -n "${TRAVIS}" ]; then + echo "export TESTS_ROOT_DIR=$(pwd)" >> /etc/apache2/envvars +else + echo "export TESTS_ROOT_DIR=/var/www/html" >> /etc/apache2/envvars +fi +echo "export HTTPSERVER=localhost" >> /etc/apache2/envvars + +service apache2 restart diff --git a/tests/ci/setup/setup_composer.sh b/tests/ci/setup/setup_composer.sh new file mode 100644 index 0000000..cd2f81c --- /dev/null +++ b/tests/ci/setup/setup_composer.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# Installs Composer (latest version, to avoid relying on old ones bundled with the OS) +# @todo allow users to lock down to Composer v1 if needed + +if dpkg -l composer 2>/dev/null; then + apt-get remove -y composer +fi + +### Code below taken from https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md + +EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" + +if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] +then + >&2 echo 'ERROR: Invalid installer signature' + rm composer-setup.php + exit 1 +fi + +php composer-setup.php --quiet --install-dir=/usr/local/bin +RESULT=$? +rm composer-setup.php + +### + +if [ -f /usr/local/bin/composer.phar -a "$RESULT" = 0 ]; then + mv /usr/local/bin/composer.phar /usr/local/bin/composer && chmod 755 /usr/local/bin/composer +fi + +exit $RESULT diff --git a/tests/ci/setup/setup_php.sh b/tests/ci/setup/setup_php.sh new file mode 100644 index 0000000..fe9e0b0 --- /dev/null +++ b/tests/ci/setup/setup_php.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +set -e + +configure_php_ini() { + # @todo make this idempotent so that it can be run multiple times in a row + echo "cgi.fix_pathinfo = 1" >> "${1}" + echo "always_populate_raw_post_data = -1" >> "${1}" + + # @todo this only disables xdebug for CLI. To do the same for the FPM config as well, should we use instead `phpdismod` ? + XDEBUG_INI=$(php -i | grep xdebug.ini | grep -v '=>' | head -1) + if [ "$XDEBUG_INI" != "" ]; then + XDEBUG_INI="$(echo "$XDEBUG_INI" | tr -d ',')" + mv "$XDEBUG_INI" "$XDEBUG_INI.bak"; + fi +} + +if ! which php >/dev/null; then + + # install php + PHP_VERSION="$1" + DEBIAN_VERSION="$(lsb_release -s -c)" + + if [ "${PHP_VERSION}" = default ]; then + if [ "${DEBIAN_VERSION}" = jessie -o "${DEBIAN_VERSION}" = precise -o "${DEBIAN_VERSION}" = trusty ]; then + PHPSUFFIX=5 + else + PHPSUFFIX= + fi + # @todo check for mbstring presence in php5 (jessie) packages + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + php${PHPSUFFIX} \ + php${PHPSUFFIX}-cli \ + php${PHPSUFFIX}-dom \ + php${PHPSUFFIX}-curl \ + php${PHPSUFFIX}-fpm \ + php${PHPSUFFIX}-mbstring \ + php${PHPSUFFIX}-xdebug + else + DEBIAN_FRONTEND=noninteractive apt-get install -y language-pack-en-base software-properties-common + LC_ALL=en_US.UTF-8 add-apt-repository ppa:ondrej/php + apt-get update + + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + php${PHP_VERSION} \ + php${PHP_VERSION}-cli \ + php${PHP_VERSION}-dom \ + php${PHP_VERSION}-curl \ + php${PHP_VERSION}-fpm \ + php${PHP_VERSION}-mbstring \ + php${PHP_VERSION}-xdebug + + update-alternatives --set php /usr/bin/php${PHP_VERSION} + fi + + PHPVER=$(php -r 'echo implode(".",array_slice(explode(".",PHP_VERSION),0,2));' 2>/dev/null) + + configure_php_ini /etc/php/${PHPVER}/fpm/php.ini + + # use a nice name for the php-fpm service, so that it does not depend on php version running + service "php${PHPVER}-fpm" stop + ln -s "/etc/init.d/php${PHPVER}-fpm" /etc/init.d/php-fpm + + # @todo shall we configure php-fpm? + + service php-fpm start + + # configure apache + a2enconf php${PHPVER}-fpm + service apache2 restart +fi + +if [ -n "$TRAVIS" ]; then + + # php is already installed, via phpenv + + PHPVER=$(phpenv version-name) + + configure_php_ini ~/.phpenv/versions/${PHPVER}/etc/php.ini + + # configure php-fpm + cp ~/.phpenv/versions/${PHPVER}/etc/php-fpm.conf.default ~/.phpenv/versions/${PHPVER}/etc/php-fpm.conf + + # work around travis issue #3385 + if [ -d ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d ]; then + if [ "$TRAVIS_PHP_VERSION" = "7.0" -a -n "$(ls -A ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d)" ]; then + cp ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf + fi + if [ "$TRAVIS_PHP_VERSION" = "7.1" -a -n "$(ls -A ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d)" ]; then + cp ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf + fi + if [ "$TRAVIS_PHP_VERSION" = "7.2" -a -n "$(ls -A ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d)" ]; then + cp ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf + fi + if [ "$TRAVIS_PHP_VERSION" = "7.3" -a -n "$(ls -A ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d)" ]; then + cp ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/${PHPVER}/etc/php-fpm.d/www.conf + fi + fi + + ~/.phpenv/versions/${PHPVER}/sbin/php-fpm + + # @todo configure apache for php-fpm via mod_proxy_fcgi +fi diff --git a/tests/ci/setup/setup_privoxy.sh b/tests/ci/setup/setup_privoxy.sh new file mode 100644 index 0000000..a0477dd --- /dev/null +++ b/tests/ci/setup/setup_privoxy.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +# install and configure privoxy + +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" + +DEBIAN_FRONTEND=noninteractive apt-get install -y privoxy + +cp -f "$SCRIPT_DIR/../config/privoxy" /etc/privoxy/config +service privoxy restart diff --git a/tests/ci/travis/apache_vhost b/tests/ci/travis/apache_vhost deleted file mode 100644 index 1130479..0000000 --- a/tests/ci/travis/apache_vhost +++ /dev/null @@ -1,84 +0,0 @@ -# Configuration file for Apache running on Travis. -# PHP setup in FCGI mode - - - - DocumentRoot %TRAVIS_BUILD_DIR% - - ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log" - CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined - - - Options FollowSymLinks MultiViews ExecCGI - AllowOverride All - - Require all granted - - # needed for basic auth (PHP_AUTH_USER and PHP_AUTH_PW) - RewriteEngine on - RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] - - - # Wire up Apache to use Travis CI's php-fpm. - - AddHandler php5-fcgi .php - Action php5-fcgi /php5-fcgi - Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi - FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization - - Require all granted - - - - - - - - - - DocumentRoot %TRAVIS_BUILD_DIR% - - ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log" - CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined - - - Options FollowSymLinks MultiViews ExecCGI - AllowOverride All - - Require all granted - - # needed for basic auth (PHP_AUTH_USER and PHP_AUTH_PW) - RewriteEngine on - RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] - - - # Wire up Apache to use Travis CI's php-fpm. - - AddHandler php5-fcgi .php - Action php5-fcgi /php5-fcgi - Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi - #FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization - - Require all granted - - - - SSLEngine on - # This cert is bundled by default in Ubuntu - SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem - SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key - - - SSLOptions +StdEnvVars - - - BrowserMatch "MSIE [2-6]" \ - nokeepalive ssl-unclean-shutdown \ - downgrade-1.0 force-response-1.0 - BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown - - - - diff --git a/tests/ci/travis/setup_apache.sh b/tests/ci/travis/setup_apache.sh deleted file mode 100755 index 81aaf66..0000000 --- a/tests/ci/travis/setup_apache.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# make sure all files and folders are accessible by Apache -sudo find /home -type d -exec chmod 755 {} \; -sudo find . -type f -name "*.php" -exec chmod 644 {} \; - -# set up Apache for php-fpm -# @see https://github.com/travis-ci/travis-ci.github.com/blob/master/docs/user/languages/php.md#apache--php - -sudo a2enmod rewrite actions fastcgi alias ssl - -# configure apache virtual hosts -sudo cp -f tests/ci/travis/apache_vhost /etc/apache2/sites-available/000-default.conf -sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf -sudo service apache2 restart diff --git a/tests/ci/travis/setup_php_fpm.sh b/tests/ci/travis/setup_php_fpm.sh deleted file mode 100755 index 05098ea..0000000 --- a/tests/ci/travis/setup_php_fpm.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# enable php-fpm -sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf -# work around travis issue #3385 -if [ "-d ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d" ]; then - if [ "$TRAVIS_PHP_VERSION" = "7.0" -a -n "$(ls -A ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d)" ]; then - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf - fi - if [ "$TRAVIS_PHP_VERSION" = "7.1" -a -n "$(ls -A ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d)" ]; then - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf - fi - if [ "$TRAVIS_PHP_VERSION" = "7.2" -a -n "$(ls -A ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d)" ]; then - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf - fi - if [ "$TRAVIS_PHP_VERSION" = "7.3" -a -n "$(ls -A ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d)" ]; then - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf - fi -fi -echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini -echo "always_populate_raw_post_data = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini -~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm diff --git a/tests/ci/travis/setup_privoxy.sh b/tests/ci/travis/setup_privoxy.sh deleted file mode 100755 index 12e0e61..0000000 --- a/tests/ci/travis/setup_privoxy.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# configure privoxy - -sudo cp -f tests/ci/travis/privoxy /etc/privoxy/config -sudo service privoxy restart diff --git a/tests/ci/vm.sh b/tests/ci/vm.sh new file mode 100644 index 0000000..9075c2f --- /dev/null +++ b/tests/ci/vm.sh @@ -0,0 +1,128 @@ +#!/bin/sh + +# @todo support getting the 2 vars as cli args as well as via env vars? + +set -e + +ACTION="${1}" + +# Valid values: 'default', 5.6, 7.0 .. 7.4, 8.0 +export PHP_VERSION=${PHP_VERSION:-default} +# Valid values: precise (12), trusty (14), xenial (16), bionic (18), focal (20) +# We default to the same version we use on Travis +export UBUNTU_VERSION=${UBUNTU_VERSION:-xenial} + +IMAGE_NAME=phpxmlrpc:${UBUNTU_VERSION}-${PHP_VERSION} +CONTAINER_NAME=phpxmlrpc_${UBUNTU_VERSION}_${PHP_VERSION} +ROOT_DIR="$(dirname -- "$(dirname -- "$(dirname -- "$(readlink -f "$0")")")")" + +cd "$(dirname -- "$(readlink -f "$0")")" + +help() { +printf "Usage: vm.sh [OPTIONS] ACTION [OPTARGS] + +Manages the Test Environment Docker Stack + +Commands: + build build or rebuild the containers and set up the test env + enter enter the test container + #exec \$cmd execute a single shell command in the test container + #runtests [\$suite] execute the test suite using the test container (or a single test scenario eg. Tests/1ParsingBugsTest.php) + start start the containers + #status + stop stop containers + +Options: + -h print help +" +} + +build() { + stop + docker build --build-arg PHP_VERSION --build-arg UBUNTU_VERSION -t "${IMAGE_NAME}" . + if docker inspect "${CONTAINER_NAME}" >/dev/null 2>/dev/null; then + docker rm "${CONTAINER_NAME}" + fi + docker run -d \ + -p 80:80 -p 443:443 -p 8080:8080 \ + --name "${CONTAINER_NAME}" \ + --env CONTAINER_USER_UID=$(id -u) --env CONTAINER_USER_GID=$(id -g) --env TESTS_ROOT_DIR=/home/test \ + --env HTTPSERVER=localhost \ + --env HTTPURI=/demo/server/server.php \ + --env HTTPSSERVER=localhost \ + --env HTTPSURI=/demo/server/server.php \ + --env PROXYSERVER=localhost:8080 \ + --env HTTPSVERIFYHOST=0 \ + --env HTTPSIGNOREPEER=1 \ + --env SSLVERSION=0 \ + --env DEBUG=0 \ + -v "${ROOT_DIR}":/home/test "${IMAGE_NAME}" +} + +start() { + if docker inspect "${CONTAINER_NAME}" >/dev/null 2>/dev/null; then + docker start "${CONTAINER_NAME}" + else + build + fi +} + +stop() { + if docker inspect "${CONTAINER_NAME}" >/dev/null 2>/dev/null; then + docker stop "${CONTAINER_NAME}" + fi +} + +case "${ACTION}" in + + build) + build + stop + ;; + + cleanup) + docker rm "${CONTAINER_NAME}" + docker rmi "${IMAGE_NAME}" + ;; + + enter | shell | cli) + docker exec -it "${CONTAINER_NAME}" su test + ;; + + #exec) + # ;; + + restart) + stop + start + ;; + + #runtests) + # ;; + + start) + start + ;; + + #status) + # : + # ;; + + stop) + stop + ;; + + ps) + docker ps --filter "name=${CONTAINER_NAME}" + ;; + + diff | inspect | kill | logs | pause | port | stats | top | unpause) + docker container "${ACTION}" "${CONTAINER_NAME}" + ;; + + *) + printf "\n\e[31mERROR:\e[0m unknown action '${ACTION}'\n\n" >&2 + help + exit 1 + ;; +esac diff --git a/tests/parse_args.php b/tests/parse_args.php index f9c4562..6fdef4b 100644 --- a/tests/parse_args.php +++ b/tests/parse_args.php @@ -4,8 +4,8 @@ * Common parameter parsing for benchmark and tests scripts. * * @param integer DEBUG - * @param string LOCALSERVER - * @param string URI + * @param string HTTPSERVER + * @param string HTTPURI * @param string HTTPSSERVER * @param string HTTPSURI * @param bool HTTPSIGNOREPEER @@ -18,18 +18,27 @@ **/ class argParser { + /** + * @return array + */ public static function getArgs() { + /// @todo should we prefix all test parameters with TESTS_ ? $args = array( 'DEBUG' => 0, - 'LOCALSERVER' => 'localhost', - 'HTTPSSERVER' => 'gggeek.altervista.org', - 'HTTPSURI' => '/sw/xmlrpc/demo/server/server.php', + 'HTTPSERVER' => 'localhost', + 'HTTPURI' => null, + // now that we run tests in Docker by default, with a webserver set up for https, let's default to it + 'HTTPSSERVER' => 'localhost', + 'HTTPSURI' => null, + // example alternative: + //'HTTPSSERVER' => 'gggeek.altervista.org', + //'HTTPSURI' => '/sw/xmlrpc/demo/server/server.php', 'HTTPSIGNOREPEER' => false, 'HTTPSVERIFYHOST' => 2, 'SSLVERSION' => 0, 'PROXYSERVER' => null, - 'LOCALPATH' => __DIR__, + //'LOCALPATH' => __DIR__, ); // check for command line (env vars) vs. web page input params @@ -48,30 +57,61 @@ class argParser if (isset($DEBUG)) { $args['DEBUG'] = intval($DEBUG); } - if (isset($LOCALSERVER)) { - $args['LOCALSERVER'] = $LOCALSERVER; + + if (isset($HTTPSERVER)) { + $args['HTTPSERVER'] = $HTTPSERVER; } else { if (isset($HTTP_HOST)) { - $args['LOCALSERVER'] = $HTTP_HOST; + $args['HTTPSERVER'] = $HTTP_HOST; } elseif (isset($_SERVER['HTTP_HOST'])) { - $args['LOCALSERVER'] = $_SERVER['HTTP_HOST']; + $args['HTTPSERVER'] = $_SERVER['HTTP_HOST']; + } + } + + if (!isset($HTTPURI) || $HTTPURI == '') { + // GUESTIMATE the url of local demo server + // play nice to php 3 and 4-5 in retrieving URL of server.php + /// @todo filter out query string from REQUEST_URI + if (isset($REQUEST_URI)) { + $HTTPURI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $REQUEST_URI); + $HTTPURI = str_replace('/testsuite.php', '/server.php', $HTTPURI); + $HTTPURI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $HTTPURI); + $HTTPURI = str_replace('/benchmark.php', '/server.php', $HTTPURI); + } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['REQUEST_METHOD'])) { + $HTTPURI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $_SERVER['PHP_SELF']); + $HTTPURI = str_replace('/testsuite.php', '/server.php', $HTTPURI); + $HTTPURI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $HTTPURI); + $HTTPURI = str_replace('/benchmark.php', '/server.php', $HTTPURI); + } else { + $HTTPURI = '/demo/server/server.php'; } } + if ($HTTPURI[0] != '/') { + $HTTPURI = '/' . $HTTPURI; + } + $args['HTTPURI'] = $HTTPURI; + if (isset($HTTPSSERVER)) { $args['HTTPSSERVER'] = $HTTPSSERVER; } + + /// @todo if $HTTPSURI is unset, and HTTPSSERVER == localhost, use HTTPURI if (isset($HTTPSURI)) { $args['HTTPSURI'] = $HTTPSURI; } + if (isset($HTTPSIGNOREPEER)) { $args['HTTPSIGNOREPEER'] = (bool)$HTTPSIGNOREPEER; } + if (isset($HTTPSVERIFYHOST)) { $args['HTTPSVERIFYHOST'] = (int)$HTTPSVERIFYHOST; } + if (isset($SSLVERSION)) { $args['SSLVERSION'] = (int)$SSLVERSION; } + if (isset($PROXYSERVER)) { $arr = explode(':', $PROXYSERVER); $args['PROXYSERVER'] = $arr[0]; @@ -81,31 +121,10 @@ class argParser $args['PROXYPORT'] = 8080; } } - if (!isset($URI)) { - // GUESTIMATE the url of local demo server - // play nice to php 3 and 4-5 in retrieving URL of server.php - /// @todo filter out query string from REQUEST_URI - if (isset($REQUEST_URI)) { - $URI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $REQUEST_URI); - $URI = str_replace('/testsuite.php', '/server.php', $URI); - $URI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $URI); - $URI = str_replace('/benchmark.php', '/server.php', $URI); - } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['REQUEST_METHOD'])) { - $URI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $_SERVER['PHP_SELF']); - $URI = str_replace('/testsuite.php', '/server.php', $URI); - $URI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $URI); - $URI = str_replace('/benchmark.php', '/server.php', $URI); - } else { - $URI = '/demo/server/server.php'; - } - } - if ($URI[0] != '/') { - $URI = '/' . $URI; - } - $args['URI'] = $URI; - if (isset($LOCALPATH)) { - $args['LOCALPATH'] = $LOCALPATH; - } + + //if (isset($LOCALPATH)) { + // $args['LOCALPATH'] = $LOCALPATH; + //} return $args; }