#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
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
// 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;
// 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;
-
- // 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(root, severity, dbglevel);
- 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);
-}
-
} // Anonymous namespace
namespace isc {
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
#include <string>
#include <log/logger.h>
+// Include the unit test function declarations here for compatibility
+#include <log/logger_unittest_support.h>
+
namespace isc {
namespace log {
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 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.
-
-void initLogger(isc::log::Severity severity = isc::log::DEBUG,
- int dbglevel = isc::log::MAX_DEBUG_LEVEL);
} // namespace log
} // namespace isc
--- /dev/null
+// 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
+setUnitTestRootLoggerCharacteristics() {
+
+ 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.)
+ setUnitTestRootLoggerCharacteristics();
+}
+
+} // namespace log
+} // namespace isc
--- /dev/null
+// 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>
+
+// Note: this file holds logging functions used by unit tests.
+
+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 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 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 Logger Characteristics
+///
+/// This is a simplified interface into the setting 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
+setUnitTestRootLoggerCharacteristics();
+
+} // namespace log
+} // namespace isc
+
+
+
+#endif // __LOGGER_UNITTEST_SUPPORT_H
#include <boost/lexical_cast.hpp>
#include <log/logger_level_impl.h>
+#include <log/logger_support.h>
#include <log4cplus/logger.h>
using namespace isc::log;
class LoggerLevelImplTest : public ::testing::Test {
protected:
- LoggerLevelImplTest()
- {}
+ LoggerLevelImplTest() {
+ // Ensure logging set to default for unit tests
+ setUnitTestRootLoggerCharacteristics();
+ }
~LoggerLevelImplTest()
{}
#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;
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.
+ setUnitTestRootLoggerCharacteristics();
}
~LoggerLevelTest() {
LoggerManager::reset();
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"));
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.
+ setUnitTestRootLoggerCharacteristics();
+ }
+ ~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.
// 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();