From de49797014ee4bc44e1a0b7099f18aa2ae300c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 19 Nov 2018 13:48:13 +0200 Subject: [PATCH] Rewrite bug561.sh in C++ Rewrote the bug561.sh test as the error_messages test that covers what was tested by the script as well as some new parts that were untested. This revealed a bug in the error messages where MaxScale always returns the database name in the error. --- maxscale-system-test/CMakeLists.txt | 2 +- maxscale-system-test/bug561.sh | 74 ---------------- maxscale-system-test/error_messages.cpp | 110 ++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 75 deletions(-) delete mode 100755 maxscale-system-test/bug561.sh create mode 100644 maxscale-system-test/error_messages.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index abbf16d86..794f7c7eb 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -102,7 +102,7 @@ add_test_executable(bug547.cpp bug547 replication LABELS readwritesplit REPL_BAC add_test_executable(bug681.cpp bug681 bug681 LABELS readwritesplit REPL_BACKEND) # Regression case for the bug ""Different error messages from MariaDB and Maxscale" -add_test_script(bug561.sh bug561.sh replication LABELS MySQLAuth REPL_BACKEND) +add_test_executable(error_messages.cpp error_messages replication LABELS MySQLAuth REPL_BACKEND) # Regression case for the bug "Wrong error message for Access denied error" add_test_script(bug562.sh bug562.sh replication LABELS MySQLAuth REPL_BACKEND) diff --git a/maxscale-system-test/bug561.sh b/maxscale-system-test/bug561.sh deleted file mode 100755 index b2136c4b4..000000000 --- a/maxscale-system-test/bug561.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash - -### -## @file bug561.sh Regression case for the bug "Different error messages from MariaDB and Maxscale" -## - try to connect to non existing DB directly to MariaDB server and via Maxscale -## - compare error messages -## - repeat for RWSplit, ReadConn - - -rp=`realpath $0` -export src_dir=`dirname $rp` -export test_dir=`pwd` -export test_name=`basename $rp` - -$test_dir/non_native_setup $test_name - -if [ $? -ne 0 ] ; then - echo "configuring maxscale failed" - exit 1 -fi -export ssl_options="--ssl-cert=$src_dir/ssl-cert/client-cert.pem --ssl-key=$src_dir/ssl-cert/client-key.pem" - -#echo "Waiting for 15 seconds" -#sleep 15 - -mariadb_err=`mysql -u$node_user -p$node_password -h $node_000_network $ssl_options --socket=$node_000_socket -P $node_000_port non_existing_db 2>&1` -maxscale_err=`mysql -u$node_user -p$node_password -h $maxscale_IP -P 4006 $ssl_options non_existing_db 2>&1` - -maxscale_err1=`mysql -u$node_user -p$node_password -h $maxscale_IP -P 4008 $ssl_options non_existing_db 2>&1` -maxscale_err2=`mysql -u$node_user -p$node_password -h $maxscale_IP -P 4009 $ssl_options non_existing_db 2>&1` - -echo "MariaDB message" -echo "$mariadb_err" -echo " " -echo "Maxscale message from RWSplit" -echo "$maxscale_err" -echo "Maxscale message from ReadConn master" -echo "$maxscale_err1" -echo "Maxscale message from ReadConn slave" -echo "$maxscale_err2" - -res=0 - -#echo "$maxscale_err" | grep "$mariadb_err" -if [ "$maxscale_err" != "$mariadb_err" ] ; then - echo "Messages are different!" - echo "MaxScale: $maxscale_err" - echo "Server: $mariadb_err" - res=1 -else - echo "Messages are same" -fi - -if [ "$maxscale_err1" != "$mariadb_err" ] ; then - echo "Messages are different!" - echo "MaxScale: $maxscale_err1" - echo "Server: $mariadb_err" - res=1 -else - echo "Messages are same" -fi - -if [ "$maxscale_err2" != "$mariadb_err" ] ; then - echo "Messages are different!" - echo "MaxScale: $maxscale_err2" - echo "Server: $mariadb_err" - - res=1 -else - echo "Messages are same" -fi - -$src_dir/copy_logs.sh bug561 -exit $res diff --git a/maxscale-system-test/error_messages.cpp b/maxscale-system-test/error_messages.cpp new file mode 100644 index 000000000..43f526d41 --- /dev/null +++ b/maxscale-system-test/error_messages.cpp @@ -0,0 +1,110 @@ +/** + * Regression case for the bug "Different error messages from MariaDB and Maxscale" + * + * - try to connect to non existing DB directly to MariaDB server and via Maxscale + * - compare error messages + * - repeat for RWSplit, ReadConn + */ + +#include "testconnections.h" +#include +#include + +using std::cout; +using std::endl; + +std::string remove_host(std::string str) +{ + auto start = std::find(str.begin(), str.end(), '@'); + if (start != str.end()) + { + start += 2; + auto end = std::find(start, str.end(), '\''); + if (end != str.end()) + { + str.erase(start, end); + } + } + + return str; +} + + +bool is_equal_error(MYSQL* direct, MYSQL* conn) +{ + bool rval = true; + std::string direct_err = remove_host(mysql_error(direct)); + std::string conn_err = remove_host(mysql_error(conn)); + + if (direct_err != conn_err) + { + rval = false; + cout << "Wrong error: `" << conn_err << "` (original: `" << direct_err << "`)" << endl; + } + + return rval; +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + + cout << "Non-existent database" << endl; + test.repl->connect(0, "non_existing_db"); + test.maxscales->connect(0, "non_existing_db"); + test.expect(is_equal_error(test.repl->nodes[0], test.maxscales->conn_rwsplit[0]), "readwritesplit returned wrong error"); + test.expect(is_equal_error(test.repl->nodes[0], test.maxscales->conn_master[0]), "readconnroute returned wrong error"); + test.repl->disconnect(); + test.maxscales->disconnect(); + + cout << "Non-existent user" << endl; + auto conn_direct = open_conn(test.repl->port[0], test.repl->IP[0], "not-a-user", "not-a-password", false); + auto conn_rwsplit = open_conn(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "not-a-user", "not-a-password", false); + auto conn_rconn = open_conn(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "not-a-user", "not-a-password", false); + + test.expect(is_equal_error(conn_direct, conn_rwsplit), "readwritesplit returned wrong error"); + test.expect(is_equal_error(conn_direct, conn_rconn), "readconnroute returned wrong error"); + + mysql_close(conn_direct); + mysql_close(conn_rwsplit); + mysql_close(conn_rconn); + + cout << "Wrong password" << endl; + conn_direct = open_conn(test.repl->port[0], test.repl->IP[0], "skysql", "not-a-password", false); + conn_rwsplit = open_conn(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "skysql", "not-a-password", false); + conn_rconn = open_conn(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "skysql", "not-a-password", false); + + test.expect(is_equal_error(conn_direct, conn_rwsplit), "readwritesplit returned wrong error"); + test.expect(is_equal_error(conn_direct, conn_rconn), "readconnroute returned wrong error"); + + mysql_close(conn_direct); + mysql_close(conn_rwsplit); + mysql_close(conn_rconn); + + // Create a database and a user without access to it + test.repl->connect(); + test.try_query(test.repl->nodes[0], "%s", "CREATE USER 'bob'@'%' IDENTIFIED BY 's3cret'"); + test.try_query(test.repl->nodes[0], "%s", "CREATE DATABASE error_messages"); + test.repl->sync_slaves(); + test.repl->disconnect(); + + cout << "No permissions on database" << endl; + conn_direct = open_conn_db(test.repl->port[0], test.repl->IP[0], "error_messages", "bob", "s3cret", false); + conn_rwsplit = open_conn_db(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "error_messages", "bob", "s3cret", false); + conn_rconn = open_conn_db(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "error_messages", "bob", "s3cret", false); + + test.expect(is_equal_error(conn_direct, conn_rwsplit), "readwritesplit returned wrong error"); + test.expect(is_equal_error(conn_direct, conn_rconn), "readconnroute returned wrong error"); + + mysql_close(conn_direct); + mysql_close(conn_rwsplit); + mysql_close(conn_rconn); + + // Create a database and a user without access to it + test.repl->connect(); + test.try_query(test.repl->nodes[0], "%s", "DROP USER 'bob'@'%'"); + test.try_query(test.repl->nodes[0], "%s", "DROP DATABASE error_messages"); + test.repl->disconnect(); + + return test.global_result; +}