Parcourir la source

[2956] Changes to address review comments. Note that the module name is
now b10-dhcp-ddns.

Thomas Markwalder il y a 12 ans
Parent
commit
21f3ea9067

+ 19 - 19
src/bin/d2/Makefile.am

@@ -18,15 +18,15 @@ pkglibexecdir = $(libexecdir)/@PACKAGE@
 
 
 CLEANFILES  = *.gcno *.gcda spec_config.h d2_messages.h d2_messages.cc
 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)
 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
 if GENERATE_DOCS
-b10-d2.8: b10-d2.xml
+b10-dhcp-ddns.8: b10-dhcp-ddns.xml
 	@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
 	@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
         http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
         http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
-	$(srcdir)/b10-d2.xml
+	$(srcdir)/b10-dchdp-ddns.xml
 
 
 else
 else
 
 
@@ -44,23 +44,23 @@ d2_messages.h d2_messages.cc: d2_messages.mes
 
 
 BUILT_SOURCES = spec_config.h d2_messages.h d2_messages.cc
 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
 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

+ 7 - 7
src/bin/d2/b10-d2.xml

@@ -24,13 +24,13 @@
   </refentryinfo>
   </refentryinfo>
 
 
   <refmeta>
   <refmeta>
-    <refentrytitle>b10-d2</refentrytitle>
+    <refentrytitle>b10-dhcp-ddns</refentrytitle>
     <manvolnum>8</manvolnum>
     <manvolnum>8</manvolnum>
     <refmiscinfo>BIND10</refmiscinfo>
     <refmiscinfo>BIND10</refmiscinfo>
   </refmeta>
   </refmeta>
 
 
   <refnamediv>
   <refnamediv>
-    <refname>b10-d2</refname>
+    <refname>b10-dhcp-ddns</refname>
     <refpurpose>D2 process in BIND 10 architecture</refpurpose>
     <refpurpose>D2 process in BIND 10 architecture</refpurpose>
   </refnamediv>
   </refnamediv>
 
 
@@ -43,14 +43,14 @@
 
 
   <refsynopsisdiv>
   <refsynopsisdiv>
     <cmdsynopsis>
     <cmdsynopsis>
-      <command>b10-d2</command>
+      <command>b10-dhcp-ddns</command>
       <arg><option>-v</option></arg>
       <arg><option>-v</option></arg>
     </cmdsynopsis>
     </cmdsynopsis>
   </refsynopsisdiv>
   </refsynopsisdiv>
 
 
   <refsynopsisdiv>
   <refsynopsisdiv>
     <cmdsynopsis>
     <cmdsynopsis>
-      <command>b10-d2</command>
+      <command>b10-dhcp-ddns</command>
       <arg><option>-s</option></arg>
       <arg><option>-s</option></arg>
     </cmdsynopsis>
     </cmdsynopsis>
   </refsynopsisdiv>
   </refsynopsisdiv>
@@ -59,7 +59,7 @@
   <refsect1>
   <refsect1>
     <title>DESCRIPTION</title>
     <title>DESCRIPTION</title>
     <para>
     <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.
       to update DNS mapping based on DHCP lease change events.
     </para>
     </para>
 
 
@@ -95,7 +95,7 @@
     <title>SEE ALSO</title>
     <title>SEE ALSO</title>
     <para>
     <para>
       <citerefentry>
       <citerefentry>
-        <refentrytitle>b10-d2</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>b10-dhcp-ddns</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       </citerefentry>,
       <citerefentry>
       <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
@@ -106,7 +106,7 @@
   <refsect1>
   <refsect1>
     <title>HISTORY</title>
     <title>HISTORY</title>
     <para>
     <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.
       May 2013 by the ISC Kea/Dhcp team.
     </para>
     </para>
   </refsect1>
   </refsect1>

+ 4 - 3
src/bin/d2/d2_controller.cc

@@ -23,10 +23,11 @@ DControllerBasePtr&
 D2Controller::instance() {
 D2Controller::instance() {
     // If the instance hasn't been created yet, create it.  Note this method
     // 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 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()) {
     if (!getController()) {
-        setController(new D2Controller());
+        DControllerBasePtr controller_ptr(new D2Controller());
+        setController(controller_ptr);
     }
     }
 
 
     return (getController());
     return (getController());

+ 1 - 1
src/bin/d2/d2_log.cc

@@ -21,7 +21,7 @@ namespace d2 {
 
 
 /// @brief Defines the service name which is used in the controller constructor
 /// @brief Defines the service name which is used in the controller constructor
 /// and ultimately defines the BIND10 module name.
 /// 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.
 /// @brief Defines the logger used within D2.
 isc::log::Logger d2_logger(D2_MODULE_NAME);
 isc::log::Logger d2_logger(D2_MODULE_NAME);

+ 7 - 5
src/bin/d2/d2_messages.mes

@@ -27,11 +27,11 @@ This is a debug message issued when the service process has been instructed
 to shut down by the controller.
 to shut down by the controller.
 
 
 % D2PRC_PROCESS_INIT DHCP-DDNS application init invoked
 % 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. 
 init method. 
 
 
 % D2PRC_RUN_ENTER process has entered the event loop 
 % 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. 
 run method. 
 
 
 % D2PRC_RUN_EXIT process is exiting the event loop
 % D2PRC_RUN_EXIT process is exiting the event loop
@@ -52,15 +52,17 @@ has been invoked.
 
 
 % D2CTL_INIT_PROCESS initializing application proces 
 % D2CTL_INIT_PROCESS initializing application proces 
 This debug message is issued just before the controller attempts
 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
 % D2CTL_SESSION_FAIL failed to establish BIND 10 session: %1
 The controller has failed to establish communication with the rest of BIND
 The controller has failed to establish communication with the rest of BIND
 10 and will exit. 
 10 and will exit. 
 
 
 % D2CTL_DISCONNECT_FAIL failed to disconnect from BIND 10 session: %1
 % 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
 % D2CTL_STANDALONE skipping message queue, running standalone
 This is a debug message indicating that the controller is running in the
 This is a debug message indicating that the controller is running in the

+ 1 - 1
src/bin/d2/d2_process.cc

@@ -45,7 +45,7 @@ D2Process::run() {
         } catch (const std::exception& ex) {
         } catch (const std::exception& ex) {
             LOG_FATAL(d2_logger, D2PRC_FAILED).arg(ex.what());
             LOG_FATAL(d2_logger, D2PRC_FAILED).arg(ex.what());
             isc_throw (DProcessBaseError,
             isc_throw (DProcessBaseError,
-                std::string("Process run method failed:") + ex.what());
+                       "Process run method failed:" << ex.what());
         }
         }
     }
     }
 
 

+ 27 - 44
src/bin/d2/d_controller.cc

@@ -32,7 +32,7 @@ DControllerBase::DControllerBase(const char* name)
 }
 }
 
 
 void
 void
-DControllerBase::setController(DControllerBase* controller) {
+DControllerBase::setController(const DControllerBasePtr& controller) {
     if (controller_) {
     if (controller_) {
         // This shouldn't happen, but let's make sure it can't be done.
         // This shouldn't happen, but let's make sure it can't be done.
         // It represents a programmatic error.
         // It represents a programmatic error.
@@ -40,41 +40,34 @@ DControllerBase::setController(DControllerBase* controller) {
                 "Multiple controller instances attempted.");
                 "Multiple controller instances attempted.");
     }
     }
 
 
-    controller_ = DControllerBasePtr(controller);
+    controller_ = controller;
 }
 }
 
 
-int
+void
 DControllerBase::launch(int argc, char* argv[]) {
 DControllerBase::launch(int argc, char* argv[]) {
-    int ret = d2::NORMAL_EXIT;
-
     // Step 1 is to parse the command line arguments.
     // Step 1 is to parse the command line arguments.
     try {
     try {
         parseArgs(argc, argv);
         parseArgs(argc, argv);
     } catch (const InvalidUsage& ex) {
     } catch (const InvalidUsage& ex) {
         usage(ex.what());
         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.
     // Now that we know what the mode flags are, we can init logging.
     // If standalone is enabled, do not buffer initial log messages
     // If standalone is enabled, do not buffer initial log messages
     isc::log::initLogger(name_,
     isc::log::initLogger(name_,
                          ((verbose_ && stand_alone_)
                          ((verbose_ && stand_alone_)
                           ? isc::log::DEBUG : isc::log::INFO),
                           ? isc::log::DEBUG : isc::log::INFO),
                          isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone_);
                          isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone_);
-#endif
 
 
     LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2CTL_STARTING).arg(getpid());
     LOG_DEBUG(d2_logger, DBGLVL_START_SHUT, D2CTL_STARTING).arg(getpid());
     try {
     try {
-        // Step 2 is to create and initialize the application process.
+        // Step 2 is to create and initialize the application process object.
         initProcess();
         initProcess();
     } catch (const std::exception& ex) {
     } 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.
     // Next we connect if we are running integrated.
@@ -84,8 +77,9 @@ DControllerBase::launch(int argc, char* argv[]) {
         try {
         try {
             establishSession();
             establishSession();
         } catch (const std::exception& ex) {
         } 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());
         }
         }
     }
     }
 
 
@@ -95,24 +89,25 @@ DControllerBase::launch(int argc, char* argv[]) {
         runProcess();
         runProcess();
     } catch (const std::exception& ex) {
     } catch (const std::exception& ex) {
         LOG_FATAL(d2_logger, D2CTL_FAILED).arg(ex.what());
         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_) {
     if (!stand_alone_) {
         try {
         try {
             disconnectSession();
             disconnectSession();
         } catch (const std::exception& ex) {
         } catch (const std::exception& ex) {
             LOG_ERROR(d2_logger, D2CTL_DISCONNECT_FAIL).arg(ex.what());
             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.
     // All done, so bail out.
     LOG_INFO(d2_logger, D2CTL_STOPPING);
     LOG_INFO(d2_logger, D2CTL_STOPPING);
-    return (ret);
 }
 }
 
 
+
 void
 void
 DControllerBase::parseArgs(int argc, char* argv[])
 DControllerBase::parseArgs(int argc, char* argv[])
 {
 {
@@ -137,11 +132,10 @@ DControllerBase::parseArgs(int argc, char* argv[])
 
 
         case '?': {
         case '?': {
             // We hit an invalid option.
             // 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;
             break;
             }
             }
 
 
@@ -149,10 +143,9 @@ DControllerBase::parseArgs(int argc, char* argv[])
             // We hit a valid custom option
             // We hit a valid custom option
             if (!customOption(ch, optarg)) {
             if (!customOption(ch, optarg)) {
                 // This would be a programmatic error.
                 // 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;
             break;
         }
         }
@@ -160,9 +153,7 @@ DControllerBase::parseArgs(int argc, char* argv[])
 
 
     // There was too much information on the command line.
     // There was too much information on the command line.
     if (argc > optind) {
     if (argc > optind) {
-        std::stringstream tmp;
-        tmp << "extraneous command line information";
-        isc_throw(InvalidUsage,tmp.str());
+        isc_throw(InvalidUsage, "extraneous command line information");
     }
     }
 }
 }
 
 
@@ -181,13 +172,13 @@ DControllerBase::initProcess() {
     try {
     try {
         process_.reset(createProcess());
         process_.reset(createProcess());
     } catch (const std::exception& ex) {
     } 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..
     // This is pretty unlikely, but will test for it just to be safe..
     if (!process_) {
     if (!process_) {
-        isc_throw (DControllerBaseError, "createProcess returned NULL");
+        isc_throw(DControllerBaseError, "createProcess returned NULL");
     }
     }
 
 
     // Invoke application's init method (Note this call should throw
     // Invoke application's init method (Note this call should throw
@@ -300,7 +291,7 @@ DControllerBase::configHandler(isc::data::ConstElementPtr new_config) {
 // Static callback which invokes non-static handler on singleton
 // Static callback which invokes non-static handler on singleton
 isc::data::ConstElementPtr
 isc::data::ConstElementPtr
 DControllerBase::commandHandler(const std::string& command,
 DControllerBase::commandHandler(const std::string& command,
-                            isc::data::ConstElementPtr args) {
+                                isc::data::ConstElementPtr args) {
 
 
     LOG_DEBUG(d2_logger, DBGLVL_COMMAND, D2CTL_COMMAND_RECEIVED)
     LOG_DEBUG(d2_logger, DBGLVL_COMMAND, D2CTL_COMMAND_RECEIVED)
               .arg(command).arg(args->str());
               .arg(command).arg(args->str());
@@ -403,14 +394,6 @@ DControllerBase::customControllerCommand(const std::string& command,
 
 
 isc::data::ConstElementPtr
 isc::data::ConstElementPtr
 DControllerBase::shutdown() {
 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_) {
     if (process_) {
         process_->shutdown();
         process_->shutdown();
     } else {
     } else {

+ 68 - 41
src/bin/d2/d_controller.h

@@ -35,19 +35,6 @@ namespace d2 {
 /// normal or otherwise, the Controller's launch method will return one of
 /// normal or otherwise, the Controller's launch method will return one of
 /// these values.
 /// 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.
 /// @brief Exception thrown when the command line is invalid.
 class InvalidUsage : public isc::Exception {
 class InvalidUsage : public isc::Exception {
 public:
 public:
@@ -55,6 +42,36 @@ public:
         isc::Exception(file, line, what) { };
         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.
 /// @brief Exception thrown when the controller encounters an operational error.
 class DControllerBaseError : public isc::Exception {
 class DControllerBaseError : public isc::Exception {
 public:
 public:
@@ -82,15 +99,24 @@ typedef boost::shared_ptr<isc::config::ModuleCCSession> ModuleCCSessionPtr;
 /// integrated mode as a BIND10 module or stand-alone. It coordinates command
 /// integrated mode as a BIND10 module or stand-alone. It coordinates command
 /// line argument parsing, process instantiation and initialization, and runtime
 /// line argument parsing, process instantiation and initialization, and runtime
 /// control through external command and configuration event handling.
 /// 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
 /// 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)
 /// NOTE: Derivations must supply their own static singleton instance method(s)
 /// for creating and fetching the instance. The base class declares the instance
 /// 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
 /// 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 {
 class DControllerBase : public boost::noncopyable {
 public:
 public:
     /// @brief Constructor
     /// @brief Constructor
@@ -119,16 +145,16 @@ public:
     /// @param argc  is the number of command line arguments supplied
     /// @param argc  is the number of command line arguments supplied
     /// @param argv  is the array of string (char *) command line arguments
     /// @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).
     /// 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.
     /// @brief A dummy configuration handler that always returns success.
     ///
     ///
@@ -240,11 +266,11 @@ protected:
     virtual bool customOption(int option, char *optarg);
     virtual bool customOption(int option, char *optarg);
 
 
     /// @brief Abstract method that is responsible for instantiating the
     /// @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
     /// command line argument parsing as part of the process initialization
     /// (see initProcess method).
     /// (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.
     /// or NULL if the create fails.
     /// Note this value is subsequently wrapped in a smart pointer.
     /// Note this value is subsequently wrapped in a smart pointer.
     virtual DProcessBase* createProcess() = 0;
     virtual DProcessBase* createProcess() = 0;
@@ -294,7 +320,7 @@ protected:
     /// invalid usage conditions.
     /// invalid usage conditions.
     ///
     ///
     /// @return returns the desired text.
     /// @return returns the desired text.
-    virtual const std::string getUsageText() {
+    virtual const std::string getUsageText() const {
         return ("");
         return ("");
     }
     }
 
 
@@ -304,21 +330,21 @@ protected:
     /// line interpretation.
     /// line interpretation.
     ///
     ///
     /// @return returns a string containing the custom option letters.
     /// @return returns a string containing the custom option letters.
-    virtual const std::string getCustomOpts() {
+    virtual const std::string getCustomOpts() const {
         return ("");
         return ("");
     }
     }
 
 
     /// @brief Supplies the controller name.
     /// @brief Supplies the controller name.
     ///
     ///
     /// @return returns the controller name string
     /// @return returns the controller name string
-    const std::string& getName() {
+    const std::string getName() const {
         return (name_);
         return (name_);
     }
     }
 
 
     /// @brief Supplies whether or not the controller is in stand alone mode.
     /// @brief Supplies whether or not the controller is in stand alone mode.
     ///
     ///
     /// @return returns true if in stand alone mode, false otherwise
     /// @return returns true if in stand alone mode, false otherwise
-    bool isStandAlone() {
+    const bool isStandAlone() const {
         return (stand_alone_);
         return (stand_alone_);
     }
     }
 
 
@@ -332,7 +358,7 @@ protected:
     /// @brief Supplies whether or not verbose logging is enabled.
     /// @brief Supplies whether or not verbose logging is enabled.
     ///
     ///
     /// @return returns true if verbose logging is enabled.
     /// @return returns true if verbose logging is enabled.
-    bool isVerbose() {
+    const bool isVerbose() const {
         return (verbose_);
         return (verbose_);
     }
     }
 
 
@@ -354,7 +380,7 @@ protected:
     /// file.
     /// file.
     ///
     ///
     /// @return returns the file name string.
     /// @return returns the file name string.
-    const std::string& getSpecFileName() {
+    const std::string getSpecFileName() const {
         return (spec_file_name_);
         return (spec_file_name_);
     }
     }
 
 
@@ -373,13 +399,13 @@ protected:
         return (controller_);
         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
     /// @throw throws DControllerBase error if an attempt is made to set the
     /// instance a second time.
     /// instance a second time.
-    static void setController(DControllerBase* controller);
+    static void setController(const DControllerBasePtr& controller);
 
 
 private:
 private:
     /// @brief Processes the command line arguments. It is the first step
     /// @brief Processes the command line arguments. It is the first step
@@ -452,7 +478,7 @@ private:
     ///
     ///
     /// @param text is a string message which will preceded the usage text.
     /// @param text is a string message which will preceded the usage text.
     /// This is intended to be used for specific usage violation messages.
     /// This is intended to be used for specific usage violation messages.
-    void usage(const std::string & text);
+    void usage(const std::string& text);
 
 
 private:
 private:
     /// @brief Text label for the controller. Typically this would be the
     /// @brief Text label for the controller. Typically this would be the
@@ -462,9 +488,10 @@ private:
     /// @brief Indicates if the controller stand alone mode is enabled. When
     /// @brief Indicates if the controller stand alone mode is enabled. When
     /// enabled, the controller will not establish connectivity with BIND10.
     /// enabled, the controller will not establish connectivity with BIND10.
     bool stand_alone_;
     bool stand_alone_;
-    /// @brief Indicates if the verbose logging mode is enabled.
 
 
+    /// @brief Indicates if the verbose logging mode is enabled.
     bool verbose_;
     bool verbose_;
+
     /// @brief The absolute file name of the BIND10 spec file.
     /// @brief The absolute file name of the BIND10 spec file.
     std::string spec_file_name_;
     std::string spec_file_name_;
 
 

+ 18 - 6
src/bin/d2/d_process.h

@@ -72,20 +72,24 @@ public:
     /// to application. It must be invoked prior to invoking run. This would
     /// to application. It must be invoked prior to invoking run. This would
     /// likely include the creation of additional IO sources and their
     /// likely include the creation of additional IO sources and their
     /// integration into the io_service.
     /// integration into the io_service.
-    /// @throw throws a DProcessBaseError if the initialization fails.
+    /// @throw throws DProcessBaseError if the initialization fails.
     virtual void init() = 0;
     virtual void init() = 0;
 
 
     /// @brief Implements the process's event loop. In its simplest form it
     /// @brief Implements the process's event loop. In its simplest form it
     /// would an invocation io_service_->run().  This method should not exit
     /// would an invocation io_service_->run().  This method should not exit
     /// until the process itself is exiting due to a request to shutdown or
     /// until the process itself is exiting due to a request to shutdown or
     /// some anomaly is forcing an exit.
     /// 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;
     virtual void run() = 0;
 
 
     /// @brief Implements the process's shutdown processing. When invoked, it
     /// @brief Implements the process's shutdown processing. When invoked, it
     /// should ensure that the process gracefully exits the run method.
     /// 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 Processes the given configuration.
     ///
     ///
@@ -123,7 +127,7 @@ public:
     /// @brief Checks if the process has been instructed to shut down.
     /// @brief Checks if the process has been instructed to shut down.
     ///
     ///
     /// @return returns true if process shutdown flag is true.
     /// @return returns true if process shutdown flag is true.
-    bool shouldShutdown() {
+    const bool shouldShutdown() const {
         return (shut_down_flag_);
         return (shut_down_flag_);
     }
     }
 
 
@@ -137,7 +141,7 @@ public:
     /// @brief Fetches the name of the controller.
     /// @brief Fetches the name of the controller.
     ///
     ///
     /// @return returns a reference the controller's name string.
     /// @return returns a reference the controller's name string.
-    const std::string& getName() const {
+    const std::string getName() const {
         return (name_);
         return (name_);
     }
     }
 
 
@@ -148,6 +152,14 @@ public:
         return (io_service_);
         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:
 private:
     /// @brief Text label for the process. Generally used in log statements,
     /// @brief Text label for the process. Generally used in log statements,
     /// but otherwise can be arbitrary.
     /// but otherwise can be arbitrary.

+ 1 - 1
src/bin/d2/d2.spec

@@ -7,7 +7,7 @@
     "commands": [
     "commands": [
       {
       {
         "command_name": "shutdown",
         "command_name": "shutdown",
-        "command_description": "Shut down the stats httpd",
+        "command_description": "Shut down the DHCP-DDNS service",
         "command_args": [
         "command_args": [
           {
           {
             "item_name": "pid",
             "item_name": "pid",

+ 13 - 13
src/bin/d2/main.cc

@@ -15,6 +15,7 @@
 #include <config.h>
 #include <config.h>
 #include <d2/d2_log.h>
 #include <d2/d2_log.h>
 #include <d2/d2_controller.h>
 #include <d2/d2_controller.h>
+#include <exceptions/exceptions.h>
 #include <log/logger_support.h>
 #include <log/logger_support.h>
 #include <log/logger_manager.h>
 #include <log/logger_manager.h>
 
 
@@ -26,23 +27,22 @@ using namespace std;
 /// This file contains entry point (main() function) for standard DHCP-DDNS
 /// This file contains entry point (main() function) for standard DHCP-DDNS
 /// process, b10-dhcp-ddns, component for BIND10 framework.  It fetches
 /// process, b10-dhcp-ddns, component for BIND10 framework.  It fetches
 /// the D2Controller singleton instance and invokes its launch method.
 /// 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.
     // Instantiate/fetch the DHCP-DDNS application controller singleton.
     DControllerBasePtr& controller = D2Controller::instance();
     DControllerBasePtr& controller = D2Controller::instance();
 
 
     // Launch the controller passing in command line arguments.
     // Launch the controller passing in command line arguments.
     // Exit program with the controller's return code.
     // 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);
 }
 }

+ 10 - 9
src/bin/d2/tests/d2_controller_unittests.cc

@@ -81,7 +81,9 @@ TEST_F(D2ControllerTest, basicInstanceTesting) {
 /// 1. Standard command line options are supported.
 /// 1. Standard command line options are supported.
 /// 2. Invalid options are detected.
 /// 2. Invalid options are detected.
 TEST_F(D2ControllerTest, commandLineArgs) {
 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;
     int argc = 3;
 
 
     // Verify that both flags are false initially.
     // Verify that both flags are false initially.
@@ -96,9 +98,10 @@ TEST_F(D2ControllerTest, commandLineArgs) {
     EXPECT_TRUE(checkVerbose(true));
     EXPECT_TRUE(checkVerbose(true));
 
 
     // Verify that an unknown option is detected.
     // 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;
     argc = 2;
-    EXPECT_THROW (parseArgs(argc, argv2), InvalidUsage);
+    EXPECT_THROW(parseArgs(argc, argv2), InvalidUsage);
 }
 }
 
 
 /// @brief Tests application process creation and initialization.
 /// @brief Tests application process creation and initialization.
@@ -111,10 +114,11 @@ TEST_F(D2ControllerTest, initProcessTesting) {
 /// @brief Tests launch and normal shutdown (stand alone mode).
 /// @brief Tests launch and normal shutdown (stand alone mode).
 /// This creates an interval timer to generate a normal shutdown and then
 /// This creates an interval timer to generate a normal shutdown and then
 /// launches with a valid, stand-alone command line and no simulated errors.
 /// launches with a valid, stand-alone command line and no simulated errors.
-/// Launch exit code should be d2::NORMAL_EXIT.
 TEST_F(D2ControllerTest, launchNormalShutdown) {
 TEST_F(D2ControllerTest, launchNormalShutdown) {
     // command line to run standalone
     // 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;
     int argc = 3;
 
 
     // Use an asiolink IntervalTimer and callback to generate the
     // Use an asiolink IntervalTimer and callback to generate the
@@ -124,14 +128,11 @@ TEST_F(D2ControllerTest, launchNormalShutdown) {
 
 
     // Record start time, and invoke launch().
     // Record start time, and invoke launch().
     ptime start = microsec_clock::universal_time();
     ptime start = microsec_clock::universal_time();
-    int rcode = launch(argc, argv);
+    EXPECT_NO_THROW(launch(argc, argv));
 
 
     // Record stop time.
     // Record stop time.
     ptime stop = microsec_clock::universal_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
     // Verify that duration of the run invocation is the same as the
     // timer duration.  This demonstrates that the shutdown was driven
     // timer duration.  This demonstrates that the shutdown was driven
     // by an io_service event and callback.
     // by an io_service event and callback.

+ 2 - 1
src/bin/d2/tests/d2_test.py

@@ -159,7 +159,8 @@ class TestD2Daemon(unittest.TestCase):
         print("Note: Simple test to verify that D2 server can be started.")
         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
         # note that "-s" for stand alone is necessary in order to flush the log output
         # soon enough to catch it.
         # 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)
         output_text = str(output) + str(error)
         self.assertEqual(output_text.count("D2CTL_STARTING"), 1)
         self.assertEqual(output_text.count("D2CTL_STARTING"), 1)
 
 

+ 33 - 40
src/bin/d2/tests/d_controller_unittests.cc

@@ -78,7 +78,9 @@ TEST_F(DStubControllerTest, commandLineArgs) {
     EXPECT_TRUE(checkVerbose(false));
     EXPECT_TRUE(checkVerbose(false));
 
 
     // Verify that standard options can be parsed without error.
     // 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;
     int argc = 3;
     EXPECT_NO_THROW(parseArgs(argc, argv));
     EXPECT_NO_THROW(parseArgs(argc, argv));
 
 
@@ -87,23 +89,24 @@ TEST_F(DStubControllerTest, commandLineArgs) {
     EXPECT_TRUE(checkVerbose(true));
     EXPECT_TRUE(checkVerbose(true));
 
 
     // Verify that the custom command line option is parsed without error.
     // 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;
     argc = 2;
     EXPECT_NO_THROW (parseArgs(argc, argv1));
     EXPECT_NO_THROW (parseArgs(argc, argv1));
 
 
     // Verify that an unknown option is detected.
     // 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;
     argc = 2;
     EXPECT_THROW (parseArgs(argc, argv2), InvalidUsage);
     EXPECT_THROW (parseArgs(argc, argv2), InvalidUsage);
 
 
     // Verify that extraneous information is detected.
     // 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;
     argc = 3;
     EXPECT_THROW (parseArgs(argc, argv3), InvalidUsage);
     EXPECT_THROW (parseArgs(argc, argv3), InvalidUsage);
-
-
 }
 }
 
 
 /// @brief Tests application process creation and initialization.
 /// @brief Tests application process creation and initialization.
@@ -141,44 +144,42 @@ TEST_F(DStubControllerTest, initProcessTesting) {
 }
 }
 
 
 /// @brief Tests launch handling of invalid command line.
 /// @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) {
 TEST_F(DStubControllerTest, launchInvalidUsage) {
     // Command line to run integrated
     // Command line to run integrated
-    char* argv[] = { (char*)"progName",(char*) "-z" };
+    char* argv[] = { const_cast<char*>("progName"),
+                     const_cast<char*>("-z") };
     int argc = 2;
     int argc = 2;
 
 
     // Launch the controller in integrated mode.
     // 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
 /// @brief Tests launch handling of failure in application process
 /// initialization.  This test launches with a valid command line but with
 /// 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) {
 TEST_F(DStubControllerTest, launchProcessInitError) {
     // Command line to run integrated
     // 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;
     int argc = 3;
 
 
     // Launch the controller in stand alone mode.
     // Launch the controller in stand alone mode.
     SimFailure::set(SimFailure::ftCreateProcessException);
     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).
 /// @brief Tests launch and normal shutdown (stand alone mode).
 /// This creates an interval timer to generate a normal shutdown and then
 /// This creates an interval timer to generate a normal shutdown and then
 /// launches with a valid, stand-alone command line and no simulated errors.
 /// launches with a valid, stand-alone command line and no simulated errors.
-/// Launch exit code should be d2::NORMAL_EXIT.
 TEST_F(DStubControllerTest, launchNormalShutdown) {
 TEST_F(DStubControllerTest, launchNormalShutdown) {
     // command line to run standalone
     // 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;
     int argc = 3;
 
 
     // Use an asiolink IntervalTimer and callback to generate the
     // Use an asiolink IntervalTimer and callback to generate the
@@ -188,14 +189,11 @@ TEST_F(DStubControllerTest, launchNormalShutdown) {
 
 
     // Record start time, and invoke launch().
     // Record start time, and invoke launch().
     ptime start = microsec_clock::universal_time();
     ptime start = microsec_clock::universal_time();
-    int rcode = launch(argc, argv);
+    EXPECT_NO_THROW(launch(argc, argv));
 
 
     // Record stop time.
     // Record stop time.
     ptime stop = microsec_clock::universal_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
     // Verify that duration of the run invocation is the same as the
     // timer duration.  This demonstrates that the shutdown was driven
     // timer duration.  This demonstrates that the shutdown was driven
     // by an io_service event and callback.
     // by an io_service event and callback.
@@ -207,10 +205,12 @@ TEST_F(DStubControllerTest, launchNormalShutdown) {
 /// @brief Tests launch with an operational error during application execution.
 /// @brief Tests launch with an operational error during application execution.
 /// This test creates an interval timer to generate a runtime exception during
 /// 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
 /// 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) {
 TEST_F(DStubControllerTest, launchRuntimeError) {
     // command line to run standalone
     // 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;
     int argc = 3;
 
 
     // Use an asiolink IntervalTimer and callback to generate the
     // Use an asiolink IntervalTimer and callback to generate the
@@ -220,14 +220,11 @@ TEST_F(DStubControllerTest, launchRuntimeError) {
 
 
     // Record start time, and invoke launch().
     // Record start time, and invoke launch().
     ptime start = microsec_clock::universal_time();
     ptime start = microsec_clock::universal_time();
-    int rcode = launch(argc, argv);
+    EXPECT_THROW(launch(argc, argv), ProcessRunError);
 
 
     // Record stop time.
     // Record stop time.
     ptime stop = microsec_clock::universal_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
     // Verify that duration of the run invocation is the same as the
     // timer duration.  This demonstrates that the shutdown was driven
     // timer duration.  This demonstrates that the shutdown was driven
     // by an io_service event and callback.
     // by an io_service event and callback.
@@ -239,18 +236,14 @@ TEST_F(DStubControllerTest, launchRuntimeError) {
 /// @brief Tests launch with a session establishment failure.
 /// @brief Tests launch with a session establishment failure.
 /// This test launches with a valid command line for integrated mode and no.
 /// 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
 /// 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) {
 TEST_F(DStubControllerTest, launchSessionFailure) {
     // Command line to run integrated
     // Command line to run integrated
     char* argv[] = { (char*)"progName" };
     char* argv[] = { (char*)"progName" };
     int argc = 1;
     int argc = 1;
 
 
     // Launch the controller in integrated mode.
     // 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.
 /// @brief Configuration update event testing.

+ 10 - 6
src/bin/d2/tests/d_test_stubs.cc

@@ -12,6 +12,7 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
+#include <d2/d2_log.h>
 #include <d2/spec_config.h>
 #include <d2/spec_config.h>
 #include <d2/tests/d_test_stubs.h>
 #include <d2/tests/d_test_stubs.h>
 
 
@@ -24,7 +25,7 @@ namespace d2 {
 SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure;
 SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure;
 
 
 // Define custom process command supported by DStubProcess.
 // 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)
 DStubProcess::DStubProcess(const char* name, IOServicePtr io_service)
     : DProcessBase(name, io_service) {
     : DProcessBase(name, io_service) {
@@ -69,7 +70,8 @@ DStubProcess::shutdown() {
         // Simulates a failure during shutdown process.
         // Simulates a failure during shutdown process.
         isc_throw(DProcessBaseError, "DStubProcess simulated shutdown failure");
         isc_throw(DProcessBaseError, "DStubProcess simulated shutdown failure");
     }
     }
-    setShutdownFlag(true);
+
+    DProcessBase::shutdown();
 }
 }
 
 
 isc::data::ConstElementPtr
 isc::data::ConstElementPtr
@@ -113,7 +115,7 @@ DStubProcess::~DStubProcess() {
 //************************** DStubController *************************
 //************************** DStubController *************************
 
 
 // Define custom controller command supported by 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.
 // Define custom command line option command supported by DStubController.
 const char* DStubController::stub_option_x_ = "x";
 const char* DStubController::stub_option_x_ = "x";
@@ -122,7 +124,9 @@ DControllerBasePtr&
 DStubController::instance() {
 DStubController::instance() {
     // If the singleton hasn't been created, do it now.
     // If the singleton hasn't been created, do it now.
     if (!getController()) {
     if (!getController()) {
-        setController(new DStubController());
+        //setController(new DStubController());
+        DControllerBasePtr p(new DStubController());
+        setController(p);
     }
     }
 
 
     return (getController());
     return (getController());
@@ -143,7 +147,7 @@ bool
 DStubController::customOption(int option, char* /* optarg */)
 DStubController::customOption(int option, char* /* optarg */)
 {
 {
     // Check for the custom option supported by DStubController.
     // 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 (true);
     }
     }
 
 
@@ -183,7 +187,7 @@ DStubController::customControllerCommand(const std::string& command,
     return (answer);
     return (answer);
 }
 }
 
 
-const std::string DStubController::getCustomOpts(){
+const std::string DStubController::getCustomOpts() const {
     // Return the "list" of custom options supported by DStubController.
     // Return the "list" of custom options supported by DStubController.
     return (std::string(stub_option_x_));
     return (std::string(stub_option_x_));
 }
 }

+ 5 - 5
src/bin/d2/tests/d_test_stubs.h

@@ -96,7 +96,7 @@ class DStubProcess : public DProcessBase {
 public:
 public:
 
 
     /// @brief Static constant that defines a custom process command string.
     /// @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 Constructor
     ///
     ///
@@ -184,7 +184,7 @@ public:
 
 
     /// @brief Defines a custom controller command string. This is a
     /// @brief Defines a custom controller command string. This is a
     /// custom command supported by DStubController.
     /// 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
     /// @brief Defines a custom command line option supported by
     /// DStubController.
     /// DStubController.
@@ -234,7 +234,7 @@ protected:
     /// addition option, stub_option_x_.
     /// addition option, stub_option_x_.
     ///
     ///
     /// @return returns a string containing the option letters.
     /// @return returns a string containing the option letters.
-    virtual const std::string getCustomOpts();
+    virtual const std::string getCustomOpts() const;
 
 
 private:
 private:
     /// @brief Constructor is private to protect singleton integrity.
     /// @brief Constructor is private to protect singleton integrity.
@@ -378,9 +378,9 @@ public:
 
 
     /// @Wrapper to invoke the Controller's launch method.  Please refer to
     /// @Wrapper to invoke the Controller's launch method.  Please refer to
     /// DControllerBase::launch for details.
     /// DControllerBase::launch for details.
-    int launch(int argc, char* argv[]) {
+    void launch(int argc, char* argv[]) {
         optind = 1;
         optind = 1;
-        return (getController()->launch(argc, argv));
+        getController()->launch(argc, argv);
     }
     }
 
 
     /// @Wrapper to invoke the Controller's disconnectSession method.  Please
     /// @Wrapper to invoke the Controller's disconnectSession method.  Please