MXS-2196: Fix filter unit tests
Fixed the use of DCBs and sessions in the mock testing framework and adapted them to the changes done to the objects in question. Extended the testing utility functions to allow preloading modules as well as making it possible to only partially initialize the query classifier.
This commit is contained in:
@ -31,7 +31,18 @@
|
|||||||
#include "../internal/poll.hh"
|
#include "../internal/poll.hh"
|
||||||
#include "../internal/modules.hh"
|
#include "../internal/modules.hh"
|
||||||
|
|
||||||
void init_test_env(char* path)
|
void preload_module(const char* name, const char* path, const char* type)
|
||||||
|
{
|
||||||
|
std::string old_libdir = get_libdir();
|
||||||
|
std::string fullpath = TEST_DIR;
|
||||||
|
fullpath += "/";
|
||||||
|
fullpath += path;
|
||||||
|
set_libdir(MXS_STRDUP(fullpath.c_str()));
|
||||||
|
load_module(name, type);
|
||||||
|
set_libdir(MXS_STRDUP(old_libdir.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_test_env(char* __attribute((unused)) path = nullptr, uint32_t init_type = QC_INIT_BOTH)
|
||||||
{
|
{
|
||||||
config_get_global_options()->n_threads = 1;
|
config_get_global_options()->n_threads = 1;
|
||||||
|
|
||||||
@ -41,21 +52,19 @@ void init_test_env(char* path)
|
|||||||
}
|
}
|
||||||
atexit(mxs_log_finish);
|
atexit(mxs_log_finish);
|
||||||
dcb_global_init();
|
dcb_global_init();
|
||||||
|
std::string old_libdir = get_libdir();
|
||||||
set_libdir(MXS_STRDUP(TEST_DIR "/query_classifier/qc_sqlite/"));
|
set_libdir(MXS_STRDUP(TEST_DIR "/query_classifier/qc_sqlite/"));
|
||||||
qc_setup(NULL, QC_SQL_MODE_DEFAULT, NULL, NULL);
|
qc_setup(NULL, QC_SQL_MODE_DEFAULT, NULL, NULL);
|
||||||
qc_process_init(QC_INIT_BOTH);
|
qc_process_init(init_type);
|
||||||
poll_init();
|
poll_init();
|
||||||
maxbase::init();
|
maxbase::init();
|
||||||
maxscale::RoutingWorker::init();
|
maxscale::RoutingWorker::init();
|
||||||
hkinit();
|
hkinit();
|
||||||
set_libdir(MXS_STRDUP(TEST_DIR "/server/modules/protocol/MySQL/mariadbclient/"));
|
set_libdir(MXS_STRDUP(old_libdir.c_str()));
|
||||||
load_module("mariadbclient", MODULE_PROTOCOL);
|
|
||||||
set_libdir(MXS_STRDUP(TEST_DIR "/server/modules/routing/readconnroute/"));
|
preload_module("mariadbclient", "server/modules/protocol/MySQL/mariadbclient/", MODULE_PROTOCOL);
|
||||||
load_module("readconnroute", MODULE_ROUTER);
|
preload_module("readconnroute", "server/modules/routing/readconnroute/", MODULE_ROUTER);
|
||||||
set_libdir(MXS_STRDUP(TEST_DIR "/server/modules/routing/readwritesplit/"));
|
preload_module("mysqlauth", "/server/modules/authenticator/MySQLAuth/", MODULE_AUTHENTICATOR);
|
||||||
load_module("readwritesplit", MODULE_ROUTER);
|
|
||||||
set_libdir(MXS_STRDUP(TEST_DIR "/server/modules/authenticator/MySQLAuth/"));
|
|
||||||
load_module("mysqlauth", MODULE_AUTHENTICATOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include <maxscale/mock/session.hh>
|
#include <maxscale/mock/session.hh>
|
||||||
#include "../cachefilter.hh"
|
#include "../cachefilter.hh"
|
||||||
|
|
||||||
|
#include "../../../../core/test/test_utils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using maxscale::FilterModule;
|
using maxscale::FilterModule;
|
||||||
namespace mock = maxscale::mock;
|
namespace mock = maxscale::mock;
|
||||||
@ -286,11 +288,14 @@ int test(FilterModule::Instance& filter_instance, const TEST_CASE& tc)
|
|||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
mock::ResultSetBackend backend;
|
|
||||||
mock::RouterSession router_session(&backend);
|
|
||||||
|
|
||||||
|
auto service = service_alloc("service", "readconnroute", nullptr);
|
||||||
|
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
|
||||||
mock::Client client("bob", "127.0.0.1");
|
mock::Client client("bob", "127.0.0.1");
|
||||||
mock::Session session(&client);
|
mock::Session session(&client, listener);
|
||||||
|
mock::ResultSetBackend backend;
|
||||||
|
mock::RouterSession router_session(&backend, &session);
|
||||||
|
|
||||||
|
|
||||||
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
||||||
|
|
||||||
@ -419,30 +424,14 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
|
init_test_env(nullptr, QC_INIT_SELF);
|
||||||
{
|
preload_module("cache", "server/modules/filter/cache/", MODULE_FILTER);
|
||||||
if (qc_setup(NULL, QC_SQL_MODE_DEFAULT, "qc_sqlite", NULL))
|
|
||||||
{
|
|
||||||
if (qc_process_init(QC_INIT_SELF))
|
|
||||||
{
|
|
||||||
rv = run();
|
|
||||||
|
|
||||||
cout << rv << " failures." << endl;
|
rv = run();
|
||||||
|
|
||||||
qc_process_end(QC_INIT_SELF);
|
cout << rv << " failures." << endl;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cerr << "error: Could not initialize query classifier." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cerr << "error: Could not setup query classifier." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxs_log_finish();
|
qc_process_end(QC_INIT_SELF);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include <maxscale/mock/client.hh>
|
#include <maxscale/mock/client.hh>
|
||||||
#include "tempfile.hh"
|
#include "tempfile.hh"
|
||||||
|
|
||||||
|
#include "../../../../core/test/test_utils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using maxscale::FilterModule;
|
using maxscale::FilterModule;
|
||||||
using maxscale::QueryClassifierModule;
|
using maxscale::QueryClassifierModule;
|
||||||
@ -757,9 +759,6 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
|
|||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
mock::OkBackend backend;
|
|
||||||
mock::RouterSession router_session(&backend);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < N_MAX_CASES; ++i)
|
for (size_t i = 0; i < N_MAX_CASES; ++i)
|
||||||
{
|
{
|
||||||
const FW_TEST_CASE& c = t.cases[i];
|
const FW_TEST_CASE& c = t.cases[i];
|
||||||
@ -770,7 +769,11 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
|
|||||||
const char* zHost = c.zHost ? c.zHost : DEFAULT_HOST;
|
const char* zHost = c.zHost ? c.zHost : DEFAULT_HOST;
|
||||||
|
|
||||||
mock::Client client(zUser, zHost);
|
mock::Client client(zUser, zHost);
|
||||||
mock::Session session(&client);
|
auto service = service_alloc("service", "readconnroute", nullptr);
|
||||||
|
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
|
||||||
|
mock::Session session(&client, listener);
|
||||||
|
mock::OkBackend backend;
|
||||||
|
mock::RouterSession router_session(&backend, &session);
|
||||||
|
|
||||||
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
||||||
|
|
||||||
@ -991,30 +994,14 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_STDOUT))
|
init_test_env(nullptr, QC_INIT_SELF);
|
||||||
{
|
preload_module("dbfwfilter", "server/modules/filter/dbfwfilter/", MODULE_FILTER);
|
||||||
if (qc_setup(NULL, QC_SQL_MODE_DEFAULT, "qc_sqlite", NULL))
|
|
||||||
{
|
|
||||||
if (qc_process_init(QC_INIT_SELF))
|
|
||||||
{
|
|
||||||
rv = run();
|
|
||||||
|
|
||||||
cout << rv << " failures." << endl;
|
rv = run();
|
||||||
|
|
||||||
qc_process_end(QC_INIT_SELF);
|
cout << rv << " failures." << endl;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cerr << "error: Could not initialize query classifier." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cerr << "error: Could not setup query classifier." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxs_log_finish();
|
qc_process_end(QC_INIT_SELF);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <maxscale/router.hh>
|
#include <maxscale/router.hh>
|
||||||
|
#include <maxscale/session.hh>
|
||||||
#include "../filtermodule.hh"
|
#include "../filtermodule.hh"
|
||||||
#include "mock.hh"
|
#include "mock.hh"
|
||||||
|
#include "session.hh"
|
||||||
|
|
||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
@ -42,7 +44,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param pBackend The backend associated with the router.
|
* @param pBackend The backend associated with the router.
|
||||||
*/
|
*/
|
||||||
RouterSession(Backend* pBackend);
|
RouterSession(Backend* pBackend, maxscale::mock::Session* session);
|
||||||
~RouterSession();
|
~RouterSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,6 +92,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void discard_all_responses();
|
void discard_all_responses();
|
||||||
|
|
||||||
|
MXS_SESSION* session() const
|
||||||
|
{
|
||||||
|
return static_cast<MXS_SESSION*>(m_pSession);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement);
|
int32_t routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement);
|
||||||
|
|
||||||
@ -99,6 +106,8 @@ private:
|
|||||||
MXS_ROUTER m_instance;
|
MXS_ROUTER m_instance;
|
||||||
Backend* m_pBackend;
|
Backend* m_pBackend;
|
||||||
FilterModule::Session* m_pUpstream_filter_session;
|
FilterModule::Session* m_pUpstream_filter_session;
|
||||||
|
|
||||||
|
maxscale::mock::Session* m_pSession;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "mock.hh"
|
#include "mock.hh"
|
||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
|
#include <maxscale/listener.hh>
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
|
|
||||||
#include "../../../core/internal/session.hh"
|
#include "../../../core/internal/session.hh"
|
||||||
@ -42,7 +43,7 @@ public:
|
|||||||
* @param pClient The client of the session. Must remain valid for
|
* @param pClient The client of the session. Must remain valid for
|
||||||
* the lifetime of the Session.
|
* the lifetime of the Session.
|
||||||
*/
|
*/
|
||||||
Session(Client* pClient);
|
Session(Client* pClient, const SListener& listener);
|
||||||
~Session();
|
~Session();
|
||||||
|
|
||||||
Client& client() const;
|
Client& client() const;
|
||||||
|
@ -173,8 +173,8 @@ namespace
|
|||||||
class ResultSetDCB : public DCB
|
class ResultSetDCB : public DCB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResultSetDCB()
|
ResultSetDCB(MXS_SESSION* session)
|
||||||
: DCB(DCB_ROLE_CLIENT_HANDLER, nullptr)
|
: DCB(DCB_ROLE_CLIENT_HANDLER, session)
|
||||||
{
|
{
|
||||||
DCB* pDcb = this;
|
DCB* pDcb = this;
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ void ResultSetBackend::handle_statement(RouterSession* pSession, GWBUF* pStateme
|
|||||||
{
|
{
|
||||||
std::unique_ptr<ResultSet> set = ResultSet::create({"a"});
|
std::unique_ptr<ResultSet> set = ResultSet::create({"a"});
|
||||||
set->add_row({std::to_string(++m_counter)});
|
set->add_row({std::to_string(++m_counter)});
|
||||||
ResultSetDCB dcb;
|
ResultSetDCB dcb(pSession->session());
|
||||||
set->write(&dcb);
|
set->write(&dcb);
|
||||||
|
|
||||||
enqueue_response(pSession, dcb.create_response());
|
enqueue_response(pSession, dcb.create_response());
|
||||||
|
@ -34,7 +34,7 @@ Dcb::Dcb(MXS_SESSION* pSession,
|
|||||||
const char* zUser,
|
const char* zUser,
|
||||||
const char* zHost,
|
const char* zHost,
|
||||||
Handler* pHandler)
|
Handler* pHandler)
|
||||||
: DCB(DCB_ROLE_CLIENT_HANDLER, nullptr)
|
: DCB(DCB_ROLE_CLIENT_HANDLER, pSession)
|
||||||
, m_user(zUser)
|
, m_user(zUser)
|
||||||
, m_host(zHost)
|
, m_host(zHost)
|
||||||
, m_pHandler(pHandler)
|
, m_pHandler(pHandler)
|
||||||
@ -43,8 +43,8 @@ Dcb::Dcb(MXS_SESSION* pSession,
|
|||||||
initialize_dcb(this);
|
initialize_dcb(this);
|
||||||
|
|
||||||
pDcb->session = pSession;
|
pDcb->session = pSession;
|
||||||
pDcb->remote = const_cast<char*>(zHost);
|
pDcb->remote = MXS_STRDUP(zHost);
|
||||||
pDcb->user = const_cast<char*>(zUser);
|
pDcb->user = MXS_STRDUP(zUser);
|
||||||
|
|
||||||
pDcb->func.write = &Dcb::write;
|
pDcb->func.write = &Dcb::write;
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,9 @@ namespace maxscale
|
|||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
|
|
||||||
RouterSession::RouterSession(Backend* pBackend)
|
RouterSession::RouterSession(Backend* pBackend, maxscale::mock::Session* session)
|
||||||
: m_pBackend(pBackend)
|
: m_pBackend(pBackend)
|
||||||
|
, m_pSession(session)
|
||||||
{
|
{
|
||||||
memset(&m_instance, 0, sizeof(m_instance));
|
memset(&m_instance, 0, sizeof(m_instance));
|
||||||
}
|
}
|
||||||
|
@ -13,20 +13,14 @@
|
|||||||
|
|
||||||
#include "maxscale/mock/session.hh"
|
#include "maxscale/mock/session.hh"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
SERVICE dummy_service;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
|
|
||||||
Session::Session(Client* pClient)
|
Session::Session(Client* pClient, const SListener& listener)
|
||||||
: mxs::Session(nullptr)
|
: mxs::Session(listener)
|
||||||
, m_client(*pClient)
|
, m_client(*pClient)
|
||||||
, m_client_dcb(this, pClient->user(), pClient->host(), pClient)
|
, m_client_dcb(this, pClient->user(), pClient->host(), pClient)
|
||||||
{
|
{
|
||||||
@ -47,6 +41,8 @@ Session::Session(Client* pClient)
|
|||||||
|
|
||||||
Session::~Session()
|
Session::~Session()
|
||||||
{
|
{
|
||||||
|
// This prevents the protocol module from freeing the data
|
||||||
|
m_client_dcb.data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client& Session::client() const
|
Client& Session::client() const
|
||||||
|
Reference in New Issue
Block a user