Files
MaxScale/maxscale-system-test/long_test.cpp
Timofey Turenko 2440b48ccc Mxs 2236 own longtest (#189)
MXS-2236 Add own long test and possibility to run tests under Valgrind

Long test executes INSERT queries, transactions, prepared statements in parallel to create weird load on Maxscale to catch crashes and leaks

Test is not included into ctest scope. Test should be executed manually. For BuildBot (and also for run_test.sh) 'test_set' should be set 'NAME# ./long_test'

Time to run test is defined by 'long_test_time' variable (in seconds)

Possibility to run Maxscale under Valgrind is also added. To run Maxscale under Vaslgrind 'use_valgrind=yes' variable have to be defined
2019-02-22 16:12:57 +02:00

353 lines
9.9 KiB
C++

/**
* @file long_test.cpp Run different load for long long execution (long load test)
*
* time to execute test is defined by 'long_test_time' environmental variable
* e.g. 'long_test_time=3600 ./long_test'
*/
#include "testconnections.h"
#include "big_transaction.h"
typedef void * FUNC(void * ptr);
FUNC query_thread;
FUNC prepared_stmt_thread;
FUNC transaction_thread;
FUNC short_session_thread;
FUNC read_thread;
TestConnections * Test;
const int threads_type_num = 4;
int threads_num[threads_type_num];
const int max_threads_num = 32;
int port;
char * IP;
typedef struct
{
int id;
bool exit_flag;
char * sql;
} t_data;
t_data data[threads_type_num][max_threads_num];
int main(int argc, char *argv[])
{
Test = new TestConnections(argc, argv);
int i, j;
Test->tprintf("***************************************************\n"
"This is long running test to catch memory leaks and crashes\n"
"please define 'long_test_time' variable to set running time (seconds)\n"
"***************************************************\n");
pthread_t thread_id[threads_type_num][max_threads_num];
FUNC * thread[threads_type_num];
thread[0] = query_thread;
threads_num[0] = 1;
thread[1] = transaction_thread;
threads_num[1] = 1;
thread[2] = prepared_stmt_thread;
threads_num[2] = 1;
thread[3] = read_thread;
threads_num[3] = 1;
//thread[4] = short_session_thread;
//threads_num[4] = 4;
port = Test->maxscales->rwsplit_port[0];
IP = Test->maxscales->IP[0];
//port = 3306;
//IP = Test->repl->IP[0];
Test->set_timeout(60);
Test->tprintf("Set big maximums\n");
Test->repl->execute_query_all_nodes((char *) "set global max_connections = 300000;");
Test->repl->execute_query_all_nodes((char *) "set global max_connect_errors = 10000000;");
Test->repl->execute_query_all_nodes((char *) "set global expire_logs_days = 1;");
Test->maxscales->connect_rwsplit(0);
Test->repl->execute_query_all_nodes( (char *) "set global max_allowed_packet=100000000");
Test->tprintf("create t1 in `test` DB\n");
create_t1(Test->maxscales->conn_rwsplit[0]);
execute_query(Test->maxscales->conn_rwsplit[0], "DROP DATABASE test1");
execute_query(Test->maxscales->conn_rwsplit[0], "DROP DATABASE test2");
Test->tprintf("create`test1` DB\n");
Test->try_query(Test->maxscales->conn_rwsplit[0], "CREATE DATABASE test1");
Test->tprintf("create`test2` DB\n");
Test->try_query(Test->maxscales->conn_rwsplit[0], "CREATE DATABASE test2");
Test->tprintf("Waiting for slaves after DB creation\n");
Test->repl->sync_slaves(0);
//sleep(15);
Test->tprintf("...ok\n");
Test->tprintf("create t1 in `test1` DB\n");
Test->tprintf("... use\n");
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test1");
Test->tprintf("... create\n");
create_t1(Test->maxscales->conn_rwsplit[0]);
Test->tprintf("create t1 in `test2` DB\n");
Test->tprintf("... use\n");
Test->try_query(Test->maxscales->conn_rwsplit[0], "USE test2");
Test->tprintf("... create\n");
create_t1(Test->maxscales->conn_rwsplit[0]);
Test->tprintf("Waiting for slaves after tables creation\n");
Test->repl->sync_slaves(0);
Test->tprintf("...ok\n");
Test->set_timeout(60);
// Create threads
Test->tprintf("Starting threads\n");
for (j = 0; j < threads_type_num; j++)
{
for (i = 0; i < threads_num[j]; i++)
{
data[j][i].sql = (char*) malloc((i +1) * 32 * 14 + 32);
create_insert_string(data[j][i].sql, (i + 1) * 32 , i);
Test->tprintf("sqL %d: %d\n", i, strlen(data[j][i].sql));
data[j][i].exit_flag = false;
data[j][i].id = i;
pthread_create(&thread_id[j][i], NULL, thread[j], &data[j][i]);
}
}
Test->set_log_copy_interval(100);
Test->stop_timeout();
char * env = getenv("long_test_time");
int test_time = 0;
if (env != NULL)
{
sscanf(env, "%d", &test_time);
}
if (test_time <= 0)
{
test_time = 3600;
Test->tprintf("´long_test_time´ variable is not defined, set test_time to %d\n", test_time);
}
Test->tprintf("´test_time´ is %d\n", test_time);
sleep(test_time);
Test->set_timeout(180);
Test->tprintf("Stopping threads\n");
for (j = 0; j < threads_type_num; j++)
{
for (i = 0; i < threads_num[j]; i++)
{
data[j][i].exit_flag = true;
pthread_join(thread_id[j][i], NULL);
}
}
//Test->tprintf("Checking if MaxScale is still alive!\n");
//fflush(stdout);
//Test->check_maxscale_alive(0);
Test->maxscales->stop_maxscale(0);
int rval = Test->global_result;
delete Test;
return rval;
}
void try_and_reconnect(MYSQL * conn, char * db, char * sql)
{
if (execute_query(conn, sql))
{
Test->tprintf("reconnect");
mysql_close(conn);
conn = open_conn_db_timeout(port,
IP,
db,
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
}
}
void *query_thread(void *ptr )
{
MYSQL * conn;
t_data * data = (t_data *) ptr;
int inserts_until_optimize = 100000;
int tn = 0;
conn = open_conn_db_timeout(port,
IP,
(char *) "test",
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
while (!data->exit_flag)
{
//Test->try_query(conn, data->sql);
try_and_reconnect(conn, (char *) "test", data->sql);
if (tn >= inserts_until_optimize)
{
tn = 0;
Test->tprintf("Removing everything from table in the queries thread");
try_and_reconnect(conn, (char *) "test", (char *) "DELETE FROM t1");
Test->tprintf("Optimizing table in the queries thread");
try_and_reconnect(conn, (char *) "test", (char *) "OPTIMIZE TABLE t1");
}
tn++;
}
mysql_close(conn);
return NULL;
}
void *read_thread(void *ptr )
{
MYSQL * conn;
t_data * data = (t_data *) ptr;
int i = 0;
char sql[256];
conn = open_conn_db_timeout(port,
IP,
(char *) "test",
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
while (!data->exit_flag)
{
sprintf(sql, "SELECT * FROM t1 WHERE fl=%d", data->id);
try_and_reconnect(conn, (char *) "test", sql);
i++;
}
mysql_close(conn);
return NULL;
}
void *transaction_thread(void *ptr )
{
MYSQL * conn;
int transactions_until_optimize = 10;
int tn = 0;
t_data * data = (t_data *) ptr;
conn = open_conn_db_timeout(port,
IP,
(char *) "test1",
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
while (!data->exit_flag)
{
try_and_reconnect(conn, (char *) "test1", (char *) "START TRANSACTION");
try_and_reconnect(conn, (char *) "test1", (char *) "SET autocommit = 0");
int stmt_num = 200000 / strlen(data->sql);
for (int i = 0; i < stmt_num; i++)
{
try_and_reconnect(conn, (char *) "test1", data->sql);
}
Test->try_query(conn, (char *) "COMMIT");
if (tn >= transactions_until_optimize)
{
tn = 0;
Test->tprintf("Removing everything from table in the transactions thread");
try_and_reconnect(conn, (char *) "test1", (char *) "DELETE FROM t1");
Test->tprintf("Optimizing table in the transactions thread");
try_and_reconnect(conn, (char *) "test1", (char *) "OPTIMIZE TABLE t1");
}
tn++;
}
mysql_close(conn);
conn = open_conn_db_timeout(port,
IP,
(char *) "",
Test->maxscales->user_name,
Test->maxscales->password,
20,
Test->ssl);
Test->try_query(conn, "DROP DATABASE test1");
mysql_close(conn);
return NULL;
}
void *short_session_thread(void *ptr )
{
MYSQL * conn;
t_data * data = (t_data *) ptr;
while (!data->exit_flag)
{
conn = open_conn_db_timeout(port,
IP,
(char *) "test",
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
mysql_close(conn);
}
return NULL;
}
void *prepared_stmt_thread(void *ptr )
{
MYSQL * conn;
t_data * data = (t_data *) ptr;
char sql[256];
conn = open_conn_db_timeout(port,
IP,
(char *) "test2",
Test->repl->user_name,
Test->repl->password,
20,
Test->ssl);
while (!data->exit_flag)
{
sprintf(sql, "PREPARE stmt%d FROM 'SELECT * FROM t1 WHERE fl=@x;';", data->id);
try_and_reconnect(conn, (char *) "test2", sql);
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 3;");
sprintf(sql, "EXECUTE stmt%d", data->id);
try_and_reconnect(conn, (char *) "test2", sql);
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 4;");
try_and_reconnect(conn, (char *) "test2", sql);
try_and_reconnect(conn, (char *) "test2", (char *) "SET @x = 400;");
try_and_reconnect(conn, (char *) "test2", sql);
sprintf(sql, "DEALLOCATE PREPARE stmt%d", data->id);
try_and_reconnect(conn, (char *) "test2", sql);
}
mysql_close(conn);
conn = open_conn_db_timeout(port,
IP,
(char *) "",
Test->maxscales->user_name,
Test->maxscales->password,
20,
Test->ssl);
Test->try_query(conn, "DROP DATABASE test2");
mysql_close(conn);
return NULL;
}