From e5cdefa69d98aaa5663ba22427eb80b513f64622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 30 Jan 2019 12:58:42 +0200 Subject: [PATCH] MXS-2300: Add history pruning test The test checks that the session command history pruning works as expected. --- maxscale-system-test/CMakeLists.txt | 3 + ...scale.cnf.template.mxs2300_history_pruning | 51 ++++++++ maxscale-system-test/mariadb_nodes.cpp | 12 ++ maxscale-system-test/mariadb_nodes.h | 7 ++ .../mxs2300_history_pruning.cpp | 109 ++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100755 maxscale-system-test/cnf/maxscale.cnf.template.mxs2300_history_pruning create mode 100644 maxscale-system-test/mxs2300_history_pruning.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 29f6f1b92..3de14a9c3 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -918,6 +918,9 @@ add_test_executable(mxs2115_version_string.cpp mxs2115_version_string replicatio # MXS-2295: COM_CHANGE_USER does not clear out session command history add_test_executable(mxs2295_change_user_loop.cpp mxs2295_change_user_loop mxs2295_change_user_loop LABELS REPL_BACKEND) +# MXS-2300: Prune session command history +add_test_executable(mxs2300_history_pruning.cpp mxs2300_history_pruning mxs2300_history_pruning LABELS REPL_BACKEND) + ############################################ # BEGIN: binlogrouter and avrorouter tests # ############################################ diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.mxs2300_history_pruning b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2300_history_pruning new file mode 100755 index 000000000..6c8da9817 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2300_history_pruning @@ -0,0 +1,51 @@ +[maxscale] +threads=###threads### +log_info=1 + +[server1] +type=server +address=###node_server_IP_1### +port=###node_server_port_1### +protocol=MySQLBackend + +[server2] +type=server +address=###node_server_IP_2### +port=###node_server_port_2### +protocol=MySQLBackend + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend + +[server4] +type=server +address=###node_server_IP_4### +port=###node_server_port_4### +protocol=MySQLBackend + +[MySQL Monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3,server4 +user=maxskysql +password=skysql +monitor_interval=1000 + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxskysql +password=skysql +max_sescmd_history=10 +prune_sescmd_history=true +max_slave_connections=1 + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 diff --git a/maxscale-system-test/mariadb_nodes.cpp b/maxscale-system-test/mariadb_nodes.cpp index 676e6ed84..5ace71070 100644 --- a/maxscale-system-test/mariadb_nodes.cpp +++ b/maxscale-system-test/mariadb_nodes.cpp @@ -936,6 +936,18 @@ std::string Mariadb_nodes::get_server_id_str(int index) return ss.str(); } +std::vector Mariadb_nodes::get_all_server_ids() +{ + std::vector rval; + + for (int i = 0; i < N; i++) + { + rval.push_back(get_server_id(i)); + } + + return rval; +} + bool do_flush_hosts(MYSQL* conn) { int local_result = 0; diff --git a/maxscale-system-test/mariadb_nodes.h b/maxscale-system-test/mariadb_nodes.h index 5875c0a47..7cd19a03f 100644 --- a/maxscale-system-test/mariadb_nodes.h +++ b/maxscale-system-test/mariadb_nodes.h @@ -316,6 +316,13 @@ public: int get_server_id(int index); std::string get_server_id_str(int index); + /** + * Get server IDs of all servers + * + * @return List of server IDs + */ + std::vector get_all_server_ids(); + /** * @brief Execute 'mysqladmin flush-hosts' on all nodes * @return 0 in case of success diff --git a/maxscale-system-test/mxs2300_history_pruning.cpp b/maxscale-system-test/mxs2300_history_pruning.cpp new file mode 100644 index 000000000..6c3d107ad --- /dev/null +++ b/maxscale-system-test/mxs2300_history_pruning.cpp @@ -0,0 +1,109 @@ +/** + * MXS-2300: Session command history pruning + */ + +#include "testconnections.h" +#include + +std::vector ids; + +void block_by_id(TestConnections& test, int id) +{ + for (size_t i = 0; i < ids.size(); i++) + { + if (ids[i] == id) + { + test.repl->block_node(i); + } + } +} + +void unblock_by_id(TestConnections& test, int id) +{ + for (size_t i = 0; i < ids.size(); i++) + { + if (ids[i] == id) + { + test.repl->unblock_node(i); + } + } +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + + test.repl->connect(); + ids = test.repl->get_all_server_ids(); + test.repl->disconnect(); + + int master_id = test.get_master_server_id(); + Connection conn = test.maxscales->rwsplit(); + test.expect(conn.connect(), "Connection failed: %s", conn.error()); + + test.tprintf("Get the ID of the server we first start with"); + int first_id = std::stoi(conn.field("SELECT @@server_id")); + + test.tprintf("The history size is set to 10 commands, execute five and check that they are retained"); + for (int i = 0; i < 5; i++) + { + std::stringstream query; + query << "SET @a" << i << " = " << i; + conn.query(query.str()); + } + + block_by_id(test, first_id); + test.maxscales->wait_for_monitor(); + + int second_id = std::stoi(conn.field("SELECT @@server_id")); + + test.tprintf("Make sure that a reconnection actually took place"); + test.expect(first_id != second_id && second_id > 0, "Invalid server ID: %d", second_id); + test.expect(master_id != second_id, "SELECT should not go to the master"); + + test.tprintf("Check that the values were correctly set"); + for (int i = 0; i < 5; i++) + { + std::string value = std::to_string(i); + std::string query = "SELECT @a" + value; + test.expect(conn.check(query, value), "Invalid value for user variable @a%s", value.c_str()); + } + + unblock_by_id(test, first_id); + + test.tprintf("Execute 15 commands and check that we lose the first five values"); + for (int i = 0; i < 15; i++) + { + std::stringstream query; + query << "SET @b" << i << " =" << i; + conn.query(query.str()); + } + + block_by_id(test, second_id); + test.maxscales->wait_for_monitor(); + + int third_id = std::stoi(conn.field("SELECT @@server_id")); + + test.expect(third_id != second_id && third_id > 0, "Invalid server ID: %d", third_id); + test.expect(master_id != third_id, "SELECT should not go to the master"); + + for (int i = 0; i < 5; i++) + { + std::string variable = "@b" + std::to_string(i); + std::string query = "SELECT IFNULL(" + variable + ", '" + variable + " is null')"; + test.expect(conn.check(query, variable + " is null"), "%s should not be set", variable.c_str()); + } + + test.tprintf("Check that the remaining values were correctly set"); + for (int i = 5; i < 15; i++) + { + std::string value = std::to_string(i); + std::string query = "SELECT @b" + value; + std::string f = conn.field(query); + test.expect(conn.check(query, value), "Invalid value for user variable @b%s: %s", value.c_str(), f.c_str()); + } + + unblock_by_id(test, second_id); + + return test.global_result; +}