From 239b8e6a9ea2837f55a19de1e52dd0942b7cf096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 27 Jul 2020 20:56:17 +0200 Subject: [PATCH] Fixed 'session_track_gtids' check logic and failing tests exit code --- test/tap/tests/set_testing-multi-t.cpp | 37 ++++++++++++++++++++++++-- test/tap/tests/set_testing-t.cpp | 37 ++++++++++++++++++++++++-- test/tap/tests/set_testing-t.csv | 1 + 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/test/tap/tests/set_testing-multi-t.cpp b/test/tap/tests/set_testing-multi-t.cpp index 0ff0ef1aa..9b88323d4 100644 --- a/test/tap/tests/set_testing-multi-t.cpp +++ b/test/tap/tests/set_testing-multi-t.cpp @@ -365,6 +365,35 @@ void queryInternalStatus(MYSQL *mysql, json& j) { } } +/** + * @brief Checks that after setting 'session_track_gtids', the new set value follows ProxySQL rules + * for this particular variable. This is: + * - backend connections are by default set to `mysql-default_session_track_gtids`. + * - if `mysql-default_session_track_gtids=OFF` (the default), `session_track_gtids` is not changed on backend. + * - if the client asks for `session_track_gtids=OFF`, proxysql ignores it (it just acknowledge it). + * - if the client asks for `session_track_gtids=OWN_GTID`, proxysql will apply it. + * - if the client asks for `session_track_gtids=ALL_GTIDS`, proxysql will switch to OWN_GTID and generate a warning. + * - if the backend doesn't support `session_track_gtids` (for example in MySQL 5.5 and MySQL 5.6), proxysql won't apply it. It knows checking server capabilities + * + * @param expVal The value to which 'session_track_gtids' have been set. + * @param sVal The ProxySQL session value for 'session_track_gtids'. + * @param mVal The MySQL session value for 'session_track_gtids'. + * @return True in case the check succeed, false otherwise. + */ +bool check_session_track_gtids(const std::string& expVal, const std::string& sVal, const std::string& mVal) { + bool res = false; + + if (expVal == "OFF") { + res = expVal == sVal; + } else if (expVal == "OWN_GTID" && (sVal == mVal && sVal == "OWN_GTID")) { + res = true; + } else if (expVal == "ALL_GTIDS" && (sVal == mVal && sVal == "OWN_GTID")) { + res = true; + } + + return res; +} + void * my_conn_thread(void *arg) { g_seed = time(NULL) ^ getpid() ^ pthread_self(); unsigned int select_OK=0; @@ -513,13 +542,17 @@ void * my_conn_thread(void *arg) { fprintf(stderr, "Variable %s->%s in proxysql resultset was not found.\nmysql data : %s\nproxysql data: %s\ncsv data %s\n", el.value().dump().c_str(), el.key().c_str(), mysql_vars.dump().c_str(), proxysql_vars.dump().c_str(), vars.dump().c_str()); - if (k.value() != el.value() || s.value() != el.value()) { + if ( + (el.key() != "session_track_gtids" && (k.value() != el.value() || s.value() != el.value())) || + (el.key() == "session_track_gtids" && !check_session_track_gtids(el.value(), s.value(), k.value())) + ) { __sync_fetch_and_add(&g_failed, 1); testPassed = false; fprintf(stderr, "Test failed for this case %s->%s.\n\nmysql data %s\n\n proxysql data %s\n\n csv data %s\n\n\n", el.value().dump().c_str(), el.key().c_str(), mysql_vars.dump().c_str(), proxysql_vars.dump().c_str(), vars.dump().c_str()); ok(testPassed, "mysql connection [%p], thread_id [%lu], command [%s]", mysql, mysql->thread_id, testCases[r2].command.c_str()); - exit(0); + // In case of failing test, exit completely. + exit(EXIT_FAILURE); } else { variables_tested++; } diff --git a/test/tap/tests/set_testing-t.cpp b/test/tap/tests/set_testing-t.cpp index 6dd8a9450..11811e740 100644 --- a/test/tap/tests/set_testing-t.cpp +++ b/test/tap/tests/set_testing-t.cpp @@ -385,6 +385,35 @@ void queryInternalStatus(MYSQL *mysql, json& j) { std::vector forgotten_vars {}; +/** + * @brief Checks that after setting 'session_track_gtids', the new set value follows ProxySQL rules + * for this particular variable. This is: + * - backend connections are by default set to `mysql-default_session_track_gtids`. + * - if `mysql-default_session_track_gtids=OFF` (the default), `session_track_gtids` is not changed on backend. + * - if the client asks for `session_track_gtids=OFF`, proxysql ignores it (it just acknowledge it). + * - if the client asks for `session_track_gtids=OWN_GTID`, proxysql will apply it. + * - if the client asks for `session_track_gtids=ALL_GTIDS`, proxysql will switch to OWN_GTID and generate a warning. + * - if the backend doesn't support `session_track_gtids` (for example in MySQL 5.5 and MySQL 5.6), proxysql won't apply it. It knows checking server capabilities + * + * @param expVal The value to which 'session_track_gtids' have been set. + * @param sVal The ProxySQL session value for 'session_track_gtids'. + * @param mVal The MySQL session value for 'session_track_gtids'. + * @return True in case the check succeed, false otherwise. + */ +bool check_session_track_gtids(const std::string& expVal, const std::string& sVal, const std::string& mVal) { + bool res = false; + + if (expVal == "OFF") { + res = expVal == sVal; + } else if (expVal == "OWN_GTID" && (sVal == mVal && sVal == "OWN_GTID")) { + res = true; + } else if (expVal == "ALL_GTIDS" && (sVal == mVal && sVal == "OWN_GTID")) { + res = true; + } + + return res; +} + void * my_conn_thread(void *arg) { g_seed = time(NULL) ^ getpid() ^ pthread_self(); unsigned int select_OK=0; @@ -536,13 +565,17 @@ void * my_conn_thread(void *arg) { fprintf(stderr, "Variable %s->%s in proxysql resultset was not found.\nmysql data : %s\nproxysql data: %s\ncsv data %s\n", el.value().dump().c_str(), el.key().c_str(), mysql_vars.dump().c_str(), proxysql_vars.dump().c_str(), vars.dump().c_str()); - if ((k.value() != el.value() || s.value() != el.value()) && el.key() != "session_track_gtids") { + if ( + (el.key() != "session_track_gtids" && (k.value() != el.value() || s.value() != el.value())) || + (el.key() == "session_track_gtids" && !check_session_track_gtids(el.value(), s.value(), k.value())) + ) { __sync_fetch_and_add(&g_failed, 1); testPassed = false; fprintf(stderr, "Test failed for this case %s->%s.\n\nmysql data %s\n\n proxysql data %s\n\n csv data %s\n\n\n", el.value().dump().c_str(), el.key().c_str(), mysql_vars.dump().c_str(), proxysql_vars.dump().c_str(), vars.dump().c_str()); ok(testPassed, "mysql connection [%p], thread_id [%lu], command [%s]", mysql, mysql->thread_id, testCases[r2].command.c_str()); - exit(0); + // In case of failing test, exit completely. + exit(EXIT_FAILURE); } else { variables_tested++; } diff --git a/test/tap/tests/set_testing-t.csv b/test/tap/tests/set_testing-t.csv index 4882048ec..4550416e2 100644 --- a/test/tap/tests/set_testing-t.csv +++ b/test/tap/tests/set_testing-t.csv @@ -79,3 +79,4 @@ "SET CHARACTER SET 'utf8'", "{'character_set_results':'utf8', 'character_set_client':'utf8'}", "['character_set_connection', 'collation_connection']" "SET time_zone='+04:00', sql_mode='NO_ENGINE_SUBSTITUTION', max_join_size=10000; SET CHARACTER SET 'latin1'", "{'time_zone':'+04:00', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'max_join_size':'10000', 'character_set_results':'latin1', 'character_set_client':'latin1'}", "['character_set_connection', 'collation_connection']" "SET time_zone='+04:00', sql_mode='NO_ENGINE_SUBSTITUTION', max_join_size=10000; SET CHARSET 'latin1'", "{'time_zone':'+04:00', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'max_join_size':'10000', 'character_set_results':'latin1', 'character_set_client':'latin1'}", "['character_set_connection', 'collation_connection']" +"SET session_track_gtids=ALL_GTIDS", "{'session_track_gtids':'ALL_GTIDS'}" \ No newline at end of file