diff --git a/query_classifier/test/CMakeLists.txt b/query_classifier/test/CMakeLists.txt index 1311ad572..a67ea4da6 100644 --- a/query_classifier/test/CMakeLists.txt +++ b/query_classifier/test/CMakeLists.txt @@ -22,6 +22,9 @@ if (BUILD_QC_MYSQLEMBEDDED) add_executable(compare compare.cc testreader.cc) target_link_libraries(compare maxscale-common) + add_executable(version_sensitivity version_sensitivity.cc) + target_link_libraries(version_sensitivity maxscale-common) + add_executable(crash_qc_sqlite crash_qc_sqlite.c) target_link_libraries(crash_qc_sqlite maxscale-common) @@ -39,6 +42,8 @@ if (BUILD_QC_MYSQLEMBEDDED) add_test(TestQC_CompareUpdate compare -v 2 ${CMAKE_CURRENT_SOURCE_DIR}/update.test) add_test(TestQC_CompareMaxScale compare -v 2 ${CMAKE_CURRENT_SOURCE_DIR}/maxscale.test) add_test(TestQC_CompareWhiteSpace compare -v 2 -S -s "select user from mysql.user; ") + + add_test(TestQC_version_sensitivity version_sensitivity) endif() add_subdirectory(canonical_tests) diff --git a/query_classifier/test/version_sensitivity.cc b/query_classifier/test/version_sensitivity.cc new file mode 100644 index 000000000..3e43963ad --- /dev/null +++ b/query_classifier/test/version_sensitivity.cc @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2020-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +#include +#define MYSQL_COM_QUIT COM_QUIT +#define MYSQL_COM_INIT_DB COM_INIT_DB +#define MYSQL_COM_CHANGE_USER COM_CHANGE_USER +#include +#include +#include +#include +#include + +using namespace std; + +namespace +{ + +GWBUF* create_gwbuf(const string& s) +{ + size_t len = s.length(); + size_t payload_len = len + 1; + size_t gwbuf_len = MYSQL_HEADER_LEN + payload_len; + + GWBUF* gwbuf = gwbuf_alloc(gwbuf_len); + + *((unsigned char*)((char*)GWBUF_DATA(gwbuf))) = payload_len; + *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 1)) = (payload_len >> 8); + *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 2)) = (payload_len >> 16); + *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 3)) = 0x00; + *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 4)) = 0x03; + memcpy((char*)GWBUF_DATA(gwbuf) + 5, s.c_str(), len); + + return gwbuf; +} + +} + +namespace +{ + +bool test(const string& s, uint32_t expected) +{ + GWBUF* pBuf = create_gwbuf(s); + + uint32_t type_mask = qc_get_type_mask(pBuf); + + gwbuf_free(pBuf); + + bool success = (type_mask == expected); + + if (!success) + { + cout << "error: " << s << " classified wrong." << endl; + } + + return success; +} + +int test() +{ + int rc = EXIT_SUCCESS; + + string valid_json("SELECT Json_Array(56, 3.1416, 'My name is \"Foo\"', NULL)"); + string invalid_json("SELECT Json_Foo(56, 3.1416, 'My name is \"Foo\"', NULL)"); + + SERVER_VERSION sv; + + // pre-Json + sv.major = 10; + sv.minor = 0; + sv.patch = 0; + + cout << "Testing pre-Json server." << endl; + + qc_set_server_version(server_encode_version(&sv)); + + if (!test(valid_json, QUERY_TYPE_READ | QUERY_TYPE_WRITE)) + { + rc = EXIT_FAILURE; + } + + if (!test(invalid_json, QUERY_TYPE_READ | QUERY_TYPE_WRITE)) + { + rc = EXIT_FAILURE; + } + + cout << "Testing post-Json server." << endl; + + // post-Json + sv.major = 10; + sv.minor = 2; + sv.patch = 3; + + qc_set_server_version(server_encode_version(&sv)); + + if (!test(valid_json, QUERY_TYPE_READ)) + { + rc = EXIT_FAILURE; + } + + if (!test(invalid_json, QUERY_TYPE_READ | QUERY_TYPE_WRITE)) + { + rc = EXIT_FAILURE; + } + + return rc; +} + +} + +int main(int argc, char* argv[]) +{ + int rc = EXIT_FAILURE; + + set_datadir(strdup("/tmp")); + set_langdir(strdup(".")); + set_process_datadir(strdup("/tmp")); + + if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) + { + const char QC_LIB[] = "qc_sqlite"; + const char LIBDIR[] = "../qc_sqlite"; + + set_libdir(strdup(LIBDIR)); + + if (qc_setup(QC_LIB, NULL)) + { + if (qc_process_init(QC_INIT_BOTH)) + { + rc = test(); + } + else + { + cerr << "error: Could not perform process initialization for " << QC_LIB << "." << endl; + } + } + else + { + cerr << "error: Could not setup " << QC_LIB << "." << endl; + } + + mxs_log_finish(); + } + else + { + cerr << "error: Could not initialize log." << endl; + } + + return rc; +}