Commit 7076a02b authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2977] Disable logger initialization in the D2 controller when unit testing

When logger initialization was disabled for a unit test, a few NULL pointer
assertions came up. This was because, some module commands were executed
without arguments (NULL pointer objects). NULL pointers were not checked
before logging arguments. This led to assertions. NULL pointers are now
checked and "(no arg)" string is logged if present.
parent 64b9c908
......@@ -75,8 +75,8 @@ D2Process::command(const std::string& command, isc::data::ConstElementPtr args){
// @TODO This is the initial implementation. If and when D2 is extended
// to support its own commands, this implementation must change. Otherwise
// it should reject all commands as it does now.
LOG_DEBUG(dctl_logger, DBGLVL_TRACE_BASIC,
DHCP_DDNS_COMMAND).arg(command).arg(args->str());
LOG_DEBUG(dctl_logger, DBGLVL_TRACE_BASIC, DHCP_DDNS_COMMAND)
.arg(command).arg(args ? args->str() : "(no args)");
return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
+ command));
......
......@@ -85,7 +85,7 @@ public:
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// command. It can be a NULL pointer if no arguments exist for a command.
/// @return an Element that contains the results of command composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
......
......@@ -46,7 +46,7 @@ DControllerBase::setController(const DControllerBasePtr& controller) {
}
void
DControllerBase::launch(int argc, char* argv[]) {
DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
// Step 1 is to parse the command line arguments.
try {
parseArgs(argc, argv);
......@@ -55,12 +55,16 @@ DControllerBase::launch(int argc, char* argv[]) {
throw; // rethrow it
}
// Do not initialize logger here if we are running unit tests. It would
// replace an instance of unit test specific logger.
if (!test_mode) {
// 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(bin_name_,
((verbose_ && stand_alone_)
? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone_);
}
LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STARTING)
.arg(app_name_).arg(getpid());
......@@ -295,7 +299,8 @@ 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->str());
.arg(controller_->getAppName()).arg(command)
.arg(args ? args->str() : "(no args)");
// Invoke the instance method on the controller singleton.
return (controller_->executeCommand(command, args));
......@@ -368,7 +373,7 @@ DControllerBase::executeCommand(const std::string& command,
if (rcode == COMMAND_INVALID)
{
// It wasn't controller command, so may be an application command.
answer = process_->command(command,args);
answer = process_->command(command, args);
}
}
......
......@@ -144,8 +144,19 @@ public:
/// arguments. Note this method is deliberately not virtual to ensure the
/// proper sequence of events occur.
///
/// This function can be run in the test mode. It prevents initialization
/// of D2 module logger. This is used in unit tests which initialize logger
/// in their main function. Such logger uses environmental variables to
/// control severity, verbosity etc. Reinitialization of logger by this
/// function would replace unit tests specific logger configuration with
/// this suitable for D2 running as a bind10 module.
///
/// @param argc is the number of command line arguments supplied
/// @param argv is the array of string (char *) command line arguments
/// @param test_mode is a bool value which indicates if
/// @c DControllerBase::launch should be run in the test mode (if true).
/// This parameter doesn't have default value to force test implementers to
/// enable test mode explicitly.
///
/// @throw throws one of the following exceptions:
/// InvalidUsage - Indicates invalid command line.
......@@ -156,7 +167,7 @@ public:
/// process event loop.
/// SessionEndError - Could not disconnect from BIND10 (integrated mode
/// only).
void launch(int argc, char* argv[]);
void launch(int argc, char* argv[], const bool test_mode);
/// @brief A dummy configuration handler that always returns success.
///
......@@ -198,7 +209,8 @@ public:
/// the virtual instance method, executeCommand.
///
/// @param command textual representation of the command
/// @param args parameters 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
......
......@@ -38,7 +38,8 @@ int main(int argc, char* argv[]) {
// Launch the controller passing in command line arguments.
// Exit program with the controller's return code.
try {
controller->launch(argc, argv);
// 'false' value disables test mode.
controller->launch(argc, argv, false);
} catch (const isc::Exception& ex) {
std::cerr << "Service failed:" << ex.what() << std::endl;
ret = EXIT_FAILURE;
......
......@@ -397,7 +397,7 @@ public:
/// DControllerBase::launch for details.
void launch(int argc, char* argv[]) {
optind = 1;
getController()->launch(argc, argv);
getController()->launch(argc, argv, true);
}
/// @Wrapper to invoke the Controller's disconnectSession method. Please
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment