MXS-1461 Modify mock classes
This commit is contained in:
@ -59,6 +59,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool idle(const RouterSession* pSession) const = 0;
|
virtual bool idle(const RouterSession* pSession) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards an available response.
|
||||||
|
*
|
||||||
|
* @param pSession A router session.
|
||||||
|
*
|
||||||
|
* @return True if there are additional responses for the router session.
|
||||||
|
*/
|
||||||
|
virtual bool discard_one_response(const RouterSession* pSession) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards all available responses.
|
||||||
|
*
|
||||||
|
* @param pSession A router session.
|
||||||
|
*/
|
||||||
|
virtual void discard_all_responses(const RouterSession* pSession) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Backend();
|
Backend();
|
||||||
};
|
};
|
||||||
@ -79,6 +95,10 @@ public:
|
|||||||
|
|
||||||
bool idle(const RouterSession* pSession) const;
|
bool idle(const RouterSession* pSession) const;
|
||||||
|
|
||||||
|
bool discard_one_response(const RouterSession* pSession);
|
||||||
|
|
||||||
|
void discard_all_responses(const RouterSession* pSession);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BufferBackend();
|
BufferBackend();
|
||||||
|
|
||||||
@ -88,7 +108,10 @@ protected:
|
|||||||
* @param pSession The session to enqueue the response for.
|
* @param pSession The session to enqueue the response for.
|
||||||
* @param pResponse The response.
|
* @param pResponse The response.
|
||||||
*/
|
*/
|
||||||
void enqueue_response(RouterSession* pSession, GWBUF* pResponse);
|
void enqueue_response(const RouterSession* pSession, GWBUF* pResponse);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GWBUF* dequeue_response(const RouterSession* pSession, bool* pEmpty);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::deque<GWBUF*> Responses;
|
typedef std::deque<GWBUF*> Responses;
|
||||||
|
@ -31,18 +31,42 @@ class Dcb : public DCB
|
|||||||
Dcb& operator = (const Dcb&);
|
Dcb& operator = (const Dcb&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
class Handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int32_t write(GWBUF* pBuffer) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param pSession The session object of the DCB.
|
* @param pSession The session object of the DCB.
|
||||||
* @param zUser The client of the connection.
|
* @param zUser The client of the connection.
|
||||||
* @param zHost The host of the connection.
|
* @param zHost The host of the connection.
|
||||||
|
* @param pHandler Optional handler.
|
||||||
*/
|
*/
|
||||||
Dcb(MXS_SESSION* pSession,
|
Dcb(MXS_SESSION* pSession,
|
||||||
const char* zUser,
|
const char* zUser,
|
||||||
const char* zHost);
|
const char* zHost,
|
||||||
|
Handler* pHandler = NULL);
|
||||||
~Dcb();
|
~Dcb();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current handler of the Dcb.
|
||||||
|
*
|
||||||
|
* @return A Handler or NULL.
|
||||||
|
*/
|
||||||
|
Handler* handler() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current handler of the Dcb.
|
||||||
|
*
|
||||||
|
* @param pHandler The new handler.
|
||||||
|
*
|
||||||
|
* @return The previous handler or NULL.
|
||||||
|
*/
|
||||||
|
Handler* set_handler(Handler* pHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t write(GWBUF* pData);
|
int32_t write(GWBUF* pData);
|
||||||
|
|
||||||
@ -51,6 +75,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
std::string m_user;
|
std::string m_user;
|
||||||
std::string m_host;
|
std::string m_host;
|
||||||
|
Handler* m_pHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool idle() const;
|
bool idle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards one response.
|
||||||
|
*
|
||||||
|
* @return True, if there are additional responses.
|
||||||
|
*/
|
||||||
|
bool discard_one_response();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards all responses.
|
||||||
|
*/
|
||||||
|
void discard_all_responses();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement);
|
int32_t routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement);
|
||||||
|
|
||||||
|
@ -36,11 +36,13 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param zUser The client of the session,
|
* @param zUser The client of the session,
|
||||||
* @param zHost The host of the client.
|
* @param zHost The host of the client.
|
||||||
|
* @param pHandler Handler for the client Dcb.
|
||||||
*/
|
*/
|
||||||
Session(const char* zUser,
|
Session(const char* zUser,
|
||||||
const char* zHost = "127.0.0.1");
|
const char* zHost,
|
||||||
|
Dcb::Handler* pHandler = NULL);
|
||||||
~Session();
|
~Session();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <maxscale/filter.h>
|
#include <maxscale/filter.h>
|
||||||
#include "../filtermodule.hh"
|
#include "../filtermodule.hh"
|
||||||
|
#include "dcb.hh"
|
||||||
|
|
||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
@ -27,6 +28,7 @@ namespace mock
|
|||||||
* An instance of Upstream represents an upstream object of a filter.
|
* An instance of Upstream represents an upstream object of a filter.
|
||||||
*/
|
*/
|
||||||
class Upstream : public MXS_FILTER_SESSION
|
class Upstream : public MXS_FILTER_SESSION
|
||||||
|
, public Dcb::Handler
|
||||||
{
|
{
|
||||||
Upstream(const Upstream&);
|
Upstream(const Upstream&);
|
||||||
Upstream& operator = (const Upstream&);
|
Upstream& operator = (const Upstream&);
|
||||||
@ -47,7 +49,16 @@ public:
|
|||||||
*
|
*
|
||||||
* @return 1 if processing should continue, 0 otherwise.
|
* @return 1 if processing should continue, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
virtual int32_t clientReply(GWBUF* pResponse) = 0;
|
virtual int32_t backend_reply(GWBUF* pResponse) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a response is sent directly by a filter.
|
||||||
|
*
|
||||||
|
* @param pResponse The response packet.
|
||||||
|
*
|
||||||
|
* @return 1 if processing should continue, 0 otherwise.
|
||||||
|
*/
|
||||||
|
virtual int32_t maxscale_reply(GWBUF* pResponse) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when @reset is called on the @c Upstream instance.
|
* Called when @reset is called on the @c Upstream instance.
|
||||||
@ -98,6 +109,9 @@ private:
|
|||||||
|
|
||||||
static int32_t clientReply(MXS_FILTER* pInstance, MXS_FILTER_SESSION* pSession, GWBUF* pResponse);
|
static int32_t clientReply(MXS_FILTER* pInstance, MXS_FILTER_SESSION* pSession, GWBUF* pResponse);
|
||||||
|
|
||||||
|
// Dcb::Handler
|
||||||
|
int32_t write(GWBUF* pBuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MXS_FILTER m_instance;
|
MXS_FILTER m_instance;
|
||||||
Handler* m_pHandler;
|
Handler* m_pHandler;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "maxscale/mock/backend.hh"
|
#include "maxscale/mock/backend.hh"
|
||||||
|
#include <algorithm>
|
||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -48,24 +49,15 @@ BufferBackend::~BufferBackend()
|
|||||||
|
|
||||||
bool BufferBackend::respond(RouterSession* pSession)
|
bool BufferBackend::respond(RouterSession* pSession)
|
||||||
{
|
{
|
||||||
ss_dassert(!idle(pSession));
|
bool empty = false;
|
||||||
|
GWBUF* pResponse = dequeue_response(pSession, &empty);
|
||||||
|
|
||||||
bool rv = false;
|
if (pResponse)
|
||||||
|
|
||||||
if (!idle(pSession))
|
|
||||||
{
|
{
|
||||||
Responses& responses = m_session_responses[pSession];
|
|
||||||
ss_dassert(!responses.empty());
|
|
||||||
|
|
||||||
GWBUF* pResponse = responses.front();
|
|
||||||
responses.pop_front();
|
|
||||||
|
|
||||||
pSession->clientReply(pResponse);
|
pSession->clientReply(pResponse);
|
||||||
|
|
||||||
rv = !responses.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return !empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferBackend::idle(const RouterSession* pSession) const
|
bool BufferBackend::idle(const RouterSession* pSession) const
|
||||||
@ -83,13 +75,59 @@ bool BufferBackend::idle(const RouterSession* pSession) const
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferBackend::enqueue_response(RouterSession* pSession, GWBUF* pResponse)
|
bool BufferBackend::discard_one_response(const RouterSession* pSession)
|
||||||
|
{
|
||||||
|
bool empty = false;
|
||||||
|
gwbuf_free(dequeue_response(pSession, &empty));
|
||||||
|
|
||||||
|
return !empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferBackend::discard_all_responses(const RouterSession* pSession)
|
||||||
|
{
|
||||||
|
ss_dassert(!idle(pSession));
|
||||||
|
|
||||||
|
if (!idle(pSession))
|
||||||
|
{
|
||||||
|
Responses& responses = m_session_responses[pSession];
|
||||||
|
ss_dassert(!responses.empty());
|
||||||
|
|
||||||
|
std::for_each(responses.begin(), responses.end(), gwbuf_free);
|
||||||
|
responses.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferBackend::enqueue_response(const RouterSession* pSession, GWBUF* pResponse)
|
||||||
{
|
{
|
||||||
Responses& responses = m_session_responses[pSession];
|
Responses& responses = m_session_responses[pSession];
|
||||||
|
|
||||||
responses.push_back(pResponse);
|
responses.push_back(pResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GWBUF* BufferBackend::dequeue_response(const RouterSession* pSession, bool* pEmpty)
|
||||||
|
{
|
||||||
|
ss_dassert(!idle(pSession));
|
||||||
|
GWBUF* pResponse = NULL;
|
||||||
|
*pEmpty = true;
|
||||||
|
|
||||||
|
if (!idle(pSession))
|
||||||
|
{
|
||||||
|
Responses& responses = m_session_responses[pSession];
|
||||||
|
ss_dassert(!responses.empty());
|
||||||
|
|
||||||
|
if (!responses.empty())
|
||||||
|
{
|
||||||
|
pResponse = responses.front();
|
||||||
|
responses.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
*pEmpty = responses.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// OkBackend
|
// OkBackend
|
||||||
//
|
//
|
||||||
|
@ -37,9 +37,11 @@ namespace mock
|
|||||||
|
|
||||||
Dcb::Dcb(MXS_SESSION* pSession,
|
Dcb::Dcb(MXS_SESSION* pSession,
|
||||||
const char* zUser,
|
const char* zUser,
|
||||||
const char* zHost)
|
const char* zHost,
|
||||||
|
Handler* pHandler)
|
||||||
: m_user(zUser)
|
: m_user(zUser)
|
||||||
, m_host(zHost)
|
, m_host(zHost)
|
||||||
|
, m_pHandler(pHandler)
|
||||||
{
|
{
|
||||||
DCB* pDcb = this;
|
DCB* pDcb = this;
|
||||||
initialize_dcb(this);
|
initialize_dcb(this);
|
||||||
@ -55,11 +57,32 @@ Dcb::~Dcb()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dcb::Handler* Dcb::handler() const
|
||||||
|
{
|
||||||
|
return m_pHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dcb::Handler* Dcb::set_handler(Handler* pHandler)
|
||||||
|
{
|
||||||
|
Handler* p = m_pHandler;
|
||||||
|
m_pHandler = pHandler;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t Dcb::write(GWBUF* pData)
|
int32_t Dcb::write(GWBUF* pData)
|
||||||
{
|
{
|
||||||
// TODO: Should be routed somewhere
|
int32_t rv = 1;
|
||||||
gwbuf_free(pData);
|
|
||||||
return 1;
|
if (m_pHandler)
|
||||||
|
{
|
||||||
|
rv = m_pHandler->write(pData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gwbuf_free(pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
|
@ -52,6 +52,16 @@ bool RouterSession::idle() const
|
|||||||
return m_pBackend->idle(this);
|
return m_pBackend->idle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RouterSession::discard_one_response()
|
||||||
|
{
|
||||||
|
return m_pBackend->discard_one_response(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterSession::discard_all_responses()
|
||||||
|
{
|
||||||
|
return m_pBackend->discard_all_responses(this);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t RouterSession::routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement)
|
int32_t RouterSession::routeQuery(MXS_ROUTER* pInstance, GWBUF* pStatement)
|
||||||
{
|
{
|
||||||
ss_dassert(pInstance == &m_instance);
|
ss_dassert(pInstance == &m_instance);
|
||||||
|
@ -19,9 +19,10 @@ namespace maxscale
|
|||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
|
|
||||||
Session::Session(const char* zUser,
|
Session::Session(const char* zUser,
|
||||||
const char* zHost)
|
const char* zHost,
|
||||||
: m_client_dcb(this, zUser, zHost)
|
Dcb::Handler* pHandler)
|
||||||
|
: m_client_dcb(this, zUser, zHost, pHandler)
|
||||||
{
|
{
|
||||||
MXS_SESSION* pSession = this;
|
MXS_SESSION* pSession = this;
|
||||||
|
|
||||||
|
@ -67,13 +67,31 @@ void Upstream::set_as_upstream_on(FilterModule::Session& filter_session)
|
|||||||
|
|
||||||
int32_t Upstream::clientReply(GWBUF* pResponse)
|
int32_t Upstream::clientReply(GWBUF* pResponse)
|
||||||
{
|
{
|
||||||
int rv = 1;
|
int32_t rv = 1;
|
||||||
|
|
||||||
++m_n_responses;
|
++m_n_responses;
|
||||||
|
|
||||||
if (m_pHandler)
|
if (m_pHandler)
|
||||||
{
|
{
|
||||||
rv = m_pHandler->clientReply(pResponse);
|
rv = m_pHandler->backend_reply(pResponse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gwbuf_free(pResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Upstream::write(GWBUF* pResponse)
|
||||||
|
{
|
||||||
|
int32_t rv = 1;
|
||||||
|
|
||||||
|
++m_n_responses;
|
||||||
|
|
||||||
|
if (m_pHandler)
|
||||||
|
{
|
||||||
|
rv = m_pHandler->maxscale_reply(pResponse);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -136,7 +136,7 @@ int test(FilterModule::Session& filter_session,
|
|||||||
{
|
{
|
||||||
if (!router_session.idle()) // Statement reached backend
|
if (!router_session.idle()) // Statement reached backend
|
||||||
{
|
{
|
||||||
router_session.respond(); // To discard. TODO: Provide router_session.discard().
|
router_session.discard_one_response();
|
||||||
log_success(c);
|
log_success(c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -155,7 +155,7 @@ int test(FilterModule::Session& filter_session,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
router_session.respond();
|
router_session.discard_one_response();
|
||||||
log_error(c);
|
log_error(c);
|
||||||
rv = 1;
|
rv = 1;
|
||||||
}
|
}
|
||||||
@ -177,7 +177,8 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
|
|||||||
|
|
||||||
if (c.zStatement)
|
if (c.zStatement)
|
||||||
{
|
{
|
||||||
mock::Session session(c.zUser, c.zHost);
|
mock::Upstream upstream;
|
||||||
|
mock::Session session(c.zUser, c.zHost, &upstream);
|
||||||
|
|
||||||
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
auto_ptr<FilterModule::Session> sFilter_session = filter_instance.newSession(&session);
|
||||||
|
|
||||||
@ -185,8 +186,6 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
|
|||||||
{
|
{
|
||||||
router_session.set_as_downstream_on(sFilter_session.get());
|
router_session.set_as_downstream_on(sFilter_session.get());
|
||||||
|
|
||||||
mock::Upstream upstream;
|
|
||||||
|
|
||||||
upstream.set_as_upstream_on(*sFilter_session.get());
|
upstream.set_as_upstream_on(*sFilter_session.get());
|
||||||
|
|
||||||
rv += test(*sFilter_session.get(), router_session, c);
|
rv += test(*sFilter_session.get(), router_session, c);
|
||||||
|
Reference in New Issue
Block a user