diff --git a/.env.default b/.env.default index 848e9c9..84de84c 100644 --- a/.env.default +++ b/.env.default @@ -59,4 +59,20 @@ export WPT_SSH_PRIVATE_KEY_BASE64= # Output logging # Use 'verbose' to increase verbosity -export WPT_DEBUG= \ No newline at end of file +export WPT_DEBUG= + +# Certificate validation +# Use 1 to validate, and 0 to not validate +export WPT_CERTIFICATE_VALIDATION=1 + +# WordPress flavor +# 0 = WordPress (simple version) +# 1 = WordPress Multisite +export WPT_FLAVOR=1 + +# Extra tests (groups) +# 0 = none +# 1 = ajax +# 2 = ms-files +# 3 = external-http +export WPT_EXTRATESTS=0 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d3f46f2..a71895b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ on: # - cron: '0 0 * * *' # Every 30 minutes. # - cron: '0/30 * * * *' + workflow_dispatch: # Cancels all previous workflow runs for pull requests that have not completed. concurrency: @@ -42,7 +43,7 @@ jobs: test: name: Run Core PHPUnit tests runs-on: ubuntu-latest - + # Remove this line if Github Actions is your preferred means of running the tests. if: ${{ false }} @@ -63,16 +64,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up PHP - uses: shivammathur/setup-php@947009a71769c25ab5292f073f5343624b7c879d # v2.12.0 + uses: shivammathur/setup-php@c5fc0d8281aba02c7fda07d3a70cc5371548067d # v2.25.2 with: php-version: '7.4' coverage: none - name: Install NodeJS - uses: actions/setup-node@25316bbc1f10ac9d8798711f44914b1cf3c4e954 # v2.4.0 + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version: 14 diff --git a/.gitignore b/.gitignore index b1b8150..0721216 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store .env* vendor/ +package-lock.json \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index c406a62..71890f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php node_js: - - node + - 14 before_install: - npm install -g npm@latest diff --git a/README.md b/README.md index f6a3a55..046dfad 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# phpunit-test-runner +# PHPUnit Test Runner Thanks for running the WordPress PHPUnit test suite on your infrastructure. We appreciate you helping to ensure WordPress’s compatibility for your users. -If you haven't already, [please first read through the "Getting Started" documentation](https://make.wordpress.org/hosting/test-results-getting-started/). +If you haven't already, [please first read through the "Getting Started" documentation](https://make.wordpress.org/hosting/handbook/tests/). -The test suite runner is designed to be used without any file modification. Configuration happens with a series of environment variables (see [.env.default](.env.default) for an annotated overview). Use the [repository wiki](../../wiki) to document implementation details, to avoid README conflicts with the upstream. +The test suite runner is designed to be used without any file modification. Configuration happens with a series of environment variables (see [.env.default](.env.default) for an annotated overview). At a high level, the test suite runner: @@ -13,7 +13,7 @@ At a high level, the test suite runner: 3. Reports the PHPUnit test results to WordPress.org 4. Cleans up the test suite environment. -## Configuring +## Setup The test suite runner can be used in one of two ways: @@ -24,94 +24,373 @@ The test runner is configured through environment variables, documented in [`.en With a direct Git clone, you can: - # Copy the default .env file. - cp .env.default .env - # Edit the .env file to define your variables. - vim .env - # Load your variables into scope. - source .env +```bash +# Copy the default .env file. +cp .env.default .env +# Edit the .env file to define your variables. +vim .env +# Load your variables into scope. +source .env +``` In a CI service, you can set these environment variables through the service's web console. Importantly, the `WPT_SSH_CONNECT` environment variable determines whether the test suite is run locally or against a remote environment. Concurrently run tests in the same environment by appending build ids to the test directory and table prefix: - export WPT_TEST_DIR=wp-test-runner-$TRAVIS_BUILD_NUMBER - export WPT_TABLE_PREFIX=wptests_$TRAVIS_BUILD_NUMBER\_ +```bash +export WPT_TEST_DIR=wp-test-runner-$TRAVIS_BUILD_NUMBER +export WPT_TABLE_PREFIX=wptests_$TRAVIS_BUILD_NUMBER\_ +``` Connect to a remote environment over SSH by having the CI job provision the SSH key: - # 1. Create a SSH key pair for the controller to use - ssh-keygen -t rsa -b 4096 -C "travis@travis-ci.org" - # 2. base64 encode the private key for use with the environment variable - cat ~/.ssh/id_rsa | base64 --wrap=0 - # 3. Append id_rsa.pub to authorized_keys so the CI service can SSH in - cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys +```bash +# 1. Create a SSH key pair for the controller to use +ssh-keygen -t rsa -b 4096 -C "travis@travis-ci.org" +# 2. base64 encode the private key for use with the environment variable +cat ~/.ssh/id_rsa | base64 --wrap=0 +# 3. Append id_rsa.pub to authorized_keys so the CI service can SSH in +cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys +``` + +Use a more complex SSH connection process by creating an SSH alias: + +```bash +# 1. Add the following to ~/.ssh/config to create a 'wpt' alias +Host wpt + Hostname 123.45.67.89 + User wpt + Port 1234 +# 2. Use 'wpt' wherever you might normally use a SSH connection string +ssh wpt +``` -Use a more complex SSH connection process by creating a SSH alias: +## Running - # 1. Add the following to ~/.ssh/config to create a 'wpt' alias - Host wpt - Hostname 123.45.67.89 - User wpt - Port 1234 - # 2. Use 'wpt' wherever you might normally use a SSH connection string - ssh wpt +The test suite runner is run in four steps. This explanation is for the local execution. -## Running +### Requirements -The test suite runner is run in four steps. +To use the Runner, the following is required (testing WordPress 6.5): -### 0. Requirements +- Server / hosting (infrastructure) with the usual configuration you use +- A database where you can test (tables will be created and destroyed several times) +- PHP 7.0+ (view ) +- MySQL 5.5+ / MariaDB 10.0+ +- NodeJS 20.x / npm 10.x / grunt +- PHP Composer +- Git, RSync, WGet, UnZip -Both the prep and test environments must meet some basic requirements. +Test environment: -Prep environment: +- Writable filesystem for the entire test directory (see [#40910](https://core.trac.wordpress.org/ticket/40910)). +- Run with a non-root user, both for security and practical purposes (see [#44233](https://core.trac.wordpress.org/ticket/44233#comment:34)/[#46577](https://core.trac.wordpress.org/ticket/46577)). -* PHP 5.6 or greater (to run scripts). -* Utilities: `git` version 1.8.5 or greater, `rsync`, `wget`, `unzip`. -* Node.js including `npm` and `grunt` packages +#### Database creation -Test environment: +_This is an example for MySQL / MariaDB._ + +```sql +CREATE DATABASE wordpressdatabase CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; +GRANT ALL ON wordpressdatabase.* TO 'wordpressusername'@'localhost' IDENTIFIED BY 'wordpresspassword'; +GRANT ALL ON wordpressdatabase.* TO 'wordpressusername'@'127.0.0.1' IDENTIFIED BY 'wordpresspassword'; +FLUSH PRIVILEGES; +``` + +#### NodeJS installation + +_This is an example for Debian / Ubuntu._ + +```bash +curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - +sudo apt -y install nodejs +sudo npm install -g npm@latest +nodejs --version +npm --version +``` + +#### PHP Composer + +_This is an example for Debian / Ubuntu._ + +```bash +curl -sS https://getcomposer.org/installer -o composer-setup.php +php composer-setup.php --install-dir=/usr/local/bin --filename=composer +composer --version +``` + +#### Git + +_This is an example for Debian / Ubuntu._ + +```bash +apt -y install git +git --version +``` + +### Installing the Test Runner + +First, download the software. This example uses `/home/wptestrunner/` folder, but set the best for this environment. + +```bash +cd /home/wptestrunner/ +git clone https://github.com/WordPress/phpunit-test-runner.git +cd phpunit-test-runner/ +``` + +The next step will be to configure the environment. To do this, make a copy of the example file and then configure it. + +```bash +cp .env.default .env +vim .env +``` + +The content (in summary form) can be something like this: + +```bash +### +# Configuration environment variables used by the test runner +# +# # Create a copy for your local environment +# $ cp .env.default .env +# +# # Make any necessary changes to the default values +# $ vim .env +# +# # Load your variables into your environment +# $ source .env +### + +# Path to the directory where files can be prepared before being delivered to the environment. +export WPT_PREPARE_DIR=/tmp/wp-test-runner + +# Path to the directory where the WordPress develop checkout can be placed and tests can be run. +# When running tests in the same environment, set WPT_TEST_DIR to WPT_PREPARE_DIR +export WPT_TEST_DIR=/tmp/wp-test-runner + +# API key to authenticate with the reporting service in 'username:password' format. +export WPT_REPORT_API_KEY= + +# (Optionally) define an alternate reporting URL +export WPT_REPORT_URL= + +# Credentials for a database that can be written to and reset. +# WARNING!!! This database will be destroyed between tests. Only use safe database credentials. +# Please note that you must escape _or_ refrain from using # as special character in your credentials. +export WPT_DB_NAME= +export WPT_DB_USER= +export WPT_DB_PASSWORD= +export WPT_DB_HOST= + +# (Optionally) set a custom table prefix to permit concurrency against the same database. +export WPT_TABLE_PREFIX=${WPT_TABLE_PREFIX-wptests_} + +# (Optionally) define the PHP executable to be called +export WPT_PHP_EXECUTABLE=${WPT_PHP_EXECUTABLE-php} + +# (Optionally) define the PHPUnit command execution call. +# Use if `php phpunit.phar` can't be called directly for some reason. +export WPT_PHPUNIT_CMD= + +# (Optionally) define the command execution to remove the test directory +# Use if `rm -r` can't be called directly for some reason. +export WPT_RM_TEST_DIR_CMD= + +# SSH connection string (can also be an alias). +# Leave empty if tests are meant to run in the same environment. +export WPT_SSH_CONNECT= + +# Any options to be passed to the SSH connection +# Defaults to '-o StrictHostKeyChecking=no' +export WPT_SSH_OPTIONS= + +# SSH private key, base64 encoded. +export WPT_SSH_PRIVATE_KEY_BASE64= + +# Output logging +# Use 'verbose' to increase verbosity +export WPT_DEBUG= + +# Certificate validation +# Use 1 to validate, and 0 to not validate +export WPT_CERTIFICATE_VALIDATION=1 + +# WordPress flavor +# 0 = WordPress (simple version) +# 1 = WordPress Multisite +export WPT_FLAVOR=1 + +# Extra tests (groups) +# 0 = none +# 1 = ajax +# 2 = ms-files +# 3 = external-http +export WPT_EXTRATESTS=0 +``` + +Configure the folder where the WordPress software downloads and the database accesses will be made in order to prepare the tests. + +### Preparing the environment + +Before performing the first test, let’s update all the components. This process can be run before each test in this environment if wanted to keep it up to date, although it will depend more if it is in a production environment. + +```bash +cd /home/wptestrunner/phpunit-test-runner/ +git pull +source .env +git checkout master +``` + +If you want to check a different branch, you can change it doing: + +```bash +git checkout example-branch +``` + +## Preparing the test + +Now there is the environment ready, run the test preparation. + +```bash +php prepare.php +``` + +The system will run a long series of installations, configurations and compilations of different elements in order to prepare the test. If warnings and warnings come out you should not worry too much, as it is quite normal. At the end of the process it will warn you if it needs something it doesn’t have. If it works, you should see something like this at the end: + +``` +Success: Prepared environment. +``` + +Now that the environment has been prepared, the next step is to run the tests for the first time. + +### Running the test + +Now that the environment is ready, let’s run the tests. To do this, execute the file that will perform it. + +```bash +php test.php +``` + +What do the symbols mean? + +`.` → Each dot means that the test has been passed correctly. + +`S` → It means the test has been skipped. This is usually because these tests are only valid in certain configurations. + +`F` → Means that the test has failed. Information about why this happened is displayed at the end. + +`E` → It means that the test has failed due to a PHP error, which can be an error, warning or notice. + +`I` → Means that the test has been marked as incomplete. + +If you follow these steps, everything should work perfectly and not make any mistakes. In case you get any error, it may be normal due to some missing adjustment or extension of PHP, among others. We recommend that you adjust the configuration until it works correctly. After all, this tool is to help you improve the optimal configuration for WordPress in that infrastructure. + +### Creating a report + +Even if the test has failed, a report will be made. The first one shows the information about our environment. Among the most important elements are the extensions that are commonly used in WordPress and some utilities that are also generally useful. + +```bash +cat /tmp/wp-test-runner/tests/phpunit/build/logs/env.json +``` -* PHP 5.6 or greater with Phar support enabled (for PHPUnit). -* MySQL or MariaDB with access to a writable database. -* Writable filesystem for the entire test directory (see [#40910](https://core.trac.wordpress.org/ticket/40910)). -* Run with a non-root user, both for security and practical purposes (see [#44233](https://core.trac.wordpress.org/ticket/44233#comment:34)/[#46577](https://core.trac.wordpress.org/ticket/46577)). +The content of this file is somewhat similar to this: -### 1. Prepare +```bash +{ + "php_version": "7.4.5", + "php_modules": { + "bcmath": false, + "curl": "7.4.5", + "filter": "7.4.5", + "gd": false, + "libsodium": false, + "mcrypt": false, + "mod_xml": false, + "mysqli": "7.4.5", + "imagick": false, + "pcre": "7.4.5", + "xml": "7.4.5", + "xmlreader": "7.4.5", + "zlib": "7.4.5" + }, + "system_utils": { + "curl": "7.58.0 (x86_64-pc-linux-gnu) libcurl\/7.58.0 OpenSSL\/1.1.1g zlib\/1.2.11 libidn2\/2.3.0 libpsl\/0.19.1 (+libidn2\/2.0.4) nghttp2\/1.30.0 librtmp\/2.3", + "ghostscript": "", + "imagemagick": false, + "openssl": "1.1.1g 21 Apr 2020" + }, + "mysql_version": "mysql Ver 15.1 Distrib 10.4.12-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2", + "os_name": "Linux", + "os_version": "4.15.0-20-generic" +} +``` -The [`prepare.php`](prepare.php) step: +In addition to this report, a definitive file with all the information of what happened in the tests. This is the one that includes all the tests that are made (more than 10,000) giving information of the time that they take to be executed, problems that have arisen… -1. Extracts the base64-encoded SSH private key, if necessary. -2. Clones the master branch of the WordPress develop git repo into the preparation directory. -3. Downloads `phpunit.phar` to the preparation directory. -4. Generates `wp-tests-config.php` and puts it into the preparation directory. -5. Delivers the prepared test directory to the test environment. +```bash +cat /tmp/wp-test-runner/tests/phpunit/build/logs/junit.xml +``` -### 2. Test +At this point we can generate the reports by sending them to WordPress.org, if necessary. Even if you haven’t included the WordPress user (see below for how to create it), you can still run this file. -The [`test.php`](test.php) step: +```bash +php report.php +``` -1. Calls `php phpunit.phar` to produce `tests/phpunit/build/logs/junit.xml`. +### Cleaning up the environment for other tests -### 3. Report +Having the tests working, all that remains is to delete all the files that have been created so that we can start over. To do this, execute the following command: -The [`report.php`](report.php) step: +```bash +php cleanup.php +``` -1. Processes PHPUnit XML log into a JSON blob. -2. Sends the JSON to WordPress.org. +### Automatic running -### 4. Cleanup +The best way to run this test is to create a cron that runs everything. Having in mind that the tests can overlap, the best way can be using a systemd timer. -The [`cleanup.php`](cleanup.php) step: +```bash +cat > /etc/systemd/system/wordpressphpunittestrunner.service << EOF +[Unit] +Description=WordPress PHPUnit Test Runner +[Service] +Type=oneshot +ExecStart=cd /home/wptestrunner/phpunit-test-runner/ && source .env && php prepare.php && php test.php && php report.php && php cleanup.php +User=wptestrunner +Group=wptestrunner +EOF +``` -1. Resets the database. -2. Deletes all files delivered to the test environment. +```bash +cat > /etc/systemd/system/wordpressphpunittestrunner.timer << EOF +[Unit] +Description=WordPress PHPUnit Test Runner +[Timer] +OnCalendar=*-*-* *:*:00 +Persistent=true +[Install] +WantedBy=timers.target +EOF +``` + +```bash +systemctl daemon-reload +systemctl enable wordpressphpunittestrunner.timer +systemctl start wordpressphpunittestrunner.timer +systemctl status wordpressphpunittestrunner.timer +``` + +If you want to check how is everything working... + +```bash +journalctl -u wordpressphpunittestrunner.timer +journalctl -n 120 -u wordpressphpunittestrunner.service +``` ## Contributing -tk +If you have questions about the process or run into test failures along the way, please [open an issue in the project repository](https://github.com/WordPress/phpunit-test-runner/issues) and we’ll help diagnose/get the documentation updated. Alternatively, you can also pop into the `#hosting` channel on [WordPress.org Slack](https://make.wordpress.org/chat/) for help. ## License -See [LICENSE](LICENSE) for project license. +See [LICENSE](LICENSE) for project license. \ No newline at end of file diff --git a/cleanup.php b/cleanup.php index f2e03cf..e584c6c 100644 --- a/cleanup.php +++ b/cleanup.php @@ -1,30 +1,51 @@ phpversion(), 'php_modules' => array(), + 'gd_info' => extension_loaded( 'gd' ) ? gd_info() : array(), + 'imagick_info' => extension_loaded( 'imagick' ) ? Imagick::queryFormats() : array(), 'system_utils' => array(), - 'mysql_version' => trim( shell_exec( 'mysql --version' ) ), 'os_name' => trim( shell_exec( 'uname -s' ) ), 'os_version' => trim( shell_exec( 'uname -r' ) ), ); $php_modules = array( 'bcmath', + 'ctype', 'curl', + 'date', + 'dom', + 'exif', + 'fileinfo', 'filter', + 'ftp', 'gd', + 'gettext', + 'gmagick', + 'hash', + 'iconv', + 'imagick', + 'imap', + 'intl', + 'json', 'libsodium', + 'libxml', + 'mbstring', 'mcrypt', 'mod_xml', 'mysqli', - 'imagick', - 'gmagick', + 'mysqlnd', + 'openssl', 'pcre', + 'pdo_mysql', + 'soap', + 'sockets', + 'sodium', 'xml', 'xmlreader', + 'zip', 'zlib', ); foreach( $php_modules as $php_module ) { @@ -214,6 +336,10 @@ function get_env_details() { function curl_selected_bits($k) { return in_array($k, array('version', 'ssl_version', 'libz_version')); } $curl_bits = curl_version(); $env['system_utils']['curl'] = implode(' ',array_values(array_filter($curl_bits, 'curl_selected_bits',ARRAY_FILTER_USE_KEY) )); + $mysqli = new mysqli($WPT_DB_HOST, $WPT_DB_USER, $WPT_DB_PASSWORD, $WPT_DB_NAME); + $env['mysql_version'] = $mysqli->query("SELECT VERSION()")->fetch_row()[0]; + $mysqli->close(); + if ( class_exists( 'Imagick' ) ) { $imagick = new Imagick(); $version = $imagick->getVersion(); diff --git a/prepare.php b/prepare.php index a572b51..52b5aa1 100644 --- a/prepare.php +++ b/prepare.php @@ -1,49 +1,154 @@ phpversion(), 'php_modules' => array(), + 'gd_info' => extension_loaded( 'gd' ) ? gd_info() : array(), + 'imagick_info' => extension_loaded( 'imagick' ) ? Imagick::queryFormats() : array(), 'system_utils' => array(), - 'mysql_version' => trim( shell_exec( 'mysql --version' ) ), 'os_name' => trim( shell_exec( 'uname -s' ) ), 'os_version' => trim( shell_exec( 'uname -r' ) ), ); \$php_modules = array( 'bcmath', + 'ctype', 'curl', + 'date', + 'dom', + 'exif', + 'fileinfo', 'filter', + 'ftp', 'gd', + 'gettext', + 'gmagick', + 'hash', + 'iconv', + 'imagick', + 'imap', + 'intl', + 'json', 'libsodium', + 'libxml', + 'mbstring', 'mcrypt', 'mod_xml', 'mysqli', - 'imagick', - 'gmagick', + 'mysqlnd', + 'openssl', 'pcre', + 'pdo_mysql', + 'soap', + 'sockets', + 'sodium', 'xml', 'xmlreader', + 'zip', 'zlib', ); foreach( \$php_modules as \$php_module ) { @@ -92,6 +219,10 @@ function curl_selected_bits(\$k) { return in_array(\$k, array('version', 'ssl_ve \$env['system_utils']['graphicsmagick'] = \$version[1]; } \$env['system_utils']['openssl'] = str_replace( 'OpenSSL ', '', trim( shell_exec( 'openssl version' ) ) ); + +\$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); +\$env['mysql_version'] = \$mysqli->query("SELECT VERSION()")->fetch_row()[0]; +\$mysqli->close(); file_put_contents( __DIR__ . '/tests/phpunit/build/logs/env.json', json_encode( \$env, JSON_PRETTY_PRINT ) ); if ( 'cli' === php_sapi_name() && defined( 'WP_INSTALLING' ) && WP_INSTALLING ) { echo PHP_EOL; @@ -99,88 +230,136 @@ function curl_selected_bits(\$k) { return in_array(\$k, array('version', 'ssl_ve echo PHP_EOL; } EOT; + +// Initialize a string that will be used to identify the database settings section in the configuration file. $logger_replace_string = '// ** Database settings ** //' . PHP_EOL; + +// Prepend the logger script to the database settings identifier to ensure it gets included in the wp-tests-config.php file. $system_logger = $logger_replace_string . $system_logger; + +// Define a string that will set the 'WP_PHP_BINARY' constant to the path of the PHP executable. $php_binary_string = 'define( \'WP_PHP_BINARY\', \''. $WPT_PHP_EXECUTABLE . '\' );'; + +/** + * An associative array mapping configuration file placeholders to environment-specific values. + * This array is used in the subsequent str_replace operation to replace placeholders + * in the wp-tests-config-sample.php file with values from the environment or defaults if none are provided. + */ $search_replace = array( - 'wptests_' => getenv( 'WPT_TABLE_PREFIX' ) ? : 'wptests_', - 'youremptytestdbnamehere' => getenv( 'WPT_DB_NAME' ), - 'yourusernamehere' => getenv( 'WPT_DB_USER' ), - 'yourpasswordhere' => getenv( 'WPT_DB_PASSWORD' ), - 'localhost' => getenv( 'WPT_DB_HOST' ), + 'wptests_' => trim( getenv( 'WPT_TABLE_PREFIX' ) ) ? : 'wptests_', + 'youremptytestdbnamehere' => trim( getenv( 'WPT_DB_NAME' ) ), + 'yourusernamehere' => trim( getenv( 'WPT_DB_USER' ) ), + 'yourpasswordhere' => trim( getenv( 'WPT_DB_PASSWORD' ) ), + 'localhost' => trim( getenv( 'WPT_DB_HOST' ) ), 'define( \'WP_PHP_BINARY\', \'php\' );' => $php_binary_string, $logger_replace_string => $system_logger, ); + +// Replace the placeholders in the wp-tests-config-sample.php file content with actual values. $contents = str_replace( array_keys( $search_replace ), array_values( $search_replace ), $contents ); + +// Write the modified content to the wp-tests-config.php file, which will be used by the test suite. file_put_contents( $WPT_PREPARE_DIR . '/wp-tests-config.php', $contents ); -// Now, install PHPUnit based on the test environment's PHP Version +/** + * Determines the PHP version of the test environment to ensure the correct version of PHPUnit is installed. + * It constructs a command that prints out the PHP version in a format compatible with PHPUnit's version requirements. + */ $php_version_cmd = $WPT_PHP_EXECUTABLE . " -r \"print PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;\""; + +/** + * If an SSH connection string is provided, the command to determine the PHP version is modified + * to execute remotely over SSH. This is required if the test environment is not the local machine. + */ if ( ! empty( $WPT_SSH_CONNECT ) ) { + // The PHP version check command is prefixed with the SSH command, including SSH options, + // and the connection string, ensuring the command is executed on the remote machine. $php_version_cmd = 'ssh ' . $WPT_SSH_OPTIONS . ' ' . escapeshellarg( $WPT_SSH_CONNECT ) . ' ' . escapeshellarg( $php_version_cmd ); } +// Initialize return value variable for the exec function call. $retval = 0; + +/** + * Executes the constructed command to obtain the PHP version of the test environment. + * The output is stored in $env_php_version, and the return value of the command execution is stored in $retval. + */ $env_php_version = exec( $php_version_cmd, $output, $retval ); + +// Check if the command execution was successful by inspecting the return value. if ( $retval !== 0 ) { + // If the return value is not zero, an error occurred, and a message is logged. error_message( 'Could not retrieve the environment PHP Version.' ); } -log_message( "Environment PHP Version: $env_php_version" ); -// If PHP Version is 8.X.X, set PHP Version to 7.4 for compatibility with core PHPUnit tests. -if ( substr( $env_php_version, 0 , 2 ) === '8.' ) { - log_message( 'Version 8.x.x Found. Downloading PHPUnit for PHP 7.4 instead for compatibility.' ); - $env_php_version = '7.4'; -} +// Log the obtained PHP version for confirmation and debugging purposes. +log_message( 'Environment PHP Version: ' . $env_php_version ); -if ( version_compare( $env_php_version, '5.6', '<' ) ) { - error_message( "The test runner is not compatible with PHP < 5.6." ); +/** + * Checks if the detected PHP version is below 7.0. + * The test runner requires PHP version 7.0 or above, and if the environment's PHP version + * is lower, it logs an error message and could terminate the script. + */ +if ( version_compare( $env_php_version, '7.0', '<' ) ) { + // Logs an error message indicating the test runner's incompatibility with PHP versions below 7.0. + error_message( 'The test runner is not compatible with PHP < 7.0.' ); } -// If PHP version is 5.6-7.0, download PHPUnit 5.7 phar directly. -if ( version_compare( $env_php_version, '7.1', '<' ) ) { - perform_operations( array( - 'wget -O ' . escapeshellarg( $WPT_PREPARE_DIR . '/phpunit.phar' ) . ' https://phar.phpunit.de/phpunit-5.7.phar', - ) ); +/** + * Use Composer to manage PHPUnit and its dependencies. + * This allows for better dependency management and compatibility. + */ -// Otherwise, use Composer to download PHPUnit to get further necessary dependencies. -} else { +// Check if Composer is installed and available in the PATH. +$composer_cmd = 'cd ' . escapeshellarg( $WPT_PREPARE_DIR ) . ' && '; +$retval = 0; +$composer_path = escapeshellarg( system( 'which composer', $retval ) ); - // First, check if composer is available. Download if not. - $composer_cmd = 'cd ' . escapeshellarg( $WPT_PREPARE_DIR ) . ' && '; +if ( $retval === 0 ) { - $retval = 0; - $composer_path = escapeshellarg( system( 'which composer', $retval ) ); - if ( $retval === 0 ) { - $composer_cmd .= $composer_path . ' '; - } else { - log_message( 'Local Composer not found. Downloading latest stable ...' ); + // If Composer is available, prepare the command to use the Composer binary. + $composer_cmd .= $composer_path . ' '; - perform_operations( array( - 'wget -O ' . escapeshellarg( $WPT_PREPARE_DIR . '/composer.phar' ) . ' https://getcomposer.org/composer-stable.phar', - ) ); +} else { - $composer_cmd .= 'php composer.phar '; - } + // If Composer is not available, download the Composer phar file. + log_message( 'Local Composer not found. Downloading latest stable ...' ); - // Set Composer PHP environment, then run Composer. perform_operations( array( - $composer_cmd . 'config platform.php ' . escapeshellarg( $env_php_version ), - $composer_cmd . 'update', + 'wget -O ' . escapeshellarg( $WPT_PREPARE_DIR . '/composer.phar' ) . ' https://getcomposer.org/composer-stable.phar', ) ); + + // Update the command to use the downloaded Composer phar file. + $composer_cmd .= 'php composer.phar '; } -// Deliver all files to test environment. +// Set the PHP version for Composer to ensure compatibility and update dependencies. +perform_operations( array( + $composer_cmd . 'config platform.php ' . escapeshellarg( $env_php_version ), + $composer_cmd . 'update', +) ); + +/** + * If an SSH connection is configured, use rsync to transfer the prepared files to the remote test environment. + * The -r option for rsync enables recursive copying to handle directory structures. + * Additional rsync options may be included for more verbose output if debugging is enabled. + */ if ( ! empty( $WPT_SSH_CONNECT ) ) { + // Initialize rsync options with recursive copying. $rsync_options = '-r'; + // If debug mode is set to verbose, append 'v' to rsync options for verbose output. if ( 'verbose' === $WPT_DEBUG ) { $rsync_options = $rsync_options . 'v'; } + // Perform the rsync operation with the configured options and exclude patterns. + // This operation synchronizes the test environment with the prepared files, excluding version control directories + // and other non-essential files for test execution. perform_operations( array( 'rsync ' . $rsync_options . ' --exclude=".git/" --exclude="node_modules/" --exclude="composer.phar" -e "ssh ' . $WPT_SSH_OPTIONS . '" ' . escapeshellarg( trailingslashit( $WPT_PREPARE_DIR ) ) . ' ' . escapeshellarg( $WPT_SSH_CONNECT . ':' . $WPT_TEST_DIR ), ) ); } +// Log a success message indicating that the environment has been prepared. log_message( 'Success: Prepared environment.' ); diff --git a/report.php b/report.php index 7384886..b690f76 100644 --- a/report.php +++ b/report.php @@ -1,50 +1,136 @@