diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index bbae57b10..743649930 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -872,7 +872,7 @@ add_test_derived(ssl sql_queries ssl LABELS maxscale readwritesplit REPL_BACKEND #add_test_script(ssl_load_galera load_balancing_galera ssl_load_galera LABELS maxscale readwritesplit GALERA_BACKEND) # Testing slaves who have lost their master and how MaxScale works with them -add_test_executable(stale_slaves.cpp stale_slaves replication LABELS mysqlmon REPL_BACKEND) +add_test_executable(stale_slaves.cpp stale_slaves stale_slaves LABELS mysqlmon REPL_BACKEND) # Run sysbech test and block one slave during test execution add_test_executable(sysbench_kill_slave.cpp sysbench_kill_slave replication LABELS UNSTABLE HEAVY REPL_BACKEND) diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.stale_slaves b/maxscale-system-test/cnf/maxscale.cnf.template.stale_slaves new file mode 100644 index 000000000..9849e60cb --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.stale_slaves @@ -0,0 +1,59 @@ +[maxscale] +threads=###threads### + +[MySQL Monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3,server4 +user=maxskysql +password=skysql +monitor_interval=1000 +failcount=1 + +[Read Connection Router Slave] +type=service +router=readconnroute +router_options=slave +servers=server1,server2,server3,server4 +user=maxskysql +password=skysql + +[Read Connection Listener Slave] +type=listener +service=Read Connection Router Slave +protocol=MySQLClient +port=4009 + +[CLI] +type=service +router=cli + +[CLI Listener] +type=listener +service=CLI +protocol=maxscaled +socket=default + +[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 diff --git a/maxscale-system-test/mariadb_func.h b/maxscale-system-test/mariadb_func.h index b220844e8..795e8f950 100644 --- a/maxscale-system-test/mariadb_func.h +++ b/maxscale-system-test/mariadb_func.h @@ -295,6 +295,12 @@ public: return get_row(m_conn, q); } + std::string field(std::string q) + { + Row r = get_row(m_conn, q); + return r.empty() ? std::string() : r[0]; + } + const char* error() const { return mysql_error(m_conn); diff --git a/maxscale-system-test/stale_slaves.cpp b/maxscale-system-test/stale_slaves.cpp index 114a467e4..e8af7e454 100644 --- a/maxscale-system-test/stale_slaves.cpp +++ b/maxscale-system-test/stale_slaves.cpp @@ -2,105 +2,80 @@ * @file stale_slaves.cpp Testing slaves who have lost their master and how MaxScale works with them * * When the master server is blocked and slaves lose their master, they should - * still be available for read queries. When a slave with no master fails, it should not - * be assigned slave status again. Once the master comes back, all slaves should get slave - * status if replication is running. + * still be available for read queries. Once the master comes back, all slaves + * should get slave status if replication is running. */ - -#include #include "testconnections.h" +#include +#include +#include + +using namespace std; + int main(int argc, char **argv) { - TestConnections *test = new TestConnections(argc, argv); + TestConnections test(argc, argv); + vector ids; - char server_id[test->repl->N][1024]; - - test->repl->connect(); - /** Get server_id for each node */ - for (int i = 0; i < test->repl->N; i++) + test.repl->connect(); + for (int i = 0; i < test.repl->N; i++) { - sprintf(server_id[i], "%d", test->repl->get_server_id(i)); + ids.push_back(test.repl->get_server_id_str(i)); } - test->tprintf("Block the master and try a read query\n"); - test->repl->block_node(0); - sleep(15); - test->maxscales->connect_readconn_slave(0); - char first_slave[1024]; - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", first_slave); - - int found = -1; - - for (int i = 0; i < test->repl->N; i++) + auto get_id = [&]() { - if (strcmp(server_id[i], first_slave) == 0) + Connection c = test.maxscales->readconn_slave(); + test.assert(c.connect(), "Connection should be OK: %s", c.error()); + string res = c.field("SELECT @@server_id"); + test.assert(!res.empty(), "Field should not be empty: %s", c.error()); + return res; + }; + + auto in_use = [&](string id) + { + for (int i = 0; i < 2 * test.repl->N; i++) { - found = i; - break; + if (get_id() == id) + { + return true; + } } - } - test->add_result(found < 0, "No server with ID '%s' found.", first_slave); + return false; + }; - test->tprintf("Blocking node %d\n", found + 1); - test->repl->block_node(found); - sleep(15); + test.tprintf("Blocking the master and doing a read query"); + test.repl->block_node(0); + test.maxscales->wait_for_monitor(); - test->tprintf("Blocked the slave that replied to us, expecting a different slave\n"); - test->maxscales->connect_readconn_slave(0); - char second_slave[1024]; - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", second_slave); - test->add_result(strcmp(first_slave, second_slave) == 0, - "Server IDs match when they shouldn't: %s - %s", - first_slave, second_slave); + string first = get_id(); + auto it = find(begin(ids), end(ids), first); + test.assert(it != end(ids), "ID should be found"); + int node = distance(begin(ids), it); - test->tprintf("Unblocking the slave that replied\n"); - test->repl->unblock_node(found); - sleep(15); + test.tprintf("Blocking the slave that replied to us"); + test.repl->block_node(node); + test.maxscales->wait_for_monitor(); + test.assert(!in_use(first), "The first slave should not be in use"); - test->tprintf("Unblocked the slave, still expecting a different slave\n"); - test->maxscales->connect_readconn_slave(0); - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", second_slave); - test->add_result(strcmp(first_slave, second_slave) == 0, - "Server IDs match when they shouldn't: %s - %s", - first_slave, second_slave); + test.tprintf("Unblocking all nodes"); + test.repl->unblock_all_nodes(); + test.maxscales->wait_for_monitor(); + test.assert(in_use(first), "The first slave should be in use"); - test->tprintf("Unblocking all nodes\n"); - test->repl->unblock_all_nodes(); - sleep(15); + test.tprintf("Stopping replication on first slave"); + execute_query(test.repl->nodes[node], "STOP SLAVE"); + test.maxscales->wait_for_monitor(); + test.assert(!in_use(first), "The first slave should not be in use"); - test->tprintf("Unblocked all nodes, expecting the server ID of the first slave server\n"); - test->maxscales->connect_readconn_slave(0); - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", second_slave); - test->add_result(strcmp(first_slave, second_slave) != 0, - "Server IDs don't match when they should: %s - %s", - first_slave, second_slave); + test.tprintf("Starting replication on first slave"); + execute_query(test.repl->nodes[node], "START SLAVE"); + test.maxscales->wait_for_monitor(); + test.assert(in_use(first), "The first slave should be in use"); + test.repl->disconnect(); - test->tprintf("Stopping replication on node %d\n", found + 1); - execute_query(test->repl->nodes[found], "stop slave"); - sleep(15); - - test->tprintf("Stopped replication, expecting a different slave\n"); - test->maxscales->connect_readconn_slave(0); - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", second_slave); - test->add_result(strcmp(first_slave, second_slave) == 0, - "Server IDs match when they shouldn't: %s - %s", - first_slave, second_slave); - - test->tprintf("Starting replication on node %d\n", found + 1); - execute_query(test->repl->nodes[found], "start slave"); - sleep(15); - - test->tprintf("Started replication, expecting the server ID of the first slave server\n"); - test->maxscales->connect_readconn_slave(0); - find_field(test->maxscales->conn_slave[0], "SELECT @@server_id", "@@server_id", second_slave); - test->add_result(strcmp(first_slave, second_slave) != 0, - "Server IDs don't match when they should: %s - %s", - first_slave, second_slave); - - int rval = test->global_result; - delete test; - return rval; + return test.global_result; }