From a0b90f7035e0501052491dbcfc84e4d1d0d00954 Mon Sep 17 00:00:00 2001 From: Jan-Willem Oostendorp Date: Thu, 13 Jun 2024 14:23:22 +0200 Subject: [PATCH 1/3] Add prepare-tests info When running composer prepare-tests and there is an errro, no usefull information is shown. Now It diesplays all the variables it uses. And when giving an error, display where to find the documentation. --- bin/install-package-tests | 59 +++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/bin/install-package-tests b/bin/install-package-tests index b683a7bf..867544d0 100755 --- a/bin/install-package-tests +++ b/bin/install-package-tests @@ -12,9 +12,13 @@ is_numeric() { case $1 in ''|*[!0-9]*) return 1;; # returns 1 if not numeric - *) return 0;; # returns 0 if numeric + *) return 0;; # returns 0 if numeric esac } +# Promt color vars. +C_RED="\033[31m" +C_BLUE="\033[34m" +NO_FORMAT="\033[0m" HOST=localhost PORT="" @@ -28,65 +32,93 @@ if [ -n "${WP_CLI_TEST_DBHOST}" ]; then if [ -n "${PORT}" ]; then # If the port is not numeric, then we assume it is a socket path. if is_numeric "${PORT}"; then + echo "Connecting to custom host: ${C_BLUE}${HOST}${NO_FORMAT} on port ${C_BLUE}${PORT}${NO_FORMAT}" HOST_STRING="${HOST_STRING} --port=${PORT} --protocol=tcp" else + echo "Connecting to custom host: ${C_BLUE}${HOST}${NO_FORMAT} on socket ${C_BLUE}${PORT}${NO_FORMAT}" HOST_STRING="${HOST_STRING} --socket=${PORT} --protocol=socket" fi + else + echo "Connecting to custom host: ${C_BLUE}${HOST}${NO_FORMAT}" fi +else + echo "Connecting to default host: ${C_BLUE}${HOST}${NO_FORMAT}" fi USER=root if [ -n "${WP_CLI_TEST_DBROOTUSER}" ]; then - USER="${WP_CLI_TEST_DBROOTUSER}" + echo "Connecting with custom root user: ${C_BLUE}${WP_CLI_TEST_DBROOTUSER}${NO_FORMAT}" + USER="${WP_CLI_TEST_DBROOTUSER}" +else + echo "Connecting with default root user: ${C_BLUE}${USER}${NO_FORMAT}" fi PASSWORD_STRING="" if [ -n "${WP_CLI_TEST_DBROOTPASS}" ]; then - PASSWORD_STRING="-p${WP_CLI_TEST_DBROOTPASS}" + echo "Connecting with custom root password: ${C_BLUE}${WP_CLI_TEST_DBROOTPASS}${NO_FORMAT}" + PASSWORD_STRING="-p${WP_CLI_TEST_DBROOTPASS}" +else + echo "Connecting with default root password: ${C_BLUE}empty${NO_FORMAT}" fi TEST_DB=wp_cli_test if [ -n "${WP_CLI_TEST_DBNAME}" ]; then - TEST_DB="${WP_CLI_TEST_DBNAME}" + echo "Using custom test database: ${C_BLUE}${WP_CLI_TEST_DBNAME}${NO_FORMAT}" + TEST_DB="${WP_CLI_TEST_DBNAME}" +else + echo "Using default test database: ${C_BLUE}${TEST_DB}${NO_FORMAT}" fi TEST_USER=wp_cli_test if [ -n "${WP_CLI_TEST_DBUSER}" ]; then - TEST_USER="${WP_CLI_TEST_DBUSER}" + echo "Using custom test user: ${C_BLUE}${WP_CLI_TEST_DBUSER}${NO_FORMAT}" + TEST_USER="${WP_CLI_TEST_DBUSER}" +else + echo "Using default test user: ${C_BLUE}${TEST_USER}${NO_FORMAT}" fi TEST_PASSWORD=password1 if [ -n "${WP_CLI_TEST_DBPASS}" ]; then - TEST_PASSWORD="${WP_CLI_TEST_DBPASS}" + echo "Using custom test password: ${C_BLUE}${WP_CLI_TEST_DBPASS}${NO_FORMAT}" + TEST_PASSWORD="${WP_CLI_TEST_DBPASS}" +else + echo "Using default test password: ${C_BLUE}${TEST_PASSWORD}${NO_FORMAT}" fi echo 'Checking if MySQL is ready...' + +MYSQL_TRIES=36 +MYSQL_WAIT=5 while ! mysql ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" | grep 'information_schema' >/dev/null; do - echo 'Waiting for MySQL...' - sleep 5 + echo "Waiting for MySQL(${i}/${MYSQL_TRIES})..." + sleep ${MYSQL_WAIT} i=$((i+1)) - if [ $i -gt 36 ]; then - echo 'MySQL failed to start. Aborting.' + if [ $i -gt $MYSQL_TRIES ]; then + echo "${C_RED}MySQL failed to start. Aborting.${NO_FORMAT}" + echo "Cannot connect to mysql server. For all available variables, check the documentation at:" + echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}" exit 1 fi done # Prepare the database for running the tests with a MySQL version 8.0 or higher. install_mysql_db_8_0_plus() { - set -ex + set -ex # print all the commands. mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}" mysql -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' 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}" + { set +ex; } 2> /dev/null # stop printing the commands } # Prepare the database for running the tests with a MySQL version lower than 8.0. install_mysql_db_lower_than_8_0() { - set -ex + set -ex # print all the commands. 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}" + { set +ex; } 2> /dev/null # stop printing the commands } VERSION_STRING=$(mysql -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}") @@ -108,3 +140,6 @@ if [ "${TYPE}" != "MariaDB" ] && [ "${MAJOR}" -ge 8 ]; then else install_mysql_db_lower_than_8_0 fi + +echo "Succesfully prepared the database for running tests." +echo "This command does not have to be run again." From bc262e29383ea3c6a24a154f108ec09f93e0db4a Mon Sep 17 00:00:00 2001 From: Jan-Willem Oostendorp Date: Thu, 13 Jun 2024 15:04:50 +0200 Subject: [PATCH 2/3] prepare tests don't do multiple attemps local. --- bin/install-package-tests | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/bin/install-package-tests b/bin/install-package-tests index 867544d0..ae6055ee 100755 --- a/bin/install-package-tests +++ b/bin/install-package-tests @@ -87,19 +87,29 @@ fi echo 'Checking if MySQL is ready...' -MYSQL_TRIES=36 -MYSQL_WAIT=5 +if [ -z "$PS1" ]; then + # These vars are because github actions gave problems in the past. + MYSQL_TRIES=36 + MYSQL_WAIT=5 +else + MYSQL_TRIES=1 + MYSQL_WAIT=0 +fi + while ! mysql ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" | grep 'information_schema' >/dev/null; do - echo "Waiting for MySQL(${i}/${MYSQL_TRIES})..." - sleep ${MYSQL_WAIT} - i=$((i+1)) - if [ $i -gt $MYSQL_TRIES ]; then - echo "${C_RED}MySQL failed to start. Aborting.${NO_FORMAT}" - echo "Cannot connect to mysql server. For all available variables, check the documentation at:" - echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}" - exit 1 - fi + i=$((i+1)) + if [ "${MYSQL_TRIES}" -gt 1 ]; then + echo "Waiting for MySQL(${i}/${MYSQL_TRIES})..." + sleep ${MYSQL_WAIT} + fi + + if [ $i -ge $MYSQL_TRIES ]; then + echo "${C_RED}MySQL failed to start. Aborting.${NO_FORMAT}" + echo "Cannot connect to mysql server. For all available variables, check the documentation at:" + echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}" + exit 1 + fi done # Prepare the database for running the tests with a MySQL version 8.0 or higher. @@ -134,7 +144,6 @@ esac echo "Detected ${TYPE} at version ${MAJOR}.${MINOR}" - if [ "${TYPE}" != "MariaDB" ] && [ "${MAJOR}" -ge 8 ]; then install_mysql_db_8_0_plus else From 928405c7a28a574fd26be99aceb63b8409b13ccd Mon Sep 17 00:00:00 2001 From: Jan-Willem Oostendorp Date: Thu, 13 Jun 2024 16:49:34 +0200 Subject: [PATCH 3/3] Add a db connection test before behat runs. --- src/Context/FeatureContext.php | 37 +++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Context/FeatureContext.php b/src/Context/FeatureContext.php index 8ceea879..d9635e91 100644 --- a/src/Context/FeatureContext.php +++ b/src/Context/FeatureContext.php @@ -8,6 +8,7 @@ use Behat\Testwork\Hook\Scope\AfterSuiteScope; use Behat\Testwork\Hook\Scope\BeforeSuiteScope; use RuntimeException; +use WP_CLI; use WP_CLI\Process; use WP_CLI\Utils; @@ -639,6 +640,7 @@ public function __construct() { $this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str( self::$db_settings ); + $this->test_connection(); $this->drop_db(); $this->set_cache_dir(); } @@ -842,6 +844,8 @@ private function set_cache_dir() { * @param string $sql_cmd Command to run. * @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. + * + * return array. */ private static function run_sql( $sql_cmd, $assoc_args = [], $add_database = false ) { $default_assoc_args = [ @@ -852,11 +856,22 @@ private static function run_sql( $sql_cmd, $assoc_args = [], $add_database = fal if ( $add_database ) { $sql_cmd .= ' ' . escapeshellarg( self::$db_settings['dbname'] ); } + $send_to_shell = true; + if ( isset( $assoc_args['send_to_shell'] ) ) { + $send_to_shell = (bool) $assoc_args['send_to_shell']; + unset( $assoc_args['send_to_shell'] ); + } + $start_time = microtime( true ); - Utils\run_mysql_command( $sql_cmd, array_merge( $assoc_args, $default_assoc_args ) ); + $result = Utils\run_mysql_command( $sql_cmd, array_merge( $assoc_args, $default_assoc_args ), null, $send_to_shell ); if ( self::$log_run_times ) { self::log_proc_method_run_time( 'run_sql ' . $sql_cmd, $start_time ); } + return [ + 'stdout' => $result[0], + 'stderr' => $result[1], + 'exit_code' => $result[2], + ]; } public function create_db() { @@ -868,6 +883,26 @@ public function create_db() { self::run_sql( 'mysql --no-defaults', [ 'execute' => "CREATE DATABASE IF NOT EXISTS $dbname" ] ); } + /** + * Test if the database connection is working. + */ + public function test_connection() { + $sql_result = self::run_sql( + 'mysql --no-defaults', + [ + 'execute' => 'SELECT 1', + 'send_to_shell' => false, + ] + ); + if ( ! empty( $sql_result['stderr'] ) ) { + # WP_CLI output functions are suppressed in behat context. + echo 'There was an error connecting to the database:' . \PHP_EOL; + echo ' ' . trim( $sql_result['stderr'] ) . \PHP_EOL; + echo 'run `composer prepare-tests` to connect to the database.' . \PHP_EOL; + die( 1 ); + } + } + public function drop_db() { if ( 'sqlite' === self::$db_type ) { return;