From 70123e3faee7418104ea8229d611f8faded00f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 26 Jun 2017 13:30:11 +0300 Subject: [PATCH] MXS-852: Add binary protocol cursor test The test uses binary protocol prepared statements with cursors. The second part of the test will not pass as the test uses parallel execution of prepared statements. --- maxscale-system-test/CMakeLists.txt | 3 +- maxscale-system-test/binary_ps_cursor.cpp | 121 ++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 maxscale-system-test/binary_ps_cursor.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index efdf75c92..29acfa96c 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -344,8 +344,9 @@ add_test_executable(mxs280_select_outfile.cpp mxs280_select_outfile replication # Tries prepared stmt 'SELECT 1,1,1,1...." with different nu,ber of '1' add_test_executable(mxs314.cpp mxs314 galera LABELS MySQLProtocol LIGHT GALERA_BACKEND) -# Binary protocol prepared statement test +# Binary protocol prepared statement tests add_test_executable(binary_ps.cpp binary_ps replication LABELS readwritesplit LIGHT REPL_BACKEND) +add_test_executable(binary_ps_cursor.cpp binary_ps_cursor replication LABELS readwritesplit LIGHT REPL_BACKEND) # Creates and closes a lot of connections, checks that 'maxadmin list servers' shows 0 connections at the end add_test_executable(mxs321.cpp mxs321 replication LABELS maxscale REPL_BACKEND) diff --git a/maxscale-system-test/binary_ps_cursor.cpp b/maxscale-system-test/binary_ps_cursor.cpp new file mode 100644 index 000000000..4e6a41ba3 --- /dev/null +++ b/maxscale-system-test/binary_ps_cursor.cpp @@ -0,0 +1,121 @@ +/** + * Test that binary protocol cursors work as expected + */ +#include "testconnections.h" +#include + +using std::cout; +using std::endl; + +void test1(TestConnections& test) +{ + test.connect_maxscale(); + test.set_timeout(20); + + MYSQL_STMT* stmt = mysql_stmt_init(test.conn_rwsplit); + const char* query = "SELECT @@server_id"; + char buffer[100] = ""; + my_bool err = false; + my_bool isnull = false; + MYSQL_BIND bind[1] = {}; + + bind[0].buffer_length = sizeof(buffer); + bind[0].buffer = buffer; + bind[0].error = &err; + bind[0].is_null = &isnull; + + cout << "Prepare" << endl; + test.add_result(mysql_stmt_prepare(stmt, query, strlen(query)), "Failed to prepare"); + + unsigned long cursor_type= CURSOR_TYPE_READ_ONLY; + unsigned long rows=0; + test.add_result(mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type), "Failed to set attributes"); + test.add_result(mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, &rows), "Failed to set attributes"); + + cout << "Execute" << endl; + test.add_result(mysql_stmt_execute(stmt), "Failed to execute"); + cout << "Bind result" << endl; + test.add_result(mysql_stmt_bind_result(stmt, bind), "Failed to bind result"); + cout << "Fetch row" << endl; + test.add_result(mysql_stmt_fetch(stmt), "Failed to fetch result"); + + test.add_result(strlen(buffer) == 0, "Expected result buffer to not be empty"); + + cout << "Close statement" << endl; + mysql_stmt_close(stmt); + test.close_maxscale_connections(); + +} + +void test2(TestConnections& test) +{ + test.set_timeout(20); + + MYSQL* conn = open_conn_db_timeout(test.rwsplit_port, test.maxscale_ip(), "test", + test.maxscale_user, test.maxscale_password, 1, false); + + MYSQL_STMT* stmt1 = mysql_stmt_init(conn); + MYSQL_STMT* stmt2 = mysql_stmt_init(conn); + const char* query = "SELECT @@server_id"; + char buffer1[100] = ""; + char buffer2[100] = ""; + my_bool err = false; + my_bool isnull = false; + MYSQL_BIND bind1[1] = {}; + MYSQL_BIND bind2[1] = {}; + + bind1[0].buffer_length = sizeof(buffer1); + bind1[0].buffer = buffer1; + bind1[0].error = &err; + bind1[0].is_null = &isnull; + + bind2[0].buffer_length = sizeof(buffer2); + bind2[0].buffer = buffer2; + bind2[0].error = &err; + bind2[0].is_null = &isnull; + + cout << "Prepare" << endl; + test.add_result(mysql_stmt_prepare(stmt1, query, strlen(query)), "Failed to prepare"); + test.add_result(mysql_stmt_prepare(stmt2, query, strlen(query)), "Failed to prepare"); + + unsigned long cursor_type= CURSOR_TYPE_READ_ONLY; + unsigned long rows=0; + test.add_result(mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &cursor_type), "Failed to set attributes"); + test.add_result(mysql_stmt_attr_set(stmt1, STMT_ATTR_PREFETCH_ROWS, &rows), "Failed to set attributes"); + test.add_result(mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &cursor_type), "Failed to set attributes"); + test.add_result(mysql_stmt_attr_set(stmt2, STMT_ATTR_PREFETCH_ROWS, &rows), "Failed to set attributes"); + + cout << "Execute" << endl; + test.add_result(mysql_stmt_execute(stmt1), "Failed to execute"); + test.add_result(mysql_stmt_execute(stmt2), "Failed to execute"); + cout << "Bind result" << endl; + test.add_result(mysql_stmt_bind_result(stmt1, bind1), "Failed to bind result"); + test.add_result(mysql_stmt_bind_result(stmt2, bind2), "Failed to bind result"); + cout << "Fetch row" << endl; + int rc1 = mysql_stmt_fetch(stmt1); + int rc2 = mysql_stmt_fetch(stmt2); + test.add_result(rc1, "Failed to fetch result: %d %s %s", rc1, mysql_stmt_error(stmt1), mysql_error(conn)); + test.add_result(rc2, "Failed to fetch result: %d %s %s", rc2, mysql_stmt_error(stmt2), mysql_error(conn)); + + test.add_result(strlen(buffer1) == 0, "Expected result buffer 1 to not be empty"); + test.add_result(strlen(buffer2) == 0, "Expected result buffer 2 to not be empty"); + + cout << "Close statement" << endl; + mysql_stmt_close(stmt1); + mysql_stmt_close(stmt2); +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + + cout << "Test 1" << endl; + test1(test); + cout << "Done" << endl << endl; + + cout << "Test 2" << endl; + test2(test); + cout << "Done" << endl << endl; + + return test.global_result; +}