MXS-1461 Add template Module
This is the first in a series of commits that introduce components that allow filters to be tested without MaxScale or backends. Obviously the environment is not suited for all cases, but allow e.g. the behaviour of the firewall filter to be tested in isolation. The environment consists of helper classes loading and manipulating modules and filters and mock-classes that provide the needed scaffolding around a filter. Currently all components exist under the test directory of the firewall filter, but once proven they can be moved to a more general purpose location.
This commit is contained in:
103
server/modules/filter/dbfwfilter/test/maxscale/module.hh
Normal file
103
server/modules/filter/dbfwfilter/test/maxscale/module.hh
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#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 <maxscale/cppdefs.hh>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace maxscale
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The template Module is an abstraction for a MaxScale module, to
|
||||||
|
* be used as the base class of a concrete module.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The template specialization Module<void> provides functionality common
|
||||||
|
* to all modules.
|
||||||
|
*/
|
||||||
|
template <>
|
||||||
|
class Module<void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Load a module with a specific name, assumed to be of a specific type.
|
||||||
|
*
|
||||||
|
* @param zFile_name The name of the module.
|
||||||
|
* @param zType_name The expected type of the module.
|
||||||
|
*
|
||||||
|
* @return The module object, if the module could be loaded, otherwise NULL.
|
||||||
|
*/
|
||||||
|
static void* load(const char *zFile_name, const char *zType_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform process initialization of all modules. Should be called only
|
||||||
|
* when all modules intended to be loaded have been loaded.
|
||||||
|
*
|
||||||
|
* @return True, if the process initialization succeeded.
|
||||||
|
*/
|
||||||
|
static bool process_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform process finalization of all modules.
|
||||||
|
*/
|
||||||
|
static void process_finish();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform thread initialization of all modules. Should be called only
|
||||||
|
* when all modules intended to be loaded have been loaded.
|
||||||
|
*
|
||||||
|
* @return True, if the thread initialization could be performed.
|
||||||
|
*/
|
||||||
|
static bool thread_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform thread finalization of all modules.
|
||||||
|
*/
|
||||||
|
static void thread_finish();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The template Module is intended to be derived from using the derived
|
||||||
|
* class as template argument.
|
||||||
|
*
|
||||||
|
* class XyzModule : public Module<XyzModule> { ... }
|
||||||
|
*
|
||||||
|
* @param zFile_name The name of the module.
|
||||||
|
*
|
||||||
|
* @return A module instance if the module could be loaded and it was of
|
||||||
|
* the expected type.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class Module
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::auto_ptr<T> load(const char* zFile_name)
|
||||||
|
{
|
||||||
|
std::auto_ptr<T> sT;
|
||||||
|
|
||||||
|
void* pApi = Module<void>::load(zFile_name, T::zName);
|
||||||
|
|
||||||
|
if (pApi)
|
||||||
|
{
|
||||||
|
sT.reset(new T(static_cast<typename T::type_t*>(pApi)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
146
server/modules/filter/dbfwfilter/test/module.cc
Normal file
146
server/modules/filter/dbfwfilter/test/module.cc
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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/module.hh"
|
||||||
|
#include "../../../../core/maxscale/modules.h"
|
||||||
|
|
||||||
|
namespace maxscale
|
||||||
|
{
|
||||||
|
|
||||||
|
//static
|
||||||
|
void* Module<void>::load(const char* zName, const char* zType)
|
||||||
|
{
|
||||||
|
return load_module(zName, zType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
bool Module<void>::process_init()
|
||||||
|
{
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
|
||||||
|
MXS_MODULE* module = NULL;
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
|
||||||
|
{
|
||||||
|
if (module->process_init)
|
||||||
|
{
|
||||||
|
int rc = (module->process_init)();
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
// If module is non-NULL it means that the initialization failed for
|
||||||
|
// that module. We now need to call finish on all modules that were
|
||||||
|
// successfully initialized.
|
||||||
|
MXS_MODULE* failed_module = module;
|
||||||
|
i = mxs_module_iterator_get(NULL);
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != failed_module)
|
||||||
|
{
|
||||||
|
if (module->process_finish)
|
||||||
|
{
|
||||||
|
(module->process_finish)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void Module<void>::process_finish()
|
||||||
|
{
|
||||||
|
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
|
||||||
|
MXS_MODULE* module = NULL;
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
|
||||||
|
{
|
||||||
|
if (module->process_finish)
|
||||||
|
{
|
||||||
|
(module->process_finish)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
bool Module<void>::thread_init()
|
||||||
|
{
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
|
||||||
|
MXS_MODULE* module = NULL;
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
|
||||||
|
{
|
||||||
|
if (module->thread_init)
|
||||||
|
{
|
||||||
|
int rc = (module->thread_init)();
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
// If module is non-NULL it means that the initialization failed for
|
||||||
|
// that module. We now need to call finish on all modules that were
|
||||||
|
// successfully initialized.
|
||||||
|
MXS_MODULE* failed_module = module;
|
||||||
|
i = mxs_module_iterator_get(NULL);
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != failed_module)
|
||||||
|
{
|
||||||
|
if (module->thread_finish)
|
||||||
|
{
|
||||||
|
(module->thread_finish)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void Module<void>::thread_finish()
|
||||||
|
{
|
||||||
|
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
|
||||||
|
MXS_MODULE* module = NULL;
|
||||||
|
|
||||||
|
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
|
||||||
|
{
|
||||||
|
if (module->thread_finish)
|
||||||
|
{
|
||||||
|
(module->thread_finish)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user