Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DB name as env variable and runtime variable #128

Merged
merged 3 commits into from
Jul 20, 2021
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
1 change: 1 addition & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ jobs:
export MYSQL_TCP_PORT=${{ job.services.mysql.ports['3306'] }}
echo "WP_CLI_TEST_DBROOTUSER=root" >> $GITHUB_ENV
echo "WP_CLI_TEST_DBROOTPASS=root" >> $GITHUB_ENV
echo "WP_CLI_TEST_DBNAME=wp_cli_test" >> $GITHUB_ENV
echo "WP_CLI_TEST_DBUSER=wp_cli_test" >> $GITHUB_ENV
echo "WP_CLI_TEST_DBPASS=password1" >> $GITHUB_ENV
echo "WP_CLI_TEST_DBHOST=$MYSQL_HOST:$MYSQL_TCP_PORT" >> $GITHUB_ENV
Expand Down
11 changes: 7 additions & 4 deletions .readme-partials/USING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ To make use of the WP-CLI testing framework, you need to complete the following
The timeout is expressed in seconds.

4. Optionally add a `behat.yml` file to the package root with the following content:
```json
```yaml
default:
paths:
features: features
bootstrap: vendor/wp-cli/wp-cli-tests/features/bootstrap
suites:
default:
contexts:
- WP_CLI\Tests\Context\FeatureContext
paths:
- features
```
This will make sure that the automated Behat system works across all platforms. This is needed on Windows.

Expand Down
60 changes: 33 additions & 27 deletions bin/install-package-tests
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,81 @@
# - WP_CLI_TEST_DBHOST is the host to use and can include a port, i.e "127.0.0.1:33060" (defaults to "localhost")
# - WP_CLI_TEST_DBROOTUSER is the user that has permission to administer databases and users (defaults to "root").
# - WP_CLI_TEST_DBROOTPASS is the password to use for the above user (defaults to an empty password).
# - WP_CLI_TEST_DBNAME is the database that the tests run under (defaults to "wp_cli_test").
# - WP_CLI_TEST_DBUSER is the user that the tests run under (defaults to "wp_cli_test").
# - WP_CLI_TEST_DBPASS is the password to use for the above user (defaults to "password1").

HOST=localhost
PORT=""
HOST_STRING=''
if [ -n "$WP_CLI_TEST_DBHOST" ]; then
if [ -n "${WP_CLI_TEST_DBHOST}" ]; then
case ${WP_CLI_TEST_DBHOST##*[]]} in
(*:*) HOST=${WP_CLI_TEST_DBHOST%:*} PORT=${WP_CLI_TEST_DBHOST##*:};;
(*) HOST=$WP_CLI_TEST_DBHOST;;
(*) HOST=${WP_CLI_TEST_DBHOST};;
esac
HOST_STRING="-h$HOST"
if [ -n "$PORT" ]; then
HOST_STRING="$HOST_STRING -P$PORT --protocol=tcp"
HOST_STRING="-h${HOST}"
if [ -n "${PORT}" ]; then
HOST_STRING="${HOST_STRING} -P${PORT} --protocol=tcp"
fi
fi

USER=root
if [ -n "$WP_CLI_TEST_DBROOTUSER" ]; then
USER="$WP_CLI_TEST_DBROOTUSER"
if [ -n "${WP_CLI_TEST_DBROOTUSER}" ]; then
USER="${WP_CLI_TEST_DBROOTUSER}"
fi

PASSWORD_STRING=""
if [ -n "$WP_CLI_TEST_DBROOTPASS" ]; then
PASSWORD_STRING="-p$WP_CLI_TEST_DBROOTPASS"
if [ -n "${WP_CLI_TEST_DBROOTPASS}" ]; then
PASSWORD_STRING="-p${WP_CLI_TEST_DBROOTPASS}"
fi

TEST_DB=wp_cli_test
if [ -n "${WP_CLI_TEST_DBNAME}" ]; then
TEST_DB="${WP_CLI_TEST_DBNAME}"
fi

TEST_USER=wp_cli_test
if [ -n "$WP_CLI_TEST_DBUSER" ]; then
TEST_USER="$WP_CLI_TEST_DBUSER"
if [ -n "${WP_CLI_TEST_DBUSER}" ]; then
TEST_USER="${WP_CLI_TEST_DBUSER}"
fi

TEST_PASSWORD=password1
if [ -n "$WP_CLI_TEST_DBPASS" ]; then
TEST_PASSWORD="$WP_CLI_TEST_DBPASS"
if [ -n "${WP_CLI_TEST_DBPASS}" ]; then
TEST_PASSWORD="${WP_CLI_TEST_DBPASS}"
fi

# Prepare the database for running the tests with a MySQL version 8.0 or higher.
install_mysql_db_8_0_plus() {
set -ex
mysql -e "CREATE DATABASE IF NOT EXISTS \`wp_cli_test\`;" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "CREATE USER IF NOT EXISTS \`wp_cli_test\`@'%' IDENTIFIED WITH mysql_native_password BY '$TEST_PASSWORD'" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "GRANT ALL PRIVILEGES ON \`wp_cli_test\`.* TO '$TEST_USER'@'%'" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "GRANT ALL PRIVILEGES ON \`wp_cli_test_scaffold\`.* TO '$TEST_USER'@'%'" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
mysql -e "CREATE USER IF NOT EXISTS \`${TEST_DB}\`@'%' IDENTIFIED WITH mysql_native_password BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
}

# Prepare the database for running the tests with a MySQL version lower than 8.0.
install_mysql_db_lower_than_8_0() {
set -ex
mysql -e "CREATE DATABASE IF NOT EXISTS \`wp_cli_test\`;" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "GRANT ALL ON \`wp_cli_test\`.* TO '$TEST_USER'@'%' IDENTIFIED BY '$TEST_PASSWORD'" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "GRANT ALL ON \`wp_cli_test_scaffold\`.* TO '$TEST_USER'@'%' IDENTIFIED BY '$TEST_PASSWORD'" $HOST_STRING -u"$USER" "$PASSWORD_STRING"
mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
mysql -e "GRANT ALL ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
mysql -e "GRANT ALL ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
}

VERSION_STRING=$(mysql -e "SELECT VERSION()" --skip-column-names $HOST_STRING -u"$USER" "$PASSWORD_STRING")
VERSION=$(echo "$VERSION_STRING" | grep -o '^[^-]*')
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
VERSION_STRING=$(mysql -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}")
VERSION=$(echo "${VERSION_STRING}" | grep -o '^[^-]*')
MAJOR=$(echo "${VERSION}" | cut -d. -f1)
MINOR=$(echo "${VERSION}" | cut -d. -f2)
TYPE="MySQL"
case "$VERSION_STRING" in
case "${VERSION_STRING}" in
*"MariaDB"*)
TYPE="MariaDB"
;;
esac

echo "Detected $TYPE at version $MAJOR.$MINOR"
echo "Detected ${TYPE} at version ${MAJOR}.${MINOR}"


if [ "$TYPE" != "MariaDB" ] && [ "$MAJOR" -ge 8 ]; then
if [ "${TYPE}" != "MariaDB" ] && [ "${MAJOR}" -ge 8 ]; then
install_mysql_db_8_0_plus
else
install_mysql_db_lower_than_8_0
Expand Down
89 changes: 47 additions & 42 deletions src/Context/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,24 @@ class FeatureContext implements SnippetAcceptingContext {
/**
* The test database settings. All but `dbname` can be set via environment variables. The database is dropped at the start of each scenario and created on a "Given a WP installation" step.
*/
private static $db_settings = array(
private static $db_settings = [
'dbname' => 'wp_cli_test',
'dbuser' => 'wp_cli_test',
'dbpass' => 'password1',
'dbhost' => '127.0.0.1',
);
];

/**
* Array of background process ids started by the current scenario. Used to terminate them at the end of the scenario.
*/
private $running_procs = array();
private $running_procs = [];

/**
* Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, DB_USER, DB_PASSWORD, DB_HOST, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest.
* Some are step-dependent: RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. One is set on use: INVOKE_WP_CLI_WITH_PHP_ARGS-args.
* Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
*/
public $variables = array();
public $variables = [];

/**
* The current feature file and scenario line number as '<file>.<line>'. Used in RUN_DIR and SUITE_CACHE_DIR directory names. Set at the start of each scenario.
Expand All @@ -84,9 +84,9 @@ class FeatureContext implements SnippetAcceptingContext {
private static $num_top_processes; // Number of processes/methods to output by longest run times. Set on `@BeforeSuite`.
private static $num_top_scenarios; // Number of scenarios to output by longest run times. Set on `@BeforeSuite`.

private static $scenario_run_times = array(); // Scenario run times (top `self::$num_top_scenarios` only).
private static $scenario_run_times = []; // Scenario run times (top `self::$num_top_scenarios` only).
private static $scenario_count = 0; // Scenario count, incremented on `@AfterScenario`.
private static $proc_method_run_times = array(); // Array of run time info for proc methods, keyed by method name and arg, each a 2-element array containing run time and run count.
private static $proc_method_run_times = []; // Array of run time info for proc methods, keyed by method name and arg, each a 2-element array containing run time and run count.

/**
* Get the path to the Composer vendor folder.
Expand Down Expand Up @@ -211,11 +211,11 @@ private static function get_process_env_variables() {
}

$path_separator = Utils\is_windows() ? ';' : ':';
$env = array(
$env = [
'PATH' => $bin_path . $path_separator . getenv( 'PATH' ),
'BEHAT_RUN' => 1,
'HOME' => sys_get_temp_dir() . '/wp-cli-home',
);
];

$config_path = getenv( 'WP_CLI_CONFIG_PATH' );
if ( false !== $config_path ) {
Expand Down Expand Up @@ -490,16 +490,28 @@ public function __construct() {
$this->variables['DB_ROOT_PASSWORD'] = getenv( 'WP_CLI_TEST_DBROOTPASS' );
}

if ( getenv( 'WP_CLI_TEST_DBNAME' ) ) {
$this->variables['DB_NAME'] = getenv( 'WP_CLI_TEST_DBNAME' );
} else {
$this->variables['DB_NAME'] = 'wp_cli_test';
}

if ( getenv( 'WP_CLI_TEST_DBUSER' ) ) {
$this->variables['DB_USER'] = getenv( 'WP_CLI_TEST_DBUSER' );
} else {
$this->variables['DB_USER'] = 'wp_cli_test';
}

if ( false !== getenv( 'WP_CLI_TEST_DBPASS' ) ) {
$this->variables['DB_PASSWORD'] = getenv( 'WP_CLI_TEST_DBPASS' );
} else {
$this->variables['DB_PASSWORD'] = 'password1';
}

if ( getenv( 'WP_CLI_TEST_DBHOST' ) ) {
$this->variables['DB_HOST'] = getenv( 'WP_CLI_TEST_DBHOST' );
} else {
$this->variables['DB_HOST'] = 'localhost';
}

if ( getenv( 'MYSQL_TCP_PORT' ) ) {
Expand All @@ -510,17 +522,10 @@ public function __construct() {
$this->variables['MYSQL_HOST'] = getenv( 'MYSQL_HOST' );
}

self::$db_settings['dbuser'] = array_key_exists( 'DB_USER', $this->variables )
? $this->variables['DB_USER']
: 'wp_cli_test';

self::$db_settings['dbpass'] = array_key_exists( 'DB_PASSWORD', $this->variables )
? $this->variables['DB_PASSWORD']
: 'password1';

self::$db_settings['dbhost'] = array_key_exists( 'DB_HOST', $this->variables )
? $this->variables['DB_HOST']
: 'localhost';
self::$db_settings['dbname'] = $this->variables['DB_NAME'];
self::$db_settings['dbuser'] = $this->variables['DB_USER'];
self::$db_settings['dbpass'] = $this->variables['DB_PASSWORD'];
self::$db_settings['dbhost'] = $this->variables['DB_HOST'];

$this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str( self::$db_settings );

Expand All @@ -536,7 +541,7 @@ public function replace_variables( $str ) {
if ( false !== strpos( $str, '{INVOKE_WP_CLI_WITH_PHP_ARGS-' ) ) {
$str = $this->replace_invoke_wp_cli_with_php_args( $str );
}
$str = preg_replace_callback( '/\{([A-Z_][A-Z_0-9]*)\}/', array( $this, 'replace_var' ), $str );
$str = preg_replace_callback( '/\{([A-Z_][A-Z_0-9]*)\}/', [ $this, 'replace_var' ], $str );
if ( false !== strpos( $str, '{WP_VERSION-' ) ) {
$str = $this->replace_wp_versions( $str );
}
Expand Down Expand Up @@ -600,9 +605,9 @@ private function replace_var( $matches ) {
private function replace_wp_versions( $str ) {
static $wp_versions = null;
if ( null === $wp_versions ) {
$wp_versions = array();
$wp_versions = [];

$response = Requests::get( 'https://api.wordpress.org/core/version-check/1.7/', null, array( 'timeout' => 30 ) );
$response = Requests::get( 'https://api.wordpress.org/core/version-check/1.7/', null, [ 'timeout' => 30 ] );
if ( 200 === $response->status_code ) {
$body = json_decode( $response->body );
if ( is_object( $body ) && isset( $body->offers ) && is_array( $body->offers ) ) {
Expand Down Expand Up @@ -724,12 +729,12 @@ private function set_cache_dir() {
* @param array $assoc_args Optional. Associative array of options. Default empty.
* @param bool $add_database Optional. Whether to add dbname to the $sql_cmd. Default false.
*/
private static function run_sql( $sql_cmd, $assoc_args = array(), $add_database = false ) {
$default_assoc_args = array(
private static function run_sql( $sql_cmd, $assoc_args = [], $add_database = false ) {
$default_assoc_args = [
'host' => self::$db_settings['dbhost'],
'user' => self::$db_settings['dbuser'],
'pass' => self::$db_settings['dbpass'],
);
];
if ( $add_database ) {
$sql_cmd .= ' ' . escapeshellarg( self::$db_settings['dbname'] );
}
Expand All @@ -742,15 +747,15 @@ private static function run_sql( $sql_cmd, $assoc_args = array(), $add_database

public function create_db() {
$dbname = self::$db_settings['dbname'];
self::run_sql( 'mysql --no-defaults', array( 'execute' => "CREATE DATABASE IF NOT EXISTS $dbname" ) );
self::run_sql( 'mysql --no-defaults', [ 'execute' => "CREATE DATABASE IF NOT EXISTS $dbname" ] );
}

public function drop_db() {
$dbname = self::$db_settings['dbname'];
self::run_sql( 'mysql --no-defaults', array( 'execute' => "DROP DATABASE IF EXISTS $dbname" ) );
self::run_sql( 'mysql --no-defaults', [ 'execute' => "DROP DATABASE IF EXISTS $dbname" ] );
}

public function proc( $command, $assoc_args = array(), $path = '' ) {
public function proc( $command, $assoc_args = [], $path = '' ) {
if ( ! empty( $assoc_args ) ) {
$command .= Utils\assoc_args_to_str( $assoc_args );
}
Expand All @@ -773,11 +778,11 @@ public function proc( $command, $assoc_args = array(), $path = '' ) {
* Start a background process. Will automatically be closed when the tests finish.
*/
public function background_proc( $cmd ) {
$descriptors = array(
$descriptors = [
0 => STDIN,
1 => array( 'pipe', 'w' ),
2 => array( 'pipe', 'w' ),
);
1 => [ 'pipe', 'w' ],
2 => [ 'pipe', 'w' ],
];

$proc = proc_open( $cmd, $descriptors, $pipes, $this->variables['RUN_DIR'], self::get_process_env_variables() );

Expand Down Expand Up @@ -883,14 +888,14 @@ public function install_wp( $subdir = '' ) {
$this->download_wp( $subdir );
$this->create_config( $subdir, $config_extra_php );

$install_args = array(
$install_args = [
'url' => 'http://example.com',
'title' => 'WP CLI Site',
'admin_user' => 'admin',
'admin_email' => 'admin@example.com',
'admin_password' => 'password1',
'skip-email' => true,
);
];

$install_cache_path = '';
if ( self::$install_cache_dir ) {
Expand All @@ -900,7 +905,7 @@ public function install_wp( $subdir = '' ) {

if ( $install_cache_path && file_exists( $install_cache_path ) ) {
self::copy_dir( $install_cache_path, $run_dir );
self::run_sql( 'mysql --no-defaults', array( 'execute' => "source {$install_cache_path}.sql" ), true /*add_database*/ );
self::run_sql( 'mysql --no-defaults', [ 'execute' => "source {$install_cache_path}.sql" ], true /*add_database*/ );
} else {
$this->proc( 'wp core install', $install_args, $subdir )->run_check();
if ( $install_cache_path ) {
Expand All @@ -914,7 +919,7 @@ public function install_wp( $subdir = '' ) {
$command .= ' --skip-column-statistics';
}

self::run_sql( $command, array( 'result-file' => "{$install_cache_path}.sql" ), true /*add_database*/ );
self::run_sql( $command, [ 'result-file' => "{$install_cache_path}.sql" ], true /*add_database*/ );
}
}
}
Expand All @@ -938,14 +943,14 @@ public function install_wp_with_composer( $vendor_directory = 'vendor' ) {

$this->create_config( 'WordPress', $config_extra_php );

$install_args = array(
$install_args = [
'url' => 'http://localhost:8080',
'title' => 'WP CLI Site with both WordPress and wp-cli as Composer dependencies',
'admin_user' => 'admin',
'admin_email' => 'admin@example.com',
'admin_password' => 'password1',
'skip-email' => true,
);
];

$this->proc( 'wp core install', $install_args )->run_check();
}
Expand Down Expand Up @@ -1065,7 +1070,7 @@ private static function dir_diff_copy( $upd_dir, $src_dir, $cop_dir ) {
$error = error_get_last();
throw new RuntimeException( sprintf( "Failed to open updated directory '%s': %s. " . __FILE__ . ':' . __LINE__, $upd_dir, $error['message'] ) );
}
foreach ( array_diff( $files, array( '.', '..' ) ) as $file ) {
foreach ( array_diff( $files, [ '.', '..' ] ) as $file ) {
$upd_file = $upd_dir . '/' . $file;
$src_file = $src_dir . '/' . $file;
$cop_file = $cop_dir . '/' . $file;
Expand Down Expand Up @@ -1129,10 +1134,10 @@ private static function log_run_times_after_suite( AfterSuiteScope $scope ) {
// Process and proc method run times.
$run_times = array_merge( Process::$run_times, self::$proc_method_run_times );
$reduce_callback = function ( $carry, $item ) {
return array( $carry[0] + $item[0], $carry[1] + $item[1] );
return [ $carry[0] + $item[0], $carry[1] + $item[1] ];
};

list( $ptime, $calls ) = array_reduce( $run_times, $reduce_callback, array( 0, 0 ) );
list( $ptime, $calls ) = array_reduce( $run_times, $reduce_callback, [ 0, 0 ] );

$overhead = $time - $ptime;
$pct = round( ( $overhead / $time ) * 100 );
Expand Down Expand Up @@ -1208,7 +1213,7 @@ private static function log_run_times_after_suite( AfterSuiteScope $scope ) {
private static function log_proc_method_run_time( $key, $start_time ) {
$run_time = microtime( true ) - $start_time;
if ( ! isset( self::$proc_method_run_times[ $key ] ) ) {
self::$proc_method_run_times[ $key ] = array( 0, 0 );
self::$proc_method_run_times[ $key ] = [ 0, 0 ];
}
self::$proc_method_run_times[ $key ][0] += $run_time;
self::$proc_method_run_times[ $key ][1]++;
Expand Down