Skip to content

Commit ef51980

Browse files
authored
Merge pull request #281 from wp-cli/copilot/fix-mariadb-detection-issue
2 parents 4322dee + 515b014 commit ef51980

File tree

2 files changed

+134
-62
lines changed

2 files changed

+134
-62
lines changed

bin/install-package-tests

Lines changed: 47 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,16 @@ fi
8787

8888
echo "Detecting database version..."
8989

90-
TYPE="MySQL"
91-
CLIENT_VERSION=$(mysql --version 2>/dev/null)
92-
93-
case "${CLIENT_VERSION}" in
94-
*"MariaDB"*)
95-
TYPE="MariaDB"
96-
;;
97-
esac
90+
# Detect which client binary is available.
91+
CLIENT_BINARY=""
92+
if command -v mysql >/dev/null 2>&1; then
93+
CLIENT_BINARY="mysql"
94+
elif command -v mariadb >/dev/null 2>&1; then
95+
CLIENT_BINARY="mariadb"
96+
else
97+
echo "${C_RED}Error: Neither 'mysql' nor 'mariadb' client binary found.${NO_FORMAT}"
98+
exit 1
99+
fi
98100

99101
if [ -z "$PS1" ]; then
100102
# These vars are because github actions gave problems in the past.
@@ -105,11 +107,16 @@ else
105107
MYSQL_WAIT=0
106108
fi
107109

108-
if [ "${TYPE}" = "MySQL" ]; then
109-
SERVER_VERSION=$(mysql -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}")
110-
else
111-
SERVER_VERSION=$(mariadb -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}")
112-
fi
110+
# Use the detected client binary to query the server version.
111+
SERVER_VERSION=$(${CLIENT_BINARY} -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}" 2>/dev/null)
112+
113+
# Detect the database type from the server version string.
114+
TYPE="MySQL"
115+
case "${SERVER_VERSION}" in
116+
*"MariaDB"*|*"mariadb"*)
117+
TYPE="MariaDB"
118+
;;
119+
esac
113120

114121
VERSION=$(echo "${SERVER_VERSION}" | grep -o '^[^-]*')
115122
MAJOR=$(echo "${VERSION}" | cut -d. -f1)
@@ -119,66 +126,49 @@ echo "Detected ${TYPE} at version ${MAJOR}.${MINOR}"
119126

120127
echo 'Checking if database is ready...'
121128

122-
if [ "${TYPE}" = "MySQL" ]; then
123-
while ! mysql ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" | grep 'information_schema' >/dev/null;
124-
do
125-
i=$((i+1))
126-
if [ "${MYSQL_TRIES}" -gt 1 ]; then
127-
echo "Waiting for MySQL(${i}/${MYSQL_TRIES})..."
128-
sleep ${MYSQL_WAIT}
129-
fi
130-
131-
if [ $i -ge $MYSQL_TRIES ]; then
132-
echo "${C_RED}MySQL failed to start. Aborting.${NO_FORMAT}"
133-
echo "Cannot connect to MySQL server. For all available variables, check the documentation at:"
134-
echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}"
135-
exit 1
136-
fi
137-
done
138-
else
139-
while ! mariadb ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" | grep 'information_schema' >/dev/null;
140-
do
141-
i=$((i+1))
142-
if [ "${MYSQL_TRIES}" -gt 1 ]; then
143-
echo "Waiting for MariaDB(${i}/${MYSQL_TRIES})..."
144-
sleep ${MYSQL_WAIT}
145-
fi
129+
i=0
130+
while ! ${CLIENT_BINARY} ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" 2>/dev/null | grep 'information_schema' >/dev/null;
131+
do
132+
i=$((i+1))
133+
if [ "${MYSQL_TRIES}" -gt 1 ]; then
134+
echo "Waiting for database server (${i}/${MYSQL_TRIES})..."
135+
sleep ${MYSQL_WAIT}
136+
fi
146137

147-
if [ $i -ge $MYSQL_TRIES ]; then
148-
echo "${C_RED}MariaDB failed to start. Aborting.${NO_FORMAT}"
149-
echo "Cannot connect to MariaDB server. For all available variables, check the documentation at:"
150-
echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}"
151-
exit 1
152-
fi
153-
done
154-
fi
138+
if [ $i -ge $MYSQL_TRIES ]; then
139+
echo "${C_RED}Database server failed to start. Aborting.${NO_FORMAT}"
140+
echo "Cannot connect to database server. For all available variables, check the documentation at:"
141+
echo " ${C_BLUE}https://github.com/wp-cli/wp-cli-tests?tab=readme-ov-file#the-database-credentials${NO_FORMAT}"
142+
exit 1
143+
fi
144+
done
155145

156146
# Prepare the database for running the tests with a MySQL version 8.0 or higher.
157147
install_mysql_db_8_0_plus() {
158148
set -ex # print all the commands.
159-
mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
160-
mysql -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' IDENTIFIED WITH caching_sha2_password BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
161-
mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
162-
mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
149+
${CLIENT_BINARY} -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
150+
${CLIENT_BINARY} -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' IDENTIFIED WITH caching_sha2_password BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
151+
${CLIENT_BINARY} -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
152+
${CLIENT_BINARY} -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
163153
{ set +ex; } 2> /dev/null # stop printing the commands
164154
}
165155

166156
# Prepare the database for running the tests with a MySQL version lower than 8.0.
167157
install_mysql_db_lower_than_8_0() {
168158
set -ex # print all the commands.
169-
mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
170-
mysql -e "GRANT ALL ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
171-
mysql -e "GRANT ALL ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
159+
${CLIENT_BINARY} -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
160+
${CLIENT_BINARY} -e "GRANT ALL ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
161+
${CLIENT_BINARY} -e "GRANT ALL ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
172162
{ set +ex; } 2> /dev/null # stop printing the commands
173163
}
174164

175165
# Prepare the database for running the tests with MariaDB
176166
install_mariadb() {
177167
set -ex
178-
mariadb -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
179-
mariadb -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
180-
mariadb -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
181-
mariadb -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
168+
${CLIENT_BINARY} -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
169+
${CLIENT_BINARY} -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
170+
${CLIENT_BINARY} -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
171+
${CLIENT_BINARY} -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
182172
}
183173

184174
if [ "${TYPE}" = "MariaDB" ]; then
@@ -189,5 +179,5 @@ else
189179
install_mysql_db_lower_than_8_0
190180
fi
191181

192-
echo "Succesfully prepared the database for running tests."
182+
echo "Successfully prepared the database for running tests."
193183
echo "This command does not have to be run again."

utils/behat-tags.php

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,88 @@ function version_tags(
4040
return $skip_tags;
4141
}
4242

43-
function get_db_version() {
44-
$version_string = exec( getenv( 'WP_CLI_TEST_DBTYPE' ) === 'mariadb' ? 'mariadb --version' : 'mysql -V' );
43+
function get_db_type_and_version() {
44+
// Detect which client binary is available.
45+
$client_binary = null;
46+
$output = array();
47+
exec( 'command -v mysql 2>/dev/null', $output, $mysql_exit_code );
48+
if ( 0 === $mysql_exit_code ) {
49+
$client_binary = 'mysql';
50+
} else {
51+
$output = array();
52+
exec( 'command -v mariadb 2>/dev/null', $output, $mariadb_exit_code );
53+
if ( 0 === $mariadb_exit_code ) {
54+
$client_binary = 'mariadb';
55+
}
56+
}
57+
58+
if ( null === $client_binary ) {
59+
// No client binary found, return defaults.
60+
return array(
61+
'type' => 'mysql',
62+
'version' => '',
63+
);
64+
}
65+
66+
// Build connection parameters from environment variables.
67+
$host = getenv( 'WP_CLI_TEST_DBHOST' ) ?: 'localhost';
68+
$user = getenv( 'WP_CLI_TEST_DBROOTUSER' ) ?: 'root';
69+
$pass = getenv( 'WP_CLI_TEST_DBROOTPASS' );
70+
71+
// Build the command to get the server version.
72+
$host_parts = explode( ':', $host );
73+
$host_arg = '-h' . escapeshellarg( $host_parts[0] );
74+
75+
$port_arg = '';
76+
if ( isset( $host_parts[1] ) ) {
77+
// Check if it's a port number or socket path.
78+
if ( is_numeric( $host_parts[1] ) ) {
79+
$port_arg = ' --port=' . escapeshellarg( $host_parts[1] ) . ' --protocol=tcp';
80+
} else {
81+
$port_arg = ' --socket=' . escapeshellarg( $host_parts[1] ) . ' --protocol=socket';
82+
}
83+
}
84+
85+
$pass_arg = false !== $pass && '' !== $pass ? '-p' . escapeshellarg( $pass ) : '';
86+
87+
$cmd = sprintf(
88+
'%s %s %s -u%s %s -e "SELECT VERSION()" --skip-column-names 2>/dev/null',
89+
escapeshellcmd( $client_binary ),
90+
$host_arg,
91+
$port_arg,
92+
escapeshellarg( $user ),
93+
$pass_arg
94+
);
95+
96+
$output = array();
97+
$return_code = 0;
98+
exec( $cmd, $output, $return_code );
99+
$version_string = isset( $output[0] ) ? $output[0] : '';
100+
101+
// If the connection failed, fall back to client binary version.
102+
if ( 0 !== $return_code || empty( $version_string ) ) {
103+
$client_version_cmd = sprintf( '%s --version 2>/dev/null', escapeshellcmd( $client_binary ) );
104+
$version_string = exec( $client_version_cmd );
105+
}
106+
107+
// Detect database type from server version string.
108+
$db_type = 'mysql';
109+
if ( false !== stripos( $version_string, 'mariadb' ) ) {
110+
$db_type = 'mariadb';
111+
}
112+
45113
preg_match( '@[0-9]+\.[0-9]+\.[0-9]+@', $version_string, $version );
46-
return $version[0];
114+
$db_version = isset( $version[0] ) ? $version[0] : '';
115+
116+
return array(
117+
'type' => $db_type,
118+
'version' => $db_version,
119+
);
120+
}
121+
122+
function get_db_version() {
123+
$db_info = get_db_type_and_version();
124+
return $db_info['version'];
47125
}
48126

49127
$features_folder = getenv( 'BEHAT_FEATURES_FOLDER' ) ?: 'features';
@@ -85,9 +163,13 @@ function get_db_version() {
85163
$skip_tags[] = '@broken-trunk';
86164
}
87165

88-
$db_version = get_db_version();
166+
$db_info = get_db_type_and_version();
167+
$db_version = $db_info['version'];
168+
// Use detected database type from server, unless WP_CLI_TEST_DBTYPE is 'sqlite'.
169+
$env_db_type = getenv( 'WP_CLI_TEST_DBTYPE' );
170+
$db_type = 'sqlite' === $env_db_type ? 'sqlite' : $db_info['type'];
89171

90-
switch ( getenv( 'WP_CLI_TEST_DBTYPE' ) ) {
172+
switch ( $db_type ) {
91173
case 'mariadb':
92174
$skip_tags = array_merge(
93175
$skip_tags,

0 commit comments

Comments
 (0)