Skip to content

Commit cbbd10b

Browse files
committed
fix(test/tap): skip native_password backend fixtures on MySQL 9.x in test_sqlite3_pass_exts-t
Fixes #5631. The test has three logical phases: Phase 1 Admin SQLite3 extension validation for MYSQL_NATIVE_PASSWORD() and CACHING_SHA2_PASSWORD() — pure hash computation inside ProxySQL, does not touch the backend. Phase 2 MySQL/Admin hash compatibility — creates USER_GEN_COUNT (100) users on the backend, half with mysql_native_password and half with caching_sha2_password, then compares the backend's authentication_string with the hash that ProxySQL's Admin SQLite3 function produces. Phase 3 End-to-end connection test — creates RAND_USERS_GEN (100) users with the same 50/50 split and attempts to connect through ProxySQL. On MySQL 9.0+ the mysql_native_password plugin is not loadable, so the first CREATE USER IDENTIFIED WITH 'mysql_native_password' in Phase 2 fails with ER_PLUGIN_IS_NOT_LOADED and the test bails after only 10 assertions (all of Phase 1 passes — ProxySQL's internal hash extensions work fine on 9.x; this was a good green signal). Fix: - Add g_mysql_supports_native_password; set to false on server_version >= 9.0. - Adjust actual_test_count so plan() matches reality: if (has_native) { count += USER_GEN_COUNT + RAND_USERS_GEN; } else { count += USER_GEN_COUNT / 2 + RAND_USERS_GEN / 2; } - Wrap the Phase 2 native_password loop in 'if (has_native)'. - Phase 3 uses 'for (i = 0 .. RAND_USERS_GEN)' with 'i < 50 ? native : sha2'. Skip the native half by starting the loop at RAND_USERS_GEN/2 when has_native is false. Phase 1 coverage is fully preserved — the ProxySQL Admin SQLite3 hash functions (including MYSQL_NATIVE_PASSWORD()) still work on 9.x; only the backend-side CREATE USER path is skipped.
1 parent 5bb19a9 commit cbbd10b

1 file changed

Lines changed: 45 additions & 16 deletions

File tree

test/tap/tests/test_sqlite3_pass_exts-t.cpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ using std::pair;
3333
// Global flag for MySQL version check
3434
static bool g_mysql_supports_random_password = false;
3535
static bool g_mysql_version_checked = false;
36+
// MySQL 9.0 removed the 'mysql_native_password' server plugin. CREATE USER
37+
// IDENTIFIED WITH 'mysql_native_password' returns ER_PLUGIN_IS_NOT_LOADED on
38+
// 9.x backends. This flag gates the backend-side native_password fixtures
39+
// (Phase 2 hash compat + Phase 3 end-to-end). ProxySQL's internal
40+
// MYSQL_NATIVE_PASSWORD() SQLite3 extension is unaffected — hash generation
41+
// is pure computation and still works.
42+
static bool g_mysql_supports_native_password = true;
3643

3744
/**
3845
* @brief Check if MySQL server supports 'BY RANDOM PASSWORD' syntax (MySQL 8.0+)
@@ -454,20 +461,37 @@ int main(int argc, char** argv) {
454461
// MySQL 8.0+ supports 'BY RANDOM PASSWORD' syntax, MySQL 5.7 does not
455462
check_mysql_random_password_support(mysql);
456463

464+
// Detect whether the 'mysql_native_password' server plugin is usable.
465+
// MySQL 9.0 removed it; we skip the native_password halves of Phase 2
466+
// (MySQL/Admin hash compat) and Phase 3 (end-to-end) on 9.x backends.
467+
unsigned long server_version = mysql_get_server_version(mysql);
468+
if (server_version >= 90000) {
469+
g_mysql_supports_native_password = false;
470+
diag("Backend MySQL %lu: 'mysql_native_password' plugin not loadable. "
471+
"Skipping native_password backend-side fixtures.", server_version);
472+
}
473+
457474
// Calculate the actual number of tests based on MySQL version
458475
uint32_t actual_test_count =
459476
INV_INPUTS.size() + // Always run
460-
PASS_GEN_COUNT * 2 + // Always run
477+
PASS_GEN_COUNT * 2 + // Always run (ProxySQL Admin SQLite3 extensions)
461478
2; // EXTRA: Two extra correctness tests
462479

463480
if (g_mysql_supports_random_password) {
464-
// These tests only run on MySQL 8.0+
465-
actual_test_count += USER_GEN_COUNT; // MySQL/Admin hash compatibility tests
466-
actual_test_count += RAND_USERS_GEN; // End-to-end connection tests
481+
// Phase 2: MySQL/Admin hash compatibility tests (USER_GEN_COUNT total,
482+
// half native + half sha2). On 9.x only the sha2 half runs.
483+
actual_test_count +=
484+
(g_mysql_supports_native_password ? USER_GEN_COUNT : USER_GEN_COUNT / 2);
485+
486+
// Phase 3: End-to-end connection tests (RAND_USERS_GEN total, same split).
487+
actual_test_count +=
488+
(g_mysql_supports_native_password ? RAND_USERS_GEN : RAND_USERS_GEN / 2);
489+
467490
actual_test_count += 1; // Connection count check
468491
}
469492

470493
diag("MySQL version supports 'BY RANDOM PASSWORD': %s", g_mysql_supports_random_password ? "yes" : "no");
494+
diag("MySQL server supports 'mysql_native_password' plugin: %s", g_mysql_supports_native_password ? "yes" : "no");
471495
diag("Planned test count: %u", actual_test_count);
472496

473497
plan(actual_test_count);
@@ -502,17 +526,19 @@ int main(int argc, char** argv) {
502526
if (g_mysql_supports_random_password) {
503527
vector<user_def_t> users {};
504528

505-
for (size_t i = 0; i < USER_GEN_COUNT/2; i++) {
506-
const string name { "rndextuser" + std::to_string(i) };
507-
pair<int,user_def_t> user_def {
508-
create_mysql_user_rnd_creds(mysql, name, "mysql_native_password")
509-
};
510-
511-
if (user_def.first) {
512-
diag("User creation failed user:'%s'", name.c_str());
513-
goto cleanup;
514-
} else {
515-
users.push_back(user_def.second);
529+
if (g_mysql_supports_native_password) {
530+
for (size_t i = 0; i < USER_GEN_COUNT/2; i++) {
531+
const string name { "rndextuser" + std::to_string(i) };
532+
pair<int,user_def_t> user_def {
533+
create_mysql_user_rnd_creds(mysql, name, "mysql_native_password")
534+
};
535+
536+
if (user_def.first) {
537+
diag("User creation failed user:'%s'", name.c_str());
538+
goto cleanup;
539+
} else {
540+
users.push_back(user_def.second);
541+
}
516542
}
517543
}
518544

@@ -594,7 +620,10 @@ int main(int argc, char** argv) {
594620
);
595621
MYSQL_QUERY(admin, "LOAD MYSQL SERVERS TO RUNTIME");
596622

597-
for (uint32_t i = 0; i < RAND_USERS_GEN; i++) {
623+
// On MySQL 9.x the native_password plugin is unavailable on the backend,
624+
// so skip the first RAND_USERS_GEN/2 iterations (those are the native ones).
625+
uint32_t rand_users_start = g_mysql_supports_native_password ? 0 : (RAND_USERS_GEN / 2);
626+
for (uint32_t i = rand_users_start; i < RAND_USERS_GEN; i++) {
598627
const string name { "username_" + std::to_string(i) };
599628
const string pass { random_string(20) };
600629
const string auth { i < 50 ? "MYSQL_NATIVE_PASSWORD" : "CACHING_SHA2_PASSWORD" };

0 commit comments

Comments
 (0)