Browse Source

[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.
Marcin Siodelski 11 years ago
parent
commit
7076a02b24

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

@@ -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
     // @TODO This is the initial implementation.  If and when D2 is extended
     // to support its own commands, this implementation must change. Otherwise
     // to support its own commands, this implementation must change. Otherwise
     // it should reject all commands as it does now.
     // 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: "
     return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
                                       + command));
                                       + command));

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

@@ -85,7 +85,7 @@ public:
     ///
     ///
     /// @param command is a string label representing the command to execute.
     /// @param command is a string label representing the command to execute.
     /// @param args is a set of arguments (if any) required for the given
     /// @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
     /// @return an Element that contains the results of command composed
     /// of an integer status value (0 means successful, non-zero means failure),
     /// of an integer status value (0 means successful, non-zero means failure),
     /// and a string explanation of the outcome.
     /// and a string explanation of the outcome.

+ 14 - 9
src/bin/d2/d_controller.cc

@@ -46,7 +46,7 @@ DControllerBase::setController(const DControllerBasePtr& controller) {
 }
 }
 
 
 void
 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.
     // Step 1 is to parse the command line arguments.
     try {
     try {
         parseArgs(argc, argv);
         parseArgs(argc, argv);
@@ -55,12 +55,16 @@ DControllerBase::launch(int argc, char* argv[]) {
         throw; // rethrow it
         throw; // rethrow it
     }
     }
 
 
-    // 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_);
+    // 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)
     LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STARTING)
               .arg(app_name_).arg(getpid());
               .arg(app_name_).arg(getpid());
@@ -295,7 +299,8 @@ DControllerBase::commandHandler(const std::string& command,
                                 isc::data::ConstElementPtr args) {
                                 isc::data::ConstElementPtr args) {
 
 
     LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_COMMAND_RECEIVED)
     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.
     // Invoke the instance method on the controller singleton.
     return (controller_->executeCommand(command, args));
     return (controller_->executeCommand(command, args));
@@ -368,7 +373,7 @@ DControllerBase::executeCommand(const std::string& command,
         if (rcode == COMMAND_INVALID)
         if (rcode == COMMAND_INVALID)
         {
         {
             // It wasn't controller command, so may be an application command.
             // It wasn't controller command, so may be an application command.
-            answer = process_->command(command,args);
+            answer = process_->command(command, args);
         }
         }
     }
     }
 
 

+ 14 - 2
src/bin/d2/d_controller.h

@@ -144,8 +144,19 @@ public:
     /// arguments. Note this method is deliberately not virtual to ensure the
     /// arguments. Note this method is deliberately not virtual to ensure the
     /// proper sequence of events occur.
     /// 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 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
+    /// @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:
     /// @throw throws one of the following exceptions:
     /// InvalidUsage - Indicates invalid command line.
     /// InvalidUsage - Indicates invalid command line.
@@ -156,7 +167,7 @@ public:
     /// process event loop.
     /// process event loop.
     /// SessionEndError - Could not disconnect from BIND10 (integrated mode
     /// SessionEndError - Could not disconnect from BIND10 (integrated mode
     /// only).
     /// 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.
     /// @brief A dummy configuration handler that always returns success.
     ///
     ///
@@ -198,7 +209,8 @@ public:
     /// the virtual instance method, executeCommand.
     /// the virtual instance method, executeCommand.
     ///
     ///
     /// @param command textual representation of the command
     /// @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
     /// @return status of the processed command
     static isc::data::ConstElementPtr
     static isc::data::ConstElementPtr

+ 2 - 1
src/bin/d2/main.cc

@@ -38,7 +38,8 @@ int main(int argc, char* argv[]) {
     // 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.
     try  {
     try  {
-        controller->launch(argc, argv);
+        // 'false' value disables test mode.
+        controller->launch(argc, argv, false);
     } catch (const isc::Exception& ex) {
     } catch (const isc::Exception& ex) {
         std::cerr << "Service failed:" << ex.what() << std::endl;
         std::cerr << "Service failed:" << ex.what() << std::endl;
         ret = EXIT_FAILURE;
         ret = EXIT_FAILURE;

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

@@ -397,7 +397,7 @@ public:
     /// DControllerBase::launch for details.
     /// DControllerBase::launch for details.
     void launch(int argc, char* argv[]) {
     void launch(int argc, char* argv[]) {
         optind = 1;
         optind = 1;
-        getController()->launch(argc, argv);
+        getController()->launch(argc, argv, true);
     }
     }
 
 
     /// @Wrapper to invoke the Controller's disconnectSession method.  Please
     /// @Wrapper to invoke the Controller's disconnectSession method.  Please