Merge branch '2.2' into develop

This commit is contained in:
Markus Mäkelä
2018-06-08 11:30:55 +03:00
44 changed files with 274 additions and 182 deletions

View File

@ -73,6 +73,7 @@ MXS_BEGIN_DECLS
#define MXS_JSON_PTR_PARAM_SSL_CA_CERT MXS_JSON_PTR_PARAMETERS "/ssl_ca_cert" #define MXS_JSON_PTR_PARAM_SSL_CA_CERT MXS_JSON_PTR_PARAMETERS "/ssl_ca_cert"
#define MXS_JSON_PTR_PARAM_SSL_VERSION MXS_JSON_PTR_PARAMETERS "/ssl_version" #define MXS_JSON_PTR_PARAM_SSL_VERSION MXS_JSON_PTR_PARAMETERS "/ssl_version"
#define MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH MXS_JSON_PTR_PARAMETERS "/ssl_cert_verify_depth" #define MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH MXS_JSON_PTR_PARAMETERS "/ssl_cert_verify_depth"
#define MXS_JSON_PTR_PARAM_SSL_VERIFY_PEER_CERT MXS_JSON_PTR_PARAMETERS "/ssl_verify_peer_certificate"
/** Non-parameter JSON pointers */ /** Non-parameter JSON pointers */
#define MXS_JSON_PTR_MODULE "/data/attributes/module" #define MXS_JSON_PTR_MODULE "/data/attributes/module"

View File

@ -33,7 +33,7 @@ any other names or paths.
## 2. Build and upgrade test ## 2. Build and upgrade test
The Jenkins The Jenkins
[Build_all](http://localhost:8089/job/build_all/) [build_for_release](http://127.0.0.1:8089/job/build_for_release/)
job should be used for building the packages. job should be used for building the packages.
Note that the above will not work unless you have set up an Note that the above will not work unless you have set up an
@ -42,57 +42,34 @@ ssh tunnel to Jenkins:
$ ssh -f -N -L 8089:127.0.0.1:8089 vagrant@max-tst-01.mariadb.com $ ssh -f -N -L 8089:127.0.0.1:8089 vagrant@max-tst-01.mariadb.com
``` ```
Usually two runs are done: one for _release_ and one for _debug_ packages.
### Parameters to define ### Parameters to define
Use defaults for all other parameters. #### `scm_source`
This is the tag that is used to build the release.
#### source
``` ```
refs/tags/maxscale-x.y.z-ttN refs/tags/maxscale-x.y.z-ttN
``` ```
#### `version_number`
#### target The version number of this release in x.y.z format. This will create two packages; maxscale-x.y.z-release and maxscale-x.y.z-debug.
Debug build:
```
maxscale-x.y.z-debug
```
Release build:
```
maxscale-x.y.z-release
```
#### cmake_flags
Debug build:
```
-DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DBUILD_MMMON=Y -DBUILD_CDC=Y
```
Release build:
```
-DBUILD_TESTS=N -DBUILD_MMMON=Y -DBUILD_CDC=Y
```
#### run_upgrade_test
``` ```
yes x.y.z
``` ```
#### old_target #### `old_target`
Name of some existing Maxscale repository The previous released version, used by upgrade tests.
(please check http://max-tst-01.mariadb.com/ci-repository/
before build).
``` ```
maxscale-x'.y'.z'-release x.y.z
``` ```
### Options for 1.4.x build ### 1.4.x build
Use the [build_all](http://127.0.0.1:8089/job/build_all/) job.
For `1.4` builds the default values of the following parameters For `1.4` builds the default values of the following parameters
should be changed: should be changed:

View File

@ -11,9 +11,9 @@ monitor_interval=1000
detect_standalone_master=true detect_standalone_master=true
failcount=2 failcount=2
allow_cluster_recovery=false allow_cluster_recovery=false
backend_connect_timeout=2 backend_connect_timeout=10
backend_read_timeout=3 backend_read_timeout=10
backend_write_timeout=3 backend_write_timeout=10
[RW Split Router] [RW Split Router]
type=service type=service

View File

@ -16,6 +16,9 @@ auto_rejoin=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
ignore_external_masters=true ignore_external_masters=true
backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router] [RW Split Router]
type=service type=service

View File

@ -14,9 +14,9 @@ allow_cluster_recovery=true
auto_failover=true auto_failover=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=15 backend_connect_timeout=10
backend_read_timeout=15 backend_read_timeout=10
backend_write_timeout=15 backend_write_timeout=10
[RW Split Router] [RW Split Router]
type=service type=service

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true allow_cluster_recovery=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=15 backend_connect_timeout=10
backend_read_timeout=15 backend_read_timeout=10
backend_write_timeout=15 backend_write_timeout=10
[RW Split Router] [RW Split Router]
type=service type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false auto_failover=false
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false auto_failover=false
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW Split Router] [RW Split Router]
type=service type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=false auto_failover=false
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -14,7 +14,10 @@ auto_failover=true
auto_rejoin=true auto_rejoin=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
failcount=1
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -13,7 +13,9 @@ detect_standalone_master=true
auto_failover=true auto_failover=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -14,7 +14,9 @@ auto_failover=true
auto_rejoin=true auto_rejoin=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -14,9 +14,10 @@ auto_failover=true
auto_rejoin=true auto_rejoin=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=5 backend_connect_timeout=10
backend_read_timeout=5 backend_read_timeout=10
backend_write_timeout=5 backend_write_timeout=10
failcount=1
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true allow_cluster_recovery=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=3 backend_connect_timeout=10
backend_read_timeout=3 backend_read_timeout=10
backend_write_timeout=3 backend_write_timeout=10
auto_failover=true auto_failover=true
auto_rejoin=true auto_rejoin=true

View File

@ -13,9 +13,9 @@ failcount=1
allow_cluster_recovery=true allow_cluster_recovery=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=3 backend_connect_timeout=10
backend_read_timeout=3 backend_read_timeout=10
backend_write_timeout=3 backend_write_timeout=10
auto_failover=true auto_failover=true
[RW Split Router] [RW Split Router]

View File

@ -14,9 +14,9 @@ auto_failover=false
auto_rejoin=true auto_rejoin=true
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=5 backend_connect_timeout=10
backend_read_timeout=5 backend_read_timeout=10
backend_write_timeout=5 backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -14,7 +14,10 @@ auto_failover=true
auto_rejoin=false auto_rejoin=false
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=1 backend_connect_timeout=10
backend_read_timeout=10
backend_write_timeout=10
failcount=1
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -14,9 +14,9 @@ auto_failover=false
auto_rejoin=false auto_rejoin=false
replication_user=repl replication_user=repl
replication_password=repl replication_password=repl
backend_connect_timeout=5 backend_connect_timeout=10
backend_read_timeout=5 backend_read_timeout=10
backend_write_timeout=5 backend_write_timeout=10
[RW-Split-Router] [RW-Split-Router]
type=service type=service

View File

@ -24,13 +24,13 @@ void reset_replication(TestConnections& test)
{ {
int ind = master_id - 1; int ind = master_id - 1;
replicate_from(test, 0, ind); replicate_from(test, 0, ind);
sleep(3); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
int ec; int ec;
stringstream switchover; stringstream switchover;
switchover << "maxadmin call command mysqlmon switchover MySQL-Monitor server1 server" << master_id; switchover << "maxadmin call command mysqlmon switchover MySQL-Monitor server1 server" << master_id;
test.maxscales->ssh_node_output(0, switchover.str().c_str() , true, &ec); test.maxscales->ssh_node_output(0, switchover.str().c_str() , true, &ec);
sleep(3); test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test); master_id = get_master_server_id(test);
cout << "Master server id is now back to " << master_id << endl; cout << "Master server id is now back to " << master_id << endl;
test.assert(master_id == 1, "Switchover back to server1 failed"); test.assert(master_id == 1, "Switchover back to server1 failed");
@ -80,11 +80,9 @@ void prepare_test_2(TestConnections& test)
cout << LINE << endl; cout << LINE << endl;
test.repl->connect(); test.repl->connect();
check(test); check(test);
sleep(1);
print_gtids(test); print_gtids(test);
test.try_query(test.repl->nodes[1], "STOP SLAVE;"); test.try_query(test.repl->nodes[1], "STOP SLAVE;");
test.try_query(test.repl->nodes[1], "RESET SLAVE ALL;"); test.try_query(test.repl->nodes[1], "RESET SLAVE ALL;");
sleep(1);
get_output(test); get_output(test);
if (test.global_result == 0) if (test.global_result == 0)
{ {
@ -108,7 +106,7 @@ void check_test_2(TestConnections& test)
// Reset state // Reset state
replicate_from(test, 1, master_id - 1); replicate_from(test, 1, master_id - 1);
sleep(3); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
StringSet node_states = test.get_server_status("server2"); StringSet node_states = test.get_server_status("server2");
test.assert(node_states.find("Slave") != node_states.end(), "Server 2 is not replicating."); test.assert(node_states.find("Slave") != node_states.end(), "Server 2 is not replicating.");
@ -145,7 +143,7 @@ void prepare_test_3(TestConnections& test)
test.repl->start_node(2, (char *) ""); test.repl->start_node(2, (char *) "");
test.repl->start_node(3, (char *) ""); test.repl->start_node(3, (char *) "");
test.maxscales->start_maxscale(0); test.maxscales->start_maxscale(0);
sleep(2); test.maxscales->wait_for_monitor();
test.repl->connect(); test.repl->connect();
test.tprintf("Settings changed."); test.tprintf("Settings changed.");
@ -182,7 +180,6 @@ void check_test_3(TestConnections& test)
test.repl->stop_node(1); test.repl->stop_node(1);
test.repl->stop_node(2); test.repl->stop_node(2);
test.repl->stop_node(3); test.repl->stop_node(3);
sleep(4);
test.repl->restore_server_settings(1); test.repl->restore_server_settings(1);
test.repl->restore_server_settings(2); test.repl->restore_server_settings(2);
@ -191,6 +188,5 @@ void check_test_3(TestConnections& test)
test.repl->start_node(1, (char *) ""); test.repl->start_node(1, (char *) "");
test.repl->start_node(2, (char *) ""); test.repl->start_node(2, (char *) "");
test.repl->start_node(3, (char *) ""); test.repl->start_node(3, (char *) "");
sleep(2);
test.maxscales->start_maxscale(0); test.maxscales->start_maxscale(0);
} }

View File

@ -33,7 +33,7 @@ int main(int argc, char *argv[])
execute_query(test->repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;"); execute_query(test->repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;");
test->tprintf("Wait for the monitor to detect it "); test->tprintf("Wait for the monitor to detect it ");
sleep(15); test.maxscales->wait_for_monitor();
test->tprintf("Connect and insert should work "); test->tprintf("Connect and insert should work ");
char *output = test->ssh_maxscale_output(true, "maxadmin list servers"); char *output = test->ssh_maxscale_output(true, "maxadmin list servers");
@ -49,7 +49,7 @@ int main(int argc, char *argv[])
test->repl->unblock_node(2); test->repl->unblock_node(2);
test->tprintf("Wait for the monitor to detect it "); test->tprintf("Wait for the monitor to detect it ");
sleep(15); test.maxscales->wait_for_monitor();
test->tprintf("Check that we are still using the last node to which we failed over " test->tprintf("Check that we are still using the last node to which we failed over "
"to and that the old nodes are in maintenance mode"); "to and that the old nodes are in maintenance mode");

View File

@ -1,4 +1,6 @@
#include "maxscales.h" #include "maxscales.h"
#include <sstream>
#include <unordered_map>
Maxscales::Maxscales(const char *pref, const char *test_cwd, bool verbose) Maxscales::Maxscales(const char *pref, const char *test_cwd, bool verbose)
{ {
@ -431,3 +433,56 @@ int Maxscales::port(enum service type, int m) const
} }
return -1; return -1;
} }
void Maxscales::wait_for_monitor(int intervals, int m)
{
//Helper for getting number of monitor ticks
auto get_ticks = [&](std::string name)
{
int rc;
char* ticks = ssh_node_output_f(m, false, &rc, "maxctrl api get monitors/%s data.attributes.ticks", name.c_str());
char* ptr;
int rval = strtol(ticks, &ptr, 10);
if (ptr == ticks || (*ptr != '\0' && !isspace(*ptr)))
{
printf("ERROR, invalid monitor tick value: %s\n", ticks);
rval = -1;
}
free(ticks);
return rval;
};
int rc = 0;
// Get a list of monitor names that are running
char* monitors = ssh_node_output_f(m, false, &rc, "maxctrl --tsv list monitors|grep Running|cut -f 1");
std::istringstream is;
is.str(monitors);
free(monitors);
std::string name;
std::unordered_map<std::string, int> ticks;
// For each monitor, store the current monitor tick
while (std::getline(is, name))
{
ticks[name] = get_ticks(name);
}
for (auto a: ticks)
{
// Wait a maximum of 60 seconds for a single monitor interval
for (int i = 0; i < 60; i++)
{
int start = a.second;
int end = get_ticks(a.first);
if (start == -1 || end == -1 || end - start >= intervals)
{
break;
}
sleep(1);
}
}
}

View File

@ -262,6 +262,16 @@ public:
*/ */
StringSet get_server_status(const char* name, int m = 0); StringSet get_server_status(const char* name, int m = 0);
/**
* Wait until the monitors have performed at least one monitoring operation
*
* The function waits until all monitors have performed at least one monitoring cycle.
*
* @param intervals The number of monitor intervals to wait
* @param m Number of Maxscale node
*/
void wait_for_monitor(int intervals = 1, int m = 0);
}; };
#endif // MAXSCALES_H #endif // MAXSCALES_H

View File

@ -19,8 +19,10 @@ void double_cursor(TestConnections& test, MYSQL* conn)
const char* query = "SELECT id FROM test.t1"; const char* query = "SELECT id FROM test.t1";
int rc = mysql_stmt_prepare(stmt1, query, strlen(query)); int rc = mysql_stmt_prepare(stmt1, query, strlen(query));
test.assert(rc == 0, "First prepare should work: %s %s", mysql_stmt_error(stmt1), mysql_error(conn)); test.assert(rc == 0, "First prepare should work: %s %s", mysql_stmt_error(stmt1), mysql_error(conn));
int type = CURSOR_TYPE_READ_ONLY; unsigned long type = CURSOR_TYPE_READ_ONLY;
mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &type); test.assert(mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &type) == 0,
"Set of first attribute should work: %s %s",
mysql_stmt_error(stmt1), mysql_error(conn));
MYSQL_BIND bind[1] {}; MYSQL_BIND bind[1] {};
uint32_t id; uint32_t id;
@ -36,7 +38,9 @@ void double_cursor(TestConnections& test, MYSQL* conn)
MYSQL_STMT* stmt2 = mysql_stmt_init(conn); MYSQL_STMT* stmt2 = mysql_stmt_init(conn);
rc = mysql_stmt_prepare(stmt2, query, strlen(query)); rc = mysql_stmt_prepare(stmt2, query, strlen(query));
test.assert(rc == 0, "Second prepare should work: %s %s", mysql_stmt_error(stmt2), mysql_error(conn)); test.assert(rc == 0, "Second prepare should work: %s %s", mysql_stmt_error(stmt2), mysql_error(conn));
mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &type); test.assert(mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &type) == 0,
"Set of second attribute should work: %s %s",
mysql_stmt_error(stmt2), mysql_error(conn));
mysql_stmt_bind_result(stmt2, bind); mysql_stmt_bind_result(stmt2, bind);
test.assert(mysql_stmt_execute(stmt2) == 0, "Execute of second statement should work: %s %s", test.assert(mysql_stmt_execute(stmt2) == 0, "Execute of second statement should work: %s %s",

View File

@ -63,10 +63,10 @@ void restore_servers(TestConnections& test, bool events_added)
replicate_from(test, 0, 3); replicate_from(test, 0, 3);
replicate_from(test, 1, 3); replicate_from(test, 1, 3);
replicate_from(test, 2, 3); replicate_from(test, 2, 3);
sleep(10); test.maxscales->wait_for_monitor();
o1 = test.maxscales->ssh_node_output(0, o1 = test.maxscales->ssh_node_output(0,
"maxadmin call command mariadbmon switchover MySQL-Monitor server1 server4", true, &dummy); "maxadmin call command mariadbmon switchover MySQL-Monitor server1 server4", true, &dummy);
sleep(10); test.maxscales->wait_for_monitor();
int master_id = get_master_server_id(test); int master_id = get_master_server_id(test);
test.assert(master_id == 1, "Switchover failed to set server1 as master."); test.assert(master_id == 1, "Switchover failed to set server1 as master.");
} }
@ -106,7 +106,7 @@ int main(int argc, char *argv[])
test.try_query(test.repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;"); test.try_query(test.repl->nodes[3], "STOP SLAVE;RESET SLAVE ALL;");
test.tprintf(" Wait for the monitor to detect it "); test.tprintf(" Wait for the monitor to detect it ");
sleep(10); test.maxscales->wait_for_monitor(3);
test.tprintf(" Connect and insert should work "); test.tprintf(" Connect and insert should work ");
get_output(test); get_output(test);
@ -136,7 +136,7 @@ int main(int argc, char *argv[])
test.repl->unblock_node(2); test.repl->unblock_node(2);
test.tprintf(" Wait for the monitor to detect it "); test.tprintf(" Wait for the monitor to detect it ");
sleep(10); test.maxscales->wait_for_monitor();
test.tprintf("Check that we are still using the last node to which we failed over " test.tprintf("Check that we are still using the last node to which we failed over "
"to and that the old nodes are in maintenance mode"); "to and that the old nodes are in maintenance mode");

View File

@ -60,14 +60,14 @@ int main(int argc, char** argv)
test.tprintf("Start by having the current master replicate from the external server"); test.tprintf("Start by having the current master replicate from the external server");
test.repl->connect(); test.repl->connect();
test.repl->replicate_from(0, 3); test.repl->replicate_from(0, 3);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should be the master"); check_status(test, "server1", master_running, "server1 should be the master");
check_status(test, "server2", slave_running, "server2 should be a slave"); check_status(test, "server2", slave_running, "server2 should be a slave");
check_status(test, "server3", slave_running, "server3 should be a slave"); check_status(test, "server3", slave_running, "server3 should be a slave");
test.tprintf("Stop server1, expect server2 to be promoted as the master"); test.tprintf("Stop server1, expect server2 to be promoted as the master");
test.repl->stop_node(0); test.repl->stop_node(0);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server1", down, "server1 should be down"); check_status(test, "server1", down, "server1 should be down");
check_status(test, "server2", master_running, "server2 should be the master"); check_status(test, "server2", master_running, "server2 should be the master");
@ -76,13 +76,13 @@ int main(int argc, char** argv)
test.tprintf("Configure master-master replication between server2 and the external server"); test.tprintf("Configure master-master replication between server2 and the external server");
test.repl->replicate_from(1, 3); test.repl->replicate_from(1, 3);
test.repl->replicate_from(3, 1); test.repl->replicate_from(3, 1);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server2", master_running, "server2 should still be the master"); check_status(test, "server2", master_running, "server2 should still be the master");
check_status(test, "server3", slave_running, "server3 should be a slave"); check_status(test, "server3", slave_running, "server3 should be a slave");
test.tprintf("Start server1, expect it to rejoin the cluster"); test.tprintf("Start server1, expect it to rejoin the cluster");
test.repl->start_node(0); test.repl->start_node(0);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server1", slave_running, "server1 should be a slave"); check_status(test, "server1", slave_running, "server1 should be a slave");
check_status(test, "server2", master_running, "server2 should still be the master"); check_status(test, "server2", master_running, "server2 should still be the master");
check_status(test, "server3", slave_running, "server3 should be a slave"); check_status(test, "server3", slave_running, "server3 should be a slave");
@ -92,7 +92,7 @@ int main(int argc, char** argv)
test.repl->connect(); test.repl->connect();
test.repl->replicate_from(0, 3); test.repl->replicate_from(0, 3);
test.repl->replicate_from(3, 0); test.repl->replicate_from(3, 0);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should be the master"); check_status(test, "server1", master_running, "server1 should be the master");
check_status(test, "server2", down, "server2 should be down"); check_status(test, "server2", down, "server2 should be down");
@ -100,7 +100,7 @@ int main(int argc, char** argv)
test.tprintf("Start server2, expect it to rejoin the cluster"); test.tprintf("Start server2, expect it to rejoin the cluster");
test.repl->start_node(1); test.repl->start_node(1);
sleep(10); test.maxscales->wait_for_monitor();
check_status(test, "server1", master_running, "server1 should still be the master"); check_status(test, "server1", master_running, "server1 should still be the master");
check_status(test, "server2", slave_running, "server2 should be a slave"); check_status(test, "server2", slave_running, "server2 should be a slave");
check_status(test, "server3", slave_running, "server3 should be a slave"); check_status(test, "server3", slave_running, "server3 should be a slave");

View File

@ -21,13 +21,13 @@ int main(int argc, char** argv)
test.repl->connect(); test.repl->connect();
delete_slave_binlogs(test); delete_slave_binlogs(test);
sleep(2); test.maxscales->wait_for_monitor();
basic_test(test); basic_test(test);
print_gtids(test); print_gtids(test);
// Part 1 // Part 1
int node0_id = prepare_test_1(test); int node0_id = prepare_test_1(test);
sleep(10); test.maxscales->wait_for_monitor();
check_test_1(test, node0_id); check_test_1(test, node0_id);
if (test.global_result != 0) if (test.global_result != 0)
@ -37,7 +37,7 @@ int main(int argc, char** argv)
// Part 2 // Part 2
prepare_test_2(test); prepare_test_2(test);
sleep(10); test.maxscales->wait_for_monitor();
check_test_2(test); check_test_2(test);
if (test.global_result != 0) if (test.global_result != 0)
@ -47,7 +47,7 @@ int main(int argc, char** argv)
// Part 3 // Part 3
prepare_test_3(test); prepare_test_3(test);
sleep(10); test.maxscales->wait_for_monitor();
check_test_3(test); check_test_3(test);
return test.global_result; return test.global_result;

View File

@ -23,7 +23,6 @@ int main(int argc, char** argv)
test.repl->connect(); test.repl->connect();
delete_slave_binlogs(test); delete_slave_binlogs(test);
sleep(2);
basic_test(test); basic_test(test);
print_gtids(test); print_gtids(test);
@ -32,10 +31,9 @@ int main(int argc, char** argv)
// Part 1 // Part 1
node0_id = prepare_test_1(test); node0_id = prepare_test_1(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD , true, &ec); test.maxscales->ssh_node_output(0, FAILOVER_CMD , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
check_test_1(test, node0_id); check_test_1(test, node0_id);
if (test.global_result != 0) if (test.global_result != 0)
@ -45,10 +43,9 @@ int main(int argc, char** argv)
// Part 2 // Part 2
prepare_test_2(test); prepare_test_2(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec); test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
check_test_2(test); check_test_2(test);
if (test.global_result != 0) if (test.global_result != 0)
@ -58,10 +55,9 @@ int main(int argc, char** argv)
// Part 3 // Part 3
prepare_test_3(test); prepare_test_3(test);
sleep(3);
test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec); test.maxscales->ssh_node_output(0, FAILOVER_CMD, true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
check_test_3(test); check_test_3(test);
return test.global_result; return test.global_result;

View File

@ -44,13 +44,13 @@ int main(int argc, char** argv)
test.try_query(nodes[3], CHANGE_CMD); test.try_query(nodes[3], CHANGE_CMD);
test.try_query(nodes[3], "START SLAVE;"); test.try_query(nodes[3], "START SLAVE;");
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
test.tprintf(LINE); test.tprintf(LINE);
test.tprintf("Stopping master. Failover should not happen."); test.tprintf("Stopping master. Failover should not happen.");
test.repl->block_node(0); test.repl->block_node(0);
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
int master_id = get_master_server_id(test); int master_id = get_master_server_id(test);
test.assert(master_id == -1, "Master was promoted even when no slave was eligible."); test.assert(master_id == -1, "Master was promoted even when no slave was eligible.");

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test) void run(TestConnections& test)
{ {
sleep(10); test.maxscales->wait_for_monitor();
int N = test.repl->N; int N = test.repl->N;
cout << "Nodes: " << N << endl; cout << "Nodes: " << N << endl;
@ -147,7 +147,7 @@ void run(TestConnections& test)
cout << "\nStopping slave " << N - 1 << endl; cout << "\nStopping slave " << N - 1 << endl;
test.repl->stop_node(N - 1); test.repl->stop_node(N - 1);
sleep(10); test.maxscales->wait_for_monitor();
// server4 was stopped, so we expect the state of it to be /Down/, // server4 was stopped, so we expect the state of it to be /Down/,
// and the states of the other ones not to have changed. // and the states of the other ones not to have changed.
@ -171,7 +171,7 @@ void run(TestConnections& test)
cout << "\nStopping master." << endl; cout << "\nStopping master." << endl;
test.repl->stop_node(0); test.repl->stop_node(0);
sleep(10); test.maxscales->wait_for_monitor();
// server1 (previous master) was taken down, so its state should be /Down/. // server1 (previous master) was taken down, so its state should be /Down/.
// server2 should have been made into master, and server4 should still be down. // server2 should have been made into master, and server4 should still be down.
@ -183,7 +183,7 @@ void run(TestConnections& test)
cout << "\nBringing up slave " << N - 1 << endl; cout << "\nBringing up slave " << N - 1 << endl;
test.repl->start_node(N - 1, (char*)""); test.repl->start_node(N - 1, (char*)"");
sleep(10); test.maxscales->wait_for_monitor();
// server1 should still be down, server2 still master, and server3 still // server1 should still be down, server2 still master, and server3 still
// a slave. server4 was brought up, so it should have been rejoined and // a slave. server4 was brought up, so it should have been rejoined and

View File

@ -204,7 +204,7 @@ void stop_node(XTestConnections& test, int index)
void run(XTestConnections& test) void run(XTestConnections& test)
{ {
sleep(10); test.maxscales->wait_for_monitor();
int N = test.repl->N; int N = test.repl->N;
cout << "Nodes: " << N << endl; cout << "Nodes: " << N << endl;
@ -236,7 +236,7 @@ void run(XTestConnections& test)
cout << "\nClosing connection to MaxScale." << endl; cout << "\nClosing connection to MaxScale." << endl;
test.maxscales->close_maxscale_connections(0); test.maxscales->close_maxscale_connections(0);
sleep(10); test.maxscales->wait_for_monitor();
list_servers(test); list_servers(test);

View File

@ -157,7 +157,7 @@ void check_server_status(TestConnections& test, int N, int down = -1)
void run(TestConnections& test) void run(TestConnections& test)
{ {
sleep(10); test.maxscales->wait_for_monitor();
int N = test.repl->N; int N = test.repl->N;
cout << "Nodes: " << N << endl; cout << "Nodes: " << N << endl;
@ -183,14 +183,14 @@ void run(TestConnections& test)
cout << "\nStopping slave " << slave << endl; cout << "\nStopping slave " << slave << endl;
test.repl->stop_node(i); test.repl->stop_node(i);
sleep(10); test.maxscales->wait_for_monitor();
check_server_status(test, N, i); check_server_status(test, N, i);
cout << "\nStarting slave " << slave << endl; cout << "\nStarting slave " << slave << endl;
test.repl->start_node(i, (char*)""); test.repl->start_node(i, (char*)"");
sleep(10); test.maxscales->wait_for_monitor();
check_server_status(test, N); check_server_status(test, N);
} }

View File

@ -525,7 +525,7 @@ void run(TestConnections& test)
while (time(NULL) - start < TEST_DURATION) while (time(NULL) - start < TEST_DURATION)
{ {
sleep(FAILOVER_DURATION); test.maxscales->wait_for_monitor();
int master_id = get_master_server_id(test); int master_id = get_master_server_id(test);
@ -534,20 +534,20 @@ void run(TestConnections& test)
cout << "\nStopping node: " << master_id << endl; cout << "\nStopping node: " << master_id << endl;
test.repl->stop_node(master_id - 1); test.repl->stop_node(master_id - 1);
sleep(2 * MONITOR_INTERVAL); test.maxscales->wait_for_monitor();
list_servers(test); list_servers(test);
sleep(FAILOVER_DURATION); test.maxscales->wait_for_monitor();
list_servers(test); list_servers(test);
sleep(FAILOVER_DURATION); test.maxscales->wait_for_monitor();
cout << "\nStarting node: " << master_id << endl; cout << "\nStarting node: " << master_id << endl;
test.repl->start_node(master_id - 1); test.repl->start_node(master_id - 1);
sleep(2 * MONITOR_INTERVAL); test.maxscales->wait_for_monitor();
list_servers(test); list_servers(test);
sleep(FAILOVER_DURATION); test.maxscales->wait_for_monitor();
list_servers(test); list_servers(test);
} }
else else
@ -556,7 +556,7 @@ void run(TestConnections& test)
} }
} }
sleep(FAILOVER_DURATION); test.maxscales->wait_for_monitor();
cout << "\nStopping clients.\n" << flush; cout << "\nStopping clients.\n" << flush;
Client::stop(); Client::stop();

View File

@ -98,7 +98,7 @@ int main(int argc, char** argv)
test.assert(false, "Could not start MaxScale."); test.assert(false, "Could not start MaxScale.");
return test.global_result; return test.global_result;
} }
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
StringSet node2_states = test.get_server_status("server3"); StringSet node2_states = test.get_server_status("server3");
@ -119,7 +119,7 @@ int main(int argc, char** argv)
snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]); snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]);
mysql_query(nodes[0], cmd); mysql_query(nodes[0], cmd);
mysql_query(nodes[0], "START SLAVE;"); mysql_query(nodes[0], "START SLAVE;");
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
int master_id = get_master_server_id(test); int master_id = get_master_server_id(test);
test.assert(master_id == 4, "Server 4 should be the cluster master."); test.assert(master_id == 4, "Server 4 should be the cluster master.");
@ -132,7 +132,7 @@ int main(int argc, char** argv)
int ec; int ec;
test.maxscales->ssh_node_output(0, test.maxscales->ssh_node_output(0,
"maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec); "maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test); master_id = get_master_server_id(test);
test.assert(master_id == 1, "Server 1 should be the cluster master."); test.assert(master_id == 1, "Server 1 should be the cluster master.");
get_output(test); get_output(test);

View File

@ -88,7 +88,7 @@ int main(int argc, char** argv)
cout << "Stopping master, should auto-failover." << endl; cout << "Stopping master, should auto-failover." << endl;
int master_id_old = get_master_server_id(test); int master_id_old = get_master_server_id(test);
test.repl->stop_node(0); test.repl->stop_node(0);
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
int master_id_new = get_master_server_id(test); int master_id_new = get_master_server_id(test);
cout << "Master server id is " << master_id_new << endl; cout << "Master server id is " << master_id_new << endl;
@ -107,7 +107,7 @@ int main(int argc, char** argv)
} }
// Restart old master. Then add some events to it. // Restart old master. Then add some events to it.
test.repl->start_node(0, (char*)""); test.repl->start_node(0, (char*)"");
sleep(3); test.maxscales->wait_for_monitor();
test.repl->connect(); test.repl->connect();
cout << "Adding more events to node 0. It should not join the cluster." << endl; cout << "Adding more events to node 0. It should not join the cluster." << endl;
generate_traffic_and_check(test, test.repl->nodes[0], 5); generate_traffic_and_check(test, test.repl->nodes[0], 5);
@ -118,7 +118,7 @@ int main(int argc, char** argv)
test.assert(false, "Could not start MaxScale."); test.assert(false, "Could not start MaxScale.");
return test.global_result; return test.global_result;
} }
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
expect(test, "server1", "Running"); expect(test, "server1", "Running");
@ -139,7 +139,7 @@ int main(int argc, char** argv)
MYSQL** nodes = test.repl->nodes; MYSQL** nodes = test.repl->nodes;
mysql_query(nodes[ind], cmd); mysql_query(nodes[ind], cmd);
mysql_query(nodes[ind], "START SLAVE;"); mysql_query(nodes[ind], "START SLAVE;");
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
expect(test, "server1", "Running"); expect(test, "server1", "Running");

View File

@ -28,7 +28,7 @@ int main(int argc, char** argv)
char result_tmp[bufsize]; char result_tmp[bufsize];
// Advance gtid:s a bit to so gtid variables are updated. // Advance gtid:s a bit to so gtid variables are updated.
generate_traffic_and_check(test, maxconn, 10); generate_traffic_and_check(test, maxconn, 10);
sleep(1); test.maxscales->wait_for_monitor();
test.tprintf(LINE); test.tprintf(LINE);
print_gtids(test); print_gtids(test);
get_input(); get_input();
@ -38,7 +38,7 @@ int main(int argc, char** argv)
const int old_master_id = get_master_server_id(test); // Read master id now before shutdown. const int old_master_id = get_master_server_id(test); // Read master id now before shutdown.
const int master_index = test.repl->master; const int master_index = test.repl->master;
test.repl->stop_node(master_index); test.repl->stop_node(master_index);
sleep(10); test.maxscales->wait_for_monitor();
// Recreate maxscale session // Recreate maxscale session
mysql_close(maxconn); mysql_close(maxconn);
maxconn = test.maxscales->open_rwsplit_connection(0); maxconn = test.maxscales->open_rwsplit_connection(0);
@ -53,7 +53,7 @@ int main(int argc, char** argv)
{ {
test.tprintf("Sending more inserts."); test.tprintf("Sending more inserts.");
generate_traffic_and_check(test, maxconn, 5); generate_traffic_and_check(test, maxconn, 5);
sleep(1); test.maxscales->wait_for_monitor();
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0) if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{ {
gtid_final = result_tmp; gtid_final = result_tmp;
@ -63,11 +63,11 @@ int main(int argc, char** argv)
test.tprintf(LINE); test.tprintf(LINE);
test.repl->start_node(master_index, (char*) ""); test.repl->start_node(master_index, (char*) "");
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
test.repl->connect(); test.repl->connect();
sleep(1); test.maxscales->wait_for_monitor();
string gtid_old_master; string gtid_old_master;
if (find_field(test.repl->nodes[master_index], GTID_QUERY, GTID_FIELD, result_tmp) == 0) if (find_field(test.repl->nodes[master_index], GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{ {
@ -81,7 +81,7 @@ int main(int argc, char** argv)
int ec; int ec;
test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover " test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover "
"MySQL-Monitor server1 server2" , true, &ec); "MySQL-Monitor server1 server2" , true, &ec);
sleep(10); // Wait for monitor to update status test.maxscales->wait_for_monitor(); // Wait for monitor to update status
get_output(test); get_output(test);
master_id = get_master_server_id(test); master_id = get_master_server_id(test);
test.assert(master_id == old_master_id, "Switchover back to server1 failed."); test.assert(master_id == old_master_id, "Switchover back to server1 failed.");
@ -89,7 +89,7 @@ int main(int argc, char** argv)
else else
{ {
test.repl->start_node(master_index, (char*) ""); test.repl->start_node(master_index, (char*) "");
sleep(10); test.maxscales->wait_for_monitor();
} }
test.repl->fix_replication(); test.repl->fix_replication();

View File

@ -40,7 +40,10 @@ int main(int argc, char** argv)
const int old_master_id = get_master_server_id(test); // Read master id now before shutdown. const int old_master_id = get_master_server_id(test); // Read master id now before shutdown.
const int master_index = test.repl->master; const int master_index = test.repl->master;
test.repl->stop_node(master_index); test.repl->stop_node(master_index);
sleep(10);
// Wait until failover is performed
test.maxscales->wait_for_monitor(3);
// Recreate maxscale session // Recreate maxscale session
mysql_close(maxconn); mysql_close(maxconn);
maxconn = test.maxscales->open_rwsplit_connection(0); maxconn = test.maxscales->open_rwsplit_connection(0);
@ -54,20 +57,16 @@ int main(int argc, char** argv)
{ {
cout << "Sending more inserts." << endl; cout << "Sending more inserts." << endl;
generate_traffic_and_check(test, maxconn, 5); generate_traffic_and_check(test, maxconn, 5);
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
gtid_final = result_tmp;
}
print_gtids(test); print_gtids(test);
cout << "Bringing old master back online..." << endl; cout << "Bringing old master back online..." << endl;
test.repl->start_node(master_index, (char*) ""); test.repl->start_node(master_index, (char*) "");
sleep(10); test.maxscales->wait_for_monitor();
test.repl->connect(); test.repl->connect();
get_output(test); get_output(test);
test.tprintf("and manually rejoining it to cluster."); test.tprintf("and manually rejoining it to cluster.");
const char REJOIN_CMD[] = "maxadmin call command mariadbmon rejoin MySQL-Monitor server1"; const char REJOIN_CMD[] = "maxadmin call command mariadbmon rejoin MySQL-Monitor server1";
test.maxscales->ssh_node_output(0, REJOIN_CMD , true, &ec); test.maxscales->ssh_node_output(0, REJOIN_CMD , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
string gtid_old_master; string gtid_old_master;
@ -75,15 +74,20 @@ int main(int argc, char** argv)
{ {
gtid_old_master = result_tmp; gtid_old_master = result_tmp;
} }
if (find_field(maxconn, GTID_QUERY, GTID_FIELD, result_tmp) == 0)
{
gtid_final = result_tmp;
}
cout << LINE << "\n"; cout << LINE << "\n";
print_gtids(test); print_gtids(test);
cout << LINE << "\n"; cout << LINE << "\n";
test.assert(gtid_final == gtid_old_master, "Old master did not successfully rejoin the cluster."); test.assert(gtid_final == gtid_old_master, "Old master did not successfully rejoin the cluster (%s != %s).", gtid_final.c_str(), gtid_old_master.c_str());
// Switch master back to server1 so last check is faster // Switch master back to server1 so last check is faster
int ec; int ec;
test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover " test.maxscales->ssh_node_output(0, "maxadmin call command mysqlmon switchover "
"MySQL-Monitor server1 server2" , true, &ec); "MySQL-Monitor server1 server2" , true, &ec);
sleep(10); // Wait for monitor to update status test.maxscales->wait_for_monitor(); // Wait for monitor to update status
get_output(test); get_output(test);
master_id = get_master_server_id(test); master_id = get_master_server_id(test);
test.assert(master_id == old_master_id, "Switchover back to server1 failed."); test.assert(master_id == old_master_id, "Switchover back to server1 failed.");
@ -91,7 +95,7 @@ int main(int argc, char** argv)
else else
{ {
test.repl->start_node(master_index, (char*) ""); test.repl->start_node(master_index, (char*) "");
sleep(10); test.maxscales->wait_for_monitor();
} }
test.repl->fix_replication(); test.repl->fix_replication();

View File

@ -94,7 +94,7 @@ int main(int argc, char** argv)
string rejoin_s4 = REJOIN_CMD + " server4"; string rejoin_s4 = REJOIN_CMD + " server4";
test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec); test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec);
test.maxscales->ssh_node_output(0, rejoin_s4.c_str() , true, &ec); test.maxscales->ssh_node_output(0, rejoin_s4.c_str() , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
StringSet node2_states = test.get_server_status("server3"); StringSet node2_states = test.get_server_status("server3");
@ -115,11 +115,11 @@ int main(int argc, char** argv)
snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]); snprintf(cmd, sizeof(cmd), CHANGE_CMD_FMT, test.repl->IP[3], test.repl->port[3]);
mysql_query(nodes[0], cmd); mysql_query(nodes[0], cmd);
mysql_query(nodes[0], "START SLAVE;"); mysql_query(nodes[0], "START SLAVE;");
sleep(10); test.maxscales->wait_for_monitor();
string rejoin_s2 = REJOIN_CMD + " server2"; string rejoin_s2 = REJOIN_CMD + " server2";
test.maxscales->ssh_node_output(0, rejoin_s2.c_str() , true, &ec); test.maxscales->ssh_node_output(0, rejoin_s2.c_str() , true, &ec);
test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec); test.maxscales->ssh_node_output(0, rejoin_s3.c_str() , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
get_output(test); get_output(test);
int master_id = get_master_server_id(test); int master_id = get_master_server_id(test);
test.assert(master_id == 4, "Server 4 should be the cluster master."); test.assert(master_id == 4, "Server 4 should be the cluster master.");
@ -132,7 +132,7 @@ int main(int argc, char** argv)
int ec; int ec;
test.maxscales->ssh_node_output(0, test.maxscales->ssh_node_output(0,
"maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec); "maxadmin call command mysqlmon switchover MySQL-Monitor server1 server4" , true, &ec);
sleep(10); test.maxscales->wait_for_monitor();
master_id = get_master_server_id(test); master_id = get_master_server_id(test);
test.assert(master_id == 1, "Server 1 should be the cluster master."); test.assert(master_id == 1, "Server 1 should be the cluster master.");
get_output(test); get_output(test);

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test) void run(TestConnections& test)
{ {
sleep(10); test.maxscales->wait_for_monitor();
int N = test.repl->N; int N = test.repl->N;
cout << "Nodes: " << N << endl; cout << "Nodes: " << N << endl;
@ -149,7 +149,7 @@ void run(TestConnections& test)
zCommand = "call command mysqlmon switchover MySQL-Monitor server2 server1"; zCommand = "call command mysqlmon switchover MySQL-Monitor server2 server1";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand); test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10); test.maxscales->wait_for_monitor();
expect(test, "server1", "Slave", "Running"); expect(test, "server1", "Slave", "Running");
expect(test, "server2", "Master", "Running"); expect(test, "server2", "Master", "Running");
@ -162,7 +162,7 @@ void run(TestConnections& test)
zCommand = "call command mysqlmon switchover MySQL-Monitor server1 server2"; zCommand = "call command mysqlmon switchover MySQL-Monitor server1 server2";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand); test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10); test.maxscales->wait_for_monitor();
expect(test, "server1", "Master", "Running"); expect(test, "server1", "Master", "Running");
expect(test, "server2", "Slave", "Running"); expect(test, "server2", "Slave", "Running");

View File

@ -122,7 +122,7 @@ void expect(TestConnections& test, const char* zServer, const char* zState1, con
void run(TestConnections& test) void run(TestConnections& test)
{ {
sleep(10); test.maxscales->wait_for_monitor();
int N = test.repl->N; int N = test.repl->N;
cout << "Nodes: " << N << endl; cout << "Nodes: " << N << endl;
@ -147,7 +147,7 @@ void run(TestConnections& test)
cout << "\nStopping slave " << N - 1 << endl; cout << "\nStopping slave " << N - 1 << endl;
test.repl->stop_node(N - 1); test.repl->stop_node(N - 1);
sleep(10); test.maxscales->wait_for_monitor();
// server4 was stopped, so we expect the state of it to be /Down/, // server4 was stopped, so we expect the state of it to be /Down/,
// and the states of the other ones not to have changed. // and the states of the other ones not to have changed.
@ -171,7 +171,7 @@ void run(TestConnections& test)
cout << "\nStopping master." << endl; cout << "\nStopping master." << endl;
test.repl->stop_node(0); test.repl->stop_node(0);
sleep(10); test.maxscales->wait_for_monitor(3);
// server1 (previous master) was taken down, so its state should be /Down/. // server1 (previous master) was taken down, so its state should be /Down/.
// server2 should have been made into master, and server4 should still be down. // server2 should have been made into master, and server4 should still be down.
@ -183,7 +183,7 @@ void run(TestConnections& test)
cout << "\nBringing up slave " << N - 1 << endl; cout << "\nBringing up slave " << N - 1 << endl;
test.repl->start_node(N - 1, (char*)""); test.repl->start_node(N - 1, (char*)"");
sleep(10); test.maxscales->wait_for_monitor();
// server1 should still be down, server2 still master, and server3 still // server1 should still be down, server2 still master, and server3 still
// a slave. server4 was brought up, but as auto_rejoin is false, it should // a slave. server4 was brought up, but as auto_rejoin is false, it should
@ -198,7 +198,7 @@ void run(TestConnections& test)
const char* zCommand = "call command mysqlmon switchover MySQL-Monitor server4 server2"; const char* zCommand = "call command mysqlmon switchover MySQL-Monitor server4 server2";
test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand); test.maxscales->execute_maxadmin_command_print(0, (char*)zCommand);
sleep(10); test.maxscales->wait_for_monitor();
// The state should not change, as server4 is not good enough as master. // The state should not change, as server4 is not good enough as master.
expect(test, "server1", "Down"); expect(test, "server1", "Down");

View File

@ -245,7 +245,8 @@ bool runtime_destroy_server(SERVER *server)
} }
static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *cert, static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *cert,
const char *ca, const char *version, const char *depth) const char *ca, const char *version, const char *depth,
const char *verify)
{ {
SSL_LISTENER *rval = NULL; SSL_LISTENER *rval = NULL;
CONFIG_CONTEXT *obj = config_context_create(name); CONFIG_CONTEXT *obj = config_context_create(name);
@ -257,7 +258,8 @@ static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *c
config_add_param(obj, CN_SSL_CERT, cert) && config_add_param(obj, CN_SSL_CERT, cert) &&
config_add_param(obj, CN_SSL_CA_CERT, ca) && config_add_param(obj, CN_SSL_CA_CERT, ca) &&
(!version || config_add_param(obj, CN_SSL_VERSION, version)) && (!version || config_add_param(obj, CN_SSL_VERSION, version)) &&
(!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth))) (!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth)) &&
(!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify)))
{ {
int err = 0; int err = 0;
SSL_LISTENER *ssl = make_ssl_structure(obj, true, &err); SSL_LISTENER *ssl = make_ssl_structure(obj, true, &err);
@ -275,14 +277,15 @@ static SSL_LISTENER* create_ssl(const char *name, const char *key, const char *c
} }
bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert, bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert,
const char *ca, const char *version, const char *depth) const char *ca, const char *version, const char *depth,
const char *verify)
{ {
bool rval = false; bool rval = false;
if (key && cert && ca) if (key && cert && ca)
{ {
spinlock_acquire(&crt_lock); spinlock_acquire(&crt_lock);
SSL_LISTENER *ssl = create_ssl(server->name, key, cert, ca, version, depth); SSL_LISTENER *ssl = create_ssl(server->name, key, cert, ca, version, depth, verify);
if (ssl) if (ssl)
{ {
@ -792,7 +795,8 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
const char *port, const char *proto, const char *auth, const char *port, const char *proto, const char *auth,
const char *auth_opt, const char *ssl_key, const char *auth_opt, const char *ssl_key,
const char *ssl_cert, const char *ssl_ca, const char *ssl_cert, const char *ssl_ca,
const char *ssl_version, const char *ssl_depth) const char *ssl_version, const char *ssl_depth,
const char *verify_ssl)
{ {
if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0) if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
@ -830,7 +834,7 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
SSL_LISTENER *ssl = NULL; SSL_LISTENER *ssl = NULL;
if (ssl_key && ssl_cert && ssl_ca && if (ssl_key && ssl_cert && ssl_ca &&
(ssl = create_ssl(name, ssl_key, ssl_cert, ssl_ca, ssl_version, ssl_depth)) == NULL) (ssl = create_ssl(name, ssl_key, ssl_cert, ssl_ca, ssl_version, ssl_depth, verify_ssl)) == NULL)
{ {
MXS_ERROR("SSL initialization for listener '%s' failed.", name); MXS_ERROR("SSL initialization for listener '%s' failed.", name);
runtime_error("SSL initialization for listener '%s' failed.", name); runtime_error("SSL initialization for listener '%s' failed.", name);
@ -1267,6 +1271,7 @@ static bool process_ssl_parameters(SERVER* server, json_t* params)
if (validate_ssl_json(params)) if (validate_ssl_json(params))
{ {
char buf[20]; // Enough to hold the string form of the ssl_cert_verify_depth char buf[20]; // Enough to hold the string form of the ssl_cert_verify_depth
char buf_verify[20]; // Enough to hold the string form of the ssl_verify_peer_certificate
const char* key = json_string_value(mxs_json_pointer(params, CN_SSL_KEY)); const char* key = json_string_value(mxs_json_pointer(params, CN_SSL_KEY));
const char* cert = json_string_value(mxs_json_pointer(params, CN_SSL_CERT)); const char* cert = json_string_value(mxs_json_pointer(params, CN_SSL_CERT));
const char* ca = json_string_value(mxs_json_pointer(params, CN_SSL_CA_CERT)); const char* ca = json_string_value(mxs_json_pointer(params, CN_SSL_CA_CERT));
@ -1280,7 +1285,16 @@ static bool process_ssl_parameters(SERVER* server, json_t* params)
depth = buf; depth = buf;
} }
if (!runtime_enable_server_ssl(server, key, cert, ca, version, depth)) const char* verify = NULL;
json_t* verify_json = mxs_json_pointer(params, CN_SSL_VERIFY_PEER_CERTIFICATE);
if (verify_json)
{
snprintf(buf_verify, sizeof(buf), "%s", json_boolean_value(verify_json) ? "true" : "false");
verify = buf_verify;
}
if (!runtime_enable_server_ssl(server, key, cert, ca, version, depth, verify))
{ {
runtime_error("Failed to initialize SSL for server '%s'. See " runtime_error("Failed to initialize SSL for server '%s'. See "
"error log for more details.", server->name); "error log for more details.", server->name);
@ -1957,11 +1971,12 @@ bool runtime_create_listener_from_json(SERVICE* service, json_t* json)
const char* ssl_ca_cert = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CA_CERT); const char* ssl_ca_cert = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CA_CERT);
const char* ssl_version = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_VERSION); const char* ssl_version = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_VERSION);
const char* ssl_cert_verify_depth = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH); const char* ssl_cert_verify_depth = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_CERT_VERIFY_DEPTH);
const char* ssl_verify_peer_certificate = get_string_or_null(json, MXS_JSON_PTR_PARAM_SSL_VERIFY_PEER_CERT);
rval = runtime_create_listener(service, id, address, port.c_str(), protocol, rval = runtime_create_listener(service, id, address, port.c_str(), protocol,
authenticator, authenticator_options, authenticator, authenticator_options,
ssl_key, ssl_cert, ssl_ca_cert, ssl_version, ssl_key, ssl_cert, ssl_ca_cert, ssl_version,
ssl_cert_verify_depth); ssl_cert_verify_depth, ssl_verify_peer_certificate);
} }
return rval; return rval;

View File

@ -105,10 +105,13 @@ bool runtime_alter_server(SERVER *server, const char *key, const char *value);
* @param ca Path to certificate authority * @param ca Path to certificate authority
* @param version Required SSL Version * @param version Required SSL Version
* @param depth Certificate verification depth * @param depth Certificate verification depth
* @param verify Verify peer certificate
*
* @return True if SSL was successfully enabled * @return True if SSL was successfully enabled
*/ */
bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert, bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert,
const char *ca, const char *version, const char *depth); const char *ca, const char *version, const char *depth,
const char *verify);
/** /**
* @brief Alter monitor parameters * @brief Alter monitor parameters
@ -158,6 +161,7 @@ bool runtime_alter_maxscale(const char* name, const char* value);
* @param ssl_ca SSL CA cert, NULL for no CA cert * @param ssl_ca SSL CA cert, NULL for no CA cert
* @param ssl_version SSL version, NULL for default of "MAX" * @param ssl_version SSL version, NULL for default of "MAX"
* @param ssl_depth SSL cert verification depth, NULL for default * @param ssl_depth SSL cert verification depth, NULL for default
* @param verify_ssl SSL peer certificate verification, NULL for default
* *
* @return True if the listener was successfully created and started * @return True if the listener was successfully created and started
*/ */
@ -165,7 +169,8 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add
const char *port, const char *proto, const char *auth, const char *port, const char *proto, const char *auth,
const char *auth_opt, const char *ssl_key, const char *auth_opt, const char *ssl_key,
const char *ssl_cert, const char *ssl_ca, const char *ssl_cert, const char *ssl_ca,
const char *ssl_version, const char *ssl_depth); const char *ssl_version, const char *ssl_depth,
const char *verify_ssl);
/** /**
* @brief Destroy a listener * @brief Destroy a listener

View File

@ -1455,6 +1455,8 @@ static json_t* server_json_attributes(const SERVER* server)
json_object_set_new(params, CN_SSL_CA_CERT, json_string(server->server_ssl->ssl_ca_cert)); json_object_set_new(params, CN_SSL_CA_CERT, json_string(server->server_ssl->ssl_ca_cert));
json_object_set_new(params, CN_SSL_CERT_VERIFY_DEPTH, json_object_set_new(params, CN_SSL_CERT_VERIFY_DEPTH,
json_integer(server->server_ssl->ssl_cert_verify_depth)); json_integer(server->server_ssl->ssl_cert_verify_depth));
json_object_set_new(params, CN_SSL_VERIFY_PEER_CERTIFICATE,
json_boolean(server->server_ssl->ssl_verify_peer_certificate));
json_object_set_new(params, CN_SSL_VERSION, json_object_set_new(params, CN_SSL_VERSION,
json_string(ssl_method_type_to_string(server->server_ssl->ssl_method_type))); json_string(ssl_method_type_to_string(server->server_ssl->ssl_method_type)));
} }

View File

@ -64,7 +64,7 @@
#include "../../../core/internal/poll.h" #include "../../../core/internal/poll.h"
#include "../../../core/internal/session.h" #include "../../../core/internal/session.h"
#define MAXARGS 12 #define MAXARGS 14
#define ARG_TYPE_NONE 0 #define ARG_TYPE_NONE 0
#define ARG_TYPE_ADDRESS 1 #define ARG_TYPE_ADDRESS 1
@ -1168,11 +1168,11 @@ static void createServer(DCB *dcb, char *name, char *address, char *port,
static void createListener(DCB *dcb, SERVICE *service, char *name, char *address, static void createListener(DCB *dcb, SERVICE *service, char *name, char *address,
char *port, char *protocol, char *authenticator, char *port, char *protocol, char *authenticator,
char *authenticator_options, char *key, char *cert, char *authenticator_options, char *key, char *cert,
char *ca, char *version, char *depth) char *ca, char *version, char *depth, char *verify)
{ {
if (runtime_create_listener(service, name, address, port, protocol, if (runtime_create_listener(service, name, address, port, protocol,
authenticator, authenticator_options, authenticator, authenticator_options,
key, cert, ca, version, depth)) key, cert, ca, version, depth, verify))
{ {
dcb_printf(dcb, "Listener '%s' created\n", name); dcb_printf(dcb, "Listener '%s' created\n", name);
} }
@ -1380,6 +1380,7 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
char *ssl_ca = NULL; char *ssl_ca = NULL;
char *ssl_version = NULL; char *ssl_version = NULL;
char *ssl_depth = NULL; char *ssl_depth = NULL;
char *ssl_verify = NULL;
bool enable = false; bool enable = false;
for (int i = 0; i < items && values[i]; i++) for (int i = 0; i < items && values[i]; i++)
@ -1413,6 +1414,10 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
{ {
ssl_depth = value; ssl_depth = value;
} }
else if (strcmp("ssl_verify_peer_certificate", key) == 0)
{
ssl_verify = value;
}
else else
{ {
enable = strcmp("ssl", key) == 0 && strcmp(value, "required") == 0; enable = strcmp("ssl", key) == 0 && strcmp(value, "required") == 0;
@ -1436,7 +1441,7 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
{ {
/** We have SSL parameters, try to process them */ /** We have SSL parameters, try to process them */
if (!runtime_enable_server_ssl(server, ssl_key, ssl_cert, ssl_ca, if (!runtime_enable_server_ssl(server, ssl_key, ssl_cert, ssl_ca,
ssl_version, ssl_depth)) ssl_version, ssl_depth, ssl_verify))
{ {
dcb_printf(dcb, "Enabling SSL for server '%s' failed, see log " dcb_printf(dcb, "Enabling SSL for server '%s' failed, see log "
"for more details.\n", server->name); "for more details.\n", server->name);
@ -1538,7 +1543,7 @@ static void alterMaxScale(DCB *dcb, char *v1, char *v2, char *v3,
struct subcommand alteroptions[] = struct subcommand alteroptions[] =
{ {
{ {
"server", 2, 12, (FN)alterServer, "server", 2, 14, (FN)alterServer,
"Alter server parameters", "Alter server parameters",
"Usage: alter server NAME KEY=VALUE ...\n" "Usage: alter server NAME KEY=VALUE ...\n"
"\n" "\n"
@ -1548,18 +1553,19 @@ struct subcommand alteroptions[] =
"\n" "\n"
"This will alter an existing parameter of a server. The accepted values for KEY are:\n" "This will alter an existing parameter of a server. The accepted values for KEY are:\n"
"\n" "\n"
"address Server address\n" "address Server address\n"
"port Server port\n" "port Server port\n"
"monitoruser Monitor user for this server\n" "monitoruser Monitor user for this server\n"
"monitorpw Monitor password for this server\n" "monitorpw Monitor password for this server\n"
"ssl Enable SSL, value must be 'required'\n" "ssl Enable SSL, value must be 'required'\n"
"ssl_key Path to SSL private key\n" "ssl_key Path to SSL private key\n"
"ssl_cert Path to SSL certificate\n" "ssl_cert Path to SSL certificate\n"
"ssl_ca_cert Path to SSL CA certificate\n" "ssl_ca_cert Path to SSL CA certificate\n"
"ssl_version SSL version\n" "ssl_version SSL version\n"
"ssl_cert_verify_depth Certificate verification depth\n" "ssl_cert_verify_depth Certificate verification depth\n"
"persistpoolmax Persisted connection pool size\n" "ssl_verify_peer_certificate Peer certificate verification\n"
"persistmaxtime Persisted connection maximum idle time\n" "persistpoolmax Persisted connection pool size\n"
"persistmaxtime Persisted connection maximum idle time\n"
"\n" "\n"
"To configure SSL for a newly created server, the 'ssl', 'ssl_cert',\n" "To configure SSL for a newly created server, the 'ssl', 'ssl_cert',\n"
"'ssl_key' and 'ssl_ca_cert' parameters must be given at the same time.\n" "'ssl_key' and 'ssl_ca_cert' parameters must be given at the same time.\n"

View File

@ -353,6 +353,7 @@ static void log_unexpected_response(SRWBackend& backend, GWBUF* buffer, GWBUF* c
"server '%s' when no response was expected. Command: 0x%02hhx " "server '%s' when no response was expected. Command: 0x%02hhx "
"Query: %s", mxs_mysql_get_command(buffer), backend->name(), "Query: %s", mxs_mysql_get_command(buffer), backend->name(),
backend->current_command(), sql.c_str()); backend->current_command(), sql.c_str());
session_dump_statements(backend->dcb()->session);
ss_dassert(false); ss_dassert(false);
} }
} }