BIND 10 master, updated. f63ff922e713a04b3f4391d509c2206ac32edbb5 [master] ChangeLog for trac1024

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 14 15:06:58 UTC 2011


The branch, master has been updated
       via  f63ff922e713a04b3f4391d509c2206ac32edbb5 (commit)
       via  72a0beb8dfe85b303f546d09986461886fe7a3d8 (commit)
       via  4d17de950b96631d01c7928b9cab24860b2e29e5 (commit)
       via  a7047de1ec7aece83271cc28605ea1d790afee67 (commit)
       via  71eee6e279d7527adbc1e325b0cca49d824b67ee (commit)
       via  0958095d36903cd821afc57be0c038896dd1acdb (commit)
       via  8e66cc336b29bd5acc1f764f26cb0b116db4dc87 (commit)
       via  e540aaf2cedae6cfeb4c0ea063f8693cf5999822 (commit)
       via  0d68ac445710fdb4d9d89ca2055b206c9a06dc94 (commit)
       via  b5e49faa3340628865ea28a60d3dc36d3e08511d (commit)
       via  99c025349129904b864806049ea8761940ba0ecc (commit)
      from  aa4405d57bec097972c4d5b60d1cfd6a06f84bf1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f63ff922e713a04b3f4391d509c2206ac32edbb5
Author: Stephen Morris <stephen at isc.org>
Date:   Thu Jul 14 16:06:40 2011 +0100

    [master] ChangeLog for trac1024

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |    6 +
 src/bin/bind10/tests/bind10_test.py.in             |    2 +
 src/bin/cmdctl/tests/cmdctl_test.py                |    2 +
 src/bin/xfrin/tests/xfrin_test.py                  |    2 +
 src/bin/xfrout/tests/xfrout_test.py.in             |    2 +
 src/lib/asiodns/tests/run_unittests.cc             |    4 +-
 src/lib/log/Makefile.am                            |    1 +
 src/lib/log/logger_support.cc                      |  150 +-----------------
 src/lib/log/logger_support.h                       |   62 +------
 src/lib/log/logger_unittest_support.cc             |  175 ++++++++++++++++++++
 ...{logger_support.h => logger_unittest_support.h} |  111 +++++++------
 src/lib/log/tests/init_logger_test.sh.in           |    6 +-
 src/lib/log/tests/logger_level_impl_unittest.cc    |    7 +-
 src/lib/log/tests/logger_level_unittest.cc         |    8 +-
 src/lib/log/tests/logger_support_unittest.cc       |   15 ++-
 src/lib/python/isc/log/log.cc                      |   30 ++++-
 16 files changed, 318 insertions(+), 265 deletions(-)
 create mode 100644 src/lib/log/logger_unittest_support.cc
 copy src/lib/log/{logger_support.h => logger_unittest_support.h} (52%)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 5d27f6e..81eea32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+271.	[func]		stephen
+	Default logging for unit tests changed to severity DEBUG (level 99)
+	with the output routed to /dev/null.  This can be altered by setting
+	the B10_LOGGER_XXX environment variables.
+	(Trac #1024, git 72a0beb8dfe85b303f546d09986461886fe7a3d8)
+
 270.	[func]		jinmei
 	Added python bindings for ACLs using the DNS request as the
 	context.  They are accessible via the isc.acl.dns module.
diff --git a/src/bin/bind10/tests/bind10_test.py.in b/src/bin/bind10/tests/bind10_test.py.in
index 91d326c..9d794a6 100644
--- a/src/bin/bind10/tests/bind10_test.py.in
+++ b/src/bin/bind10/tests/bind10_test.py.in
@@ -26,6 +26,7 @@ import socket
 from isc.net.addr import IPAddr
 import time
 import isc
+import isc.log
 
 from isc.testutils.parse_args import TestOptParser, OptsError
 
@@ -764,4 +765,5 @@ class TestBrittle(unittest.TestCase):
         self.assertFalse(bob.runnable)
 
 if __name__ == '__main__':
+    isc.log.resetUnitTestRootLogger()
     unittest.main()
diff --git a/src/bin/cmdctl/tests/cmdctl_test.py b/src/bin/cmdctl/tests/cmdctl_test.py
index e77c529..3103f47 100644
--- a/src/bin/cmdctl/tests/cmdctl_test.py
+++ b/src/bin/cmdctl/tests/cmdctl_test.py
@@ -19,6 +19,7 @@ import socket
 import tempfile
 import sys
 from cmdctl import *
+import isc.log
 
 SPEC_FILE_PATH = '..' + os.sep
 if 'CMDCTL_SPEC_PATH' in os.environ:
@@ -447,6 +448,7 @@ class TestFuncNotInClass(unittest.TestCase):
 
 
 if __name__== "__main__":
+    isc.log.resetUnitTestRootLogger()
     unittest.main()
 
 
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 2acd9d6..92bf1b0 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -18,6 +18,7 @@ import socket
 import io
 from isc.testutils.tsigctx_mock import MockTSIGContext
 from xfrin import *
+import isc.log
 
 #
 # Commonly used (mostly constant) test parameters
@@ -1115,6 +1116,7 @@ class TestMain(unittest.TestCase):
 
 if __name__== "__main__":
     try:
+        isc.log.resetUnitTestRootLogger()
         unittest.main()
     except KeyboardInterrupt as e:
         print(e)
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index adabf48..7ab4a58 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -23,6 +23,7 @@ from isc.cc.session import *
 from pydnspp import *
 from xfrout import *
 import xfrout
+import isc.log
 
 TSIG_KEY = TSIGKey("example.com:SFuWd/q99SzF8Yzd1QbB9g==")
 
@@ -670,4 +671,5 @@ class TestInitialization(unittest.TestCase):
         self.assertEqual(xfrout.UNIX_SOCKET_FILE, "The/Socket/File")
 
 if __name__== "__main__":
+    isc.log.resetUnitTestRootLogger()
     unittest.main()
diff --git a/src/lib/asiodns/tests/run_unittests.cc b/src/lib/asiodns/tests/run_unittests.cc
index df77368..5cacdaf 100644
--- a/src/lib/asiodns/tests/run_unittests.cc
+++ b/src/lib/asiodns/tests/run_unittests.cc
@@ -15,14 +15,14 @@
 #include <gtest/gtest.h>
 #include <util/unittests/run_all.h>
 
-#include <log/logger_manager.h>
+#include <log/logger_support.h>
 #include <dns/tests/unittest_util.h>
 
 int
 main(int argc, char* argv[])
 {
     ::testing::InitGoogleTest(&argc, argv);         // Initialize Google test
-    isc::log::LoggerManager::init("unittest");      // Set a root logger name
+    isc::log::initLogger();                         // Initialize logging
     isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);  // Add location of test data
 
     return (isc::util::unittests::run_all());
diff --git a/src/lib/log/Makefile.am b/src/lib/log/Makefile.am
index 63b1dfb..9f52724 100644
--- a/src/lib/log/Makefile.am
+++ b/src/lib/log/Makefile.am
@@ -20,6 +20,7 @@ liblog_la_SOURCES += logger_manager_impl.cc logger_manager_impl.h
 liblog_la_SOURCES += logger_name.cc logger_name.h
 liblog_la_SOURCES += logger_specification.h
 liblog_la_SOURCES += logger_support.cc logger_support.h
+liblog_la_SOURCES += logger_unittest_support.cc logger_unittest_support.h
 liblog_la_SOURCES += macros.h
 liblog_la_SOURCES += log_messages.cc log_messages.h
 liblog_la_SOURCES += message_dictionary.cc message_dictionary.h
diff --git a/src/lib/log/logger_support.cc b/src/lib/log/logger_support.cc
index 2c5ab45..2097136 100644
--- a/src/lib/log/logger_support.cc
+++ b/src/lib/log/logger_support.cc
@@ -12,28 +12,9 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE
 
-/// \brief Temporary Logger Support
-///
-/// Performs run-time initialization of the logger system.  In particular, it
-/// is passed information from the command line and:
-///
-/// a) Sets the severity of the messages being logged (and debug level if
-/// appropriate).
-/// b) Reads in the local message file is one has been supplied.
-///
-/// These functions will be replaced once the code has been written to obtain
-/// the logging parameters from the configuration database.
-
-#include <iostream>
-#include <algorithm>
-#include <iostream>
 #include <string>
-
-#include <log/logger_level.h>
-#include <log/logger_manager.h>
-#include <log/logger_specification.h>
 #include <log/logger_support.h>
-#include <log/output_option.h>
+#include <log/logger_manager.h>
 
 using namespace std;
 
@@ -42,77 +23,6 @@ namespace {
 // Flag to hold logging initialization state.
 bool logging_init_state = false;
 
-
-// Set logging destination according to the setting of B10_LOGGER_DESTINATION.
-// (See header for initLogger() for more details.)  This is a no-op if the
-// environment variable is not defined.
-//
-// \param root Name of the root logger
-// \param severity Severity level to be assigned to the root logger
-// \param dbglevel Debug level
-
-void
-setDestination(const char* root, const isc::log::Severity severity,
-               const int dbglevel) {
-
-    using namespace isc::log;
-
-    const char* destination = getenv("B10_LOGGER_DESTINATION");
-    if (destination != NULL) {
-
-        // Constants: not declared static as this is function is expected to be
-        // called once only
-        const string STDOUT = "stdout";
-        const string STDERR = "stderr";
-        const string SYSLOG = "syslog";
-        const string SYSLOG_COLON = "syslog:";
-
-        // Prepare the objects to define the logging specification
-        LoggerSpecification spec(root, severity, dbglevel);
-        OutputOption option;
-
-        // Set up output option according to destination specification
-        const string dest = destination;
-        if (dest == STDOUT) {
-            option.destination = OutputOption::DEST_CONSOLE;
-            option.stream = OutputOption::STR_STDOUT;
-
-        } else if (dest == STDERR) {
-            option.destination = OutputOption::DEST_CONSOLE;
-            option.stream = OutputOption::STR_STDERR;
-
-        } else if (dest == SYSLOG) {
-            option.destination = OutputOption::DEST_SYSLOG;
-            // Use default specified in OutputOption constructor for the
-            // syslog destination
-
-        } else if (dest.find(SYSLOG_COLON) == 0) {
-            option.destination = OutputOption::DEST_SYSLOG;
-            // Must take account of the string actually being "syslog:"
-            if (dest == SYSLOG_COLON) {
-                cerr << "**ERROR** value for B10_LOGGER_DESTINATION of " <<
-                        SYSLOG_COLON << " is invalid, " << SYSLOG <<
-                        " will be used instead\n";
-                // Use default for logging facility
-
-            } else {
-                // Everything else in the string is the facility name
-                option.facility = dest.substr(SYSLOG_COLON.size());
-            }
-
-        } else {
-            // Not a recognised destination, assume a file
-            option.destination = OutputOption::DEST_FILE;
-            option.filename = dest;
-        }
-
-        // ... and set the destination
-        spec.addOutputOption(option);
-        LoggerManager manager;
-        manager.process(spec);
-    }
-}
-
 } // Anonymous namespace
 
 namespace isc {
@@ -140,63 +50,5 @@ initLogger(const string& root, isc::log::Severity severity, int dbglevel,
     LoggerManager::init(root, severity, dbglevel, file);
 }
 
-// Logger Run-Time Initialization via Environment Variables
-void initLogger(isc::log::Severity severity, int dbglevel) {
-
-    // Root logger name is defined by the environment variable B10_LOGGER_ROOT.
-    // If not present, the name is "bind10".
-    const char* DEFAULT_ROOT = "bind10";
-    const char* root = getenv("B10_LOGGER_ROOT");
-    if (! root) {
-        root = DEFAULT_ROOT;
-    }
-
-    // Set the logging severity.  The environment variable is
-    // B10_LOGGER_SEVERITY, and can be one of "DEBUG", "INFO", "WARN", "ERROR"
-    // of "FATAL".  Note that the string must be in upper case with no leading
-    // of trailing blanks.
-    const char* sev_char = getenv("B10_LOGGER_SEVERITY");
-    if (sev_char) {
-        severity = isc::log::getSeverity(sev_char);
-    }
-
-    // If the severity is debug, get the debug level (environment variable
-    // B10_LOGGER_DBGLEVEL), which should be in the range 0 to 99.
-    if (severity == isc::log::DEBUG) {
-        const char* dbg_char = getenv("B10_LOGGER_DBGLEVEL");
-        if (dbg_char) {
-            int level = 0;
-            try {
-                level = boost::lexical_cast<int>(dbg_char);
-                if (level < MIN_DEBUG_LEVEL) {
-                    cerr << "**ERROR** debug level of " << level
-                         << " is invalid - a value of " << MIN_DEBUG_LEVEL
-                         << " will be used\n";
-                    level = MIN_DEBUG_LEVEL;
-                } else if (level > MAX_DEBUG_LEVEL) {
-                    cerr << "**ERROR** debug level of " << level
-                         << " is invalid - a value of " << MAX_DEBUG_LEVEL
-                         << " will be used\n";
-                    level = MAX_DEBUG_LEVEL;
-                }
-            } catch (...) {
-                // Error, but not fatal to the test
-                cerr << "**ERROR** Unable to translate "
-                        "B10_LOGGER_DBGLEVEL - a value of 0 will be used\n";
-            }
-            dbglevel = level;
-        }
-    }
-
-    // Set the local message file
-    const char* localfile = getenv("B10_LOGGER_LOCALMSG");
-
-    // Initialize logging
-    initLogger(root, severity, dbglevel, localfile);
-
-    // Now set the destination for logging output
-    setDestination(root, severity, dbglevel);
-}
-
 } // namespace log
 } // namespace isc
diff --git a/src/lib/log/logger_support.h b/src/lib/log/logger_support.h
index cf83abc..4ce3ced 100644
--- a/src/lib/log/logger_support.h
+++ b/src/lib/log/logger_support.h
@@ -19,6 +19,13 @@
 
 #include <string>
 #include <log/logger.h>
+#include <log/logger_unittest_support.h>
+
+/// \file
+/// \brief Logging initialization functions
+///
+/// Contains a set of functions relating to logging initialization that are
+/// used by the production code.
 
 namespace isc {
 namespace log {
@@ -33,17 +40,13 @@ namespace log {
 /// \return true if logging has been initialized, false if not
 bool isLoggingInitialized();
 
-/// \brief Set "logging initialized" flag
-///
-/// Sets the state of the "logging initialized" flag.
+/// \brief Set state of "logging initialized" flag
 ///
 /// \param state State to set the flag to. (This is expected to be "true" - the
 ///        default - for all code apart from specific unit tests.)
 void setLoggingInitialized(bool state = true);
 
-
-
-/// \brief Run-Time Initialization
+/// \brief Run-time initialization
 ///
 /// Performs run-time initialization of the logger in particular supplying:
 ///
@@ -62,54 +65,7 @@ void initLogger(const std::string& root,
                 isc::log::Severity severity = isc::log::INFO,
                 int dbglevel = 0, const char* file = NULL);
 
-
-/// \brief Run-Time Initialization from Environment
-///
-/// Performs run-time initialization of the logger via the setting of
-/// environment variables.  These are:
-///
-/// - B10_LOGGER_ROOT\n
-/// Name of the root logger.  If not given, the string "bind10" will be used.
-///
-/// - B10_LOGGER_SEVERITY\n
-/// Severity of messages that will be logged.  This must be one of the strings
-/// "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or "NONE". (Must be upper case
-/// and must not contain leading or trailing spaces.)  If not specified (or if
-/// specified but incorrect), the default passed as argument to this function
-/// (currently INFO) will be used.
-///
-/// - B10_LOGGER_DBGLEVEL\n
-/// Ignored if the level is not DEBUG, this should be a number between 0 and
-/// 99 indicating the logging severity.  The default is 0.  If outside these
-/// limits or if not a number, The value passed to this function (default
-/// of 0) is used.
-///
-/// - B10_LOGGER_LOCALMSG\n
-/// If defined, the path specification of a file that contains message
-/// definitions replacing ones in the default dictionary.
-///
-/// - B10_LOGGER_DESTINATION\n
-/// If defined, the destination of the logging output.  This can be one of:
-///   - \c stdout Send output to stdout.
-///   - \c stderr Send output to stderr
-///   - \c syslog Send output to syslog using the facility local0.
-///   - \c syslog:xxx  Send output to syslog, using the facility xxx. ("xxx"
-///     should be one of the syslog facilities such as "local0".)  There must
-///     be a colon between "syslog" and "xxx
-///   - \c other Anything else is interpreted as the name of a file to which
-///     output is appended.  If the file does not exist, it is created.
-///
-/// Any errors in the settings cause messages to be output to stderr.
-///
-/// This function is aimed at test programs, allowing the default settings to
-/// be overridden by the tester.  It is not intended for use in production
-/// code.
-
-void initLogger(isc::log::Severity severity = isc::log::INFO,
-                int dbglevel = 0);
-
 } // namespace log
 } // namespace isc
 
-
 #endif // __LOGGER_SUPPORT_H
diff --git a/src/lib/log/logger_unittest_support.cc b/src/lib/log/logger_unittest_support.cc
new file mode 100644
index 0000000..a0969be
--- /dev/null
+++ b/src/lib/log/logger_unittest_support.cc
@@ -0,0 +1,175 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <log/logger_level.h>
+#include <log/logger_name.h>
+#include <log/logger_manager.h>
+#include <log/logger_specification.h>
+#include <log/logger_unittest_support.h>
+#include <log/logger_support.h>
+#include <log/output_option.h>
+
+using namespace std;
+
+namespace isc {
+namespace log {
+
+// Get the logging severity.  This is defined by the environment variable
+// B10_LOGGER_SEVERITY, and can be one of "DEBUG", "INFO", "WARN", "ERROR"
+// of "FATAL".  (Note that the string must be in upper case with no leading
+// of trailing blanks.)  If not present, the default severity passed to the
+// function is returned.
+isc::log::Severity
+b10LoggerSeverity(isc::log::Severity defseverity) {
+    const char* sev_char = getenv("B10_LOGGER_SEVERITY");
+    if (sev_char) {
+        return (isc::log::getSeverity(sev_char));
+    }
+    return (defseverity);
+}
+
+// Get the debug level.  This is defined by the envornment variable
+// B10_LOGGER_DBGLEVEL.  If not defined, a default value passed to the function
+// is returned.
+int
+b10LoggerDbglevel(int defdbglevel) {
+    const char* dbg_char = getenv("B10_LOGGER_DBGLEVEL");
+    if (dbg_char) {
+        int level = 0;
+        try {
+            level = boost::lexical_cast<int>(dbg_char);
+            if (level < MIN_DEBUG_LEVEL) {
+                std::cerr << "**ERROR** debug level of " << level
+                          << " is invalid - a value of " << MIN_DEBUG_LEVEL
+                          << " will be used\n";
+                level = MIN_DEBUG_LEVEL;
+            } else if (level > MAX_DEBUG_LEVEL) {
+                std::cerr << "**ERROR** debug level of " << level
+                          << " is invalid - a value of " << MAX_DEBUG_LEVEL
+                          << " will be used\n";
+                level = MAX_DEBUG_LEVEL;
+            }
+        } catch (...) {
+            // Error, but not fatal to the test
+            std::cerr << "**ERROR** Unable to translate "
+                         "B10_LOGGER_DBGLEVEL - a value of 0 will be used\n";
+        }
+        return (level);
+    }
+
+    return (defdbglevel);
+}
+
+
+// Reset characteristics of the root logger to that set by the environment
+// variables B10_LOGGER_SEVERITY, B10_LOGGER_DBGLEVEL and B10_LOGGER_DESTINATION.
+
+void
+resetUnitTestRootLogger() {
+
+    using namespace isc::log;
+
+    // Constants: not declared static as this is function is expected to be
+    // called once only
+    const string DEVNULL = "/dev/null";
+    const string STDOUT = "stdout";
+    const string STDERR = "stderr";
+    const string SYSLOG = "syslog";
+    const string SYSLOG_COLON = "syslog:";
+
+    // Get the destination.  If not specified, assume /dev/null. (The default
+    // severity for unit tests is DEBUG, which generates a lot of output.
+    // Routing the logging to /dev/null will suppress that, whilst still
+    // ensuring that the code paths are tested.)
+    const char* destination = getenv("B10_LOGGER_DESTINATION");
+    const string dest((destination == NULL) ? DEVNULL : destination);
+
+    // Prepare the objects to define the logging specification
+    LoggerSpecification spec(getRootLoggerName(), 
+                             b10LoggerSeverity(isc::log::DEBUG),
+                             b10LoggerDbglevel(isc::log::MAX_DEBUG_LEVEL));
+    OutputOption option;
+
+    // Set up output option according to destination specification
+    if (dest == STDOUT) {
+        option.destination = OutputOption::DEST_CONSOLE;
+        option.stream = OutputOption::STR_STDOUT;
+
+    } else if (dest == STDERR) {
+        option.destination = OutputOption::DEST_CONSOLE;
+        option.stream = OutputOption::STR_STDERR;
+
+    } else if (dest == SYSLOG) {
+        option.destination = OutputOption::DEST_SYSLOG;
+        // Use default specified in OutputOption constructor for the
+        // syslog destination
+
+    } else if (dest.find(SYSLOG_COLON) == 0) {
+        option.destination = OutputOption::DEST_SYSLOG;
+        // Must take account of the string actually being "syslog:"
+        if (dest == SYSLOG_COLON) {
+            cerr << "**ERROR** value for B10_LOGGER_DESTINATION of " <<
+                    SYSLOG_COLON << " is invalid, " << SYSLOG <<
+                    " will be used instead\n";
+            // Use default for logging facility
+
+        } else {
+            // Everything else in the string is the facility name
+            option.facility = dest.substr(SYSLOG_COLON.size());
+        }
+
+    } else {
+        // Not a recognised destination, assume a file.
+        option.destination = OutputOption::DEST_FILE;
+        option.filename = dest;
+    }
+
+    // ... and set the destination
+    spec.addOutputOption(option);
+    LoggerManager manager;
+    manager.process(spec);
+}
+
+
+// Logger Run-Time Initialization via Environment Variables
+void initLogger(isc::log::Severity severity, int dbglevel) {
+
+    // Root logger name is defined by the environment variable B10_LOGGER_ROOT.
+    // If not present, the name is "bind10".
+    const char* DEFAULT_ROOT = "bind10";
+    const char* root = getenv("B10_LOGGER_ROOT");
+    if (! root) {
+        root = DEFAULT_ROOT;
+    }
+
+    // Set the local message file
+    const char* localfile = getenv("B10_LOGGER_LOCALMSG");
+
+    // Initialize logging
+    initLogger(root, isc::log::DEBUG, isc::log::MAX_DEBUG_LEVEL, localfile);
+
+    // Now set reset the output destination of the root logger, overriding
+    // the default severity, debug level and destination with those specified
+    // in the environment variables.  (The two-step approach is used as the
+    // setUnitTestRootLoggerCharacteristics() function is used in several
+    // places in the BIND 10 tests, and it avoid duplicating code.)
+    resetUnitTestRootLogger();
+} 
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_unittest_support.h b/src/lib/log/logger_unittest_support.h
new file mode 100644
index 0000000..ce9121b
--- /dev/null
+++ b/src/lib/log/logger_unittest_support.h
@@ -0,0 +1,126 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_UNITTEST_SUPPORT_H
+#define __LOGGER_UNITTEST_SUPPORT_H
+
+#include <string>
+#include <log/logger.h>
+
+/// \file
+/// \brief Miscellaneous logging functions used by the unit tests.
+///
+/// As the configuration database is unsually unavailable during unit tests,
+/// the functions defined here allow a limited amount of logging configuration
+/// through the use of environment variables
+
+namespace isc {
+namespace log {
+
+/// \brief Run-Time Initialization for Unit Tests from Environment
+///
+/// Performs run-time initialization of the logger via the setting of
+/// environment variables.  These are:
+///
+/// - B10_LOGGER_ROOT\n
+/// Name of the root logger.  If not given, the string "bind10" will be used.
+///
+/// - B10_LOGGER_SEVERITY\n
+/// Severity of messages that will be logged.  This must be one of the strings
+/// "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or "NONE". (Must be upper case
+/// and must not contain leading or trailing spaces.)  If not specified (or if
+/// specified but incorrect), the default passed as argument to this function
+/// (currently DEBUG) will be used.
+///
+/// - B10_LOGGER_DBGLEVEL\n
+/// Ignored if the level is not DEBUG, this should be a number between 0 and
+/// 99 indicating the logging severity.  The default is 0.  If outside these
+/// limits or if not a number, The value passed to this function (default
+/// of MAX_DEBUG_LEVEL) is used.
+///
+/// - B10_LOGGER_LOCALMSG\n
+/// If defined, the path specification of a file that contains message
+/// definitions replacing ones in the default dictionary.
+///
+/// - B10_LOGGER_DESTINATION\n
+/// If defined, the destination of the logging output.  This can be one of:
+///   - \c stdout Send output to stdout.
+///   - \c stderr Send output to stderr
+///   - \c syslog Send output to syslog using the facility local0.
+///   - \c syslog:xxx  Send output to syslog, using the facility xxx. ("xxx"
+///     should be one of the syslog facilities such as "local0".)  There must
+///     be a colon between "syslog" and "xxx
+///   - \c other Anything else is interpreted as the name of a file to which
+///     output is appended.  If the file does not exist, it is created.
+///
+/// Any errors in the settings cause messages to be output to stderr.
+///
+/// This function is aimed at test programs, allowing the default settings to
+/// be overridden by the tester.  It is not intended for use in production
+/// code.
+///
+/// TODO: Rename. This function overloads the initLogger() function that can
+///       be used to initialize production programs.  This may lead to confusion.
+void initLogger(isc::log::Severity severity = isc::log::DEBUG,
+                int dbglevel = isc::log::MAX_DEBUG_LEVEL);
+
+
+/// \brief Obtains logging severity from B10_LOGGER_SEVERITY
+///
+/// Support function called by the unit test logging initialization code.
+/// It returns the logging severity defined by B10_LOGGER_SEVERITY.  If
+/// not defined it returns the default passed to it.
+///
+/// \param defseverity Default severity used if B10_LOGGER_SEVERITY is not
+//         defined.
+///
+/// \return Severity to use for the logging.
+isc::log::Severity b10LoggerSeverity(isc::log::Severity defseverity);
+
+
+/// \brief Obtains logging debug level from B10_LOGGER_DBGLEVEL
+///
+/// Support function called by the unit test logging initialization code.
+/// It returns the logging debug level defined by B10_LOGGER_DBGLEVEL.  If
+/// not defined, it returns the default passed to it.
+///
+/// N.B. If there is an error, a message is written to stderr and a value
+/// related to the error is used. (This is because (a) logging is not yet
+/// initialized, hence only the error stream is known to exist, and (b) this
+/// function is only used in unit test logging initialization, so incorrect
+/// selection of a level is not really an issue.)
+///
+/// \param defdbglevel Default debug level to be used if B10_LOGGER_DBGLEVEL
+///        is not defined.
+///
+/// \return Debug level to use.
+int b10LoggerDbglevel(int defdbglevel);
+
+
+/// \brief Reset root logger characteristics
+///
+/// This is a simplified interface into the resetting of the characteristics
+/// of the root logger.  It is aimed for use in unit tests and resets the
+/// characteristics of the root logger to use a severity, debug level and
+/// destination set by the environment variables B10_LOGGER_SEVERITY,
+/// B10_LOGGER_DBGLEVEL and B10_LOGGER_DESTINATION.
+void
+resetUnitTestRootLogger();
+
+} // namespace log
+} // namespace isc
+
+
+
+#endif // __LOGGER_UNITTEST_SUPPORT_H
diff --git a/src/lib/log/tests/init_logger_test.sh.in b/src/lib/log/tests/init_logger_test.sh.in
index d26ca5d..795419b 100755
--- a/src/lib/log/tests/init_logger_test.sh.in
+++ b/src/lib/log/tests/init_logger_test.sh.in
@@ -44,7 +44,7 @@ WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
 ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
 FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
-B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=99 ./init_logger_test 2>&1 | \
+B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=99 ./init_logger_test | \
     cut -d' ' -f3- | diff $tempfile -
 passfail $?
 
@@ -57,7 +57,7 @@ WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
 ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
 FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
-B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=50 ./init_logger_test 2>&1 | \
+B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=50 ./init_logger_test | \
     cut -d' ' -f3- | diff $tempfile -
 passfail $?
 
@@ -67,7 +67,7 @@ WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
 ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
 FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
-B10_LOGGER_SEVERITY=WARN ./init_logger_test 2>&1 | \
+B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=WARN ./init_logger_test | \
     cut -d' ' -f3- | diff $tempfile -
 passfail $?
 
diff --git a/src/lib/log/tests/logger_level_impl_unittest.cc b/src/lib/log/tests/logger_level_impl_unittest.cc
index 0ded7f9..dacd202 100644
--- a/src/lib/log/tests/logger_level_impl_unittest.cc
+++ b/src/lib/log/tests/logger_level_impl_unittest.cc
@@ -20,6 +20,7 @@
 #include <boost/lexical_cast.hpp>
 
 #include <log/logger_level_impl.h>
+#include <log/logger_support.h>
 #include <log4cplus/logger.h>
 
 using namespace isc::log;
@@ -27,8 +28,10 @@ using namespace std;
 
 class LoggerLevelImplTest : public ::testing::Test {
 protected:
-    LoggerLevelImplTest()
-    {}
+    LoggerLevelImplTest() {
+        // Ensure logging set to default for unit tests
+        resetUnitTestRootLogger();
+    }
 
     ~LoggerLevelImplTest()
     {}
diff --git a/src/lib/log/tests/logger_level_unittest.cc b/src/lib/log/tests/logger_level_unittest.cc
index 8c98091..641a6cc 100644
--- a/src/lib/log/tests/logger_level_unittest.cc
+++ b/src/lib/log/tests/logger_level_unittest.cc
@@ -20,7 +20,7 @@
 #include <log/logger.h>
 #include <log/logger_manager.h>
 #include <log/log_messages.h>
-#include <log/logger_name.h>
+#include <log/logger_support.h>
 
 using namespace isc;
 using namespace isc::log;
@@ -29,7 +29,9 @@ using namespace std;
 class LoggerLevelTest : public ::testing::Test {
 protected:
     LoggerLevelTest() {
-        // Logger initialization is done in main()
+        // Logger initialization is done in main().  As logging tests may
+        // alter the default logging output, it is reset here.
+        resetUnitTestRootLogger();
     }
     ~LoggerLevelTest() {
         LoggerManager::reset();
@@ -57,7 +59,7 @@ TEST_F(LoggerLevelTest, Creation) {
     EXPECT_EQ(42, level3.dbglevel);
 }
 
-TEST(LoggerLevel, getSeverity) {
+TEST_F(LoggerLevelTest, getSeverity) {
     EXPECT_EQ(DEBUG, getSeverity("DEBUG"));
     EXPECT_EQ(DEBUG, getSeverity("debug"));
     EXPECT_EQ(DEBUG, getSeverity("DeBuG"));
diff --git a/src/lib/log/tests/logger_support_unittest.cc b/src/lib/log/tests/logger_support_unittest.cc
index 6a93652..b418906 100644
--- a/src/lib/log/tests/logger_support_unittest.cc
+++ b/src/lib/log/tests/logger_support_unittest.cc
@@ -18,12 +18,23 @@
 
 using namespace isc::log;
 
+class LoggerSupportTest : public ::testing::Test {
+protected:
+    LoggerSupportTest() {
+        // Logger initialization is done in main().  As logging tests may
+        // alter the default logging output, it is reset here.
+        resetUnitTestRootLogger();
+    }
+    ~LoggerSupportTest() {
+    }
+};
+
 // Check that the initialized flag can be manipulated.  This is a bit chicken-
 // -and-egg: we want to reset to the flag to the original value at the end
 // of the test, so use the functions to do that.  But we are trying to check
 // that these functions in fact work.
 
-TEST(LoggerSupportTest, InitializedFlag) {
+TEST_F(LoggerSupportTest, InitializedFlag) {
     bool current_flag = isLoggingInitialized();
 
     // check we can flip the flag.
@@ -51,7 +62,7 @@ TEST(LoggerSupportTest, InitializedFlag) {
 // Check that a logger will throw an exception if logging has not been
 // initialized.
 
-TEST(LoggerSupportTest, LoggingInitializationCheck) {
+TEST_F(LoggerSupportTest, LoggingInitializationCheck) {
 
     // Assert that logging has been initialized (it should be in main()).
     bool current_flag = isLoggingInitialized();
diff --git a/src/lib/python/isc/log/log.cc b/src/lib/python/isc/log/log.cc
index 484151f..aa12664 100644
--- a/src/lib/python/isc/log/log.cc
+++ b/src/lib/python/isc/log/log.cc
@@ -20,6 +20,7 @@
 
 #include <log/message_dictionary.h>
 #include <log/logger_manager.h>
+#include <log/logger_support.h>
 #include <log/logger.h>
 
 #include <config/ccsession.h>
@@ -35,7 +36,7 @@ using boost::bind;
 // (tags/RELEASE_28 115909)) on OSX, where unwinding the stack
 // segfaults the moment this exception was thrown and caught.
 //
-// Placing it in a named namespace instead of the original
+// Placing it in a named namespace instead of the originalRecommend
 // unnamed namespace appears to solve this, so as a temporary
 // workaround, we create a local randomly named namespace here
 // to solve this issue.
@@ -184,6 +185,27 @@ init(PyObject*, PyObject* args) {
     Py_RETURN_NONE;
 }
 
+// This initialization is for unit tests.  It allows message settings to be
+// be determined by a set of B10_xxx environment variables.  (See the
+// description of initLogger() for more details.)  The function has been named
+// resetUnitTestRootLogger() here as being more descriptive and
+// trying to avoid confusion.
+PyObject*
+resetUnitTestRootLogger(PyObject*, PyObject*) {
+    try {
+        isc::log::resetUnitTestRootLogger();
+    }
+    catch (const std::exception& e) {
+        PyErr_SetString(PyExc_RuntimeError, e.what());
+        return (NULL);
+    }
+    catch (...) {
+        PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+        return (NULL);
+    }
+    Py_RETURN_NONE;
+}
+
 PyObject*
 logConfigUpdate(PyObject*, PyObject* args) {
     // we have no wrappers for ElementPtr and ConfigData,
@@ -246,6 +268,12 @@ PyMethodDef methods[] = {
         "logging severity (one of 'DEBUG', 'INFO', 'WARN', 'ERROR' or "
         "'FATAL'), a debug level (integer in the range 0-99) and a file name "
         "of a dictionary with message text translations."},
+    {"resetUnitTestRootLogger", resetUnitTestRootLogger, METH_VARARGS,
+        "Resets the configuration of the root logger to that set by the "
+        "B10_XXX environment variables.  It is aimed at unit tests, where "
+        "the logging is initialized by the code under test; called before "
+        "the unit test starts, this function resets the logging configuration "
+        "to that in use for the C++ unit tests."},
     {"log_config_update", logConfigUpdate, METH_VARARGS,
         "Update logger settings. This method is automatically used when "
         "ModuleCCSession is initialized with handle_logging_config set "




More information about the bind10-changes mailing list