Add smoke-test for qc_get_trx_type_mask_using
Use the query classifier test files and compare that the result returned by qc_sqlite and the custom parser agree for every statement.
This commit is contained in:
@ -13,6 +13,7 @@ add_executable(test_queuemanager testqueuemanager.c)
|
|||||||
add_executable(test_server testserver.c)
|
add_executable(test_server testserver.c)
|
||||||
add_executable(test_service testservice.c)
|
add_executable(test_service testservice.c)
|
||||||
add_executable(test_spinlock testspinlock.c)
|
add_executable(test_spinlock testspinlock.c)
|
||||||
|
add_executable(test_trxcompare testtrxcompare.cc ../../../query_classifier/test/testreader.cc)
|
||||||
add_executable(test_trxtracking testtrxtracking.cc)
|
add_executable(test_trxtracking testtrxtracking.cc)
|
||||||
add_executable(test_users testusers.c)
|
add_executable(test_users testusers.c)
|
||||||
add_executable(testfeedback testfeedback.c)
|
add_executable(testfeedback testfeedback.c)
|
||||||
@ -34,6 +35,7 @@ target_link_libraries(test_queuemanager maxscale-common)
|
|||||||
target_link_libraries(test_server maxscale-common)
|
target_link_libraries(test_server maxscale-common)
|
||||||
target_link_libraries(test_service maxscale-common)
|
target_link_libraries(test_service maxscale-common)
|
||||||
target_link_libraries(test_spinlock maxscale-common)
|
target_link_libraries(test_spinlock maxscale-common)
|
||||||
|
target_link_libraries(test_trxcompare maxscale-common)
|
||||||
target_link_libraries(test_trxtracking maxscale-common)
|
target_link_libraries(test_trxtracking maxscale-common)
|
||||||
target_link_libraries(test_users maxscale-common)
|
target_link_libraries(test_users maxscale-common)
|
||||||
target_link_libraries(testfeedback maxscale-common)
|
target_link_libraries(testfeedback maxscale-common)
|
||||||
@ -61,6 +63,15 @@ add_test(TestUsers test_users)
|
|||||||
add_test(TestModulecmd testmodulecmd)
|
add_test(TestModulecmd testmodulecmd)
|
||||||
add_test(TestConfig testconfig)
|
add_test(TestConfig testconfig)
|
||||||
add_test(TestTrxTracking test_trxtracking)
|
add_test(TestTrxTracking test_trxtracking)
|
||||||
|
add_test(TestTrxCompare_Create test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/create.test)
|
||||||
|
add_test(TestTrxCompare_Delete test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/delete.test)
|
||||||
|
add_test(TestTrxCompare_Insert test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/insert.test)
|
||||||
|
add_test(TestTrxCompare_Join test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/join.test)
|
||||||
|
add_test(TestTrxCompare_Select test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/select.test)
|
||||||
|
add_test(TestTrxCompare_Set test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/set.test)
|
||||||
|
add_test(TestTrxCompare_Update test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/update.test)
|
||||||
|
add_test(TestTrxCompare_MaxScale test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../../../query_classifier/test/maxscale.test)
|
||||||
|
|
||||||
|
|
||||||
# This test requires external dependencies and thus cannot be run
|
# This test requires external dependencies and thus cannot be run
|
||||||
# as a part of the core test set
|
# as a part of the core test set
|
||||||
|
237
server/core/test/testtrxcompare.cc
Normal file
237
server/core/test/testtrxcompare.cc
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* 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: 2019-07-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 <maxscale/cppdefs.hh>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include "../maxscale/query_classifier.h"
|
||||||
|
#include <maxscale/alloc.h>
|
||||||
|
#include <maxscale/paths.h>
|
||||||
|
#include <maxscale/protocol/mysql.h>
|
||||||
|
#include "../../../query_classifier/test/testreader.hh"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
char USAGE[] =
|
||||||
|
"test_trxcompare [-v] (-s stmt)|[file]"
|
||||||
|
"\n"
|
||||||
|
"-s test single statement\n"
|
||||||
|
"-v 0, only return code\n"
|
||||||
|
" 1, failed cases (default)\n"
|
||||||
|
" 2, successful transactional cases\n"
|
||||||
|
" 4, successful cases\n"
|
||||||
|
" 7, all cases\n";
|
||||||
|
|
||||||
|
enum verbosity_t
|
||||||
|
{
|
||||||
|
VERBOSITY_NOTHING = 0, // 000
|
||||||
|
VERBOSITY_FAILED = 1, // 001
|
||||||
|
VERBOSITY_SUCCESSFUL_TRANSACTIONAL = 2, // 010
|
||||||
|
VERBOSITY_SUCCESSFUL = 4, // 100
|
||||||
|
VERBOSITY_ALL = 7, // 111
|
||||||
|
};
|
||||||
|
|
||||||
|
GWBUF* create_gwbuf(const char* zStmt)
|
||||||
|
{
|
||||||
|
size_t len = strlen(zStmt);
|
||||||
|
size_t payload_len = len + 1;
|
||||||
|
size_t gwbuf_len = MYSQL_HEADER_LEN + payload_len;
|
||||||
|
|
||||||
|
GWBUF* pBuf = gwbuf_alloc(gwbuf_len);
|
||||||
|
|
||||||
|
*((unsigned char*)((char*)GWBUF_DATA(pBuf))) = payload_len;
|
||||||
|
*((unsigned char*)((char*)GWBUF_DATA(pBuf) + 1)) = (payload_len >> 8);
|
||||||
|
*((unsigned char*)((char*)GWBUF_DATA(pBuf) + 2)) = (payload_len >> 16);
|
||||||
|
*((unsigned char*)((char*)GWBUF_DATA(pBuf) + 3)) = 0x00;
|
||||||
|
*((unsigned char*)((char*)GWBUF_DATA(pBuf) + 4)) = 0x03;
|
||||||
|
memcpy((char*)GWBUF_DATA(pBuf) + 5, zStmt, len);
|
||||||
|
|
||||||
|
return pBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Tester
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Tester(uint32_t verbosity)
|
||||||
|
: m_verbosity(verbosity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int run(const char* zStmt)
|
||||||
|
{
|
||||||
|
int rc = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
GWBUF* pStmt = create_gwbuf(zStmt);
|
||||||
|
|
||||||
|
uint32_t type_mask_qc = qc_get_trx_type_mask_using(pStmt, QC_TRX_PARSE_USING_QC);
|
||||||
|
uint32_t type_mask_parser = qc_get_trx_type_mask_using(pStmt, QC_TRX_PARSE_USING_PARSER);
|
||||||
|
|
||||||
|
gwbuf_free(pStmt);
|
||||||
|
|
||||||
|
if (type_mask_qc == type_mask_parser)
|
||||||
|
{
|
||||||
|
if ((m_verbosity & VERBOSITY_SUCCESSFUL) ||
|
||||||
|
((m_verbosity & VERBOSITY_SUCCESSFUL_TRANSACTIONAL) && (type_mask_qc != 0)))
|
||||||
|
{
|
||||||
|
char* zType_mask = qc_typemask_to_string(type_mask_qc);
|
||||||
|
|
||||||
|
cout << zStmt << ": " << zType_mask << endl;
|
||||||
|
|
||||||
|
MXS_FREE(zType_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_verbosity & VERBOSITY_FAILED)
|
||||||
|
{
|
||||||
|
char* zType_mask_qc = qc_typemask_to_string(type_mask_qc);
|
||||||
|
char* zType_mask_parser = qc_typemask_to_string(type_mask_parser);
|
||||||
|
|
||||||
|
cout << zStmt << "\n"
|
||||||
|
<< " QC : " << zType_mask_qc << "\n"
|
||||||
|
<< " PARSER: " << zType_mask_parser << endl;
|
||||||
|
|
||||||
|
MXS_FREE(zType_mask_qc);
|
||||||
|
MXS_FREE(zType_mask_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run(istream& in)
|
||||||
|
{
|
||||||
|
int rc = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
maxscale::TestReader reader(in);
|
||||||
|
|
||||||
|
string stmt;
|
||||||
|
|
||||||
|
while (reader.get_statement(stmt) == maxscale::TestReader::RESULT_STMT)
|
||||||
|
{
|
||||||
|
if (run(stmt.c_str()) == EXIT_FAILURE)
|
||||||
|
{
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tester(const Tester&);
|
||||||
|
Tester& operator = (const Tester&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_verbosity;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int rc = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
int verbosity = VERBOSITY_FAILED;
|
||||||
|
const char* zStatement = NULL;
|
||||||
|
|
||||||
|
int c;
|
||||||
|
while ((c = getopt(argc, argv, "s:v:")) != -1)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
zStatement = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
verbosity = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rc == EXIT_SUCCESS) && (verbosity >= VERBOSITY_NOTHING) && (verbosity <= VERBOSITY_ALL))
|
||||||
|
{
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
|
||||||
|
set_datadir(strdup("/tmp"));
|
||||||
|
set_langdir(strdup("."));
|
||||||
|
set_process_datadir(strdup("/tmp"));
|
||||||
|
|
||||||
|
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
|
||||||
|
{
|
||||||
|
// We have to setup something in order for the regexes to be compiled.
|
||||||
|
if (qc_setup("qc_sqlite", NULL) && qc_process_init(QC_INIT_BOTH))
|
||||||
|
{
|
||||||
|
Tester tester(verbosity);
|
||||||
|
|
||||||
|
int n = argc - (optind - 1);
|
||||||
|
|
||||||
|
if (zStatement)
|
||||||
|
{
|
||||||
|
rc = tester.run(zStatement);
|
||||||
|
}
|
||||||
|
else if (n == 1)
|
||||||
|
{
|
||||||
|
rc = tester.run(cin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss_dassert(n == 2);
|
||||||
|
|
||||||
|
ifstream in(argv[argc - 1]);
|
||||||
|
|
||||||
|
if (in)
|
||||||
|
{
|
||||||
|
rc = tester.run(in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "error: Could not open " << argv[argc - 1] << "." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qc_process_end(QC_INIT_BOTH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "error: Could not initialize qc_sqlite." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
mxs_log_finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "error: Could not initialize log." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cout << USAGE << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
Reference in New Issue
Block a user