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
     // 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));

+ 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 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.

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

@@ -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
     }
 
-    // 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)
               .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);
         }
     }
 

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

@@ -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

+ 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.
     // 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;

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

@@ -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