Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/phpunit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ jobs:
WPT_TEST_DIR: /tmp/wp-test-runner
WPT_DB_NAME: wordpress_test
WPT_DB_USER: wp_test
WPT_DB_PASSWORD: wp_test
# A quote, a backslash and a placeholder name, so the run proves that
# prepare.php writes the password into wp-tests-config.php as given.
WPT_DB_PASSWORD: 'wp''te\st-localhost'
WPT_DB_HOST: 127.0.0.1
WPT_REPORT_API_KEY: ''

Expand All @@ -64,6 +66,17 @@ jobs:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

# The mysql image writes MYSQL_PASSWORD into SQL without escaping it, so
# the password above is set here instead.
- name: Set the database password
env:
MYSQL_PWD: root
run: |
mysql -h 127.0.0.1 -u root <<'SQL'
SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES';
ALTER USER 'wp_test'@'%' IDENTIFIED BY 'wp''te\st-localhost';
SQL

- name: Set up PHP
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2.40.0
with:
Expand All @@ -78,6 +91,10 @@ jobs:
- name: Prepare environment
run: php prepare.php

- name: Check the database password in wp-tests-config.php
run: |
php -r 'require getenv( "WPT_PREPARE_DIR" ) . "/wp-tests-config.php"; exit( DB_PASSWORD === getenv( "WPT_DB_PASSWORD" ) ? 0 : 1 );'

- name: Run unit tests
run: php test.php
continue-on-error: true
Expand All @@ -91,7 +108,7 @@ jobs:

- name: Verify database cleanup
env:
MYSQL_PWD: wp_test
MYSQL_PWD: ${{ env.WPT_DB_PASSWORD }}
run: |
TABLES=$(mysql -h 127.0.0.1 -u wp_test wordpress_test -N -e "SHOW TABLES LIKE 'wptests\_%'")
if [ -n "$TABLES" ]; then
Expand Down
28 changes: 18 additions & 10 deletions prepare.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,27 +389,35 @@ function curl_selected_bits( $k ) {
$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\', \'' . $runner_vars['WPT_PHP_EXECUTABLE'] . '\' );';
$php_binary_string = 'define( \'WP_PHP_BINARY\', \'' . addcslashes( $runner_vars['WPT_PHP_EXECUTABLE'], "\\'" ) . '\' );';

/*
* Map configuration file placeholders to environment-specific values.
*
* This is used in the subsequent str_replace operation to replace placeholder
* values in the wp-tests-config-sample.php file with the ones provided.
* The values are written into single-quoted PHP strings, so their backslashes
* and single quotes are escaped, as WordPress does when it writes wp-config.php
* in wp-admin/setup-config.php. Without that, a database password containing a
* single quote, or ending with a backslash, makes wp-tests-config.php a parse
* error, and a double backslash is silently turned into one.
*/
$wpt_table_prefix = trim( getenv( 'WPT_TABLE_PREFIX' ) );
$search_replace = array(
'wptests_' => '' !== $wpt_table_prefix ? $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' ) ),
'wptests_' => addcslashes( '' !== $wpt_table_prefix ? $wpt_table_prefix : 'wptests_', "\\'" ),
'youremptytestdbnamehere' => addcslashes( trim( getenv( 'WPT_DB_NAME' ) ), "\\'" ),
'yourusernamehere' => addcslashes( trim( getenv( 'WPT_DB_USER' ) ), "\\'" ),
'yourpasswordhere' => addcslashes( trim( getenv( 'WPT_DB_PASSWORD' ) ), "\\'" ),
'localhost' => addcslashes( 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 );
/*
* Replace the placeholders in a single pass. str_replace() runs each pair over
* the result of the previous ones, so a value that contains a later placeholder,
* such as a password containing "localhost", would be rewritten. strtr() never
* revisits replaced text.
*/
$contents = strtr( $contents, $search_replace );

/*
* Point the test suite's temporary directory inside the test directory, so
Expand Down