mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 18:08:16 +00:00
[#3315] use internal IOService for hooks
This commit is contained in:
parent
4f935d2b86
commit
4398fb6c4a
@ -89,6 +89,7 @@ CtrlAgentProcess::run() {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
CtrlAgentProcess::runIO() {
|
CtrlAgentProcess::runIO() {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
size_t cnt = getIOService()->poll();
|
size_t cnt = getIOService()->poll();
|
||||||
if (!cnt) {
|
if (!cnt) {
|
||||||
cnt = getIOService()->runOne();
|
cnt = getIOService()->runOne();
|
||||||
@ -192,6 +193,17 @@ CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set,
|
|||||||
|
|
||||||
int rcode = 0;
|
int rcode = 0;
|
||||||
config::parseAnswer(rcode, answer);
|
config::parseAnswer(rcode, answer);
|
||||||
|
|
||||||
|
/// Let postponed hook initializations to run.
|
||||||
|
try {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::ostringstream err;
|
||||||
|
err << "Error initializing hooks: "
|
||||||
|
<< ex.what();
|
||||||
|
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||||
|
}
|
||||||
|
|
||||||
return (answer);
|
return (answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,12 +55,15 @@ to the end of this list.
|
|||||||
|
|
||||||
- @b Description: this callout is executed when the server has completed
|
- @b Description: this callout is executed when the server has completed
|
||||||
its (re)configuration. The server provides received and parsed configuration
|
its (re)configuration. The server provides received and parsed configuration
|
||||||
structures to the hook library. It also provides a pointer to the IOService
|
structures to the hook library.
|
||||||
object which is used by the server to run asynchronous operations. The hooks
|
If the library uses any IO operations, it should create a local IOService
|
||||||
libraries can use this IOService object to schedule asynchronous tasks which
|
object and register it to the main IOService which is also provided. This way
|
||||||
are triggered by the Kea DHCP DDNS's main loop. The hook library should hold
|
the local IOService is used by the server to run asynchronous operations. The
|
||||||
the provided pointer until the library is unloaded. The D2CfgContext
|
hooks library can use the local IOService object to schedule asynchronous
|
||||||
object provides access to the D2 running configuration.
|
tasks which are triggered by the D2 server's main loop. The hook library
|
||||||
|
should hold the provided pointer until the library is unloaded at which stage
|
||||||
|
it must unregister the local IOService.
|
||||||
|
The D2CfgContext object provides access to the D2 running configuration.
|
||||||
|
|
||||||
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
||||||
considers the configuration is incorrect and rejects it using the error
|
considers the configuration is incorrect and rejects it using the error
|
||||||
|
@ -129,6 +129,7 @@ D2Process::run() {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
D2Process::runIO() {
|
D2Process::runIO() {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
// We want to block until at least one handler is called. We'll use
|
// We want to block until at least one handler is called. We'll use
|
||||||
// boost::asio::io_service directly for two reasons. First off
|
// boost::asio::io_service directly for two reasons. First off
|
||||||
// asiolink::IOService::runOne is a void and boost::asio::io_service::stopped
|
// asiolink::IOService::runOne is a void and boost::asio::io_service::stopped
|
||||||
@ -148,7 +149,6 @@ D2Process::runIO() {
|
|||||||
// service is stopped it will return immediately with a cnt of zero.
|
// service is stopped it will return immediately with a cnt of zero.
|
||||||
cnt = getIOService()->runOne();
|
cnt = getIOService()->runOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (cnt);
|
return (cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +301,16 @@ D2Process::configure(isc::data::ConstElementPtr config_set, bool check_only) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Let postponed hook initializations to run.
|
||||||
|
try {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::ostringstream err;
|
||||||
|
err << "Error initializing hooks: "
|
||||||
|
<< ex.what();
|
||||||
|
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||||
|
}
|
||||||
|
|
||||||
// If we are here, configuration was valid, at least it parsed correctly
|
// If we are here, configuration was valid, at least it parsed correctly
|
||||||
// and therefore contained no invalid values.
|
// and therefore contained no invalid values.
|
||||||
// Return the success answer from above.
|
// Return the success answer from above.
|
||||||
|
@ -579,8 +579,7 @@ public:
|
|||||||
// We don't use SimpleParser::setListDefaults() as this does
|
// We don't use SimpleParser::setListDefaults() as this does
|
||||||
// not handle sub-lists or sub-maps
|
// not handle sub-lists or sub-maps
|
||||||
for (auto const& domain : config->listValue()) {
|
for (auto const& domain : config->listValue()) {
|
||||||
cnt += D2SimpleParser::
|
cnt += D2SimpleParser::setDdnsDomainDefaults(domain, D2SimpleParser::
|
||||||
setDdnsDomainDefaults(domain, D2SimpleParser::
|
|
||||||
DDNS_DOMAIN_DEFAULTS);
|
DDNS_DOMAIN_DEFAULTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +241,7 @@ ControlledDhcpv4Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
|
|||||||
HookLibsCollection loaded = HooksManager::getLibraryInfo();
|
HookLibsCollection loaded = HooksManager::getLibraryInfo();
|
||||||
HooksManager::prepareUnloadLibraries();
|
HooksManager::prepareUnloadLibraries();
|
||||||
static_cast<void>(HooksManager::unloadLibraries());
|
static_cast<void>(HooksManager::unloadLibraries());
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
bool multi_threading_enabled = true;
|
bool multi_threading_enabled = true;
|
||||||
uint32_t thread_count = 0;
|
uint32_t thread_count = 0;
|
||||||
uint32_t queue_size = 0;
|
uint32_t queue_size = 0;
|
||||||
@ -452,7 +453,7 @@ ControlledDhcpv4Srv::commandConfigSetHandler(const string&,
|
|||||||
|
|
||||||
/// Let postponed hook initializations to run.
|
/// Let postponed hook initializations to run.
|
||||||
try {
|
try {
|
||||||
getIOService()->poll();
|
getIOService()->pollExternalIOServices();
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
std::ostringstream err;
|
std::ostringstream err;
|
||||||
err << "Error initializing hooks: "
|
err << "Error initializing hooks: "
|
||||||
|
@ -55,13 +55,17 @@ to the end of this list.
|
|||||||
|
|
||||||
- @b Description: this callout is executed when the server has completed
|
- @b Description: this callout is executed when the server has completed
|
||||||
its (re)configuration. The server provides received and parsed configuration
|
its (re)configuration. The server provides received and parsed configuration
|
||||||
structures to the hook library. It also provides a pointer to the IOService
|
structures to the hook library.
|
||||||
object which is used by the server to run asynchronous operations. The hooks
|
If the library uses any IO operations, it should create a local IOService
|
||||||
libraries can use this IOService object to schedule asynchronous tasks which
|
object and register it to the main IOService which is also provided. This way
|
||||||
are triggered by the DHCP server's main loop. The hook library should hold the
|
the local IOService is used by the server to run asynchronous operations. The
|
||||||
provided pointer until the library is unloaded. The NetworkState object
|
hooks library can use the local IOService object to schedule asynchronous
|
||||||
provides access to the DHCP service state of the server and allows for
|
tasks which are triggered by the DHCP server's main loop. The hook library
|
||||||
enabling and disabling the DHCP service from the hooks libraries.
|
should hold the provided pointer until the library is unloaded at which stage
|
||||||
|
it must unregister the local IOService.
|
||||||
|
The NetworkState object provides access to the DHCP service state of the
|
||||||
|
server and allows for enabling and disabling the DHCP service from the hooks
|
||||||
|
libraries.
|
||||||
|
|
||||||
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
||||||
will interrupt the reconfiguration process. The hook callout is expected to
|
will interrupt the reconfiguration process. The hook callout is expected to
|
||||||
|
@ -706,6 +706,7 @@ Dhcpv4Srv::~Dhcpv4Srv() {
|
|||||||
}
|
}
|
||||||
LOG_ERROR(dhcp4_logger, DHCP4_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
LOG_ERROR(dhcp4_logger, DHCP4_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
||||||
}
|
}
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
io_service_->stop();
|
io_service_->stop();
|
||||||
io_service_->restart();
|
io_service_->restart();
|
||||||
try {
|
try {
|
||||||
@ -1132,6 +1133,7 @@ Dhcpv4Srv::run() {
|
|||||||
#endif // ENABLE_AFL
|
#endif // ENABLE_AFL
|
||||||
try {
|
try {
|
||||||
runOne();
|
runOne();
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
getIOService()->poll();
|
getIOService()->poll();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
// General catch-all exception that are not caught by more specific
|
// General catch-all exception that are not caught by more specific
|
||||||
|
@ -31,6 +31,9 @@ void start_service(void) {
|
|||||||
isc_throw(isc::Unexpected, "start service failed");
|
isc_throw(isc::Unexpected, "start service failed");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IOServicePtr io_service;
|
||||||
|
IOServicePtr main_io_service;
|
||||||
|
|
||||||
} // end anonymous
|
} // end anonymous
|
||||||
|
|
||||||
// Functions accessed by the hooks framework use C linkage to avoid the name
|
// Functions accessed by the hooks framework use C linkage to avoid the name
|
||||||
@ -40,6 +43,7 @@ extern "C" {
|
|||||||
|
|
||||||
int
|
int
|
||||||
do_load_impl(LibraryHandle& handle) {
|
do_load_impl(LibraryHandle& handle) {
|
||||||
|
io_service.reset(new IOService());
|
||||||
// Determine if this callout is configured to fail.
|
// Determine if this callout is configured to fail.
|
||||||
isc::dhcp::SrvConfigPtr config;
|
isc::dhcp::SrvConfigPtr config;
|
||||||
isc::data::ConstElementPtr const& parameters(handle.getParameters());
|
isc::data::ConstElementPtr const& parameters(handle.getParameters());
|
||||||
@ -51,9 +55,17 @@ do_load_impl(LibraryHandle& handle) {
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_unload_impl() {
|
||||||
|
if (main_io_service) {
|
||||||
|
main_io_service->unregisterExternalIOService(io_service);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int (*do_load)(LibraryHandle& handle) = do_load_impl;
|
int (*do_load)(LibraryHandle& handle) = do_load_impl;
|
||||||
|
|
||||||
int (*do_unload)();
|
int (*do_unload)() = do_unload_impl;
|
||||||
|
|
||||||
/// @brief Callout which appends library number and provided arguments to
|
/// @brief Callout which appends library number and provided arguments to
|
||||||
/// the marker file for dhcp4_srv_configured callout.
|
/// the marker file for dhcp4_srv_configured callout.
|
||||||
@ -79,13 +91,13 @@ dhcp4_srv_configured(CalloutHandle& handle) {
|
|||||||
|
|
||||||
// Get the IO context to post start_service on it.
|
// Get the IO context to post start_service on it.
|
||||||
std::string error("");
|
std::string error("");
|
||||||
IOServicePtr io_context;
|
|
||||||
try {
|
try {
|
||||||
handle.getArgument("io_context", io_context);
|
handle.getArgument("io_context", main_io_service);
|
||||||
if (!io_context) {
|
if (!main_io_service) {
|
||||||
error = "null io_context";
|
error = "null io_context";
|
||||||
}
|
}
|
||||||
io_context->post(start_service);
|
main_io_service->registerExternalIOService(io_service);
|
||||||
|
io_service->post(start_service);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
error = "no io_context in arguments";
|
error = "no io_context in arguments";
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,7 @@ ControlledDhcpv6Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
|
|||||||
HookLibsCollection loaded = HooksManager::getLibraryInfo();
|
HookLibsCollection loaded = HooksManager::getLibraryInfo();
|
||||||
HooksManager::prepareUnloadLibraries();
|
HooksManager::prepareUnloadLibraries();
|
||||||
static_cast<void>(HooksManager::unloadLibraries());
|
static_cast<void>(HooksManager::unloadLibraries());
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
bool multi_threading_enabled = true;
|
bool multi_threading_enabled = true;
|
||||||
uint32_t thread_count = 0;
|
uint32_t thread_count = 0;
|
||||||
uint32_t queue_size = 0;
|
uint32_t queue_size = 0;
|
||||||
@ -454,7 +455,7 @@ ControlledDhcpv6Srv::commandConfigSetHandler(const string&,
|
|||||||
|
|
||||||
/// Let postponed hook initializations to run.
|
/// Let postponed hook initializations to run.
|
||||||
try {
|
try {
|
||||||
getIOService()->poll();
|
getIOService()->pollExternalIOServices();
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
std::ostringstream err;
|
std::ostringstream err;
|
||||||
err << "Error initializing hooks: "
|
err << "Error initializing hooks: "
|
||||||
|
@ -55,14 +55,17 @@ to the end of this list.
|
|||||||
|
|
||||||
- @b Description: this callout is executed when the server has completed
|
- @b Description: this callout is executed when the server has completed
|
||||||
its (re)configuration. The server provides received and parsed configuration
|
its (re)configuration. The server provides received and parsed configuration
|
||||||
structures to the hook library. It also provides a pointer to the IOService
|
structures to the hook library.
|
||||||
object which is used by the server to run asynchronous operations. The hooks
|
If the library uses any IO operations, it should create a local IOService
|
||||||
libraries can use this IOService object to schedule asynchronous tasks which
|
object and register it to the main IOService which is also provided. This way
|
||||||
are triggered by the DHCP server's main loop. The hook library should hold the
|
the local IOService is used by the server to run asynchronous operations. The
|
||||||
provided pointer until the library is unloaded. The NetworkState object
|
hooks library can use the local IOService object to schedule asynchronous
|
||||||
provides access to the DHCP service state of the server and allows for
|
tasks which are triggered by the DHCP server's main loop. The hook library
|
||||||
enabling and disabling the DHCP service from the hooks libraries.
|
should hold the provided pointer until the library is unloaded at which stage
|
||||||
|
it must unregister the local IOService.
|
||||||
|
The NetworkState object provides access to the DHCP service state of the
|
||||||
|
server and allows for enabling and disabling the DHCP service from the hooks
|
||||||
|
libraries.
|
||||||
|
|
||||||
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
- <b>Next step status</b>: If any callout sets the status to DROP, the server
|
||||||
will interrupt the reconfiguration process. The hook callout is expected to
|
will interrupt the reconfiguration process. The hook callout is expected to
|
||||||
|
@ -302,6 +302,7 @@ Dhcpv6Srv::~Dhcpv6Srv() {
|
|||||||
}
|
}
|
||||||
LOG_ERROR(dhcp6_logger, DHCP6_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
LOG_ERROR(dhcp6_logger, DHCP6_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
||||||
}
|
}
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
io_service_->stop();
|
io_service_->stop();
|
||||||
io_service_->restart();
|
io_service_->restart();
|
||||||
try {
|
try {
|
||||||
@ -613,6 +614,7 @@ Dhcpv6Srv::run() {
|
|||||||
#endif // ENABLE_AFL
|
#endif // ENABLE_AFL
|
||||||
try {
|
try {
|
||||||
runOne();
|
runOne();
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
getIOService()->poll();
|
getIOService()->poll();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
// General catch-all standard exceptions that are not caught by more
|
// General catch-all standard exceptions that are not caught by more
|
||||||
|
@ -31,6 +31,9 @@ void start_service(void) {
|
|||||||
isc_throw(isc::Unexpected, "start service failed");
|
isc_throw(isc::Unexpected, "start service failed");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IOServicePtr io_service;
|
||||||
|
IOServicePtr main_io_service;
|
||||||
|
|
||||||
} // end anonymous
|
} // end anonymous
|
||||||
|
|
||||||
// Functions accessed by the hooks framework use C linkage to avoid the name
|
// Functions accessed by the hooks framework use C linkage to avoid the name
|
||||||
@ -40,6 +43,7 @@ extern "C" {
|
|||||||
|
|
||||||
int
|
int
|
||||||
do_load_impl(LibraryHandle& handle) {
|
do_load_impl(LibraryHandle& handle) {
|
||||||
|
io_service.reset(new IOService());
|
||||||
// Determine if this callout is configured to fail.
|
// Determine if this callout is configured to fail.
|
||||||
isc::dhcp::SrvConfigPtr config;
|
isc::dhcp::SrvConfigPtr config;
|
||||||
isc::data::ConstElementPtr const& parameters(handle.getParameters());
|
isc::data::ConstElementPtr const& parameters(handle.getParameters());
|
||||||
@ -51,9 +55,17 @@ do_load_impl(LibraryHandle& handle) {
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_unload_impl() {
|
||||||
|
if (main_io_service) {
|
||||||
|
main_io_service->unregisterExternalIOService(io_service);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int (*do_load)(LibraryHandle& handle) = do_load_impl;
|
int (*do_load)(LibraryHandle& handle) = do_load_impl;
|
||||||
|
|
||||||
int (*do_unload)();
|
int (*do_unload)() = do_unload_impl;
|
||||||
|
|
||||||
/// @brief Callout which appends library number and provided arguments to
|
/// @brief Callout which appends library number and provided arguments to
|
||||||
/// the marker file for dhcp6_srv_configured callout.
|
/// the marker file for dhcp6_srv_configured callout.
|
||||||
@ -79,13 +91,13 @@ dhcp6_srv_configured(CalloutHandle& handle) {
|
|||||||
|
|
||||||
// Get the IO context to post start_service on it.
|
// Get the IO context to post start_service on it.
|
||||||
std::string error("");
|
std::string error("");
|
||||||
IOServicePtr io_context;
|
|
||||||
try {
|
try {
|
||||||
handle.getArgument("io_context", io_context);
|
handle.getArgument("io_context", main_io_service);
|
||||||
if (!io_context) {
|
if (!main_io_service) {
|
||||||
error = "null io_context";
|
error = "null io_context";
|
||||||
}
|
}
|
||||||
io_context->post(start_service);
|
main_io_service->registerExternalIOService(io_service);
|
||||||
|
io_service->post(start_service);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
error = "no io_context in arguments";
|
error = "no io_context in arguments";
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ NetconfProcess::run() {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
NetconfProcess::runIO() {
|
NetconfProcess::runIO() {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
size_t cnt = getIOService()->poll();
|
size_t cnt = getIOService()->poll();
|
||||||
if (!cnt) {
|
if (!cnt) {
|
||||||
cnt = getIOService()->runOne();
|
cnt = getIOService()->runOne();
|
||||||
@ -85,6 +86,17 @@ NetconfProcess::configure(isc::data::ConstElementPtr config_set,
|
|||||||
getCfgMgr()->simpleParseConfig(config_set, check_only);
|
getCfgMgr()->simpleParseConfig(config_set, check_only);
|
||||||
int rcode = 0;
|
int rcode = 0;
|
||||||
config::parseAnswer(rcode, answer);
|
config::parseAnswer(rcode, answer);
|
||||||
|
|
||||||
|
/// Let postponed hook initializations to run.
|
||||||
|
try {
|
||||||
|
getIOService()->pollExternalIOServices();
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::ostringstream err;
|
||||||
|
err << "Error initializing hooks: "
|
||||||
|
<< ex.what();
|
||||||
|
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||||
|
}
|
||||||
|
|
||||||
return (answer);
|
return (answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -12,11 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <flex_option.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -142,6 +142,9 @@ have been introduced. These hook points are used by the DHCPv4 and the
|
|||||||
DHCPv6 servers respectively, to pass the instance of the IOService
|
DHCPv6 servers respectively, to pass the instance of the IOService
|
||||||
(via "io_context" argument) to the hooks libraries which require to
|
(via "io_context" argument) to the hooks libraries which require to
|
||||||
schedule asynchronous tasks.
|
schedule asynchronous tasks.
|
||||||
|
The hook's IOService object must be registered on the server's main IOService by
|
||||||
|
calling registerExternalIOService and must unregister it on "unload" hook point
|
||||||
|
by calling unregisterExternalIOService.
|
||||||
|
|
||||||
It is also worth to note that the blocking reception of the DHCP packets
|
It is also worth to note that the blocking reception of the DHCP packets
|
||||||
may cause up to 1 second delays in the asynchronous operations. This is
|
may cause up to 1 second delays in the asynchronous operations. This is
|
||||||
|
@ -46,9 +46,8 @@ extern "C" {
|
|||||||
/// @param handle callout handle.
|
/// @param handle callout handle.
|
||||||
int dhcp4_srv_configured(CalloutHandle& handle) {
|
int dhcp4_srv_configured(CalloutHandle& handle) {
|
||||||
try {
|
try {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", impl->getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!impl->getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
// Should not happen!
|
// Should not happen!
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
@ -57,7 +56,8 @@ int dhcp4_srv_configured(CalloutHandle& handle) {
|
|||||||
}
|
}
|
||||||
isc::dhcp::NetworkStatePtr network_state;
|
isc::dhcp::NetworkStatePtr network_state;
|
||||||
handle.getArgument("network_state", network_state);
|
handle.getArgument("network_state", network_state);
|
||||||
impl->startServices(io_service, network_state, HAServerType::DHCPv4);
|
impl->startServices(network_state, HAServerType::DHCPv4);
|
||||||
|
impl->getMainIOService()->registerExternalIOService(impl->getIOService());
|
||||||
|
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
LOG_ERROR(ha_logger, HA_DHCP4_START_SERVICE_FAILED)
|
LOG_ERROR(ha_logger, HA_DHCP4_START_SERVICE_FAILED)
|
||||||
@ -164,9 +164,8 @@ int lease4_server_decline(CalloutHandle& handle) {
|
|||||||
/// @param handle callout handle.
|
/// @param handle callout handle.
|
||||||
int dhcp6_srv_configured(CalloutHandle& handle) {
|
int dhcp6_srv_configured(CalloutHandle& handle) {
|
||||||
try {
|
try {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", impl->getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!impl->getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
// Should not happen!
|
// Should not happen!
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
@ -175,7 +174,8 @@ int dhcp6_srv_configured(CalloutHandle& handle) {
|
|||||||
}
|
}
|
||||||
isc::dhcp::NetworkStatePtr network_state;
|
isc::dhcp::NetworkStatePtr network_state;
|
||||||
handle.getArgument("network_state", network_state);
|
handle.getArgument("network_state", network_state);
|
||||||
impl->startServices(io_service, network_state, HAServerType::DHCPv6);
|
impl->startServices(network_state, HAServerType::DHCPv6);
|
||||||
|
impl->getMainIOService()->registerExternalIOService(impl->getIOService());
|
||||||
|
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
LOG_ERROR(ha_logger, HA_DHCP6_START_SERVICE_FAILED)
|
LOG_ERROR(ha_logger, HA_DHCP6_START_SERVICE_FAILED)
|
||||||
@ -442,6 +442,17 @@ int load(LibraryHandle& handle) {
|
|||||||
///
|
///
|
||||||
/// @return 0 if deregistration was successful, 1 otherwise
|
/// @return 0 if deregistration was successful, 1 otherwise
|
||||||
int unload() {
|
int unload() {
|
||||||
|
if (impl) {
|
||||||
|
if (impl->getMainIOService()) {
|
||||||
|
impl->getMainIOService()->unregisterExternalIOService(impl->getIOService());
|
||||||
|
}
|
||||||
|
impl->getIOService()->stop();
|
||||||
|
impl->getIOService()->restart();
|
||||||
|
try {
|
||||||
|
impl->getIOService()->poll();
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
impl.reset();
|
impl.reset();
|
||||||
LOG_INFO(ha_logger, HA_DEINIT_OK);
|
LOG_INFO(ha_logger, HA_DEINIT_OK);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -31,7 +31,7 @@ namespace isc {
|
|||||||
namespace ha {
|
namespace ha {
|
||||||
|
|
||||||
HAImpl::HAImpl()
|
HAImpl::HAImpl()
|
||||||
: config_(), services_(new HAServiceMapper()) {
|
: io_service_(new IOService()), config_(), services_(new HAServiceMapper()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -40,13 +40,12 @@ HAImpl::configure(const ConstElementPtr& input_config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HAImpl::startServices(const IOServicePtr& io_service,
|
HAImpl::startServices(const NetworkStatePtr& network_state,
|
||||||
const NetworkStatePtr& network_state,
|
|
||||||
const HAServerType& server_type) {
|
const HAServerType& server_type) {
|
||||||
auto configs = config_->getAll();
|
auto configs = config_->getAll();
|
||||||
for (auto id = 0; id < configs.size(); ++id) {
|
for (auto id = 0; id < configs.size(); ++id) {
|
||||||
// Create the HA service and crank up the state machine.
|
// Create the HA service and crank up the state machine.
|
||||||
auto service = boost::make_shared<HAService>(id, io_service, network_state,
|
auto service = boost::make_shared<HAService>(id, io_service_, network_state,
|
||||||
configs[id], server_type);
|
configs[id], server_type);
|
||||||
for (auto const& peer_config : configs[id]->getAllServersConfig()) {
|
for (auto const& peer_config : configs[id]->getAllServersConfig()) {
|
||||||
services_->map(peer_config.first, service);
|
services_->map(peer_config.first, service);
|
||||||
@ -54,7 +53,7 @@ HAImpl::startServices(const IOServicePtr& io_service,
|
|||||||
}
|
}
|
||||||
// Schedule a start of the services. This ensures we begin after
|
// Schedule a start of the services. This ensures we begin after
|
||||||
// the dust has settled and Kea MT mode has been firmly established.
|
// the dust has settled and Kea MT mode has been firmly established.
|
||||||
io_service->post([&]() {
|
io_service_->post([&]() {
|
||||||
for (auto const& service : services_->getAll()) {
|
for (auto const& service : services_->getAll()) {
|
||||||
service->startClientAndListener();
|
service->startClientAndListener();
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,11 @@ public:
|
|||||||
/// The caller must ensure that the HA configuration is valid before
|
/// The caller must ensure that the HA configuration is valid before
|
||||||
/// calling this function.
|
/// calling this function.
|
||||||
///
|
///
|
||||||
/// @param io_service IO service object provided by the DHCP server.
|
|
||||||
/// @param network_state pointer to the object holding a state of the
|
/// @param network_state pointer to the object holding a state of the
|
||||||
/// DHCP service (enabled/disabled).
|
/// DHCP service (enabled/disabled).
|
||||||
/// @param server_type DHCP server type for which the HA service should
|
/// @param server_type DHCP server type for which the HA service should
|
||||||
/// be created.
|
/// be created.
|
||||||
void startServices(const asiolink::IOServicePtr& io_service,
|
void startServices(const dhcp::NetworkStatePtr& network_state,
|
||||||
const dhcp::NetworkStatePtr& network_state,
|
|
||||||
const HAServerType& server_type);
|
const HAServerType& server_type);
|
||||||
|
|
||||||
/// @brief Destructor.
|
/// @brief Destructor.
|
||||||
@ -223,8 +221,42 @@ public:
|
|||||||
HAServicePtr getHAServiceByServerName(const std::string& command_name,
|
HAServicePtr getHAServiceByServerName(const std::string& command_name,
|
||||||
data::ConstElementPtr args) const;
|
data::ConstElementPtr args) const;
|
||||||
|
|
||||||
|
/// @brief Get the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @return the hook I/O service.
|
||||||
|
isc::asiolink::IOServicePtr& getIOService() {
|
||||||
|
return (io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the hook I/O service.
|
||||||
|
void setIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Get the main I/O service.
|
||||||
|
///
|
||||||
|
/// @return the main I/O service.
|
||||||
|
isc::asiolink::IOServicePtr& getMainIOService() {
|
||||||
|
return (main_io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the main I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the main I/O service.
|
||||||
|
void setMainIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
main_io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// @brief The hook I/O service.
|
||||||
|
isc::asiolink::IOServicePtr io_service_;
|
||||||
|
|
||||||
|
/// @brief The main I/O service.
|
||||||
|
isc::asiolink::IOServicePtr main_io_service_;
|
||||||
|
|
||||||
/// @brief Holds parsed configuration.
|
/// @brief Holds parsed configuration.
|
||||||
HAConfigMapperPtr config_;
|
HAConfigMapperPtr config_;
|
||||||
|
|
||||||
|
@ -12,11 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -127,11 +127,12 @@ public:
|
|||||||
const std::string& expected_response) {
|
const std::string& expected_response) {
|
||||||
io_service_.reset(new IOService());
|
io_service_.reset(new IOService());
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(ha_sync_command);
|
ConstElementPtr command = Element::fromJSON(ha_sync_command);
|
||||||
@ -174,13 +175,14 @@ public:
|
|||||||
TEST_F(HAImplTest, startServices) {
|
TEST_F(HAImplTest, startServices) {
|
||||||
// Valid configuration must be provided prior to starting the service.
|
// Valid configuration must be provided prior to starting the service.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Network state is also required.
|
// Network state is also required.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
|
|
||||||
// Start the service for DHCPv4 server.
|
// Start the service for DHCPv4 server.
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// Make sure that the HA service has been created for the requested
|
// Make sure that the HA service has been created for the requested
|
||||||
@ -193,13 +195,14 @@ TEST_F(HAImplTest, startServices) {
|
|||||||
TEST_F(HAImplTest, startServices6) {
|
TEST_F(HAImplTest, startServices6) {
|
||||||
// Valid configuration must be provided prior to starting the service.
|
// Valid configuration must be provided prior to starting the service.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Network state is also required.
|
// Network state is also required.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
|
|
||||||
// Start the service for DHCPv4 server.
|
// Start the service for DHCPv4 server.
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// Make sure that the HA service has been created for the requested
|
// Make sure that the HA service has been created for the requested
|
||||||
@ -216,11 +219,12 @@ TEST_F(HAImplTest, buffer4Receive) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// Initially the HA service is in the waiting state and serves no scopes.
|
// Initially the HA service is in the waiting state and serves no scopes.
|
||||||
@ -329,11 +333,12 @@ TEST_F(HAImplTest, subnet4Select) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -386,11 +391,12 @@ TEST_F(HAImplTest, subnet4SelectSharedNetwork) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -446,11 +452,12 @@ TEST_F(HAImplTest, subnet4SelectSingleRelationship) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// Create callout handle to be used for passing arguments to the
|
// Create callout handle to be used for passing arguments to the
|
||||||
@ -487,11 +494,12 @@ TEST_F(HAImplTest, subnet4SelectDropNoServerName) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -532,11 +540,12 @@ TEST_F(HAImplTest, subnet4SelectDropInvalidServerNameType) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -581,11 +590,12 @@ TEST_F(HAImplTest, subnet4SelectDropNotInScope) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// This server serves server1/server2 scopes but not server3/server4 scopes.
|
// This server serves server1/server2 scopes but not server3/server4 scopes.
|
||||||
@ -633,11 +643,12 @@ TEST_F(HAImplTest, subnet4SelectNoSubnet) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
test_ha_impl_->services_->get("server2")->serveFailoverScopes();
|
test_ha_impl_->services_->get("server2")->serveFailoverScopes();
|
||||||
@ -679,11 +690,12 @@ TEST_F(HAImplTest, buffer6Receive) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// Initially the HA service is in the waiting state and serves no scopes.
|
// Initially the HA service is in the waiting state and serves no scopes.
|
||||||
@ -769,11 +781,12 @@ TEST_F(HAImplTest, subnet6Select) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -823,11 +836,12 @@ TEST_F(HAImplTest, subnet6SelectSharedNetwork) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -883,11 +897,12 @@ TEST_F(HAImplTest, subnet6SelectSingleRelationship) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// Create callout handle to be used for passing arguments to the
|
// Create callout handle to be used for passing arguments to the
|
||||||
@ -924,11 +939,12 @@ TEST_F(HAImplTest, subnet6SelectDropNoServerName) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -969,11 +985,12 @@ TEST_F(HAImplTest, subnet6SelectDropInvalidServerNameType) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// The hub is a standby server and by default serves no scopes. Explicitly
|
// The hub is a standby server and by default serves no scopes. Explicitly
|
||||||
@ -1018,11 +1035,12 @@ TEST_F(HAImplTest, subnet6SelectDropNotInScope) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// This server serves server1/server2 scopes but not server3/server4 scopes.
|
// This server serves server1/server2 scopes but not server3/server4 scopes.
|
||||||
@ -1070,11 +1088,12 @@ TEST_F(HAImplTest, subnet6SelectNoSubnet) {
|
|||||||
|
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
ASSERT_NO_THROW(test_ha_impl_->configure(ha_config));
|
||||||
|
|
||||||
// Starting the service is required before any callouts.
|
// Starting the service is required before any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
test_ha_impl_->services_->get("server2")->serveFailoverScopes();
|
test_ha_impl_->services_->get("server2")->serveFailoverScopes();
|
||||||
@ -1112,11 +1131,12 @@ TEST_F(HAImplTest, subnet6SelectNoSubnet) {
|
|||||||
TEST_F(HAImplTest, leases4Committed) {
|
TEST_F(HAImplTest, leases4Committed) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// Make sure we wait for the acks from the backup server to be able to
|
// Make sure we wait for the acks from the backup server to be able to
|
||||||
@ -1198,11 +1218,12 @@ TEST_F(HAImplTest, leases4Committed) {
|
|||||||
TEST_F(HAImplTest, leases4CommittedMultipleRelationships) {
|
TEST_F(HAImplTest, leases4CommittedMultipleRelationships) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1254,11 +1275,12 @@ TEST_F(HAImplTest, leases4CommittedMultipleRelationships) {
|
|||||||
TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsNoServerName) {
|
TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsNoServerName) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1306,11 +1328,12 @@ TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsNoServerName) {
|
|||||||
TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsInvalidServerName) {
|
TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsInvalidServerName) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1360,11 +1383,12 @@ TEST_F(HAImplTest, leases4CommittedMultipleRelationshipsInvalidServerName) {
|
|||||||
TEST_F(HAImplTest, leases6Committed) {
|
TEST_F(HAImplTest, leases6Committed) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// Make sure we wait for the acks from the backup server to be able to
|
// Make sure we wait for the acks from the backup server to be able to
|
||||||
@ -1445,11 +1469,12 @@ TEST_F(HAImplTest, leases6Committed) {
|
|||||||
TEST_F(HAImplTest, leases6CommittedMultipleRelationships) {
|
TEST_F(HAImplTest, leases6CommittedMultipleRelationships) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1500,11 +1525,12 @@ TEST_F(HAImplTest, leases6CommittedMultipleRelationships) {
|
|||||||
TEST_F(HAImplTest, leases6CommittedMultipleRelationshipsNoServerName) {
|
TEST_F(HAImplTest, leases6CommittedMultipleRelationshipsNoServerName) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1551,11 +1577,12 @@ TEST_F(HAImplTest, leases6CommittedMultipleRelationshipsNoServerName) {
|
|||||||
TEST_F(HAImplTest, leases6CommittedMultipleRelationshipsInvalidServerName) {
|
TEST_F(HAImplTest, leases6CommittedMultipleRelationshipsInvalidServerName) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required before running any callouts.
|
// Starting the service is required before running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv6));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv6));
|
HAServerType::DHCPv6));
|
||||||
|
|
||||||
// By enabling this setting we ensure that the lease updates are always
|
// By enabling this setting we ensure that the lease updates are always
|
||||||
@ -1682,11 +1709,12 @@ TEST_F(HAImplTest, synchronizeHandler) {
|
|||||||
// Tests ha-continue command handler with a specified server name.
|
// Tests ha-continue command handler with a specified server name.
|
||||||
TEST_F(HAImplTest, continueHandler) {
|
TEST_F(HAImplTest, continueHandler) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON("{"
|
ConstElementPtr command = Element::fromJSON("{"
|
||||||
@ -1711,11 +1739,12 @@ TEST_F(HAImplTest, continueHandler) {
|
|||||||
// Tests ha-continue command handler without a server name.
|
// Tests ha-continue command handler without a server name.
|
||||||
TEST_F(HAImplTest, continueHandlerWithNoServerName) {
|
TEST_F(HAImplTest, continueHandlerWithNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON("{ \"command\": \"ha-continue\" }");
|
ConstElementPtr command = Element::fromJSON("{ \"command\": \"ha-continue\" }");
|
||||||
@ -1735,11 +1764,12 @@ TEST_F(HAImplTest, continueHandlerWithNoServerName) {
|
|||||||
// Tests ha-continue command handler with wrong server name.
|
// Tests ha-continue command handler with wrong server name.
|
||||||
TEST_F(HAImplTest, continueHandlerWithWrongServerName) {
|
TEST_F(HAImplTest, continueHandlerWithWrongServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON("{"
|
ConstElementPtr command = Element::fromJSON("{"
|
||||||
@ -1764,11 +1794,12 @@ TEST_F(HAImplTest, continueHandlerWithWrongServerName) {
|
|||||||
// Tests status-get command processed handler.
|
// Tests status-get command processed handler.
|
||||||
TEST_F(HAImplTest, statusGet) {
|
TEST_F(HAImplTest, statusGet) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
std::string name = "status-get";
|
std::string name = "status-get";
|
||||||
@ -1825,12 +1856,13 @@ TEST_F(HAImplTest, statusGet) {
|
|||||||
// Tests status-get command processed handler for backup server.
|
// Tests status-get command processed handler for backup server.
|
||||||
TEST_F(HAImplTest, statusGetBackupServer) {
|
TEST_F(HAImplTest, statusGetBackupServer) {
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
test_ha_impl_->config_->get()->setThisServerName("server3");
|
test_ha_impl_->config_->get()->setThisServerName("server3");
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
std::string name = "status-get";
|
std::string name = "status-get";
|
||||||
@ -1875,11 +1907,12 @@ TEST_F(HAImplTest, statusGetBackupServer) {
|
|||||||
// passive-backup state.
|
// passive-backup state.
|
||||||
TEST_F(HAImplTest, statusGetPassiveBackup) {
|
TEST_F(HAImplTest, statusGetPassiveBackup) {
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidPassiveBackupJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidPassiveBackupJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
std::string name = "status-get";
|
std::string name = "status-get";
|
||||||
@ -1924,11 +1957,12 @@ TEST_F(HAImplTest, statusGetPassiveBackup) {
|
|||||||
// hub-and-spoke mode.
|
// hub-and-spoke mode.
|
||||||
TEST_F(HAImplTest, statusGetHubAndSpoke) {
|
TEST_F(HAImplTest, statusGetHubAndSpoke) {
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidHubJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
std::string name = "status-get";
|
std::string name = "status-get";
|
||||||
@ -2009,11 +2043,12 @@ TEST_F(HAImplTest, statusGetHubAndSpoke) {
|
|||||||
// Test ha-maintenance-notify command handler with server name.
|
// Test ha-maintenance-notify command handler with server name.
|
||||||
TEST_F(HAImplTest, maintenanceNotify) {
|
TEST_F(HAImplTest, maintenanceNotify) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2041,11 +2076,12 @@ TEST_F(HAImplTest, maintenanceNotify) {
|
|||||||
// Test ha-maintenance-notify command handler without server name.
|
// Test ha-maintenance-notify command handler without server name.
|
||||||
TEST_F(HAImplTest, maintenanceNotifyNoServerName) {
|
TEST_F(HAImplTest, maintenanceNotifyNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2072,11 +2108,12 @@ TEST_F(HAImplTest, maintenanceNotifyNoServerName) {
|
|||||||
// Test ha-maintenance-notify command handler without server name.
|
// Test ha-maintenance-notify command handler without server name.
|
||||||
TEST_F(HAImplTest, maintenanceNotifyBadServerName) {
|
TEST_F(HAImplTest, maintenanceNotifyBadServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2104,11 +2141,12 @@ TEST_F(HAImplTest, maintenanceNotifyBadServerName) {
|
|||||||
// Test ha-reset command handler with a specified server name.
|
// Test ha-reset command handler with a specified server name.
|
||||||
TEST_F(HAImplTest, haReset) {
|
TEST_F(HAImplTest, haReset) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2135,11 +2173,12 @@ TEST_F(HAImplTest, haReset) {
|
|||||||
// Test ha-reset command handler without a specified server name.
|
// Test ha-reset command handler without a specified server name.
|
||||||
TEST_F(HAImplTest, haResetNoServerName) {
|
TEST_F(HAImplTest, haResetNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2163,11 +2202,12 @@ TEST_F(HAImplTest, haResetNoServerName) {
|
|||||||
// Test ha-reset command handler with a wrong server name.
|
// Test ha-reset command handler with a wrong server name.
|
||||||
TEST_F(HAImplTest, haResetBadServerName) {
|
TEST_F(HAImplTest, haResetBadServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2194,11 +2234,12 @@ TEST_F(HAImplTest, haResetBadServerName) {
|
|||||||
// Test ha-heartbeat command handler with a specified server name.
|
// Test ha-heartbeat command handler with a specified server name.
|
||||||
TEST_F(HAImplTest, haHeartbeat) {
|
TEST_F(HAImplTest, haHeartbeat) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2225,11 +2266,12 @@ TEST_F(HAImplTest, haHeartbeat) {
|
|||||||
// Test ha-heartbeat command handler without a specified server name.
|
// Test ha-heartbeat command handler without a specified server name.
|
||||||
TEST_F(HAImplTest, haHeartbeatNoServerName) {
|
TEST_F(HAImplTest, haHeartbeatNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2253,11 +2295,12 @@ TEST_F(HAImplTest, haHeartbeatNoServerName) {
|
|||||||
// Test ha-heartbeat command handler with a wrong server name.
|
// Test ha-heartbeat command handler with a wrong server name.
|
||||||
TEST_F(HAImplTest, haHeartbeatBadServerName) {
|
TEST_F(HAImplTest, haHeartbeatBadServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2284,11 +2327,12 @@ TEST_F(HAImplTest, haHeartbeatBadServerName) {
|
|||||||
// Test ha-sync-complete-notify command handler with a specified server name.
|
// Test ha-sync-complete-notify command handler with a specified server name.
|
||||||
TEST_F(HAImplTest, haSyncCompleteNotify) {
|
TEST_F(HAImplTest, haSyncCompleteNotify) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2316,11 +2360,12 @@ TEST_F(HAImplTest, haSyncCompleteNotify) {
|
|||||||
// Test ha-sync-complete-notify command handler without a specified server name.
|
// Test ha-sync-complete-notify command handler without a specified server name.
|
||||||
TEST_F(HAImplTest, haSyncCompleteNotifyNoServerName) {
|
TEST_F(HAImplTest, haSyncCompleteNotifyNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2345,11 +2390,12 @@ TEST_F(HAImplTest, haSyncCompleteNotifyNoServerName) {
|
|||||||
// Test ha-sync-complete-notify command handler with a wrong server name.
|
// Test ha-sync-complete-notify command handler with a wrong server name.
|
||||||
TEST_F(HAImplTest, haSyncCompleteNotifyBadServerName) {
|
TEST_F(HAImplTest, haSyncCompleteNotifyBadServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2376,11 +2422,12 @@ TEST_F(HAImplTest, haSyncCompleteNotifyBadServerName) {
|
|||||||
// Test ha-scopes command handler with a specified server name.
|
// Test ha-scopes command handler with a specified server name.
|
||||||
TEST_F(HAImplTest, haScopes) {
|
TEST_F(HAImplTest, haScopes) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2408,11 +2455,12 @@ TEST_F(HAImplTest, haScopes) {
|
|||||||
// Test ha-scopes command handler without a specified server name.
|
// Test ha-scopes command handler without a specified server name.
|
||||||
TEST_F(HAImplTest, haScopesNoServerName) {
|
TEST_F(HAImplTest, haScopesNoServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2439,11 +2487,12 @@ TEST_F(HAImplTest, haScopesNoServerName) {
|
|||||||
// Test ha-scopes command handler with a wrong server name.
|
// Test ha-scopes command handler with a wrong server name.
|
||||||
TEST_F(HAImplTest, haScopesBadServerName) {
|
TEST_F(HAImplTest, haScopesBadServerName) {
|
||||||
ha_impl_.reset(new HAImpl());
|
ha_impl_.reset(new HAImpl());
|
||||||
|
ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
ConstElementPtr command = Element::fromJSON(
|
ConstElementPtr command = Element::fromJSON(
|
||||||
@ -2472,11 +2521,12 @@ TEST_F(HAImplTest, haScopesBadServerName) {
|
|||||||
TEST_F(HAImplTest, lease4ServerDecline) {
|
TEST_F(HAImplTest, lease4ServerDecline) {
|
||||||
// Create implementation object and configure it.
|
// Create implementation object and configure it.
|
||||||
test_ha_impl_.reset(new TestHAImpl());
|
test_ha_impl_.reset(new TestHAImpl());
|
||||||
|
test_ha_impl_->setIOService(io_service_);
|
||||||
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
ASSERT_NO_THROW(test_ha_impl_->configure(createValidJsonConfiguration()));
|
||||||
|
|
||||||
// Starting the service is required prior to running any callouts.
|
// Starting the service is required prior to running any callouts.
|
||||||
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
NetworkStatePtr network_state(new NetworkState(NetworkState::DHCPv4));
|
||||||
ASSERT_NO_THROW(test_ha_impl_->startServices(io_service_, network_state,
|
ASSERT_NO_THROW(test_ha_impl_->startServices(network_state,
|
||||||
HAServerType::DHCPv4));
|
HAServerType::DHCPv4));
|
||||||
|
|
||||||
// Make sure we wait for the acks from the backup server to be able to
|
// Make sure we wait for the acks from the backup server to be able to
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using namespace isc::asiolink;
|
||||||
using namespace isc::cb;
|
using namespace isc::cb;
|
||||||
using namespace isc::dhcp;
|
using namespace isc::dhcp;
|
||||||
using namespace isc::hooks;
|
using namespace isc::hooks;
|
||||||
@ -67,15 +68,15 @@ int load(LibraryHandle& /* handle */) {
|
|||||||
/// @param handle callout handle passed to the callout.
|
/// @param handle callout handle passed to the callout.
|
||||||
/// @return 0 on success, 1 otherwise.
|
/// @return 0 on success, 1 otherwise.
|
||||||
int dhcp4_srv_configured(CalloutHandle& handle) {
|
int dhcp4_srv_configured(CalloutHandle& handle) {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", isc::dhcp::MySqlConfigBackendImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!isc::dhcp::MySqlConfigBackendImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
isc::dhcp::MySqlConfigBackendImpl::setIOService(io_service);
|
isc::dhcp::MySqlConfigBackendImpl::getIOService().reset(new IOService());
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getMainIOService()->registerExternalIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,15 +87,15 @@ int dhcp4_srv_configured(CalloutHandle& handle) {
|
|||||||
/// @param handle callout handle passed to the callout.
|
/// @param handle callout handle passed to the callout.
|
||||||
/// @return 0 on success, 1 otherwise.
|
/// @return 0 on success, 1 otherwise.
|
||||||
int dhcp6_srv_configured(CalloutHandle& handle) {
|
int dhcp6_srv_configured(CalloutHandle& handle) {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", isc::dhcp::MySqlConfigBackendImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!isc::dhcp::MySqlConfigBackendImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
isc::dhcp::MySqlConfigBackendImpl::setIOService(io_service);
|
isc::dhcp::MySqlConfigBackendImpl::getIOService().reset(new IOService());
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getMainIOService()->registerExternalIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,17 @@ int unload() {
|
|||||||
// Unregister the factories and remove MySQL backends
|
// Unregister the factories and remove MySQL backends
|
||||||
isc::dhcp::MySqlConfigBackendDHCPv4::unregisterBackendType();
|
isc::dhcp::MySqlConfigBackendDHCPv4::unregisterBackendType();
|
||||||
isc::dhcp::MySqlConfigBackendDHCPv6::unregisterBackendType();
|
isc::dhcp::MySqlConfigBackendDHCPv6::unregisterBackendType();
|
||||||
|
if (isc::dhcp::MySqlConfigBackendImpl::getMainIOService()) {
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getMainIOService()->unregisterExternalIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
|
||||||
|
}
|
||||||
|
if (isc::dhcp::MySqlConfigBackendImpl::getIOService()) {
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getIOService()->stop();
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getIOService()->restart();
|
||||||
|
try {
|
||||||
|
isc::dhcp::MySqlConfigBackendImpl::getIOService()->poll();
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ using namespace isc::util;
|
|||||||
namespace isc {
|
namespace isc {
|
||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
isc::asiolink::IOServicePtr MySqlConfigBackendImpl::io_service_ = isc::asiolink::IOServicePtr();
|
isc::asiolink::IOServicePtr MySqlConfigBackendImpl::io_service_;
|
||||||
|
isc::asiolink::IOServicePtr MySqlConfigBackendImpl::main_io_service_;
|
||||||
|
|
||||||
MySqlConfigBackendImpl::
|
MySqlConfigBackendImpl::
|
||||||
ScopedAuditRevision::ScopedAuditRevision(MySqlConfigBackendImpl* impl,
|
ScopedAuditRevision::ScopedAuditRevision(MySqlConfigBackendImpl* impl,
|
||||||
@ -86,6 +87,11 @@ MySqlConfigBackendImpl(const std::string& space,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MySqlConfigBackendImpl::~MySqlConfigBackendImpl() {
|
||||||
|
/// nothing to do there. The conn_ connection will be deleted and its dtor
|
||||||
|
/// will take care of releasing the compiled statements and similar.
|
||||||
|
}
|
||||||
|
|
||||||
MySqlBindingPtr
|
MySqlBindingPtr
|
||||||
MySqlConfigBackendImpl::createBinding(const Triplet<uint32_t>& triplet) {
|
MySqlConfigBackendImpl::createBinding(const Triplet<uint32_t>& triplet) {
|
||||||
if (triplet.unspecified()) {
|
if (triplet.unspecified()) {
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
const db::DbCallback db_reconnect_callback);
|
const db::DbCallback db_reconnect_callback);
|
||||||
|
|
||||||
/// @brief Destructor.
|
/// @brief Destructor.
|
||||||
virtual ~MySqlConfigBackendImpl() {};
|
virtual ~MySqlConfigBackendImpl();
|
||||||
|
|
||||||
/// @brief Creates MySQL binding from an @c Optional of integer type.
|
/// @brief Creates MySQL binding from an @c Optional of integer type.
|
||||||
///
|
///
|
||||||
@ -836,16 +836,32 @@ public:
|
|||||||
return (parameters_);
|
return (parameters_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Sets IO service to be used by the MySQL config backend.
|
/// @brief Get the hook I/O service.
|
||||||
///
|
///
|
||||||
/// @param IOService object, used for all ASIO operations.
|
/// @return the hook I/O service.
|
||||||
static void setIOService(const isc::asiolink::IOServicePtr& io_service) {
|
static isc::asiolink::IOServicePtr& getIOService() {
|
||||||
|
return (io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the hook I/O service.
|
||||||
|
static void setIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
io_service_ = io_service;
|
io_service_ = io_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Returns pointer to the IO service.
|
/// @brief Get the main I/O service.
|
||||||
static isc::asiolink::IOServicePtr& getIOService() {
|
///
|
||||||
return (io_service_);
|
/// @return the main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr& getMainIOService() {
|
||||||
|
return (main_io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the main I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the main I/O service.
|
||||||
|
static void setMainIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
main_io_service_ = io_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Represents connection to the MySQL database.
|
/// @brief Represents connection to the MySQL database.
|
||||||
@ -864,8 +880,11 @@ private:
|
|||||||
/// @brief Connection parameters
|
/// @brief Connection parameters
|
||||||
isc::db::DatabaseConnection::ParameterMap parameters_;
|
isc::db::DatabaseConnection::ParameterMap parameters_;
|
||||||
|
|
||||||
/// @brief The IOService object, used for all ASIO operations.
|
/// @brief The hook I/O service.
|
||||||
static isc::asiolink::IOServicePtr io_service_;
|
static isc::asiolink::IOServicePtr io_service_;
|
||||||
|
|
||||||
|
/// @brief The main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr main_io_service_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace isc::dhcp
|
} // end of namespace isc::dhcp
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using namespace isc::asiolink;
|
||||||
using namespace isc::cb;
|
using namespace isc::cb;
|
||||||
using namespace isc::dhcp;
|
using namespace isc::dhcp;
|
||||||
using namespace isc::hooks;
|
using namespace isc::hooks;
|
||||||
@ -67,15 +68,15 @@ int load(LibraryHandle& /* handle */) {
|
|||||||
/// @param handle callout handle passed to the callout.
|
/// @param handle callout handle passed to the callout.
|
||||||
/// @return 0 on success, 1 otherwise.
|
/// @return 0 on success, 1 otherwise.
|
||||||
int dhcp4_srv_configured(CalloutHandle& handle) {
|
int dhcp4_srv_configured(CalloutHandle& handle) {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", isc::dhcp::PgSqlConfigBackendImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
isc::dhcp::PgSqlConfigBackendImpl::setIOService(io_service);
|
isc::dhcp::PgSqlConfigBackendImpl::getIOService().reset(new IOService());
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()->registerExternalIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,15 +87,15 @@ int dhcp4_srv_configured(CalloutHandle& handle) {
|
|||||||
/// @param handle callout handle passed to the callout.
|
/// @param handle callout handle passed to the callout.
|
||||||
/// @return 0 on success, 1 otherwise.
|
/// @return 0 on success, 1 otherwise.
|
||||||
int dhcp6_srv_configured(CalloutHandle& handle) {
|
int dhcp6_srv_configured(CalloutHandle& handle) {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", isc::dhcp::PgSqlConfigBackendImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
isc::dhcp::PgSqlConfigBackendImpl::setIOService(io_service);
|
isc::dhcp::PgSqlConfigBackendImpl::getIOService().reset(new IOService());
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()->registerExternalIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,17 @@ int unload() {
|
|||||||
// Unregister the factories and remove PostgreSQL backends
|
// Unregister the factories and remove PostgreSQL backends
|
||||||
isc::dhcp::PgSqlConfigBackendDHCPv4::unregisterBackendType();
|
isc::dhcp::PgSqlConfigBackendDHCPv4::unregisterBackendType();
|
||||||
isc::dhcp::PgSqlConfigBackendDHCPv6::unregisterBackendType();
|
isc::dhcp::PgSqlConfigBackendDHCPv6::unregisterBackendType();
|
||||||
|
if (isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()) {
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getMainIOService()->unregisterExternalIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
|
||||||
|
}
|
||||||
|
if (isc::dhcp::PgSqlConfigBackendImpl::getIOService()) {
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getIOService()->stop();
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getIOService()->restart();
|
||||||
|
try {
|
||||||
|
isc::dhcp::PgSqlConfigBackendImpl::getIOService()->poll();
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@ using namespace isc::util;
|
|||||||
namespace isc {
|
namespace isc {
|
||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
isc::asiolink::IOServicePtr PgSqlConfigBackendImpl::io_service_ = isc::asiolink::IOServicePtr();
|
isc::asiolink::IOServicePtr PgSqlConfigBackendImpl::io_service_;
|
||||||
|
isc::asiolink::IOServicePtr PgSqlConfigBackendImpl::main_io_service_;
|
||||||
|
|
||||||
PgSqlTaggedStatement&
|
PgSqlTaggedStatement&
|
||||||
PgSqlConfigBackendImpl::getStatement(size_t /* index */) const {
|
PgSqlConfigBackendImpl::getStatement(size_t /* index */) const {
|
||||||
|
@ -800,18 +800,6 @@ public:
|
|||||||
return (parameters_);
|
return (parameters_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Sets IO service to be used by the PostgreSQL config backend.
|
|
||||||
///
|
|
||||||
/// @param IOService object, used for all ASIO operations.
|
|
||||||
static void setIOService(const isc::asiolink::IOServicePtr& io_service) {
|
|
||||||
io_service_ = io_service;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Returns pointer to the IO service.
|
|
||||||
static isc::asiolink::IOServicePtr& getIOService() {
|
|
||||||
return (io_service_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Fetches the SQL statement for a given statement index.
|
/// @brief Fetches the SQL statement for a given statement index.
|
||||||
///
|
///
|
||||||
/// Derivations must override the implementation. The reference
|
/// Derivations must override the implementation. The reference
|
||||||
@ -872,6 +860,34 @@ public:
|
|||||||
/// @return Number of affected rows.
|
/// @return Number of affected rows.
|
||||||
uint64_t updateDeleteQuery(size_t index, const db::PsqlBindArray& in_bindings);
|
uint64_t updateDeleteQuery(size_t index, const db::PsqlBindArray& in_bindings);
|
||||||
|
|
||||||
|
/// @brief Get the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @return the hook I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr& getIOService() {
|
||||||
|
return (io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the hook I/O service.
|
||||||
|
static void setIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Get the main I/O service.
|
||||||
|
///
|
||||||
|
/// @return the main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr& getMainIOService() {
|
||||||
|
return (main_io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the main I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the main I/O service.
|
||||||
|
static void setMainIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
main_io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Represents connection to the PostgreSQL database.
|
/// @brief Represents connection to the PostgreSQL database.
|
||||||
db::PgSqlConnection conn_;
|
db::PgSqlConnection conn_;
|
||||||
|
|
||||||
@ -888,9 +904,12 @@ private:
|
|||||||
/// @brief Connection parameters
|
/// @brief Connection parameters
|
||||||
isc::db::DatabaseConnection::ParameterMap parameters_;
|
isc::db::DatabaseConnection::ParameterMap parameters_;
|
||||||
|
|
||||||
/// @brief The IOService object, used for all ASIO operations.
|
/// @brief The hook I/O service.
|
||||||
static isc::asiolink::IOServicePtr io_service_;
|
static isc::asiolink::IOServicePtr io_service_;
|
||||||
|
|
||||||
|
/// @brief The main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr main_io_service_;
|
||||||
|
|
||||||
/// @brief Statement index of the SQL statement to use for fetching
|
/// @brief Statement index of the SQL statement to use for fetching
|
||||||
/// last inserted id in a given table.
|
/// last inserted id in a given table.
|
||||||
size_t last_insert_id_index_;
|
size_t last_insert_id_index_;
|
||||||
|
@ -12,11 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -19,8 +19,9 @@ namespace isc {
|
|||||||
namespace run_script {
|
namespace run_script {
|
||||||
|
|
||||||
IOServicePtr RunScriptImpl::io_service_;
|
IOServicePtr RunScriptImpl::io_service_;
|
||||||
|
IOServicePtr RunScriptImpl::main_io_service_;
|
||||||
|
|
||||||
RunScriptImpl::RunScriptImpl() : name_(), sync_(false) {
|
RunScriptImpl::RunScriptImpl() : io_context_(new IOService()), name_(), sync_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -30,20 +30,6 @@ public:
|
|||||||
/// @brief Destructor.
|
/// @brief Destructor.
|
||||||
~RunScriptImpl() = default;
|
~RunScriptImpl() = default;
|
||||||
|
|
||||||
/// @brief Sets IO service to be used by the @ref ProcessSpawn instance.
|
|
||||||
///
|
|
||||||
/// @param io_service The IOService object, used for all ASIO operations.
|
|
||||||
static void setIOService(const isc::asiolink::IOServicePtr& io_service) {
|
|
||||||
io_service_ = io_service;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets IO service to be used by the @ref ProcessSpawn instance.
|
|
||||||
///
|
|
||||||
/// @return The IOService object, used for all ASIO operations.
|
|
||||||
static isc::asiolink::IOServicePtr getIOService() {
|
|
||||||
return (io_service_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Extract boolean data and append to environment.
|
/// @brief Extract boolean data and append to environment.
|
||||||
///
|
///
|
||||||
/// @param value The value to be exported to target script environment.
|
/// @param value The value to be exported to target script environment.
|
||||||
@ -256,7 +242,53 @@ public:
|
|||||||
/// @brief This function parses and applies configuration parameters.
|
/// @brief This function parses and applies configuration parameters.
|
||||||
void configure(isc::hooks::LibraryHandle& handle);
|
void configure(isc::hooks::LibraryHandle& handle);
|
||||||
|
|
||||||
|
/// @brief Get the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @return the hook I/O service.
|
||||||
|
isc::asiolink::IOServicePtr& getIOContext() {
|
||||||
|
return (io_context_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the hook I/O service.
|
||||||
|
void setIOContext(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
io_context_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Get the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @return the hook I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr& getIOService() {
|
||||||
|
return (io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the hook I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the hook I/O service.
|
||||||
|
static void setIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Get the main I/O service.
|
||||||
|
///
|
||||||
|
/// @return the main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr& getMainIOService() {
|
||||||
|
return (main_io_service_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set the main I/O service.
|
||||||
|
///
|
||||||
|
/// @param io_service the main I/O service.
|
||||||
|
static void setMainIOService(isc::asiolink::IOServicePtr io_service) {
|
||||||
|
main_io_service_ = io_service;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// @brief The IOService object, used for all ASIO operations.
|
||||||
|
isc::asiolink::IOServicePtr io_context_;
|
||||||
|
|
||||||
/// @brief Script name.
|
/// @brief Script name.
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
||||||
@ -267,8 +299,11 @@ private:
|
|||||||
/// started.
|
/// started.
|
||||||
bool sync_;
|
bool sync_;
|
||||||
|
|
||||||
/// @brief The IOService object, used for all ASIO operations.
|
/// @brief The hook I/O service.
|
||||||
static isc::asiolink::IOServicePtr io_service_;
|
static isc::asiolink::IOServicePtr io_service_;
|
||||||
|
|
||||||
|
/// @brief The main I/O service.
|
||||||
|
static isc::asiolink::IOServicePtr main_io_service_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief The type of shared pointers to Run Script implementations.
|
/// @brief The type of shared pointers to Run Script implementations.
|
||||||
|
@ -80,7 +80,18 @@ int load(LibraryHandle& handle) {
|
|||||||
///
|
///
|
||||||
/// @return always 0.
|
/// @return always 0.
|
||||||
int unload() {
|
int unload() {
|
||||||
|
if (RunScriptImpl::getMainIOService()) {
|
||||||
|
RunScriptImpl::getMainIOService()->unregisterExternalIOService(impl->getIOContext());
|
||||||
|
}
|
||||||
impl.reset();
|
impl.reset();
|
||||||
|
if (RunScriptImpl::getIOService()) {
|
||||||
|
RunScriptImpl::getIOService()->stop();
|
||||||
|
RunScriptImpl::getIOService()->restart();
|
||||||
|
try {
|
||||||
|
RunScriptImpl::getIOService()->poll();
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
RunScriptImpl::setIOService(IOServicePtr());
|
RunScriptImpl::setIOService(IOServicePtr());
|
||||||
LOG_INFO(run_script_logger, RUN_SCRIPT_UNLOAD);
|
LOG_INFO(run_script_logger, RUN_SCRIPT_UNLOAD);
|
||||||
return (0);
|
return (0);
|
||||||
@ -91,16 +102,16 @@ int unload() {
|
|||||||
/// @param handle callout handle.
|
/// @param handle callout handle.
|
||||||
int dhcp4_srv_configured(CalloutHandle& handle) {
|
int dhcp4_srv_configured(CalloutHandle& handle) {
|
||||||
try {
|
try {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", RunScriptImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!RunScriptImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
// Should not happen!
|
// Should not happen!
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
RunScriptImpl::setIOService(io_service);
|
RunScriptImpl::setIOService(impl->getIOContext());
|
||||||
|
RunScriptImpl::getMainIOService()->registerExternalIOService(impl->getIOContext());
|
||||||
|
|
||||||
} catch (const exception& ex) {
|
} catch (const exception& ex) {
|
||||||
LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
|
LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
|
||||||
@ -116,16 +127,16 @@ int dhcp4_srv_configured(CalloutHandle& handle) {
|
|||||||
/// @param handle callout handle.
|
/// @param handle callout handle.
|
||||||
int dhcp6_srv_configured(CalloutHandle& handle) {
|
int dhcp6_srv_configured(CalloutHandle& handle) {
|
||||||
try {
|
try {
|
||||||
isc::asiolink::IOServicePtr io_service;
|
handle.getArgument("io_context", RunScriptImpl::getMainIOService());
|
||||||
handle.getArgument("io_context", io_service);
|
if (!RunScriptImpl::getMainIOService()) {
|
||||||
if (!io_service) {
|
|
||||||
// Should not happen!
|
// Should not happen!
|
||||||
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
|
||||||
const string error("Error: io_context is null");
|
const string error("Error: io_context is null");
|
||||||
handle.setArgument("error", error);
|
handle.setArgument("error", error);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
RunScriptImpl::setIOService(io_service);
|
RunScriptImpl::setIOService(impl->getIOContext());
|
||||||
|
RunScriptImpl::getMainIOService()->registerExternalIOService(impl->getIOContext());
|
||||||
|
|
||||||
} catch (const exception& ex) {
|
} catch (const exception& ex) {
|
||||||
LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
|
LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <cc/data.h>
|
#include <dhcpsrv/testutils/lib_load_test_fixture.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
|
||||||
#include <hooks/hooks_manager.h>
|
|
||||||
#include <process/daemon.h>
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
#include <testutils/lib_load_test_fixture.h>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -18,98 +18,102 @@ namespace isc {
|
|||||||
namespace asiolink {
|
namespace asiolink {
|
||||||
|
|
||||||
class IOServiceImpl {
|
class IOServiceImpl {
|
||||||
|
/// @brief Constructors and Destructor.
|
||||||
|
///
|
||||||
|
/// @note The copy constructor and the assignment operator are
|
||||||
|
/// intentionally defined as private, making this class non-copyable.
|
||||||
|
//@{
|
||||||
private:
|
private:
|
||||||
IOServiceImpl(const IOService& source);
|
IOServiceImpl(const IOService& source);
|
||||||
IOServiceImpl& operator=(const IOService& source);
|
IOServiceImpl& operator=(const IOService& source);
|
||||||
public:
|
public:
|
||||||
/// \brief The constructor
|
/// @brief The constructor.
|
||||||
IOServiceImpl() :
|
IOServiceImpl() :
|
||||||
io_service_(),
|
io_service_(),
|
||||||
work_(new boost::asio::io_service::work(io_service_)) {
|
work_(new boost::asio::io_service::work(io_service_)) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief The destructor.
|
/// @brief The destructor.
|
||||||
~IOServiceImpl() {
|
~IOServiceImpl() = default;
|
||||||
};
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// \brief Start the underlying event loop.
|
/// @brief Start the underlying event loop.
|
||||||
///
|
///
|
||||||
/// This method does not return control to the caller until
|
/// This method does not return control to the caller until
|
||||||
/// the \c stop() method is called via some handler.
|
/// the @ref stop() method is called via some handler.
|
||||||
void run() {
|
void run() {
|
||||||
io_service_.run();
|
io_service_.run();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a single event.
|
/// @brief Run the underlying event loop for a single event.
|
||||||
///
|
///
|
||||||
/// This method return control to the caller as soon as the
|
/// This method return control to the caller as soon as the
|
||||||
/// first handler has completed. (If no handlers are ready when
|
/// first handler has completed. (If no handlers are ready when
|
||||||
/// it is run, it will block until one is.)
|
/// it is run, it will block until one is.)
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t runOne() {
|
size_t runOne() {
|
||||||
return (static_cast<size_t>(io_service_.run_one()));
|
return (static_cast<size_t>(io_service_.run_one()));
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
/// It will return immediately if there are no ready events.
|
/// It will return immediately if there are no ready events.
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t poll() {
|
size_t poll() {
|
||||||
return (static_cast<size_t>(io_service_.poll()));
|
return (static_cast<size_t>(io_service_.poll()));
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
/// It will return immediately if there are no ready events.
|
/// It will return immediately if there are no ready events.
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t pollOne() {
|
size_t pollOne() {
|
||||||
return (static_cast<size_t>(io_service_.poll_one()));
|
return (static_cast<size_t>(io_service_.poll_one()));
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Stop the underlying event loop.
|
/// @brief Stop the underlying event loop.
|
||||||
///
|
///
|
||||||
/// This will return the control to the caller of the \c run() method.
|
/// This will return the control to the caller of the @ref run() method.
|
||||||
void stop() {
|
void stop() {
|
||||||
io_service_.stop();
|
io_service_.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Indicates if the IOService has been stopped.
|
/// @brief Indicates if the IOService has been stopped.
|
||||||
///
|
///
|
||||||
/// \return true if the IOService has been stopped, false otherwise.
|
/// @return true if the IOService has been stopped, false otherwise.
|
||||||
bool stopped() const {
|
bool stopped() const {
|
||||||
return (io_service_.stopped());
|
return (io_service_.stopped());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Restarts the IOService in preparation for a subsequent \c run() invocation.
|
/// @brief Restarts the IOService in preparation for a subsequent @ref run() invocation.
|
||||||
void restart() {
|
void restart() {
|
||||||
io_service_.reset();
|
io_service_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Removes IO service work object to let it finish running
|
/// @brief Removes IO service work object to let it finish running
|
||||||
/// when all handlers have been invoked.
|
/// when all handlers have been invoked.
|
||||||
void stopWork() {
|
void stopWork() {
|
||||||
work_.reset();
|
work_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return the native \c io_service object used in this wrapper.
|
/// @brief Return the native @ref io_service object used in this wrapper.
|
||||||
///
|
///
|
||||||
/// This is a short term work around to support other Kea modules
|
/// This is a short term work around to support other Kea modules
|
||||||
/// that share the same \c io_service with the authoritative server.
|
/// that share the same @ref io_service with the authoritative server.
|
||||||
/// It will eventually be removed once the wrapper interface is
|
/// It will eventually be removed once the wrapper interface is
|
||||||
/// generalized.
|
/// generalized.
|
||||||
boost::asio::io_service& getInternalIOService() {
|
boost::asio::io_service& getInternalIOService() {
|
||||||
return (io_service_);
|
return (io_service_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Post a callback on the IO service
|
/// @brief Post a callback on the IO service.
|
||||||
///
|
///
|
||||||
/// \param callback The callback to be run on the IO service.
|
/// @param callback The callback to be run on the IO service.
|
||||||
void post(const std::function<void ()>& callback) {
|
void post(const std::function<void ()>& callback) {
|
||||||
io_service_.post(callback);
|
io_service_.post(callback);
|
||||||
}
|
}
|
||||||
@ -175,5 +179,25 @@ IOService::post(const std::function<void ()>& callback) {
|
|||||||
return (io_impl_->post(callback));
|
return (io_impl_->post(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOService::registerExternalIOService(IOServicePtr io_service) {
|
||||||
|
external_io_services_.push_back(io_service);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOService::unregisterExternalIOService(IOServicePtr io_service) {
|
||||||
|
auto it = std::find(external_io_services_.begin(), external_io_services_.end(), io_service);
|
||||||
|
if (it != external_io_services_.end()) {
|
||||||
|
external_io_services_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOService::pollExternalIOServices() {
|
||||||
|
for (auto& io_service : external_io_services_) {
|
||||||
|
io_service->poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asiolink
|
} // namespace asiolink
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -26,84 +27,89 @@ namespace isc {
|
|||||||
namespace asiolink {
|
namespace asiolink {
|
||||||
|
|
||||||
class IOServiceImpl;
|
class IOServiceImpl;
|
||||||
|
class IOService;
|
||||||
|
|
||||||
/// \brief The \c IOService class is a wrapper for the ASIO \c io_service
|
/// @brief Defines a smart pointer to an IOService instance.
|
||||||
|
typedef boost::shared_ptr<IOService> IOServicePtr;
|
||||||
|
|
||||||
|
/// @brief The @ref IOService class is a wrapper for the ASIO @ref io_service
|
||||||
/// class.
|
/// class.
|
||||||
///
|
|
||||||
class IOService {
|
class IOService {
|
||||||
|
/// @brief Constructors and Destructor.
|
||||||
///
|
///
|
||||||
/// \name Constructors and Destructor
|
/// @note The copy constructor and the assignment operator are
|
||||||
///
|
|
||||||
/// Note: The copy constructor and the assignment operator are
|
|
||||||
/// intentionally defined as private, making this class non-copyable.
|
/// intentionally defined as private, making this class non-copyable.
|
||||||
//@{
|
//@{
|
||||||
private:
|
private:
|
||||||
IOService(const IOService& source);
|
IOService(const IOService& source);
|
||||||
IOService& operator=(const IOService& source);
|
IOService& operator=(const IOService& source);
|
||||||
public:
|
public:
|
||||||
/// \brief The constructor
|
/// @brief The constructor.
|
||||||
IOService();
|
IOService();
|
||||||
/// \brief The destructor.
|
|
||||||
|
/// @brief The destructor.
|
||||||
~IOService();
|
~IOService();
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// \brief Start the underlying event loop.
|
/// @brief Start the underlying event loop.
|
||||||
///
|
///
|
||||||
/// This method does not return control to the caller until
|
/// This method does not return control to the caller until
|
||||||
/// the \c stop() method is called via some handler.
|
/// the @ref stop() method is called via some handler.
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a single event.
|
/// @brief Run the underlying event loop for a single event.
|
||||||
///
|
///
|
||||||
/// This method return control to the caller as soon as the
|
/// This method return control to the caller as soon as the
|
||||||
/// first handler has completed. (If no handlers are ready when
|
/// first handler has completed. (If no handlers are ready when
|
||||||
/// it is run, it will block until one is.)
|
/// it is run, it will block until one is.)
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t runOne();
|
size_t runOne();
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
/// It will return immediately if there are no ready events.
|
/// It will return immediately if there are no ready events.
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t poll();
|
size_t poll();
|
||||||
|
|
||||||
/// \brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
/// It will return immediately if there are no ready events.
|
/// It will return immediately if there are no ready events.
|
||||||
///
|
///
|
||||||
/// \return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t pollOne();
|
size_t pollOne();
|
||||||
|
|
||||||
/// \brief Stop the underlying event loop.
|
/// @brief Stop the underlying event loop.
|
||||||
///
|
///
|
||||||
/// This will return the control to the caller of the \c run() method.
|
/// This will return the control to the caller of the @ref run() method.
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
/// \brief Indicates if the IOService has been stopped.
|
/// @brief Indicates if the IOService has been stopped.
|
||||||
///
|
///
|
||||||
/// \return true if the IOService has been stopped, false otherwise.
|
/// @return true if the IOService has been stopped, false otherwise.
|
||||||
bool stopped() const;
|
bool stopped() const;
|
||||||
|
|
||||||
/// \brief Restarts the IOService in preparation for a subsequent \c run() invocation.
|
/// @brief Restarts the IOService in preparation for a subsequent @ref run() invocation.
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
/// \brief Removes IO service work object to let it finish running
|
/// @brief Removes IO service work object to let it finish running
|
||||||
/// when all handlers have been invoked.
|
/// when all handlers have been invoked.
|
||||||
void stopWork();
|
void stopWork();
|
||||||
|
|
||||||
/// \brief Return the native \c io_service object used in this wrapper.
|
/// @brief Return the native @ref io_service object used in this wrapper.
|
||||||
///
|
///
|
||||||
/// This is a short term work around to support other Kea modules
|
/// This is a short term work around to support other Kea modules
|
||||||
/// that share the same \c io_service with the authoritative server.
|
/// that share the same @ref io_service with the authoritative server.
|
||||||
/// It will eventually be removed once the wrapper interface is
|
/// It will eventually be removed once the wrapper interface is
|
||||||
/// generalized.
|
/// generalized.
|
||||||
|
///
|
||||||
|
/// @return The internal io_service object.
|
||||||
boost::asio::io_service& getInternalIOService();
|
boost::asio::io_service& getInternalIOService();
|
||||||
|
|
||||||
/// \brief Post a callback to the end of the queue.
|
/// @brief Post a callback to the end of the queue.
|
||||||
///
|
///
|
||||||
/// Requests the callback be called sometime later. It is not guaranteed
|
/// Requests the callback be called sometime later. It is not guaranteed
|
||||||
/// by the underlying asio, but it can reasonably be expected the callback
|
/// by the underlying asio, but it can reasonably be expected the callback
|
||||||
@ -114,12 +120,39 @@ public:
|
|||||||
/// by small bits that are called from time to time).
|
/// by small bits that are called from time to time).
|
||||||
void post(const std::function<void ()>& callback);
|
void post(const std::function<void ()>& callback);
|
||||||
|
|
||||||
private:
|
/// @brief Register external IOService.
|
||||||
boost::shared_ptr<IOServiceImpl> io_impl_;
|
///
|
||||||
};
|
/// @param io_service The external IOService to be registered.
|
||||||
|
void registerExternalIOService(IOServicePtr io_service);
|
||||||
|
|
||||||
/// @brief Defines a smart pointer to an IOService instance.
|
/// @brief Unregister external IOService.
|
||||||
typedef boost::shared_ptr<IOService> IOServicePtr;
|
///
|
||||||
|
/// @param io_service The external IOService to be unregistered.
|
||||||
|
void unregisterExternalIOService(IOServicePtr io_service);
|
||||||
|
|
||||||
|
/// @brief Clear the list of external IOService objects.
|
||||||
|
void clearExternalIOServices() {
|
||||||
|
external_io_services_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief The count of external IOService objects.
|
||||||
|
///
|
||||||
|
// @return The count of external IOService objects.
|
||||||
|
size_t externalIOServiceCount() {
|
||||||
|
return (external_io_services_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Poll external IOService objects.
|
||||||
|
void pollExternalIOServices();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// @brief The implementation.
|
||||||
|
boost::shared_ptr<IOServiceImpl> io_impl_;
|
||||||
|
|
||||||
|
/// @brief The list of external IOService objects.
|
||||||
|
std::list<IOServicePtr> external_io_services_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace asiolink
|
} // namespace asiolink
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
@ -45,4 +45,105 @@ TEST(IOService, post) {
|
|||||||
EXPECT_EQ(3, called[2]);
|
EXPECT_EQ(3, called[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(IOService, externalIOService) {
|
||||||
|
IOServicePtr main_io_service(new IOService());
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 0);
|
||||||
|
int one_io_callback_count = 0;
|
||||||
|
auto one_f = [&one_io_callback_count] () {
|
||||||
|
one_io_callback_count++;
|
||||||
|
};
|
||||||
|
int two_io_callback_count = 0;
|
||||||
|
auto two_f = [&two_io_callback_count] () {
|
||||||
|
two_io_callback_count++;
|
||||||
|
};
|
||||||
|
{
|
||||||
|
IOServicePtr one_io_service(new IOService());
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
|
||||||
|
IOServicePtr two_io_service(new IOService());
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 0);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 0);
|
||||||
|
|
||||||
|
main_io_service->registerExternalIOService(one_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 1);
|
||||||
|
|
||||||
|
main_io_service->registerExternalIOService(two_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 2);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 1);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 1);
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 2);
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 2);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 2);
|
||||||
|
|
||||||
|
main_io_service->clearExternalIOServices();
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 0);
|
||||||
|
|
||||||
|
IOServicePtr one_io_service(new IOService());
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
|
||||||
|
IOServicePtr two_io_service(new IOService());
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 2);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 2);
|
||||||
|
|
||||||
|
main_io_service->registerExternalIOService(one_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 1);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 3);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 2);
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
|
||||||
|
main_io_service->registerExternalIOService(two_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 2);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 4);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 4);
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
|
||||||
|
main_io_service->unregisterExternalIOService(one_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 1);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 4);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 5);
|
||||||
|
one_io_service->post(one_f);
|
||||||
|
two_io_service->post(two_f);
|
||||||
|
|
||||||
|
main_io_service->unregisterExternalIOService(two_io_service);
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 0);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 4);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 5);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(main_io_service->registerExternalIOService(main_io_service));
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 1);
|
||||||
|
main_io_service->post(one_f);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 5);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 5);
|
||||||
|
EXPECT_NO_THROW(main_io_service->unregisterExternalIOService(main_io_service));
|
||||||
|
EXPECT_EQ(main_io_service->externalIOServiceCount(), 0);
|
||||||
|
|
||||||
|
main_io_service->pollExternalIOServices();
|
||||||
|
EXPECT_EQ(one_io_callback_count, 5);
|
||||||
|
EXPECT_EQ(two_io_callback_count, 5);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ libdhcpsrvtest_la_SOURCES = concrete_lease_mgr.cc concrete_lease_mgr.h
|
|||||||
libdhcpsrvtest_la_SOURCES += config_result_check.cc config_result_check.h
|
libdhcpsrvtest_la_SOURCES += config_result_check.cc config_result_check.h
|
||||||
libdhcpsrvtest_la_SOURCES += dhcp4o6_test_ipc.cc dhcp4o6_test_ipc.h
|
libdhcpsrvtest_la_SOURCES += dhcp4o6_test_ipc.cc dhcp4o6_test_ipc.h
|
||||||
libdhcpsrvtest_la_SOURCES += host_data_source_utils.cc host_data_source_utils.h
|
libdhcpsrvtest_la_SOURCES += host_data_source_utils.cc host_data_source_utils.h
|
||||||
|
libdhcpsrvtest_la_SOURCES += lib_load_test_fixture.h
|
||||||
libdhcpsrvtest_la_SOURCES += memory_host_data_source.cc memory_host_data_source.h
|
libdhcpsrvtest_la_SOURCES += memory_host_data_source.cc memory_host_data_source.h
|
||||||
libdhcpsrvtest_la_SOURCES += test_utils.cc test_utils.h
|
libdhcpsrvtest_la_SOURCES += test_utils.cc test_utils.h
|
||||||
libdhcpsrvtest_la_SOURCES += generic_backend_unittest.cc generic_backend_unittest.h
|
libdhcpsrvtest_la_SOURCES += generic_backend_unittest.cc generic_backend_unittest.h
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include <cc/data.h>
|
#include <cc/data.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <dhcpsrv/cfgmgr.h>
|
||||||
|
#include <hooks/hooks_manager.h>
|
||||||
#include <process/daemon.h>
|
#include <process/daemon.h>
|
||||||
|
|
||||||
#include <testutils/gtest_utils.h>
|
#include <testutils/gtest_utils.h>
|
||||||
|
|
||||||
namespace isc {
|
namespace isc {
|
@ -415,6 +415,8 @@ DControllerBase::configFromFile() {
|
|||||||
// case of problems.
|
// case of problems.
|
||||||
storage->applyLoggingCfg();
|
storage->applyLoggingCfg();
|
||||||
|
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
|
|
||||||
answer = updateConfig(module_config);
|
answer = updateConfig(module_config);
|
||||||
// In all cases the right logging configuration is in the context.
|
// In all cases the right logging configuration is in the context.
|
||||||
process_->getCfgMgr()->getContext()->applyLoggingCfg();
|
process_->getCfgMgr()->getContext()->applyLoggingCfg();
|
||||||
@ -655,6 +657,8 @@ DControllerBase::configSetHandler(const std::string&, ConstElementPtr args) {
|
|||||||
// case of problems.
|
// case of problems.
|
||||||
storage->applyLoggingCfg();
|
storage->applyLoggingCfg();
|
||||||
|
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
|
|
||||||
ConstElementPtr answer = updateConfig(module_config);
|
ConstElementPtr answer = updateConfig(module_config);
|
||||||
int rcode = 0;
|
int rcode = 0;
|
||||||
parseAnswer(rcode, answer);
|
parseAnswer(rcode, answer);
|
||||||
@ -844,6 +848,8 @@ DControllerBase::~DControllerBase() {
|
|||||||
LOG_ERROR(dctl_logger, DCTL_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
LOG_ERROR(dctl_logger, DCTL_UNLOAD_LIBRARIES_ERROR).arg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getIOService()->clearExternalIOServices();
|
||||||
|
|
||||||
io_signal_set_.reset();
|
io_signal_set_.reset();
|
||||||
try {
|
try {
|
||||||
getIOService()->poll();
|
getIOService()->poll();
|
||||||
|
@ -16,7 +16,6 @@ libkea_testutils_la_SOURCES += unix_control_client.cc unix_control_client.h
|
|||||||
libkea_testutils_la_SOURCES += user_context_utils.cc user_context_utils.h
|
libkea_testutils_la_SOURCES += user_context_utils.cc user_context_utils.h
|
||||||
libkea_testutils_la_SOURCES += gtest_utils.h
|
libkea_testutils_la_SOURCES += gtest_utils.h
|
||||||
libkea_testutils_la_SOURCES += multi_threading_utils.h
|
libkea_testutils_la_SOURCES += multi_threading_utils.h
|
||||||
libkea_testutils_la_SOURCES += lib_load_test_fixture.h
|
|
||||||
libkea_testutils_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
libkea_testutils_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
||||||
libkea_testutils_la_LIBADD = $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
|
libkea_testutils_la_LIBADD = $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
|
||||||
libkea_testutils_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
|
libkea_testutils_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
|
||||||
|
319
tools/check-lib-dependencies.sh
Executable file
319
tools/check-lib-dependencies.sh
Executable file
@ -0,0 +1,319 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# extract folder name containing file
|
||||||
|
#
|
||||||
|
# param ${1} file name
|
||||||
|
# return folder name
|
||||||
|
extract_folder_name() {
|
||||||
|
# return name of the file until last '/'
|
||||||
|
echo "$(echo "${1}" | rev | cut -d '/' -f 2- | rev)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract all includes found in source files found in the same folder as specified Makefile.am
|
||||||
|
#
|
||||||
|
# param ${1} path to a Makefile.am
|
||||||
|
# return all dependencies libs in the order of compilation
|
||||||
|
extract_includes() {
|
||||||
|
# extract folder name from current library Makefile.am
|
||||||
|
CURRENT_FOLDER=$(extract_folder_name "${1}")"/"
|
||||||
|
# select only files in current folder
|
||||||
|
SEARCH_FILES=$(echo "${FILE_LIST}" | grep "${CURRENT_FOLDER}")
|
||||||
|
# select all lines containing '#include ' directive
|
||||||
|
RAW_INCLUDES_LIST=$(echo "${SEARCH_FILES}" | xargs grep "^#include " 2>/dev/null)
|
||||||
|
# filter only included dependencies found in other libraries by using the form 'other_lib_name/header_file.h'
|
||||||
|
# to do this it is required to select the string between '<' and '>', searching for '/' character and returning the name until last '/'
|
||||||
|
RAW_INCLUDES_LIST=$(echo "${RAW_INCLUDES_LIST}" | cut -d "#" -f 2 | tr "\"" " " | cut -d "<" -f 2 | cut -d ">" -f 1 | grep "\/" | rev | cut -d "/" -f 2 | rev | sort | uniq)
|
||||||
|
# filter includes that are not compiled by the project's Makefiles
|
||||||
|
INCLUDES_LIST=
|
||||||
|
for i in ${LIBRARIES_LIST}; do
|
||||||
|
for j in ${RAW_INCLUDES_LIST}; do
|
||||||
|
if test "${j}" = "${i}"; then
|
||||||
|
INCLUDES_LIST="${i} ${INCLUDES_LIST}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
# remove empty spaces
|
||||||
|
INCLUDES_LIST=$(echo ${INCLUDES_LIST} | tr -s " ")
|
||||||
|
# order dependencies in the order of compilation
|
||||||
|
FILTERED_INCLUDES_LIST=
|
||||||
|
for i in ${LIBRARIES_LIST}; do
|
||||||
|
if test $(echo "${INCLUDES_LIST}" | grep "\b${i}\b" | wc -l) -ne 0; then
|
||||||
|
FILTERED_INCLUDES_LIST="${i} ${FILTERED_INCLUDES_LIST}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "${FILTERED_INCLUDES_LIST}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract all header only files and headers and source files found in the external library required by specified library
|
||||||
|
# param ${1} name of the current library
|
||||||
|
# param ${2} name of the external dependency library required by current library
|
||||||
|
# return the list of header only files as 'HEADERS: heaser1.h header2.h' and header and source files as 'HEADERS_AND_SOURCES: source1.h source1.cc source2.h source2.cpp'
|
||||||
|
extract_non_include_files() {
|
||||||
|
# extract folder name for current library Makefile.am
|
||||||
|
CURRENT_FOLDER=$(extract_folder_name "src/lib/${1}/Makefile.am")"/"
|
||||||
|
# extract folder name for external dependency library Makefile.am
|
||||||
|
EXTERNAL_FOLDER=$(extract_folder_name "src/lib/${2}/Makefile.am")"/"
|
||||||
|
# select only files in current folder
|
||||||
|
SEARCH_FILES=$(echo "${FILE_LIST}" | grep "${CURRENT_FOLDER}")
|
||||||
|
HEADERS_LIST=
|
||||||
|
NON_HEADERS_LIST=
|
||||||
|
# select all lines containing '#include ' directive
|
||||||
|
RAW_INCLUDES_LIST=$(echo "${SEARCH_FILES}" | xargs grep "^#include " 2>/dev/null)
|
||||||
|
# filter only included headers found in other libraries by using the form 'other_lib_name/header_file.h'
|
||||||
|
# to do this it is required to select the string between '<' and '>', searching for '/' character, search for the extension marker '.' and returning the name after last '/'
|
||||||
|
RAW_INCLUDES_LIST=$(echo "${RAW_INCLUDES_LIST}" | cut -d "#" -f 2 | tr "\"" " " | cut -d "<" -f 2 | cut -d ">" -f 1 | grep "\/" | grep "\b${2}\b" | cut -d "/" -f 2 | grep "\." | sort | uniq)
|
||||||
|
# select only files in dependency library folder and strip full path
|
||||||
|
RELATIVE_SEARCH_FILES=$(echo "${FILE_LIST}" | grep "${EXTERNAL_FOLDER}" | sed -e "s#${REPO_FOLDER}${EXTERNAL_FOLDER}##g")
|
||||||
|
# search for the header file but also for source files
|
||||||
|
for i in ${RAW_INCLUDES_LIST}; do
|
||||||
|
# filter by name only (no extension)
|
||||||
|
FILTER=$(echo "${i}" | cut -d "." -f 1)
|
||||||
|
# filter non header files with exact name of the header file without the extension
|
||||||
|
NON_HEADER=$(echo "${RELATIVE_SEARCH_FILES}" | grep "\b${FILTER}\." | grep -v "${i}")
|
||||||
|
if test $(echo "${NON_HEADER}" | wc -w) -ne 0; then
|
||||||
|
# append header and source file names
|
||||||
|
NON_HEADERS_LIST="${i} ${NON_HEADER} ${NON_HEADERS_LIST}"
|
||||||
|
else
|
||||||
|
# append header only file name
|
||||||
|
HEADERS_LIST="${i} ${HEADERS_LIST}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# sort header only files
|
||||||
|
HEADERS_LIST=$(echo ${HEADERS_LIST} | tr -s " " | sort | uniq)
|
||||||
|
# sort header and source files
|
||||||
|
NON_HEADERS_LIST=$(echo ${NON_HEADERS_LIST} | tr -s " " | sort | uniq)
|
||||||
|
echo "HEADERS_AND_SOURCES:${NON_HEADERS_LIST}"
|
||||||
|
echo "HEADERS:${HEADERS_LIST}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract all valid dependencies of a specified library
|
||||||
|
#
|
||||||
|
# param ${1} list of all libraries in the reverse compilation order
|
||||||
|
# param ${2} library name for which the dependency list is computed
|
||||||
|
# return the list of dependencies for specified library in the reverse compilation order
|
||||||
|
extract_dependencies() {
|
||||||
|
echo "${1}" | grep -Eo "\b${2}\b.*$"
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract computed dependency for specified library
|
||||||
|
#
|
||||||
|
# param ${1} library name for which the dependency list is retrieved
|
||||||
|
# param ${2} library path for which the dependency list is retrieved
|
||||||
|
# return stored value of computed dependencies or 'NONE' if dependencies have not been computed yet
|
||||||
|
extract_computed_dependencies() {
|
||||||
|
PATH_TO_NAME=$(echo "${2}" | tr -s "/" "_")
|
||||||
|
NAME="COMPUTED_DEPENDENCIES_${PATH_TO_NAME}_${1}"
|
||||||
|
if test -n "${!NAME+x}"; then
|
||||||
|
echo "${!NAME}"
|
||||||
|
else
|
||||||
|
echo "NONE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract library directive
|
||||||
|
#
|
||||||
|
# param ${1} artifact path
|
||||||
|
extract_library_directive() {
|
||||||
|
ARTIFACT_PATH="${1}"
|
||||||
|
echo `cat ${ARTIFACT_PATH}/Makefile.am | grep "LIBADD\|LDADD" | sort | tr -s ' ' | cut -d " " -f 1 | sort -u`
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract library name
|
||||||
|
#
|
||||||
|
# param ${1} artifact path
|
||||||
|
extract_library_name() {
|
||||||
|
ARTIFACT_PATH="${1}"
|
||||||
|
echo `cat ${ARTIFACT_PATH}/Makefile.am | grep "LIBRARIES" | tr -s ' ' | cut -d " " -f 3`
|
||||||
|
}
|
||||||
|
|
||||||
|
# compute artifact dependencies
|
||||||
|
#
|
||||||
|
# param ${1} artifact name
|
||||||
|
# param ${2} artifact path
|
||||||
|
compute_dependencies() {
|
||||||
|
ARTIFACT="${1}"
|
||||||
|
ARTIFACT_PATH="${2}"
|
||||||
|
echo ""
|
||||||
|
echo "########################################"
|
||||||
|
echo "### ${ARTIFACT_PATH}/${ARTIFACT}"
|
||||||
|
echo "########################################"
|
||||||
|
echo ""
|
||||||
|
# all valid dependencies that can be added by each dependency library
|
||||||
|
echo "${ARTIFACT_PATH}/${ARTIFACT} valid dependencies:"
|
||||||
|
echo "${VALID_LIST}"
|
||||||
|
# detect dependencies errors by searching for dependencies that are compiled after the current library and can generate missing symbols
|
||||||
|
NON_RECURSIVE_BASE_DEPENDENCIES=
|
||||||
|
for j in ${BASE_DEPENDENCIES}; do
|
||||||
|
# only add the dependency if it is in the valid dependencies list to prevent infinite recursion and log the error otherwise
|
||||||
|
if test $(echo "${VALID_LIST}" | grep "\b${j}\b" | wc -l) -eq 0; then
|
||||||
|
# search for external header and source files
|
||||||
|
INVALID_EXTERNAL_DEPENDENCIES=$(extract_non_include_files "${ARTIFACT}" "${j}")
|
||||||
|
# filter header only external files
|
||||||
|
EXTERNAL_HEADERS=$(echo "${INVALID_EXTERNAL_DEPENDENCIES}" | grep "HEADERS:" | cut -d ":" -f 2)
|
||||||
|
# filter header and source external files
|
||||||
|
EXTERNAL_ALL=$(echo "${INVALID_EXTERNAL_DEPENDENCIES}" | grep "HEADERS_AND_SOURCES:" | cut -d ":" -f 2)
|
||||||
|
echo "### ERROR ### dependencies ERROR for ${ARTIFACT_PATH}/${ARTIFACT} on ${j} with:"
|
||||||
|
# if there are any header only external files
|
||||||
|
if test $(echo "${EXTERNAL_ALL}" | wc -w) -ne 0; then
|
||||||
|
echo "non header only files: ${EXTERNAL_ALL}"
|
||||||
|
fi
|
||||||
|
# if there are any header and source external files
|
||||||
|
if test $(echo "${EXTERNAL_HEADERS}" | wc -w) -ne 0; then
|
||||||
|
echo "header only files: ${EXTERNAL_HEADERS}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# don't add current library to it's dependencies list
|
||||||
|
if test ${j} != ${ARTIFACT}; then
|
||||||
|
NON_RECURSIVE_BASE_DEPENDENCIES="${NON_RECURSIVE_BASE_DEPENDENCIES} ${j}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# all found dependencies in the reverse compilation order
|
||||||
|
BASE_DEPENDENCIES=$(echo "${BASE_DEPENDENCIES}" | xargs)
|
||||||
|
# all found and valid dependencies in the reverse compilation order
|
||||||
|
NON_RECURSIVE_BASE_DEPENDENCIES=$(echo "${NON_RECURSIVE_BASE_DEPENDENCIES}" | xargs)
|
||||||
|
echo "${ARTIFACT_PATH}/${ARTIFACT} base dependencies:"
|
||||||
|
echo "${BASE_DEPENDENCIES}"
|
||||||
|
echo "${ARTIFACT_PATH}/${ARTIFACT} non recursive dependencies:"
|
||||||
|
echo "${NON_RECURSIVE_BASE_DEPENDENCIES}"
|
||||||
|
# minimum set of dependencies for current library
|
||||||
|
DEPENDENCIES=
|
||||||
|
for j in ${NON_RECURSIVE_BASE_DEPENDENCIES}; do
|
||||||
|
NEW_DEPENDENCIES=$(extract_computed_dependencies "${j}" "src/lib")
|
||||||
|
if test "${NEW_DEPENDENCIES}" == "NONE"; then
|
||||||
|
echo "### ERROR ### computed dependency not found for ${j}"
|
||||||
|
else
|
||||||
|
DEPENDENCIES="${NEW_DEPENDENCIES} ${DEPENDENCIES}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
DEPENDENCIES=$(echo "${DEPENDENCIES} ${NON_RECURSIVE_BASE_DEPENDENCIES}" | tr -s " " "\n" | sort | uniq | xargs)
|
||||||
|
# order dependencies in the order of compilation
|
||||||
|
SORTED_DEPENDENCIES=
|
||||||
|
for j in ${LIBRARIES_LIST}; do
|
||||||
|
if test $(echo "${DEPENDENCIES}" | grep "\b${j}\b" | wc -l) -ne 0; then
|
||||||
|
SORTED_DEPENDENCIES="${j} ${SORTED_DEPENDENCIES}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "${ARTIFACT_PATH}/${ARTIFACT} minimum dependencies:"
|
||||||
|
echo "${SORTED_DEPENDENCIES}"
|
||||||
|
echo ""
|
||||||
|
echo "++++++++++++++++++++++++++++++++++++++++"
|
||||||
|
ARTIFACT_DIRECTIVE=$(extract_library_directive ${ARTIFACT_PATH}/${ARTIFACT})
|
||||||
|
for j in ${SORTED_DEPENDENCIES}; do
|
||||||
|
DEPENDENCY_LIBRARY_NAME=$(extract_library_name "src/lib/${j}")
|
||||||
|
echo "${ARTIFACT_DIRECTIVE} += \$(top_builddir)/src/lib/${j}/${DEPENDENCY_LIBRARY_NAME}"
|
||||||
|
done
|
||||||
|
echo "++++++++++++++++++++++++++++++++++++++++"
|
||||||
|
echo "########################################"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# if wrong number of parameters print usage
|
||||||
|
if test ${#} -ne 1; then
|
||||||
|
echo "Usage: ${0} path/to/kea/repo"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# folder containing full repo
|
||||||
|
REPO_FOLDER=${1}
|
||||||
|
|
||||||
|
if test $(echo -n ${REPO_FOLDER} | tail -c 1) != "/"; then
|
||||||
|
REPO_FOLDER="${REPO_FOLDER}/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# filter all Makefile.am files
|
||||||
|
MAKEFILES_LIST=$(find ${REPO_FOLDER} | grep "Makefile\.am" | sed -e "s#${REPO_FOLDER}##g" | grep "src\/" | sort)
|
||||||
|
|
||||||
|
# if no Makefile.am found exit
|
||||||
|
if test -z "${MAKEFILES_LIST}"; then
|
||||||
|
echo "invalid repo path: no Makefile.am file found"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "list of Makefile.am:"
|
||||||
|
echo "${MAKEFILES_LIST}"
|
||||||
|
|
||||||
|
# base Makefile.am for all sources is in src/lib/Makefile.am
|
||||||
|
BASE_MAKEFILE=$(echo "${MAKEFILES_LIST}" | grep "src\/lib\/Makefile.am")
|
||||||
|
|
||||||
|
# if no src/lib/Makefile.am found exit
|
||||||
|
if test -z ${BASE_MAKEFILE}; then
|
||||||
|
echo "invalid repo path: no src/lib/Makefile.am file found"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "base Makefile.am:"
|
||||||
|
echo "${BASE_MAKEFILE}"
|
||||||
|
|
||||||
|
# generate the list of libraries in the compilation order
|
||||||
|
LIBRARIES_LIST=
|
||||||
|
RAW_LIBRARIES_LIST=$(cat "${REPO_FOLDER}${BASE_MAKEFILE}" | grep "SUBDIRS")
|
||||||
|
for i in ${RAW_LIBRARIES_LIST}; do
|
||||||
|
LIBRARIES_LIST="${LIBRARIES_LIST} $(echo ${i} | grep -v "SUBDIRS" | grep -v '=')"
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove empty spaces
|
||||||
|
LIBRARIES_LIST=$(echo "${LIBRARIES_LIST}" | tr -s ' ' | xargs)
|
||||||
|
|
||||||
|
# generate the list of libraries in the reverse compilation order
|
||||||
|
REVERSE_LIBRARIES_LIST=
|
||||||
|
for i in ${LIBRARIES_LIST}; do
|
||||||
|
REVERSE_LIBRARIES_LIST="${i} ${REVERSE_LIBRARIES_LIST}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "list of libraries:"
|
||||||
|
echo "${LIBRARIES_LIST}"
|
||||||
|
|
||||||
|
echo "reverse list of libraries:"
|
||||||
|
echo "${REVERSE_LIBRARIES_LIST}"
|
||||||
|
|
||||||
|
# filter all files of interest ignoring irrelevant ones
|
||||||
|
# ignore .git, .libs, .deps doc folders and .o .lo .Plo .Po .gcno .gcda .m4 .dox .json .mes files
|
||||||
|
FILE_LIST=$(find "${REPO_FOLDER}" 2>/dev/null | grep -v "\.git" | grep -v "\/\.libs\/" | grep -v "\.o$" | grep -v "\/\.deps\/" | grep -v "\.lo$" | grep -v "\.Plo$" | grep -v "\.Po$" | grep -v "\.gcno$" | grep -v "gcda" | grep -v "\.m4$" | grep -v "\.dox$" | grep -v "\.json$" | grep -v "\/doc\/" | grep -v "\.mes$" | sort)
|
||||||
|
|
||||||
|
#echo "files:"
|
||||||
|
#echo "${FILE_LIST}"
|
||||||
|
|
||||||
|
BASE_LIBRARIES_MAKEFILES=
|
||||||
|
|
||||||
|
# generate the list of dependencies for all libraries in src/lib
|
||||||
|
for i in ${LIBRARIES_LIST}; do
|
||||||
|
# generate current library Makefile.am path
|
||||||
|
BASE_LIBRARIES_MAKEFILES="${BASE_LIBRARIES_MAKEFILES} src/lib/${i}/Makefile.am"
|
||||||
|
# extract dependencies found in the library folder
|
||||||
|
BASE_DEPENDENCIES=$(extract_includes "src/lib/${i}/Makefile.am")
|
||||||
|
# generate the list of valid dependencies for the current library (take compilation order into account)
|
||||||
|
VALID_LIST=$(extract_dependencies "${REVERSE_LIBRARIES_LIST}" "${i}")
|
||||||
|
compute_dependencies "${i}" "src/lib"
|
||||||
|
PATH_TO_NAME=$(echo "src/lib" | tr -s "/" "_")
|
||||||
|
declare COMPUTED_DEPENDENCIES_${PATH_TO_NAME}_${i}="${SORTED_DEPENDENCIES}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove empty spaces
|
||||||
|
BASE_LIBRARIES_MAKEFILES=$(echo "${BASE_LIBRARIES_MAKEFILES}" | xargs | tr -s " " "\n")
|
||||||
|
|
||||||
|
echo "base Makefiles.am files:"
|
||||||
|
echo "${BASE_LIBRARIES_MAKEFILES}"
|
||||||
|
|
||||||
|
OTHER_MAKEFILES=$(echo "${MAKEFILES_LIST}" | tr -s " " "\n" | grep -v "src/lib/" | grep -v "src/share/" | grep -v "src/Makefile.am")
|
||||||
|
# remove empty spaces
|
||||||
|
OTHER_MAKEFILES=$(echo "${OTHER_MAKEFILES}" | xargs | tr -s " " "\n")
|
||||||
|
|
||||||
|
echo "remaining Makefile.am files:"
|
||||||
|
echo "${OTHER_MAKEFILES}"
|
||||||
|
|
||||||
|
for i in ${OTHER_MAKEFILES}; do
|
||||||
|
# extract dependencies found in the artifact folder
|
||||||
|
BASE_DEPENDENCIES=$(extract_includes "${i}")
|
||||||
|
# generate the list of valid dependencies for the current artifact (take compilation order into account)
|
||||||
|
VALID_LIST="${REVERSE_LIBRARIES_LIST}"
|
||||||
|
ARTIFACT=$(echo "${i}" | rev | cut -d "/" -f 2 | rev)
|
||||||
|
ARTIFACT_PATH=$(echo "${i}" | rev | cut -d "/" -f 3- | rev)
|
||||||
|
compute_dependencies "${ARTIFACT}" "${ARTIFACT_PATH}"
|
||||||
|
PATH_TO_NAME=$(echo "${ARTIFACT_PATH}" | tr -s "/" "_")
|
||||||
|
declare COMPUTED_DEPENDENCIES_${PATH_TO_NAME}_${ARTIFACT}="${SORTED_DEPENDENCIES}"
|
||||||
|
done
|
||||||
|
|
||||||
|
exit
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user