now b10-dhcp-ddns.
CLEANFILES = *.gcno *.gcda spec_config.h d2_messages.h d2_messages.cc
-man_MANS = b10-d2.8
+man_MANS = b10-dhcp-ddns.8
DISTCLEANFILES = $(man_MANS)
-EXTRA_DIST = $(man_MANS) b10-d2.xml d2.spec
+EXTRA_DIST = $(man_MANS) b10-dhcp-ddns.xml dhcp-ddns.spec
if GENERATE_DOCS
-b10-d2.8: b10-d2.xml
+b10-dhcp-ddns.8: b10-dhcp-ddns.xml
@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
- $(srcdir)/b10-d2.xml
+ $(srcdir)/b10-dchdp-ddns.xml
else
BUILT_SOURCES = spec_config.h d2_messages.h d2_messages.cc
-pkglibexec_PROGRAMS = b10-d2
+pkglibexec_PROGRAMS = b10-dhcp-ddns
-b10_d2_SOURCES = main.cc
-b10_d2_SOURCES += d2_log.cc d2_log.h
-b10_d2_SOURCES += d_process.h
-b10_d2_SOURCES += d2_process.cc d2_process.h
-b10_d2_SOURCES += d_controller.cc d_controller.h
-b10_d2_SOURCES += d2_controller.cc d2_controller.h
+b10_dhcp_ddns_SOURCES = main.cc
+b10_dhcp_ddns_SOURCES += d2_log.cc d2_log.h
+b10_dhcp_ddns_SOURCES += d_process.h
+b10_dhcp_ddns_SOURCES += d2_process.cc d2_process.h
+b10_dhcp_ddns_SOURCES += d_controller.cc d_controller.h
+b10_dhcp_ddns_SOURCES += d2_controller.cc d2_controller.h
-nodist_b10_d2_SOURCES = d2_messages.h d2_messages.cc
+nodist_b10_dhcp_ddns_SOURCES = d2_messages.h d2_messages.cc
EXTRA_DIST += d2_messages.mes
-b10_d2_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
-b10_d2_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
-b10_d2_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
-b10_d2_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
-b10_d2_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
+b10_dhcp_ddns_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
+b10_dhcp_ddns_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+b10_dhcp_ddns_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
+b10_dhcp_ddns_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
+b10_dhcp_ddns_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
-b10_d2dir = $(pkgdatadir)
-b10_d2_DATA = d2.spec
+b10_dhcp_ddnsdir = $(pkgdatadir)
+b10_dhcp_ddns_DATA = dhcp-ddns.spec
</refentryinfo>
<refmeta>
- <refentrytitle>b10-d2</refentrytitle>
+ <refentrytitle>b10-dhcp-ddns</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo>BIND10</refmiscinfo>
</refmeta>
<refnamediv>
- <refname>b10-d2</refname>
+ <refname>b10-dhcp-ddns</refname>
<refpurpose>D2 process in BIND 10 architecture</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
- <command>b10-d2</command>
+ <command>b10-dhcp-ddns</command>
<arg><option>-v</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsynopsisdiv>
<cmdsynopsis>
- <command>b10-d2</command>
+ <command>b10-dhcp-ddns</command>
<arg><option>-s</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>
- The <command>b10-d2</command> daemon processes requests to
+ The <command>b10-dhcp-ddns</command> daemon processes requests to
to update DNS mapping based on DHCP lease change events.
</para>
<title>SEE ALSO</title>
<para>
<citerefentry>
- <refentrytitle>b10-d2</refentrytitle><manvolnum>8</manvolnum>
+ <refentrytitle>b10-dhcp-ddns</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
<refsect1>
<title>HISTORY</title>
<para>
- The <command>b10-d2</command> process was first coded in
+ The <command>b10-dhcp-ddns</command> process was first coded in
May 2013 by the ISC Kea/Dhcp team.
</para>
</refsect1>
D2Controller::instance() {
// If the instance hasn't been created yet, create it. Note this method
// must use the base class singleton instance methods. The base class
- // must own the singleton in order to use it within BIND10 static function
- // callbacks.
+ // must have access to the singleton in order to use it within BIND10
+ // static function callbacks.
if (!getController()) {
- setController(new D2Controller());
+ DControllerBasePtr controller_ptr(new D2Controller());
+ setController(controller_ptr);
}
return (getController());
/// @brief Defines the service name which is used in the controller constructor
/// and ultimately defines the BIND10 module name.
-const char* const D2_MODULE_NAME = "b10-d2";
+const char* const D2_MODULE_NAME = "b10-dhpc-ddns";
/// @brief Defines the logger used within D2.
isc::log::Logger d2_logger(D2_MODULE_NAME);
to shut down by the controller.
% D2PRC_PROCESS_INIT DHCP-DDNS application init invoked
-This is a debug message issued when the D2 process enters it's
+This is a debug message issued when the D2 process enters its
init method.
% D2PRC_RUN_ENTER process has entered the event loop
-This is a debug message issued when the D2 process enters it's
+This is a debug message issued when the D2 process enters its
run method.
% D2PRC_RUN_EXIT process is exiting the event loop
% D2CTL_INIT_PROCESS initializing application proces
This debug message is issued just before the controller attempts
-to create and initialize it's process instance.
+to create and initialize its process instance.
% D2CTL_SESSION_FAIL failed to establish BIND 10 session: %1
The controller has failed to establish communication with the rest of BIND
10 and will exit.
% D2CTL_DISCONNECT_FAIL failed to disconnect from BIND 10 session: %1
-The controller has failed to terminate communication with the rest of BIND
-10.
+This message indicates that while shutting down, the DHCP-DDNS controller
+encountered an error terminating communication with the BIND10. The service
+will still exit. While theoretically possible, this situation is rather
+unlikely.
% D2CTL_STANDALONE skipping message queue, running standalone
This is a debug message indicating that the controller is running in the
} catch (const std::exception& ex) {
LOG_FATAL(d2_logger, D2PRC_FAILED).arg(ex.what());
isc_throw (DProcessBaseError,
- std::string("Process run method failed:") + ex.what());
+ "Process run method failed:" << ex.what());
}
}
}
void
-DControllerBase::setController(DControllerBase* controller) {
+DControllerBase::setController(const DControllerBasePtr& controller) {
if (controller_) {
// This shouldn't happen, but let's make sure it can't be done.
// It represents a programmatic error.
"Multiple controller instances attempted.");
}
- controller_ = DControllerBasePtr(controller);
+ controller_ = controller;
}
-int
+void
DControllerBase::launch(int argc, char* argv[]) {
- int ret = d2::NORMAL_EXIT;
-
// Step 1 is to parse the command line arguments.
try {
parseArgs(argc, argv);
} catch (const InvalidUsage& ex) {
usage(ex.what());
- return (d2::INVALID_USAGE);
+ throw; // rethrow it
}
-#if 1
- //@TODO During initial development default to max log, no buffer
- isc::log::initLogger(name_, isc::log::DEBUG,
- isc::log::MAX_DEBUG_LEVEL, NULL, false);
-#else
// Now that we know what the mode flags are, we can init logging.
// If standalone is enabled, do not buffer initial log messages
isc::log::initLogger(name_,
((verbose_ && stand_alone_)
? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone_);
-#endif
LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2CTL_STARTING).arg(getpid());
try {
- // Step 2 is to create and initialize the application process.
+ // Step 2 is to create and initialize the application process object.
initProcess();
} catch (const std::exception& ex) {
- LOG_ERROR(d2_logger, D2CTL_SESSION_FAIL).arg(ex.what());
- return (PROCESS_INIT_ERROR);
+ LOG_FATAL(d2_logger, D2CTL_INIT_PROCESS).arg(ex.what());
+ isc_throw (ProcessInitError,
+ "Application Process initialization failed:" << ex.what());
}
// Next we connect if we are running integrated.
try {
establishSession();
} catch (const std::exception& ex) {
- LOG_ERROR(d2_logger, D2CTL_SESSION_FAIL).arg(ex.what());
- return (d2::SESSION_START_ERROR);
+ LOG_FATAL(d2_logger, D2CTL_SESSION_FAIL).arg(ex.what());
+ isc_throw (SessionStartError,
+ "Session start up failed:" << ex.what());
}
}
runProcess();
} catch (const std::exception& ex) {
LOG_FATAL(d2_logger, D2CTL_FAILED).arg(ex.what());
- ret = d2::RUN_ERROR;
+ isc_throw (ProcessRunError,
+ "Application process event loop failed:" << ex.what());
}
- // If running integrated, always try to disconnect.
+ // If running integrated, disconnect.
if (!stand_alone_) {
try {
disconnectSession();
} catch (const std::exception& ex) {
LOG_ERROR(d2_logger, D2CTL_DISCONNECT_FAIL).arg(ex.what());
- ret = d2::SESSION_END_ERROR;
+ isc_throw (SessionEndError, "Session end failed:" << ex.what());
}
}
// All done, so bail out.
LOG_INFO(d2_logger, D2CTL_STOPPING);
- return (ret);
}
+
void
DControllerBase::parseArgs(int argc, char* argv[])
{
case '?': {
// We hit an invalid option.
- std::stringstream tmp;
- tmp << " unsupported option: [" << (char)optopt << "] "
- << (!optarg ? "" : optarg);
+ isc_throw(InvalidUsage, "unsupported option: ["
+ << static_cast<char>(optopt) << "] "
+ << (!optarg ? "" : optarg));
- isc_throw(InvalidUsage,tmp.str());
break;
}
// We hit a valid custom option
if (!customOption(ch, optarg)) {
// This would be a programmatic error.
- std::stringstream tmp;
- tmp << " Option listed but implemented?: [" <<
- (char)ch << "] " << (!optarg ? "" : optarg);
- isc_throw(InvalidUsage,tmp.str());
+ isc_throw(InvalidUsage, " Option listed but implemented?: ["
+ << static_cast<char>(ch) << "] "
+ << (!optarg ? "" : optarg));
}
break;
}
// There was too much information on the command line.
if (argc > optind) {
- std::stringstream tmp;
- tmp << "extraneous command line information";
- isc_throw(InvalidUsage,tmp.str());
+ isc_throw(InvalidUsage, "extraneous command line information");
}
}
try {
process_.reset(createProcess());
} catch (const std::exception& ex) {
- isc_throw (DControllerBaseError, std::string("createProcess failed:")
- + ex.what());
+ isc_throw(DControllerBaseError, std::string("createProcess failed:")
+ + ex.what());
}
// This is pretty unlikely, but will test for it just to be safe..
if (!process_) {
- isc_throw (DControllerBaseError, "createProcess returned NULL");
+ isc_throw(DControllerBaseError, "createProcess returned NULL");
}
// Invoke application's init method (Note this call should throw
// Static callback which invokes non-static handler on singleton
isc::data::ConstElementPtr
DControllerBase::commandHandler(const std::string& command,
- isc::data::ConstElementPtr args) {
+ isc::data::ConstElementPtr args) {
LOG_DEBUG(d2_logger, DBGLVL_COMMAND, D2CTL_COMMAND_RECEIVED)
.arg(command).arg(args->str());
isc::data::ConstElementPtr
DControllerBase::shutdown() {
- // @TODO (tmark) - not sure about io_service_->stop here
- // IF application is using this service for all of its IO, stopping
- // here would mean, no more work by the application.. UNLESS it resets
- // it. People have discussed letting the application finish any in-progress
- // updates before shutting down. If we don't stop it here, then
- // application can't use io_service_->run(), it will never "see" the
- // shutdown.
- io_service_->stop();
if (process_) {
process_->shutdown();
} else {
/// normal or otherwise, the Controller's launch method will return one of
/// these values.
-/// @brief Indicates normal shutdown.
-static const int NORMAL_EXIT = 0;
-/// @brief Indicates invalid command line.
-static const int INVALID_USAGE = 1;
-/// @brief Failed to create and initialize application process.
-static const int PROCESS_INIT_ERROR = 2;
-/// @brief Could not connect to BIND10 (integrated mode only).
-static const int SESSION_START_ERROR = 3;
-/// @brief A fatal error occurred in the application process.
-static const int RUN_ERROR = 4;
-/// @brief Error occurred disconnecting from BIND10 (integrated mode only).
-static const int SESSION_END_ERROR = 5;
-
/// @brief Exception thrown when the command line is invalid.
class InvalidUsage : public isc::Exception {
public:
isc::Exception(file, line, what) { };
};
+/// @brief Exception thrown when the application process fails.
+class ProcessInitError: public isc::Exception {
+public:
+ ProcessInitError (const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) { };
+};
+
+/// @brief Exception thrown when the session start up fails.
+class SessionStartError: public isc::Exception {
+public:
+ SessionStartError (const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) { };
+};
+
+/// @brief Exception thrown when the application process encounters an
+/// operation in its event loop (i.e. run method).
+class ProcessRunError: public isc::Exception {
+public:
+ ProcessRunError (const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) { };
+};
+
+/// @brief Exception thrown when the session end fails.
+class SessionEndError: public isc::Exception {
+public:
+ SessionEndError (const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) { };
+};
+
+
/// @brief Exception thrown when the controller encounters an operational error.
class DControllerBaseError : public isc::Exception {
public:
/// integrated mode as a BIND10 module or stand-alone. It coordinates command
/// line argument parsing, process instantiation and initialization, and runtime
/// control through external command and configuration event handling.
-/// It creates the io_service_ instance which is used for runtime control
-/// events and passes the io_service into the application process at process
+/// It creates the IOService instance which is used for runtime control
+/// events and passes the IOService into the application process at process
/// creation. In integrated mode it is responsible for establishing BIND10
-/// session(s) and passes this io_service_ into the session creation method(s).
-/// It also provides the callback handlers for command and configuration events.
+/// session(s) and passes this IOService into the session creation method(s).
+/// It also provides the callback handlers for command and configuration events
+/// received from the external framework (aka BIND10). For example, when
+/// running in integrated mode and a user alters the configuration with the
+/// bindctl tool, BIND10 will emit a configuration message which is sensed by
+/// the controller's IOService. The IOService in turn invokes the configuration
+/// callback, DControllerBase::configHandler(). If the user issues a command
+/// such as shutdown via bindctl, BIND10 will emit a command message, which is
+/// sensed by controller's IOService which invokes the command callback,
+/// DControllerBase::commandHandler().
+///
/// NOTE: Derivations must supply their own static singleton instance method(s)
/// for creating and fetching the instance. The base class declares the instance
/// member in order for it to be available for BIND10 callback functions. This
-/// would not be required if BIND10 supported instance method callbacks.
+/// would not be required if BIND10 supported instance method callbacks.
class DControllerBase : public boost::noncopyable {
public:
/// @brief Constructor
/// @param argc is the number of command line arguments supplied
/// @param argv is the array of string (char *) command line arguments
///
- /// @return returns one of the following integer values:
- /// d2::NORMAL_EXIT - Indicates normal shutdown.
- /// d2::INVALID_USAGE - Indicates invalid command line.
- /// d2::PROCESS_INIT_ERROR - Failed to create and initialize application
- /// process
- /// d2::SESSION_START_ERROR - Could not connect to BIND10 (integrated mode
+ /// @throw throws one of the following exceptions:
+ /// InvalidUsage - Indicates invalid command line.
+ /// ProcessInitError - Failed to create and initialize application
+ /// process object.
+ /// SessionStartError - Could not connect to BIND10 (integrated mode only).
+ /// ProcessRunError - A fatal error occurred while in the application
+ /// process event loop.
+ /// SessionEndError - Could not disconnect from BIND10 (integrated mode
/// only).
- /// d2::RUN_ERROR - An fatal error occurred in the application process
- /// d2::SESSION_END_ERROR = 4;
- int launch(int argc, char* argv[]);
+ void launch(int argc, char* argv[]);
/// @brief A dummy configuration handler that always returns success.
///
virtual bool customOption(int option, char *optarg);
/// @brief Abstract method that is responsible for instantiating the
- /// application process instance. It is invoked by the controller after
+ /// application process object. It is invoked by the controller after
/// command line argument parsing as part of the process initialization
/// (see initProcess method).
///
- /// @return returns a pointer to the new process instance (DProcessBase*)
+ /// @return returns a pointer to the new process object (DProcessBase*)
/// or NULL if the create fails.
/// Note this value is subsequently wrapped in a smart pointer.
virtual DProcessBase* createProcess() = 0;
/// invalid usage conditions.
///
/// @return returns the desired text.
- virtual const std::string getUsageText() {
+ virtual const std::string getUsageText() const {
return ("");
}
/// line interpretation.
///
/// @return returns a string containing the custom option letters.
- virtual const std::string getCustomOpts() {
+ virtual const std::string getCustomOpts() const {
return ("");
}
/// @brief Supplies the controller name.
///
/// @return returns the controller name string
- const std::string& getName() {
+ const std::string getName() const {
return (name_);
}
/// @brief Supplies whether or not the controller is in stand alone mode.
///
/// @return returns true if in stand alone mode, false otherwise
- bool isStandAlone() {
+ const bool isStandAlone() const {
return (stand_alone_);
}
/// @brief Supplies whether or not verbose logging is enabled.
///
/// @return returns true if verbose logging is enabled.
- bool isVerbose() {
+ const bool isVerbose() const {
return (verbose_);
}
/// file.
///
/// @return returns the file name string.
- const std::string& getSpecFileName() {
+ const std::string getSpecFileName() const {
return (spec_file_name_);
}
return (controller_);
}
- /// @brief Static setter which returns the singleton instance.
+ /// @brief Static setter which sets the singleton instance.
+ ///
+ /// @param controller is a pointer to the singleton instance.
///
- /// @return returns a pointer reference to the private singleton instance
- /// member.
/// @throw throws DControllerBase error if an attempt is made to set the
/// instance a second time.
- static void setController(DControllerBase* controller);
+ static void setController(const DControllerBasePtr& controller);
private:
/// @brief Processes the command line arguments. It is the first step
///
/// @param text is a string message which will preceded the usage text.
/// This is intended to be used for specific usage violation messages.
- void usage(const std::string & text);
+ void usage(const std::string& text);
private:
/// @brief Text label for the controller. Typically this would be the
/// @brief Indicates if the controller stand alone mode is enabled. When
/// enabled, the controller will not establish connectivity with BIND10.
bool stand_alone_;
- /// @brief Indicates if the verbose logging mode is enabled.
+ /// @brief Indicates if the verbose logging mode is enabled.
bool verbose_;
+
/// @brief The absolute file name of the BIND10 spec file.
std::string spec_file_name_;
/// to application. It must be invoked prior to invoking run. This would
/// likely include the creation of additional IO sources and their
/// integration into the io_service.
- /// @throw throws a DProcessBaseError if the initialization fails.
+ /// @throw throws DProcessBaseError if the initialization fails.
virtual void init() = 0;
/// @brief Implements the process's event loop. In its simplest form it
/// would an invocation io_service_->run(). This method should not exit
/// until the process itself is exiting due to a request to shutdown or
/// some anomaly is forcing an exit.
- /// @throw throws a DProcessBaseError if an operational error is encountered.
+ /// @throw throws DProcessBaseError if an operational error is encountered.
virtual void run() = 0;
/// @brief Implements the process's shutdown processing. When invoked, it
/// should ensure that the process gracefully exits the run method.
- /// @throw throws a DProcessBaseError if an operational error is encountered.
- virtual void shutdown() = 0;
+ /// The default implementation sets the shutdown flag and stops IOService.
+ /// @throw throws DProcessBaseError if an operational error is encountered.
+ virtual void shutdown() {
+ setShutdownFlag(true);
+ stopIOService();
+ };
/// @brief Processes the given configuration.
///
/// @brief Checks if the process has been instructed to shut down.
///
/// @return returns true if process shutdown flag is true.
- bool shouldShutdown() {
+ const bool shouldShutdown() const {
return (shut_down_flag_);
}
/// @brief Fetches the name of the controller.
///
/// @return returns a reference the controller's name string.
- const std::string& getName() const {
+ const std::string getName() const {
return (name_);
}
return (io_service_);
}
+ /// @brief Convenience method for stopping IOservice processing.
+ /// Invoking this will cause the process to exit any blocking
+ /// IOService method such as run(). No further IO events will be
+ /// processed.
+ void stopIOService() {
+ io_service_->stop();
+ }
+
private:
/// @brief Text label for the process. Generally used in log statements,
/// but otherwise can be arbitrary.
"commands": [
{
"command_name": "shutdown",
- "command_description": "Shut down the stats httpd",
+ "command_description": "Shut down the DHCP-DDNS service",
"command_args": [
{
"item_name": "pid",
#include <config.h>
#include <d2/d2_log.h>
#include <d2/d2_controller.h>
+#include <exceptions/exceptions.h>
#include <log/logger_support.h>
#include <log/logger_manager.h>
/// This file contains entry point (main() function) for standard DHCP-DDNS
/// process, b10-dhcp-ddns, component for BIND10 framework. It fetches
/// the D2Controller singleton instance and invokes its launch method.
-/// The exit value of the program will the return value of launch:
-/// d2::NORMAL_EXIT - Indicates normal shutdown.
-/// d2::INVALID_USAGE - Indicates invalid command line.
-/// d2::PROCESS_INIT_ERROR - Failed to create and initialize application
-/// process
-/// d2::SESSION_START_ERROR - Could not connect to BIND10 (integrated mode
-/// only).
-/// d2::RUN_ERROR - A fatal error occurred in the application process
-/// d2::SESSION_END_ERROR - Error occurred disconnecting from BIND10 (integrated
-/// mode only).
-int
-main(int argc, char* argv[]) {
+/// The exit value of the program will be EXIT_SUCCESS if there were no
+/// errors, EXIT_FAILURE otherwise.
+int main(int argc, char* argv[]) {
+ int ret = EXIT_SUCCESS;
// Instantiate/fetch the DHCP-DDNS application controller singleton.
DControllerBasePtr& controller = D2Controller::instance();
// Launch the controller passing in command line arguments.
// Exit program with the controller's return code.
- return (controller->launch(argc, argv));
+ try {
+ controller->launch(argc, argv);
+ } catch (const isc::Exception& ex) {
+ std::cerr << "Service failed:" << ex.what() << std::endl;
+ ret = EXIT_FAILURE;
+ }
+
+ return (ret);
}
/// 1. Standard command line options are supported.
/// 2. Invalid options are detected.
TEST_F(D2ControllerTest, commandLineArgs) {
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
// Verify that both flags are false initially.
EXPECT_TRUE(checkVerbose(true));
// Verify that an unknown option is detected.
- char* argv2[] = { (char*)"progName", (char*)"-x" };
+ char* argv2[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-x") };
argc = 2;
- EXPECT_THROW (parseArgs(argc, argv2), InvalidUsage);
+ EXPECT_THROW(parseArgs(argc, argv2), InvalidUsage);
}
/// @brief Tests application process creation and initialization.
/// @brief Tests launch and normal shutdown (stand alone mode).
/// This creates an interval timer to generate a normal shutdown and then
/// launches with a valid, stand-alone command line and no simulated errors.
-/// Launch exit code should be d2::NORMAL_EXIT.
TEST_F(D2ControllerTest, launchNormalShutdown) {
// command line to run standalone
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
// Use an asiolink IntervalTimer and callback to generate the
// Record start time, and invoke launch().
ptime start = microsec_clock::universal_time();
- int rcode = launch(argc, argv);
+ EXPECT_NO_THROW(launch(argc, argv));
// Record stop time.
ptime stop = microsec_clock::universal_time();
- // Verify normal shutdown status.
- EXPECT_EQ(d2::NORMAL_EXIT, rcode);
-
// Verify that duration of the run invocation is the same as the
// timer duration. This demonstrates that the shutdown was driven
// by an io_service event and callback.
print("Note: Simple test to verify that D2 server can be started.")
# note that "-s" for stand alone is necessary in order to flush the log output
# soon enough to catch it.
- (returncode, output, error) = self.runCommand(["../b10-d2", "-s", "-v"])
+ (returncode, output, error) = self.runCommand(["../b10-dhcp-ddns",
+ "-s", "-v"])
output_text = str(output) + str(error)
self.assertEqual(output_text.count("D2CTL_STARTING"), 1)
EXPECT_TRUE(checkVerbose(false));
// Verify that standard options can be parsed without error.
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
EXPECT_NO_THROW(parseArgs(argc, argv));
EXPECT_TRUE(checkVerbose(true));
// Verify that the custom command line option is parsed without error.
- char xopt[3]="";
- sprintf (xopt, "-%c", *DStubController::stub_option_x_);
- char* argv1[] = { (char*)"progName", xopt};
+ char xopt[3] = "- ";
+ xopt[1] = *DStubController::stub_option_x_;
+ char* argv1[] = { const_cast<char*>("progName"), xopt};
argc = 2;
EXPECT_NO_THROW (parseArgs(argc, argv1));
// Verify that an unknown option is detected.
- char* argv2[] = { (char*)"progName", (char*)"-bs" };
+ char* argv2[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-bs") };
argc = 2;
EXPECT_THROW (parseArgs(argc, argv2), InvalidUsage);
// Verify that extraneous information is detected.
- char* argv3[] = { (char*)"progName", (char*)"extra", (char*)"information" };
+ char* argv3[] = { const_cast<char*>("progName"),
+ const_cast<char*>("extra"),
+ const_cast<char*>("information") };
argc = 3;
EXPECT_THROW (parseArgs(argc, argv3), InvalidUsage);
-
-
}
/// @brief Tests application process creation and initialization.
}
/// @brief Tests launch handling of invalid command line.
-/// This test launches with an invalid command line which should exit with
-/// an status of d2::INVALID_USAGE.
+/// This test launches with an invalid command line which should throw
+/// an InvalidUsage.
TEST_F(DStubControllerTest, launchInvalidUsage) {
// Command line to run integrated
- char* argv[] = { (char*)"progName",(char*) "-z" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-z") };
int argc = 2;
// Launch the controller in integrated mode.
- int rcode = launch(argc, argv);
-
- // Verify session failure exit status.
- EXPECT_EQ(d2::INVALID_USAGE, rcode);
+ EXPECT_THROW(launch(argc, argv), InvalidUsage);
}
/// @brief Tests launch handling of failure in application process
/// initialization. This test launches with a valid command line but with
-/// SimFailure set to fail during process creation. Launch exit code should
-/// be d2::PROCESS_INIT_ERROR.
+/// SimFailure set to fail during process creation. Launch should throw
+/// ProcessInitError.
TEST_F(DStubControllerTest, launchProcessInitError) {
// Command line to run integrated
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
// Launch the controller in stand alone mode.
SimFailure::set(SimFailure::ftCreateProcessException);
- int rcode = launch(argc, argv);
-
- // Verify session failure exit status.
- EXPECT_EQ(d2::PROCESS_INIT_ERROR, rcode);
+ EXPECT_THROW(launch(argc, argv), ProcessInitError);
}
/// @brief Tests launch and normal shutdown (stand alone mode).
/// This creates an interval timer to generate a normal shutdown and then
/// launches with a valid, stand-alone command line and no simulated errors.
-/// Launch exit code should be d2::NORMAL_EXIT.
TEST_F(DStubControllerTest, launchNormalShutdown) {
// command line to run standalone
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
// Use an asiolink IntervalTimer and callback to generate the
// Record start time, and invoke launch().
ptime start = microsec_clock::universal_time();
- int rcode = launch(argc, argv);
+ EXPECT_NO_THROW(launch(argc, argv));
// Record stop time.
ptime stop = microsec_clock::universal_time();
- // Verify normal shutdown status.
- EXPECT_EQ(d2::NORMAL_EXIT, rcode);
-
// Verify that duration of the run invocation is the same as the
// timer duration. This demonstrates that the shutdown was driven
// by an io_service event and callback.
/// @brief Tests launch with an operational error during application execution.
/// This test creates an interval timer to generate a runtime exception during
/// the process event loop. It launches wih a valid, stand-alone command line
-/// and no simulated errors. Launch exit code should be d2::RUN_ERROR.
+/// and no simulated errors. Launch should throw ProcessRunError.
TEST_F(DStubControllerTest, launchRuntimeError) {
// command line to run standalone
- char* argv[] = { (char*)"progName", (char*)"-s", (char*)"-v" };
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-s"),
+ const_cast<char*>("-v") };
int argc = 3;
// Use an asiolink IntervalTimer and callback to generate the
// Record start time, and invoke launch().
ptime start = microsec_clock::universal_time();
- int rcode = launch(argc, argv);
+ EXPECT_THROW(launch(argc, argv), ProcessRunError);
// Record stop time.
ptime stop = microsec_clock::universal_time();
- // Verify abnormal shutdown status.
- EXPECT_EQ(d2::RUN_ERROR, rcode);
-
// Verify that duration of the run invocation is the same as the
// timer duration. This demonstrates that the shutdown was driven
// by an io_service event and callback.
/// @brief Tests launch with a session establishment failure.
/// This test launches with a valid command line for integrated mode and no.
/// Attempting to connect to BIND10 should fail, even if BIND10 is running
-/// UNLESS the test is run as root. Launch exit code should be
-/// d2::SESSION_START_ERROR.
+/// UNLESS the test is run as root. Launch should throw SessionStartError.
TEST_F(DStubControllerTest, launchSessionFailure) {
// Command line to run integrated
char* argv[] = { (char*)"progName" };
int argc = 1;
// Launch the controller in integrated mode.
- int rcode = launch(argc, argv);
-
- // Verify session failure exit status.
- EXPECT_EQ(d2::SESSION_START_ERROR, rcode);
+ EXPECT_THROW(launch(argc, argv), SessionStartError);
}
/// @brief Configuration update event testing.
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <d2/d2_log.h>
#include <d2/spec_config.h>
#include <d2/tests/d_test_stubs.h>
SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure;
// Define custom process command supported by DStubProcess.
-const std::string DStubProcess::stub_proc_command_("cool_proc_cmd");
+const char* DStubProcess::stub_proc_command_("cool_proc_cmd");
DStubProcess::DStubProcess(const char* name, IOServicePtr io_service)
: DProcessBase(name, io_service) {
// Simulates a failure during shutdown process.
isc_throw(DProcessBaseError, "DStubProcess simulated shutdown failure");
}
- setShutdownFlag(true);
+
+ DProcessBase::shutdown();
}
isc::data::ConstElementPtr
//************************** DStubController *************************
// Define custom controller command supported by DStubController.
-const std::string DStubController::stub_ctl_command_("spiffy");
+const char* DStubController::stub_ctl_command_("spiffy");
// Define custom command line option command supported by DStubController.
const char* DStubController::stub_option_x_ = "x";
DStubController::instance() {
// If the singleton hasn't been created, do it now.
if (!getController()) {
- setController(new DStubController());
+ //setController(new DStubController());
+ DControllerBasePtr p(new DStubController());
+ setController(p);
}
return (getController());
DStubController::customOption(int option, char* /* optarg */)
{
// Check for the custom option supported by DStubController.
- if ((char)(option) == *stub_option_x_) {
+ if (static_cast<char>(option) == *stub_option_x_) {
return (true);
}
return (answer);
}
-const std::string DStubController::getCustomOpts(){
+const std::string DStubController::getCustomOpts() const {
// Return the "list" of custom options supported by DStubController.
return (std::string(stub_option_x_));
}
public:
/// @brief Static constant that defines a custom process command string.
- static const std::string stub_proc_command_;
+ static const char* stub_proc_command_;
/// @brief Constructor
///
/// @brief Defines a custom controller command string. This is a
/// custom command supported by DStubController.
- static const std::string stub_ctl_command_;
+ static const char* stub_ctl_command_;
/// @brief Defines a custom command line option supported by
/// DStubController.
/// addition option, stub_option_x_.
///
/// @return returns a string containing the option letters.
- virtual const std::string getCustomOpts();
+ virtual const std::string getCustomOpts() const;
private:
/// @brief Constructor is private to protect singleton integrity.
/// @Wrapper to invoke the Controller's launch method. Please refer to
/// DControllerBase::launch for details.
- int launch(int argc, char* argv[]) {
+ void launch(int argc, char* argv[]) {
optind = 1;
- return (getController()->launch(argc, argv));
+ getController()->launch(argc, argv);
}
/// @Wrapper to invoke the Controller's disconnectSession method. Please