MXS-1506: Extend test case
Extended test case to cover interrupted writes.
This commit is contained in:
@ -14,17 +14,19 @@ using namespace std;
|
||||
struct TestCase
|
||||
{
|
||||
string description;
|
||||
function<void ()> pre; // Called before master goes down
|
||||
function<void ()> main; // Called after master goes down
|
||||
function<void ()> check; // Called after connection is closed
|
||||
function<void ()> pre; // Called before master goes down
|
||||
function<void ()> block; // Executed in a separate thread before `main` is called
|
||||
function<void ()> main; // Called after master goes down
|
||||
function<void ()> check; // Called after `main` and `block` are completed
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
auto query = [&test](string q)
|
||||
auto query = [&test](string q, int t = 0)
|
||||
{
|
||||
sleep(t);
|
||||
return execute_query_silent(test.maxscales->conn_rwsplit[0], q.c_str()) == 0;
|
||||
};
|
||||
|
||||
@ -37,18 +39,19 @@ int main(int argc, char** argv)
|
||||
test.assert(rc, "Query '%s' did not produce result of '%s'", q.c_str(), res.c_str());
|
||||
};
|
||||
|
||||
auto ok = [&test, &query](string q)
|
||||
auto ok = [&test, &query](string q, int t = 0)
|
||||
{
|
||||
test.assert(query(q), "Query '%' should work: %s", q.c_str(), mysql_error(test.maxscales->conn_rwsplit[0]));
|
||||
test.assert(query(q, t), "Query '%' should work: %s", q.c_str(), mysql_error(test.maxscales->conn_rwsplit[0]));
|
||||
};
|
||||
|
||||
auto err = [&test, &query](string q)
|
||||
auto err = [&test, &query](string q, int t = 0)
|
||||
{
|
||||
test.assert(!query(q), "Query should fail: %s", q.c_str());
|
||||
test.assert(!query(q, t), "Query should fail: %s", q.c_str());
|
||||
};
|
||||
|
||||
auto block_master = [&test]()
|
||||
auto block_master = [&test](int pre = 0)
|
||||
{
|
||||
sleep(pre);
|
||||
test.repl->block_node(0);
|
||||
sleep(10);
|
||||
test.repl->unblock_node(0);
|
||||
@ -57,28 +60,67 @@ int main(int argc, char** argv)
|
||||
vector<TestCase> tests(
|
||||
{
|
||||
{
|
||||
"Test autocommit insert with master disconnection",
|
||||
"Normal insert",
|
||||
bind(ok, "SELECT 1"),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES (1)"),
|
||||
bind(block_master, 0),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES (1)", 5),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 1", "1")
|
||||
},
|
||||
{
|
||||
"Test user variables in insert with master disconnection",
|
||||
"Insert with user variables",
|
||||
bind(ok, "SET @a = 2"),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES (@a)"),
|
||||
bind(block_master, 0),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES (@a)", 5),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 2", "1")
|
||||
},
|
||||
{
|
||||
"Check that writes in transactions aren't retried",
|
||||
"Normal transaction",
|
||||
bind(ok, "START TRANSACTION"),
|
||||
bind(err, "INSERT INTO test.t1 VALUES (3)"),
|
||||
bind(block_master, 0),
|
||||
bind(err, "INSERT INTO test.t1 VALUES (3)", 5),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 3", "0")
|
||||
},
|
||||
{
|
||||
"Check that writes without autocommit aren't retried",
|
||||
bind(ok, "SET autocommit=0"),
|
||||
bind(err, "INSERT INTO test.t1 VALUES (4)"),
|
||||
"Read-only transaction",
|
||||
bind(ok, "START TRANSACTION READ ONLY"),
|
||||
bind(block_master, 0),
|
||||
bind(err, "INSERT INTO test.t1 VALUES (4)", 5),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 4", "0")
|
||||
},
|
||||
{
|
||||
"Insert with autocommit=0",
|
||||
bind(ok, "SET autocommit=0"),
|
||||
bind(block_master, 0),
|
||||
bind(err, "INSERT INTO test.t1 VALUES (5)", 5),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 5", "0")
|
||||
},
|
||||
{
|
||||
"Interrupted insert (should cause duplicate statement execution)",
|
||||
bind(ok, "SELECT 1"),
|
||||
bind(block_master, 5),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES ((SELECT SLEEP(10) + 6))", 0),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 6", "2")
|
||||
},
|
||||
{
|
||||
"Interrupted insert with user variable (should cause duplicate statement execution)",
|
||||
bind(ok, "SET @b = 7"),
|
||||
bind(block_master, 5),
|
||||
bind(ok, "INSERT INTO test.t1 VALUES ((SELECT SLEEP(10) + @b))", 0),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 7", "2")
|
||||
},
|
||||
{
|
||||
"Interrupted insert in transaction",
|
||||
bind(ok, "START TRANSACTION"),
|
||||
bind(block_master, 5),
|
||||
bind(err, "INSERT INTO test.t1 VALUES ((SELECT SLEEP(10) + 8))", 0),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 8", "0")
|
||||
},
|
||||
{
|
||||
"Interrupted insert in read-only transaction",
|
||||
bind(ok, "START TRANSACTION READ ONLY"),
|
||||
bind(block_master, 5),
|
||||
bind(err, "INSERT INTO test.t1 VALUES ((SELECT SLEEP(10) + 9))", 0),
|
||||
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id = 9", "0")
|
||||
}
|
||||
});
|
||||
|
||||
@ -93,8 +135,7 @@ int main(int argc, char** argv)
|
||||
cout << a.description << endl;
|
||||
test.maxscales->connect();
|
||||
a.pre();
|
||||
thread thr(block_master);
|
||||
sleep(5);
|
||||
thread thr(a.block);
|
||||
a.main();
|
||||
test.maxscales->disconnect();
|
||||
thr.join();
|
||||
|
||||
Reference in New Issue
Block a user