diff --git a/test/tap/tap/noise_utils.cpp b/test/tap/tap/noise_utils.cpp index a94954490..b35c26563 100644 --- a/test/tap/tap/noise_utils.cpp +++ b/test/tap/tap/noise_utils.cpp @@ -40,56 +40,77 @@ void stop_internal_noise_threads() { // --- Standard Internal Noise Functions Implementation --- void internal_noise_admin_pinger(const CommandLine& cl, std::atomic& stop) { - MYSQL* admin = mysql_init(NULL); - if (!admin) return; + MYSQL* admin_my = mysql_init(NULL); + PGconn* admin_pg = NULL; - if (!mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { - mysql_close(admin); - return; + if (admin_my) { + mysql_real_connect(admin_my, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0); } + std::string conninfo = "host=" + std::string(cl.host) + " port=" + std::to_string(cl.pgsql_admin_port) + + " user=" + std::string(cl.admin_username) + " password=" + std::string(cl.admin_password) + + " dbname=stats connect_timeout=2"; + admin_pg = PQconnectdb(conninfo.c_str()); + while (!stop) { - if (mysql_query(admin, "SELECT 1")) { - // Silently ignore errors in noise thread - } else { - MYSQL_RES* res = mysql_store_result(admin); - if (res) mysql_free_result(res); + if (admin_my && mysql_ping(admin_my) == 0) { + if (mysql_query(admin_my, "SELECT 1") == 0) { + MYSQL_RES* res = mysql_store_result(admin_my); + if (res) mysql_free_result(res); + } + } + if (admin_pg && PQstatus(admin_pg) == CONNECTION_OK) { + pg_noise_query(admin_pg, "SELECT 1"); } std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - mysql_close(admin); + if (admin_my) mysql_close(admin_my); + if (admin_pg) PQfinish(admin_pg); } void internal_noise_stats_poller(const CommandLine& cl, std::atomic& stop) { - MYSQL* admin = mysql_init(NULL); - if (!admin) return; + MYSQL* admin_my = mysql_init(NULL); + PGconn* admin_pg = NULL; - if (!mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { - mysql_close(admin); - return; + if (admin_my) { + mysql_real_connect(admin_my, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0); } + std::string conninfo = "host=" + std::string(cl.host) + " port=" + std::to_string(cl.pgsql_admin_port) + + " user=" + std::string(cl.admin_username) + " password=" + std::string(cl.admin_password) + + " dbname=stats connect_timeout=2"; + admin_pg = PQconnectdb(conninfo.c_str()); + while (!stop) { - const char* queries[] = { + const char* my_queries[] = { "SELECT * FROM stats_mysql_query_digest", "SELECT * FROM stats_mysql_connection_pool", "SELECT * FROM stats_mysql_processlist" }; + const char* pg_queries[] = { + "SELECT * FROM stats_pgsql_query_digest", + "SELECT * FROM stats_pgsql_connection_pool", + "SELECT * FROM stats_pgsql_processlist" + }; - for (const char* q : queries) { + for (size_t i = 0; i < 3; ++i) { if (stop) break; - if (mysql_query(admin, q)) { - // Ignore - } else { - MYSQL_RES* res = mysql_store_result(admin); - if (res) mysql_free_result(res); + if (admin_my && mysql_ping(admin_my) == 0) { + if (mysql_query(admin_my, my_queries[i]) == 0) { + MYSQL_RES* res = mysql_store_result(admin_my); + if (res) mysql_free_result(res); + } + } + if (admin_pg && PQstatus(admin_pg) == CONNECTION_OK) { + pg_noise_query(admin_pg, pg_queries[i]); } } std::this_thread::sleep_for(std::chrono::milliseconds(200)); } - mysql_close(admin); + if (admin_my) mysql_close(admin_my); + if (admin_pg) PQfinish(admin_pg); } void internal_noise_prometheus_poller(const CommandLine& cl, std::atomic& stop) { @@ -174,3 +195,70 @@ void internal_noise_random_stats_poller(const CommandLine& cl, std::atomic if (admin_my) mysql_close(admin_my); if (admin_pg) PQfinish(admin_pg); } + +void internal_noise_mysql_traffic(const CommandLine& cl, std::atomic& stop) { + MYSQL* conn = mysql_init(NULL); + if (!conn) return; + + if (!mysql_real_connect(conn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + mysql_close(conn); + return; + } + + const char* queries[] = { + "SELECT 1", "SELECT @@version", "SELECT NOW()", "SHOW TABLES", "SELECT 'noise'" + }; + std::random_device rd; + std::mt19937 g(rd()); + + while (!stop) { + if (mysql_ping(conn) != 0) { + // Reconnect if needed + mysql_close(conn); + conn = mysql_init(NULL); + if (!conn || !mysql_real_connect(conn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + continue; + } + } + + const char* q = queries[g() % 5]; + if (mysql_query(conn, q) == 0) { + MYSQL_RES* res = mysql_store_result(conn); + if (res) mysql_free_result(res); + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + mysql_close(conn); +} + +void internal_noise_pgsql_traffic(const CommandLine& cl, std::atomic& stop) { + std::string conninfo = "host=" + std::string(cl.host) + " port=" + std::to_string(cl.pgsql_port) + + " user=" + std::string(cl.pgsql_username) + " password=" + std::string(cl.pgsql_password) + + " dbname=test connect_timeout=2"; + PGconn* conn = PQconnectdb(conninfo.c_str()); + + const char* queries[] = { + "SELECT 1", "SELECT version()", "SELECT current_timestamp", "SELECT 'noise'" + }; + std::random_device rd; + std::mt19937 g(rd()); + + while (!stop) { + if (PQstatus(conn) != CONNECTION_OK) { + PQfinish(conn); + conn = PQconnectdb(conninfo.c_str()); + if (PQstatus(conn) != CONNECTION_OK) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + continue; + } + } + + const char* q = queries[g() % 4]; + pg_noise_query(conn, q); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + PQfinish(conn); +} diff --git a/test/tap/tap/noise_utils.h b/test/tap/tap/noise_utils.h index eb1ec8298..eafa68d91 100644 --- a/test/tap/tap/noise_utils.h +++ b/test/tap/tap/noise_utils.h @@ -49,4 +49,14 @@ void internal_noise_prometheus_poller(const CommandLine& cl, std::atomic& */ void internal_noise_random_stats_poller(const CommandLine& cl, std::atomic& stop); +/** + * @brief Periodically executes simple queries against the main MySQL port. + */ +void internal_noise_mysql_traffic(const CommandLine& cl, std::atomic& stop); + +/** + * @brief Periodically executes simple queries against the main PostgreSQL port. + */ +void internal_noise_pgsql_traffic(const CommandLine& cl, std::atomic& stop); + #endif // #ifndef NOISE_UTILS_H diff --git a/test/tap/tests/test_noise_injection-t.cpp b/test/tap/tests/test_noise_injection-t.cpp index 270699a36..f94dc502d 100644 --- a/test/tap/tests/test_noise_injection-t.cpp +++ b/test/tap/tests/test_noise_injection-t.cpp @@ -43,9 +43,11 @@ int main(int argc, char** argv) { // --- Internal Noise Test --- spawn_internal_noise(cl, internal_noise_admin_pinger); - // There isn't an easy way to verify the thread is running from outside - // but we can verify it doesn't crash the test and that stop works. - ok(1, "Internal noise thread spawned without crash"); + spawn_internal_noise(cl, internal_noise_prometheus_poller); + spawn_internal_noise(cl, internal_noise_mysql_traffic); + spawn_internal_noise(cl, internal_noise_pgsql_traffic); + + ok(1, "Internal noise threads spawned without crash"); // --- Cleanup Verification --- stop_noise_tools();