Extend text protocol PS test

The test now checks that text protocol prepared statements are load
balanced just like normal queries.
This commit is contained in:
Markus Mäkelä
2017-07-08 08:15:42 +03:00
parent 8b5c6f7286
commit deef6bb030

View File

@ -11,48 +11,89 @@
* - check if Maxscale is alive
*/
#include <iostream>
#include "testconnections.h"
#include "sql_t1.h"
using namespace std;
int main(int argc, char *argv[])
void test_basic(TestConnections& test)
{
TestConnections * Test = new TestConnections(argc, argv);
Test->set_timeout(60);
test.set_timeout(60);
int N = 4;
Test->repl->connect();
if (Test->connect_maxscale() != 0 )
test.repl->connect();
test.connect_maxscale();
create_t1(test.conn_rwsplit);
insert_into_t1(test.conn_rwsplit, N);
test.set_timeout(20);
test.try_query(test.conn_rwsplit, "PREPARE stmt FROM 'SELECT * FROM t1 WHERE fl=@x;';");
test.try_query(test.conn_rwsplit, "SET @x = 3;");
test.try_query(test.conn_rwsplit, "EXECUTE stmt");
test.try_query(test.conn_rwsplit, "SET @x = 4;");
test.try_query(test.conn_rwsplit, "EXECUTE stmt");
test.check_maxscale_alive();
test.stop_timeout();
}
void test_routing(TestConnections& test)
{
printf("Error connecting to MaxScale\n");
delete Test;
exit(1);
test.set_timeout(60);
test.repl->connect();
int server_id = test.repl->get_server_id(0);
test.connect_maxscale();
// Test that reads are routed to slaves
char buf[1024] = "-1";
test.try_query(test.conn_rwsplit, "PREPARE ps1 FROM 'SELECT @@server_id'");
test.add_result(find_field(test.conn_rwsplit, "EXECUTE ps1", "@@server_id", buf),
"Execute should succeed");
int res = atoi(buf);
test.add_result(res == server_id, "Query should be routed to a slave (got %d, master is %d)", res, server_id);
// Test reads inside transactions are routed to master
test.try_query(test.conn_rwsplit, "BEGIN");
test.add_result(find_field(test.conn_rwsplit, "EXECUTE ps1", "@@server_id", buf),
"Execute should succeed");
res = atoi(buf);
test.add_result(res != server_id, "Query should be routed to master inside a transaction (got %d, master is %d)", res, server_id);
test.try_query(test.conn_rwsplit, "COMMIT");
// Test reads inside read-only transactions are routed slaves
test.try_query(test.conn_rwsplit, "START TRANSACTION READ ONLY");
test.add_result(find_field(test.conn_rwsplit, "EXECUTE ps1", "@@server_id", buf),
"Execute should succeed");
res = atoi(buf);
test.add_result(res == server_id, "Query should be routed to a slave inside a read-only transaction (got %d, master is %d)", res, server_id);
test.try_query(test.conn_rwsplit, "COMMIT");
// Test prepared statements that modify data
test.try_query(test.conn_rwsplit, "CREATE OR REPLACE TABLE test.t1 (id INT)");
test.try_query(test.conn_rwsplit, "PREPARE ps2 FROM 'INSERT INTO test.t1 VALUES (?)'");
test.try_query(test.conn_rwsplit, "SET @a = 1");
test.try_query(test.conn_rwsplit, "EXECUTE ps2 USING @a");
test.add_result(find_field(test.conn_rwsplit, "SELECT id FROM test.t1", "id", buf),
"Read should succeed");
res = atoi(buf);
test.add_result(res != server_id, "Writes should be routed to the master (got %d, master is %d)", res, server_id);
// Cleanup
test.check_maxscale_alive();
test.stop_timeout();
}
create_t1(Test->conn_rwsplit);
insert_into_t1(Test->conn_rwsplit, N);
int main(int argc, char *argv[])
{
TestConnections test(argc, argv);
Test->set_timeout(20);
Test->try_query(Test->conn_rwsplit, (char *) "PREPARE stmt FROM 'SELECT * FROM t1 WHERE fl=@x;';");
Test->try_query(Test->conn_rwsplit, (char *) "SET @x = 3;");
Test->try_query(Test->conn_rwsplit, (char *) "EXECUTE stmt");
Test->try_query(Test->conn_rwsplit, (char *) "SET @x = 4;");
Test->try_query(Test->conn_rwsplit, (char *) "EXECUTE stmt");
test.tprintf("Running basic test");
test_basic(test);
Test->check_maxscale_alive();
int rval = Test->global_result;
delete Test;
return rval;
test.tprintf("Running text PS routing test");
test_routing(test);
return test.global_result;
}
/*
Hi Timofey, I can't imagine repeatable way to run in to the situation where session command replies would arrive in different order, at least without additional instrumentation. You can, however, increase the probability for it to occur by setting up master and multiple slaves, the more the better.
Then start to prepare statements which return much data. The length of response packet depends on number of columns so good query would be something that produces lots of columns, like select a.user, b.user, c.user, ... z.user from mysql.user a, mysql.user b, mysql.user c, ... mysql.user z
I'm not sure that it will happen but it is possible. You can also try to make it happen by decreasing the size of network packet because the smaller that is the more likely it is that responses are split into multiple packets - which can then becomen interleaved with packets from different slaves.
*/