From 1edccba8858f7a856ed681700110930b8e542253 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 14 Nov 2017 14:23:06 +0200 Subject: [PATCH] MXS-1461 Add mock Backend class --- .../dbfwfilter/test/maxscale/mock/backend.hh | 117 +++++++++++++++++ .../filter/dbfwfilter/test/mock_backend.cc | 118 ++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 server/modules/filter/dbfwfilter/test/maxscale/mock/backend.hh create mode 100644 server/modules/filter/dbfwfilter/test/mock_backend.cc diff --git a/server/modules/filter/dbfwfilter/test/maxscale/mock/backend.hh b/server/modules/filter/dbfwfilter/test/maxscale/mock/backend.hh new file mode 100644 index 000000000..b0fea2a80 --- /dev/null +++ b/server/modules/filter/dbfwfilter/test/maxscale/mock/backend.hh @@ -0,0 +1,117 @@ +#pragma once +/* + * 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 +#include +#include "routersession.hh" + +namespace maxscale +{ + +namespace mock +{ + +/** + * The abstract class Backend represents a backend. + */ +class Backend +{ + Backend(const Backend&); + Backend& operator = (const Backend&); + +public: + virtual ~Backend(); + + /** + * Called to handle a statement from a "client". + * + * @param pSession The originating router session. + * @param pStatement A buffer containing a statement. + */ + virtual void handle_statement(RouterSession* pSession, GWBUF* pStatement) = 0; + + /** + * Called when the backend should respond to the client. + * + * @param pSession The router session to respond to. + * + * @return True, if the backend has additional responses to the router session. + */ + virtual bool respond(RouterSession* pSession) = 0; + + /** + * Whether the backend has a response for some router. + * + * @param pSession A router session. + * + * @return True if there are responses for the router session. + */ + virtual bool idle(const RouterSession* pSession) const = 0; + +protected: + Backend(); +}; + +/** + * The abstract class BufferBackend is a helper class for concrete + * backend classes. + */ +class BufferBackend : public Backend +{ + BufferBackend(const BufferBackend&); + BufferBackend& operator = (const BufferBackend&); + +public: + ~BufferBackend(); + + bool respond(RouterSession* pSession); + + bool idle(const RouterSession* pSession) const; + +protected: + BufferBackend(); + + /** + * Enqueues a response for a particular router session. + * + * @param pSession The session to enqueue the response for. + * @param pResponse The response. + */ + void enqueue_response(RouterSession* pSession, GWBUF* pResponse); + +private: + typedef std::deque Responses; + typedef std::map SessionResponses; + + SessionResponses m_session_responses; +}; + +/** + * The OkBackend is a concrete backend class that response with an + * OK packet to all statements. + */ +class OkBackend : public BufferBackend +{ + OkBackend(const OkBackend&); + OkBackend& operator = (const OkBackend&); + +public: + OkBackend(); + + void handle_statement(RouterSession* pSession, GWBUF* pStatement); +}; + +} + +} diff --git a/server/modules/filter/dbfwfilter/test/mock_backend.cc b/server/modules/filter/dbfwfilter/test/mock_backend.cc new file mode 100644 index 000000000..dd78d0402 --- /dev/null +++ b/server/modules/filter/dbfwfilter/test/mock_backend.cc @@ -0,0 +1,118 @@ +/* + * 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 "maxscale/mock/backend.hh" +#include +#include + +using namespace std; + +namespace maxscale +{ + +namespace mock +{ + +// +// Backend +// + +Backend::Backend() +{ +} + +Backend::~Backend() +{ +} + +// +// BufferBackend +// +BufferBackend::BufferBackend() +{ +} + +BufferBackend::~BufferBackend() +{ +} + +bool BufferBackend::respond(RouterSession* pSession) +{ + ss_dassert(!idle(pSession)); + + bool rv = false; + + if (!idle(pSession)) + { + Responses& responses = m_session_responses[pSession]; + ss_dassert(!responses.empty()); + + GWBUF* pResponse = responses.front(); + responses.pop_front(); + + pSession->clientReply(pResponse); + + rv = !responses.empty(); + } + + return rv; +} + +bool BufferBackend::idle(const RouterSession* pSession) const +{ + bool rv = true; + + SessionResponses::const_iterator i = m_session_responses.find(pSession); + ss_dassert(i != m_session_responses.end()); + + if (i != m_session_responses.end()) + { + const Responses& responses = i->second; + rv = responses.empty(); + } + + return rv; +} + +void BufferBackend::enqueue_response(RouterSession* pSession, GWBUF* pResponse) +{ + Responses& responses = m_session_responses[pSession]; + + responses.push_back(pResponse); +} + +// +// OkBackend +// + +OkBackend::OkBackend() +{ +} + +void OkBackend::handle_statement(RouterSession* pSession, GWBUF* pStatement) +{ + /* Note: sequence id is always 01 (4th byte) */ + const static uint8_t ok[MYSQL_OK_PACKET_MIN_LEN] = + { 07, 00, 00, 01, 00, 00, 00, 02, 00, 00, 00 }; + + GWBUF* pResponse = gwbuf_alloc_and_load(sizeof(ok), &ok); + ss_dassert(pResponse); + + enqueue_response(pSession, pResponse); + + gwbuf_free(pStatement); +} + +} // mock + +} // maxscale