
The sanity check replaces several old regression tests and provides a quick test for checking mainly the readwritesplit routing behavior. It also checks some of the connection counts and runs queries that once caused a crash. The set of tests that the sanity check obsoletes is: bug422 bug469 bug448 bug507 bug509 bug634 bug694 bug669 bug711 mxs127 mxs47 mxs682_cyrillic mxs957 mxs1786_statistics rwsplit_read_only_trx
132 lines
4.4 KiB
C++
132 lines
4.4 KiB
C++
/**
|
|
* Sanity check for basic functionality
|
|
*
|
|
* Combines several old regression tests into one quick test.
|
|
*/
|
|
|
|
#include "testconnections.h"
|
|
|
|
|
|
void test_rwsplit(TestConnections& test)
|
|
{
|
|
test.set_timeout(300);
|
|
test.repl->connect();
|
|
std::string master_id = test.repl->get_server_id_str(0);
|
|
test.repl->disconnect();
|
|
|
|
auto c = test.maxscales->rwsplit();
|
|
test.expect(c.connect(), "Connection to readwritesplit should succeed");
|
|
|
|
// Transactions to master
|
|
c.query("START TRANSACTION");
|
|
test.expect(c.field("SELECT @@server_id") == master_id,
|
|
"START TRANSACTION should go to the master");
|
|
c.query("COMMIT");
|
|
|
|
// Read-only transactions to slave
|
|
c.query("START TRANSACTION READ ONLY");
|
|
test.expect(c.field("SELECT @@server_id") != master_id,
|
|
"START TRANSACTION READ ONLY should go to a slave");
|
|
c.query("COMMIT");
|
|
|
|
// @@last_insert_id routed to master
|
|
test.expect(c.field("SELECT @@server_id, @@last_insert_id") == master_id,
|
|
"@@last_insert_id should go to the master");
|
|
test.expect(c.field("SELECT last_insert_id(), @@server_id", 1) == master_id,
|
|
"@@last_insert_id should go to the master");
|
|
|
|
// Replication related queries
|
|
test.expect(!c.row("SHOW SLAVE STATUS").empty(),
|
|
"SHOW SLAVE STATUS should go to a slave");
|
|
|
|
// User variable modification in SELECT
|
|
test.expect(!c.query("SELECT @a:=@a+1 as a, user FROM mysql"),
|
|
"Query with variable modification should fail");
|
|
|
|
// Repeated session commands
|
|
for (int i = 0; i < 10000; i++)
|
|
{
|
|
test.expect(c.query("set @test=" + std::to_string(i)), "SET should work: %s", c.error());
|
|
}
|
|
|
|
// Large result sets
|
|
for (int i = 1; i < 5000; i += 7)
|
|
{
|
|
c.query("SELECT REPEAT('a'," + std::to_string(i) + ")");
|
|
}
|
|
|
|
// Non ASCII characters
|
|
c.query("CREATE OR REPLACE TABLE test.t1 AS SELECT 'Кот'");
|
|
c.query("BEGIN");
|
|
c.check("SELECT * FROM test.t1", "Кот");
|
|
c.query("COMMIT");
|
|
c.query("DROP TABLE test.t1");
|
|
|
|
// Temporary tables
|
|
for (auto a : {
|
|
"USE test",
|
|
"CREATE OR REPLACE TABLE t1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
|
"CREATE OR REPLACE TABLE t2(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
|
"CREATE TEMPORARY TABLE temp1(`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY)",
|
|
"INSERT INTO temp1 values (1), (2), (3)",
|
|
"INSERT INTO t1 values (1), (2), (3)",
|
|
"INSERT INTO t2 values (1), (2), (3)",
|
|
"CREATE TEMPORARY TABLE temp2 SELECT DISTINCT p.id FROM temp1 p JOIN t1 t "
|
|
" ON (t.id = p.id) LEFT JOIN t2 ON (t.id = t2.id) WHERE p.id IS NOT NULL "
|
|
" AND @@server_id IS NOT NULL",
|
|
"SELECT * FROM temp2",
|
|
"DROP TABLE t1",
|
|
"DROP TABLE t2"
|
|
})
|
|
{
|
|
test.expect(c.query(a), "Temp table query failed");
|
|
}
|
|
|
|
// Temporary and real table overlap
|
|
c.query("CREATE OR REPLACE TABLE test.t1 AS SELECT 1 AS id");
|
|
c.query("CREATE TEMPORARY TABLE test.t1 AS SELECT 2 AS id");
|
|
c.check("SELECT id FROM test.t1", "2");
|
|
c.query("DROP TABLE test.t1");
|
|
c.query("DROP TABLE test.t1");
|
|
|
|
// COM_STATISTICS
|
|
test.maxscales->connect();
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
mysql_stat(test.maxscales->conn_rwsplit[0]);
|
|
test.try_query(test.maxscales->conn_rwsplit[0], "SELECT 1");
|
|
}
|
|
test.maxscales->disconnect();
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
TestConnections test(argc, argv);
|
|
|
|
auto connections = [&]() {
|
|
return test.maxctrl("api get servers/server1 data.attributes.statistics.connections").second;
|
|
};
|
|
|
|
test.expect(connections()[0] == '0', "The master should have no connections");
|
|
test.maxscales->connect();
|
|
test.expect(connections()[0] == '2', "The master should have two connections");
|
|
test.maxscales->disconnect();
|
|
test.expect(connections()[0] == '0', "The master should have no connections");
|
|
|
|
test.maxscales->connect();
|
|
for (auto a : {"show status", "show variables", "show global status"})
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
test.try_query(test.maxscales->conn_rwsplit[0], "%s", a);
|
|
test.try_query(test.maxscales->conn_master[0], "%s", a);
|
|
}
|
|
}
|
|
test.maxscales->disconnect();
|
|
|
|
// Readwritesplit sanity checks
|
|
test_rwsplit(test);
|
|
|
|
return test.global_result;
|
|
}
|