MaxScale/maxscale-system-test/mxs1507_trx_replay.cpp
Markus Mäkelä f476266637
Increase number of monitor waits in mxs1507_trx_replay
The test appears to have failed at least once when the monitor did not,
for some reason, notice that a server was down. Also adjusted the queries
to be more unique across the test cases.
2019-01-31 14:23:27 +02:00

288 lines
7.8 KiB
C++

/**
* MXS-1507: Transaction replay tests
*
* https://jira.mariadb.org/browse/MXS-1507
*/
#include "testconnections.h"
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
TestConnections test(argc, argv);
auto query = [&](string q) {
return execute_query_silent(test.maxscales->conn_rwsplit[0], q.c_str()) == 0;
};
auto ok = [&](string q) {
test.expect(query(q),
"Query '%s' should work: %s",
q.c_str(),
mysql_error(test.maxscales->conn_rwsplit[0]));
};
auto err = [&](string q) {
test.expect(!query(q), "Query should not work: %s", q.c_str());
};
auto check = [&](string q, string res) {
Row row = get_row(test.maxscales->conn_rwsplit[0], q.c_str());
test.expect(!row.empty() && row[0] == res,
"Query '%s' should return 1: %s (%s)",
q.c_str(),
row.empty() ? "<empty>" : row[0].c_str(),
mysql_error(test.maxscales->conn_rwsplit[0]));
};
struct TrxTest
{
string description;
vector<function<void ()>> pre;
vector<function<void ()>> post;
vector<function<void ()>> check;
};
std::vector<TrxTest> tests
({
{
"Basic transaction",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT 1"),
},
{
bind(ok, "SELECT 2"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Large result",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT REPEAT('a', 100000)"),
},
{
bind(ok, "SELECT REPEAT('a', 100000)"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Transaction with a write",
{
bind(ok, "BEGIN"),
bind(ok, "INSERT INTO test.t1 VALUES (1)"),
},
{
bind(ok, "INSERT INTO test.t1 VALUES (2)"),
bind(ok, "COMMIT"),
},
{
bind(check, "SELECT COUNT(*) FROM test.t1 WHERE id IN (1, 2)", "2"),
}
},
{
"Read-only transaction",
{
bind(ok, "START TRANSACTION READ ONLY"),
bind(ok, "SELECT 1"),
},
{
bind(ok, "SELECT 2"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Trx started, no queries",
{
bind(ok, "BEGIN"),
},
{
bind(ok, "SELECT 1"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Trx waiting on commit",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT 1"),
},
{
bind(ok, "COMMIT"),
},
{
}
},
{
"Trx with NOW()",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT NOW(), SLEEP(1)"),
},
{
bind(err, "SELECT 1"),
},
{
}
},
{
"Commit trx with NOW()",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT NOW(), SLEEP(1)"),
},
{
bind(err, "COMMIT"),
},
{
}
},
{
"NOW() used after replay",
{
bind(ok, "BEGIN"),
bind(ok, "SELECT 1"),
},
{
bind(ok, "SELECT NOW()"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Exceed transaction length limit",
{
bind(ok, "BEGIN"),
bind(ok,
"SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'"),
},
{
bind(err, "SELECT 7"),
bind(err, "COMMIT"),
},
{
}
},
{
"Normal trx after hitting limit",
{
bind(ok, "BEGIN"),
bind(ok,
"SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'"),
},
{
bind(err, "SELECT 8"),
bind(err, "COMMIT"),
},
{
bind(ok, "BEGIN"),
bind(ok, "SELECT 1"),
bind(ok, "SELECT 2"),
bind(ok, "COMMIT"),
}
},
{
"Session command inside transaction",
{
bind(ok, "BEGIN"),
bind(ok, "SET @a = 1"),
},
{
bind(check, "SELECT @a", "1"),
bind(ok, "COMMIT"),
},
{
}
},
{
"Empty transaction",
{
bind(ok, "BEGIN"),
},
{
bind(ok, "COMMIT"),
},
{
}
}
});
// Create a table for testing
test.maxscales->connect();
test.try_query(test.maxscales->conn_rwsplit[0], "CREATE OR REPLACE TABLE test.t1(id INT)");
test.maxscales->disconnect();
int i = 1;
for (auto& a : tests)
{
test.set_timeout(90);
test.tprintf("%d: %s", i++, a.description.c_str());
test.maxscales->connect();
for (auto& f : a.pre)
{
f();
}
// Block and unblock the master
test.repl->block_node(0);
test.maxscales->wait_for_monitor(2);
test.repl->unblock_node(0);
test.maxscales->wait_for_monitor(2);
for (auto& f : a.post)
{
f();
}
test.maxscales->disconnect();
test.repl->connect();
test.repl->sync_slaves();
test.repl->disconnect();
test.maxscales->connect();
for (auto& f : a.check)
{
f();
}
test.maxscales->disconnect();
// Clear the table at the end of the test
test.maxscales->connect();
test.try_query(test.maxscales->conn_rwsplit[0], "TRUNCATE TABLE test.t1");
test.maxscales->disconnect();
}
test.maxscales->connect();
test.try_query(test.maxscales->conn_rwsplit[0], "DROP TABLE test.t1");
test.maxscales->disconnect();
return test.global_result;
}