Commit 2c0ab179 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[3401] Addressed reveiw comments

Static handlers were removed from DControllerBase.
Developer's guide has been updated to with --with-kea-config
discussion and updated diagrams.
Other minor corrections.

(Note ingore diffs in the diagram .svg files, they aren't particularly
meaningful to the human eye).
parent 8daa5237
...@@ -52,39 +52,45 @@ base are shown in the following class diagram: ...@@ -52,39 +52,45 @@ base are shown in the following class diagram:
- isc::d2::DControllerBase - provides all of the services necessary to manage - isc::d2::DControllerBase - provides all of the services necessary to manage
an application process class derived from isc::d2::DProcess. These services include: an application process class derived from isc::d2::DProcess. These services include:
- Command line argument handling - Command line argument handling
- Process instantiation and initialization - Process instantiation and initialization0
- Support for stand-alone execution - Support for stand-alone execution
- Support for integrated operation as a BIND10 module (session management - Support for integrated operation as a BUNDY module (session management
and event handling) and event handling)
- Process event loop invocation and shutdown - Process event loop invocation and shutdown
.
It creates and manages an instance of isc::d2::DProcessBase. The CPL is designed It creates and manages an instance of isc::d2::DProcessBase. The CPL is
for asynchronous event processing applications. It is constructed to use ASIO designed for asynchronous event processing applications. It is constructed
library for IO processing. DControllerBase own an isc::asiolink::io_service instance and it pas ses this into the @c DProcessBase constructor and it is this to use ASIO library for IO processing. DControllerBase owns an
service that is used drivel the process's event loop. isc::asiolink::io_service instance and it passes this into the @c
DProcessBase constructor. It is this io_service that is used drive the
@c DControllerBase also provides the ability to operate one of two modes: process's event loop. The controller is designed to provide any interfaces
"stand-alone" mode or "managed" mode. In stand-alone mode, the controller has between the process it controls and the outside world.
no IO of it's own, thus there is two-way control communication between the application and the outside world.
@c DControllerBase provides configuration for its process via a JSON file
In "managed mode" the controller creates a BIND10 Session, allowing it to specified as a mandatory command line argument. The file structure is
participate as a BIND10 module and therefore receive control commands such as expected be as follows:
configuration updates, status requests, and shutdown. BIND10 modules are
required to supply two callbacks: one for configuration events and one for { "<module-name>": {<module-config>} }
command events. @c DControllerBase supplies these callbacks which largely
pass the information through to its @c DProcessBase instance. The key aspect where:
to take from this is that the controller handles the interface for receiving module-name : is a label which uniquely identifies the
asynchronous commands and the invokes the appropriate services in the process's configuration data for the (i.e. the controlled process.)
interface. It is the value returned by @ref
isc::d2::DControllerBase::getAppName()
@todo DControllerBase does yet support reading the configuration from a
command line argument. It's command line argument processing can be very easily module-config: a set of zero or more JSON elements which comprise
extended to do so. application's configuration values. Element syntax is governed
by those elements supported in isc::cc.
@todo At the time of this writing Kea is being separated from the BIND10
framework. As such, use of the BIND10 Session will be removed but could The file may contain an arbitrary number of other modules.
readily be replaced with an authenticated socket connection for receiving and
responding to directives asynchronously. @todo DControllerBase will soon support dynamic reloading of the
configuration file upon receipt of the SIGHUP signal, and graceful
shutdown upon receipt of either SIGTERM or SIGINT.
@todo Eventually, some sort of secure socket interface which supports remote
control operations such as configuration changes or status reporting will
likely be implemented.
- isc::d2::DProcessBase - defines an asynchronous-event processor (i.e. - isc::d2::DProcessBase - defines an asynchronous-event processor (i.e.
application) which provides a uniform interface to: application) which provides a uniform interface to:
...@@ -105,10 +111,10 @@ information or "context". It provides a single enclosure for the storage of ...@@ -105,10 +111,10 @@ information or "context". It provides a single enclosure for the storage of
configuration parameters or any other information that needs to accessible configuration parameters or any other information that needs to accessible
within a given context. within a given context.
The following sequence diagram shows how a configuration update, received The following sequence diagram shows how a configuration from file moves
asynchronously through the session command channel, moves through the CPL: through the CPL layer:
@image html config_sequence.svg "CPL Configuration Update Sequence" @image html config_from_file_sequence.svg "CPL Configuration From File Sequence"
The CPL classes will likely move into a common library. The CPL classes will likely move into a common library.
...@@ -122,6 +128,30 @@ in the diagram below: ...@@ -122,6 +128,30 @@ in the diagram below:
- isc::d2::D2Controller - entry point for running D2, it processes command line - isc::d2::D2Controller - entry point for running D2, it processes command line
options, starts and controls the application process, @c D2Process. options, starts and controls the application process, @c D2Process.
Currently there are two implementations of D2Controller selected through the
configuration script switch, "--with-kea-config":
1. --with-kea-config=JSON - The implementation is contained in isc/d2/d2_controller.*. This form allows D2 to run as a stand-alone process configured via JSON
text file specified as a command line argument. The file content is described
in isc/d2/dhcp-ddns.spec, unit tests are in
isc/d2/tests/bundy_d2_controller_unittests.cc. As of Kea 0.9, this form will
be the default form.
2. --with-kea-config=BUNDY - The implementation is containd in
isc/d2/bundy_d2_controller.*, unit tests are in isc/d2/tests/d2_controller_unittests.cc and d_controller_unittests.cc This form allows D2 to run as a a Bundy
module. It creates a BUNDY Session, allowing it to receive control commands
such as configuration updates, status requests, and shutdown. BUNDY modules
are required to supply two callbacks: one for configuration events and one for
command events. This form of D2Controller supplies these callbacks which
largely pass the information through to its @c D2Process instance. If the
controller cannot establish a BUNDY session it will exit with a fatal error.
The configuration switch deteremines which of two forms and tests are compiled
and they are mutually exclusive.
@note The inclusion of the BUNDY form should be considered temporary. Long range
planning should be based on the JSON form.
- isc::d2::D2Process - creates and manages D2's primary resources and implements - isc::d2::D2Process - creates and manages D2's primary resources and implements
the main event loop described in @ref d2EventLoop. the main event loop described in @ref d2EventLoop.
......
...@@ -31,9 +31,7 @@ const char* D2Controller::d2_bin_name_ = "b10-dhcp-ddns"; ...@@ -31,9 +31,7 @@ const char* D2Controller::d2_bin_name_ = "b10-dhcp-ddns";
DControllerBasePtr& 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.
// must have access to the singleton in order to use it within BIND10
// static function callbacks.
if (!getController()) { if (!getController()) {
DControllerBasePtr controller_ptr(new D2Controller()); DControllerBasePtr controller_ptr(new D2Controller());
setController(controller_ptr); setController(controller_ptr);
......
...@@ -156,28 +156,6 @@ DControllerBase::parseArgs(int argc, char* argv[]) ...@@ -156,28 +156,6 @@ DControllerBase::parseArgs(int argc, char* argv[])
} }
} }
isc::data::ConstElementPtr
DControllerBase::configHandler(isc::data::ConstElementPtr new_config) {
LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_CONFIG_UPDATE)
.arg(controller_->getAppName()).arg(new_config->str());
// Invoke the instance method on the controller singleton.
return (controller_->updateConfig(new_config));
}
// Static callback which invokes non-static handler on singleton
isc::data::ConstElementPtr
DControllerBase::commandHandler(const std::string& command,
isc::data::ConstElementPtr args) {
LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_COMMAND_RECEIVED)
.arg(controller_->getAppName()).arg(command)
.arg(args ? args->str() : "(no args)");
// Invoke the instance method on the controller singleton.
return (controller_->executeCommand(command, args));
}
bool bool
DControllerBase::customOption(int /* option */, char* /*optarg*/) DControllerBase::customOption(int /* option */, char* /*optarg*/)
{ {
...@@ -212,7 +190,7 @@ DControllerBase::configFromFile() { ...@@ -212,7 +190,7 @@ DControllerBase::configFromFile() {
isc::data::ConstElementPtr module_config; isc::data::ConstElementPtr module_config;
try { try {
std::string config_file = getConfigFileName(); std::string config_file = getConfigFile();
if (config_file.empty()) { if (config_file.empty()) {
// Basic sanity check: file name must not be empty. // Basic sanity check: file name must not be empty.
isc_throw(BadValue, "JSON configuration file not specified. Please " isc_throw(BadValue, "JSON configuration file not specified. Please "
...@@ -328,11 +306,6 @@ DControllerBase::usage(const std::string & text) ...@@ -328,11 +306,6 @@ DControllerBase::usage(const std::string & text)
DControllerBase::~DControllerBase() { DControllerBase::~DControllerBase() {
} }
std::string
DControllerBase::getConfigFileName() {
return (Daemon::getConfigFile());
}
}; // namespace isc::d2 }; // namespace isc::d2
// Provide an implementation until we figure out a better way to do this. // Provide an implementation until we figure out a better way to do this.
......
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
namespace isc { namespace isc {
namespace d2 { namespace d2 {
/// @brief DControllerBase launch exit status values. Upon service shutdown
/// normal or otherwise, the Controller's launch method will return one of
/// these values.
/// @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:
...@@ -206,44 +202,17 @@ public: ...@@ -206,44 +202,17 @@ public:
isc::data:: isc::data::
ConstElementPtr args); ConstElementPtr args);
/// @brief A callback for handling all incoming configuration updates.
///
/// Provides a static callback that can be used to handle asynchronsouly
/// received configurations. It acts as a wrapper around the singleton's
/// virtual instance method, updateConfig.
///
/// @param new_config textual representation of the new configuration
///
/// @return status of the config update
static isc::data::ConstElementPtr configHandler(isc::data::ConstElementPtr
new_config);
/// @brief A callback for handling all incoming commands.
///
/// Provides a static callback that can be used to handle asynchronsouly
/// received commands. It acts as a wrapper around the singleton's virtual
/// instance method, executeCommand.
///
/// @param command textual representation of the command
/// @param args parameters of the command. It can be NULL pointer if no
/// arguments exist for a particular command.
///
/// @return status of the processed command
static isc::data::ConstElementPtr commandHandler(const std::string& command,
isc::data::ConstElementPtr
args);
/// @brief Fetches the name of the application under control. /// @brief Fetches the name of the application under control.
/// ///
/// @return returns the controller service name string /// @return returns the controller service name string
const std::string getAppName() const { std::string getAppName() const {
return (app_name_); return (app_name_);
} }
/// @brief Fetches the name of the application executable. /// @brief Fetches the name of the application executable.
/// ///
/// @return returns the controller logger name string /// @return returns the controller logger name string
const std::string getBinName() const { std::string getBinName() const {
return (bin_name_); return (bin_name_);
} }
...@@ -414,11 +383,6 @@ protected: ...@@ -414,11 +383,6 @@ protected:
/// non-zero means failure), and a string explanation of the outcome. /// non-zero means failure), and a string explanation of the outcome.
isc::data::ConstElementPtr shutdownProcess(isc::data::ConstElementPtr args); isc::data::ConstElementPtr shutdownProcess(isc::data::ConstElementPtr args);
/// @brief Fetches the name of the configuration file
///
/// @return the configuration file name as a string
virtual std::string getConfigFileName();
/// @brief Fetches the current process /// @brief Fetches the current process
/// ///
/// @return the a pointer to the current process instance. /// @return the a pointer to the current process instance.
......
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Bouml (http://bouml.free.fr/) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="746" height="226" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="214" y1="45" x2="214" y2="226" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="261" y="8" width="3" height="18" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="167" y="23" width="97" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="163" y="4" width="98" height="19" />
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="212" y="20">:DControllerBase</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="730" y="8" width="3" height="18" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="648" y="23" width="85" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="644" y="4" width="86" height="19" />
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="687" y="20">:DCfgMgrBase</text>
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="689" y1="45" x2="689" y2="226" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="488" y="8" width="3" height="18" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="402" y="23" width="89" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="398" y="4" width="90" height="19" />
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="443" y="20">:DProcessBase</text>
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="445" y1="45" x2="445" y2="226" />
</g>
<g>
<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="684" y="180" width="10" height="24" />
</g>
<g>
<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="440" y="175" width="10" height="28" />
</g>
<g>
<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="209" y="67" width="10" height="147" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="451" y1="194" x2="684" y2="194" />
<polygon fill="#000000" stroke="none" points="684,194 680,190 680,198" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="39" y1="72" x2="209" y2="72" />
<polygon fill="#000000" stroke="none" points="209,72 205,68 205,76" />
</g>
<ellipse fill="black" stroke="none" cx="34.5" cy="73.5" rx="4.5" ry="4.5" />
<g>
<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="215" y="164" width="10" height="37" />
</g>
<g>
<rect fill="none" stroke="black" stroke-width="1" stroke-opacity="1" x="215" y="99" width="10" height="24" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="226" y1="187" x2="440" y2="187" />
<polygon fill="#000000" stroke="none" points="440,187 436,183 436,191" />
</g>
<g>
<path fill="none" stroke="black" stroke-opacity="1" d="M 227 100 L 244 100 L 244 107 L 227 107" />
<polygon fill="#000000" stroke="none" points="227,107 231,111 231,103" />
</g>
<g>
<path fill="none" stroke="black" stroke-opacity="1" d="M 227 165 L 244 165 L 244 172 L 227 172" />
<polygon fill="#000000" stroke="none" points="227,172 231,176 231,168" />
</g>
<g>
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="231" y="160">updateConfig()</text>
</g>
<g>
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="111" y="67">configFromFile()</text>
</g>
<g>
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="591" y="191">parseConfig()</text>
</g>
<g>
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="372" y="182">configure()</text>
</g>
<g>
<text font-family="Helvetica" font-size="12" fill="#000000" xml:space="preserve" x="224" y="95">getConfigFileName()</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Bouml (http://bouml.free.fr/) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="847" height="290" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="674" y="8" width="3" height="16" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="606" y="21" width="71" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="602" y="4" width="72" height="17" />
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="638" y="18">:DCfgMgrBase</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="116" y="8" width="3" height="16" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="28" y="21" width="91" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="24" y="4" width="92" height="17" />
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="70" y="18">:ModuleCCSession</text>
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="72" y1="45" x2="72" y2="290" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="469" y="8" width="3" height="16" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="397" y="21" width="75" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="393" y="4" width="76" height="17" />
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="431" y="18">:DProcessBase</text>
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="640" y1="45" x2="640" y2="290" />
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="433" y1="45" x2="433" y2="290" />
</g>
<g>
<line stroke="black" stroke-dasharray="18,6" stroke-opacity="1" x1="260" y1="45" x2="260" y2="290" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="300" y="8" width="3" height="16" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="221" y="21" width="82" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="217" y="4" width="83" height="17" />
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" text-decoration="underline" text-anchor="middle" x="259" y="18">:DControllerBase</text>
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="635" y="153" width="10" height="34" />
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="255" y="62" width="10" height="125" />
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="67" y="59" width="10" height="131" />
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="428" y="144" width="10" height="43" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="439" y1="182" x2="635" y2="182" />
<polygon fill="#000000" stroke="none" points="635,182 631,178 631,186" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="78" y1="67" x2="255" y2="67" />
<polygon fill="#000000" stroke="none" points="255,67 251,63 251,71" />
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="73" y="104" width="10" height="25" />
</g>
<g>
<rect fill="#ffffff" stroke="black" stroke-width="1" stroke-opacity="1" x="261" y="95" width="10" height="84" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="272" y1="152" x2="428" y2="152" />
<polygon fill="#000000" stroke="none" points="428,152 424,148 424,156" />
</g>
<g>
<path fill="none" stroke="black" stroke-opacity="1" d="M 273 96 L 290 96 L 290 103 L 273 103" />
<polygon fill="#000000" stroke="none" points="273,103 277,107 277,99" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="84" y1="116" x2="261" y2="116" />
<polygon fill="#000000" stroke="none" points="84,116 88,112 88,120" />
</g>
<g>
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="446" y="206">parseConfig(in new_config : isc::data::ElementPtr) : isc::data::ConstElementPtr</text>
</g>
<g>
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="277" y="89">updateConfig(in new_config : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
</g>
<g>
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="96" y="113">getFullConfig() : ConstElementPtr</text>
</g>
<g>
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="281" y="145">configure(in config_set : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
</g>
<g>
<text font-family="Helvetica" font-size="10" fill="#000000" xml:space="preserve" x="79" y="59">configHandler(in new_config : isc::data::ConstElementPtr) : isc::data::ConstElementPtr</text>
</g>
</svg>
This diff is collapsed.
...@@ -154,8 +154,7 @@ TEST_F(D2ControllerTest, launchNormalShutdown) { ...@@ -154,8 +154,7 @@ TEST_F(D2ControllerTest, launchNormalShutdown) {
/// This really tests just the ability of the handlers to invoke the necessary /// This really tests just the ability of the handlers to invoke the necessary
/// chain of methods and handle error conditions. Configuration parsing and /// chain of methods and handle error conditions. Configuration parsing and
/// retrieval should be tested as part of the d2 configuration management /// retrieval should be tested as part of the d2 configuration management
/// implementation. Note that this testing calls the configuration update event /// implementation.
/// callback, configHandler, directly.
/// This test verifies that: /// This test verifies that:
/// 1. A valid configuration yields a successful parse result. /// 1. A valid configuration yields a successful parse result.
/// 2. That an application process error in configuration updating is handled /// 2. That an application process error in configuration updating is handled
...@@ -173,22 +172,21 @@ TEST_F(D2ControllerTest, configUpdateTests) { ...@@ -173,22 +172,21 @@ TEST_F(D2ControllerTest, configUpdateTests) {
isc::data::Element::fromJSON(valid_d2_config); isc::data::Element::fromJSON(valid_d2_config);
// Verify that given a valid config we get a successful update result. // Verify that given a valid config we get a successful update result.
answer = DControllerBase::configHandler(config_set); answer = updateConfig(config_set);
isc::config::parseAnswer(rcode, answer); isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(0, rcode); EXPECT_EQ(0, rcode);
// Use an invalid configuration to verify parsing error return. // Use an invalid configuration to verify parsing error return.
std::string config = "{ \"bogus\": 1000 } "; std::string config = "{ \"bogus\": 1000 } ";
config_set = isc::data::Element::fromJSON(config); config_set = isc::data::Element::fromJSON(config);
answer = DControllerBase::configHandler(config_set); answer = updateConfig(config_set);
isc::config::parseAnswer(rcode, answer); isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(1, rcode); EXPECT_EQ(1, rcode);
} }
/// @brief Command execution tests. /// @brief Command execution tests.
/// This really tests just the ability of the handler to invoke the necessary /// This really tests just the ability of the handler to invoke the necessary
/// chain of methods and to handle error conditions. Note that this testing /// chain of methods and to handle error conditions.
/// calls the executeCommand method directly.
/// This test verifies that: /// This test verifies that:
/// 1. That an unrecognized command is detected and returns a status of /// 1. That an unrecognized command is detected and returns a status of
/// d2::COMMAND_INVALID. /// d2::COMMAND_INVALID.
...@@ -204,13 +202,13 @@ TEST_F(D2ControllerTest, executeCommandTests) { ...@@ -204,13 +202,13 @@ TEST_F(D2ControllerTest, executeCommandTests) {
// Verify that an unknown command returns an COMMAND_INVALID response. // Verify that an unknown command returns an COMMAND_INVALID response.
std::string bogus_command("bogus"); std::string bogus_command("bogus");
answer = DControllerBase::commandHandler(bogus_command, arg_set); answer = executeCommand(bogus_command, arg_set);
isc::config::parseAnswer(rcode, answer); isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(COMMAND_INVALID, rcode); EXPECT_EQ(COMMAND_INVALID, rcode);
// Verify that shutdown command returns COMMAND_SUCCESS response. // Verify that shutdown command returns COMMAND_SUCCESS response.
//answer = executeCommand(SHUT_DOWN_COMMAND, isc::data::ElementPtr()); //answer = executeCommand(SHUT_DOWN_COMMAND, isc::data::ElementPtr());
answer = DControllerBase::commandHandler(SHUT_DOWN_COMMAND, arg_set); answer = executeCommand(SHUT_DOWN_COMMAND, arg_set);
isc::config::parseAnswer(rcode, answer); isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(COMMAND_SUCCESS, rcode); EXPECT_EQ(COMMAND_SUCCESS, rcode);
......
...@@ -290,8 +290,7 @@ TEST_F(DStubControllerTest, launchRuntimeError) { ...@@ -290,8 +290,7 @@ TEST_F(DStubControllerTest, launchRuntimeError) {
/// This really tests just the ability of the handlers to invoke the necessary /// This really tests just the ability of the handlers to invoke the necessary
/// chain of methods and handle error conditions. Configuration parsing and /// chain of methods and handle error conditions. Configuration parsing and
/// retrieval should be tested as part of the d2 configuration management /// retrieval should be tested as part of the d2 configuration management
/// implementation. Note that this testing calls the configuration update event /// implementation.
/// callback, configHandler, directly.
/// This test verifies that: /// This test verifies that:
/// 1. That a valid configuration update results in successful status return. /// 1. That a valid configuration update results in successful status return.
/// 2. That an application process error in configuration updating is handled /// 2. That an application process error in configuration updating is handled
...@@ -310,21 +309,20 @@ TEST_F(DStubControllerTest, configUpdateTests) { ...@@ -310,21 +309,20 @@ TEST_F(DStubControllerTest, configUpdateTests) {
isc::data::ElementPtr config_set = isc::data::Element::fromJSON(config); isc::data::ElementPtr config_set = isc::data::Element::fromJSON(config);
// Verify that a valid config gets a successful update result. // Verify that a valid config gets a successful update result.
answer = DControllerBase::configHandler(config_set); answer = updateConfig(config_set);
isc::config::parseAnswer(rcode, answer); isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(0, rcode); EXPECT_EQ(0, rcode);
// Verify that an error in process configure method is handled. // Verify that an error in process configure method is handled.
SimFailure::set(SimFailure::ftProcessConfigure); SimFailure::set(SimFailure::ftProcessConfigure);
answer = DControllerBase::configHandler(config_set); answer = updateConfig(config_set);
isc::config::parseAnswer(rcode, answer);