BIND 10 trac555, updated. 58ec390c5c70c0c7625e3f52caf4c4f20b3bffa3 [trac555] Checkpoint

BIND 10 source code commits bind10-changes at lists.isc.org
Mon May 23 17:54:26 UTC 2011


The branch, trac555 has been updated
       via  58ec390c5c70c0c7625e3f52caf4c4f20b3bffa3 (commit)
       via  34ebe17e3d731f19c6c44a8777b994241b5de7ee (commit)
       via  67c6c4489b2daeb6001cf2f462cc189f2c841b5a (commit)
      from  862e13c5c852b8ea55c1b53a67803105d473a342 (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 58ec390c5c70c0c7625e3f52caf4c4f20b3bffa3
Author: Stephen Morris <stephen at isc.org>
Date:   Mon May 23 18:53:24 2011 +0100

    [trac555] Checkpoint
    
    Checkpoint of work at end of 23 May (so that code is copied down to
    the BIND 10 server).  Work is in progress on the logger manager
    implementation class.

commit 34ebe17e3d731f19c6c44a8777b994241b5de7ee
Author: Stephen Morris <stephen at isc.org>
Date:   Mon May 23 16:26:24 2011 +0100

    [trac555] Add LoggerSpecification class and associated tests

commit 67c6c4489b2daeb6001cf2f462cc189f2c841b5a
Author: Stephen Morris <stephen at isc.org>
Date:   Mon May 23 15:42:08 2011 +0100

    [trac555] Added OutputOption structure and test

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

Summary of changes:
 src/lib/log/Makefile.am                            |    3 +
 .../resolver_callback.cc => log/logger_manager.cc} |   36 +++--
 src/lib/log/logger_manager.h                       |   88 ++++++++++
 src/lib/log/logger_manager_impl.h                  |   62 +++++++
 src/lib/log/logger_specification.h                 |  154 ++++++++++++++++
 src/lib/log/output_option.h                        |   81 +++++++++
 src/lib/log/tests/Makefile.am                      |   17 +-
 src/lib/log/tests/logger_manager_unittest.cc       |  183 ++++++++++++++++++++
 src/lib/log/tests/logger_specification_unittest.cc |  106 +++++++++++
 .../tests/output_option_unittest.cc}               |   37 +++--
 10 files changed, 735 insertions(+), 32 deletions(-)
 copy src/lib/{resolve/resolver_callback.cc => log/logger_manager.cc} (57%)
 create mode 100644 src/lib/log/logger_manager.h
 create mode 100644 src/lib/log/logger_manager_impl.h
 create mode 100644 src/lib/log/logger_specification.h
 create mode 100644 src/lib/log/output_option.h
 create mode 100644 src/lib/log/tests/logger_manager_unittest.cc
 create mode 100644 src/lib/log/tests/logger_specification_unittest.cc
 copy src/lib/{asiolink/tests/io_socket_unittest.cc => log/tests/output_option_unittest.cc} (52%)

-----------------------------------------------------------------------
diff --git a/src/lib/log/Makefile.am b/src/lib/log/Makefile.am
index cb7d273..24a348b 100644
--- a/src/lib/log/Makefile.am
+++ b/src/lib/log/Makefile.am
@@ -14,6 +14,8 @@ liblog_la_SOURCES += logger_impl.cc logger_impl.h
 liblog_la_SOURCES += logger_level.h
 liblog_la_SOURCES += logger_level.h
 liblog_la_SOURCES += logger_level_impl.cc logger_level_impl.h
+liblog_la_SOURCES += logger_manager.cc logger_manager.h
+liblog_la_SOURCES += logger_specification.h
 liblog_la_SOURCES += logger_support.cc logger_support.h
 liblog_la_SOURCES += macros.h
 liblog_la_SOURCES += messagedef.cc messagedef.h
@@ -22,6 +24,7 @@ liblog_la_SOURCES += message_exception.h
 liblog_la_SOURCES += message_initializer.cc message_initializer.h
 liblog_la_SOURCES += message_reader.cc message_reader.h
 liblog_la_SOURCES += message_types.h
+liblog_la_SOURCES += output_option.h
 liblog_la_SOURCES += root_logger_name.cc root_logger_name.h
 
 EXTRA_DIST  = README
diff --git a/src/lib/log/logger_manager.cc b/src/lib/log/logger_manager.cc
new file mode 100644
index 0000000..a5b38c5
--- /dev/null
+++ b/src/lib/log/logger_manager.cc
@@ -0,0 +1,44 @@
+// 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 <log/logger_manager_impl.h>
+#include <log/logger_manager.h>
+
+// Constructor - create the implementation  class.
+LoggerManager::LoggerManager() {
+    impl_ = new LoggerManagerImpl();
+}
+
+// Destructor - get rid of the implementation class
+LoggerManager::~LoggerManager() {
+    delete impl_;
+}
+
+// Initialize processing
+void
+LoggerManager::processInit() {
+    impl_->processInit();
+}
+
+// Process loggging specification
+void
+LoggerManager::processSpecification(const LoggerSpecification& spec) {
+    impl_->processSpecification(spec);
+}
+
+// End Processing
+void
+LoggerManager::processEnd() {
+    impl_->processEnd();
+}
diff --git a/src/lib/log/logger_manager.h b/src/lib/log/logger_manager.h
new file mode 100644
index 0000000..4a2fd80
--- /dev/null
+++ b/src/lib/log/logger_manager.h
@@ -0,0 +1,88 @@
+// 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_MANAGER_H
+#define __LOGGER_MANAGER_H
+
+#include </log/logger_specification.h>
+
+namespace isc {
+namespace log {
+
+class LoggerManagerImpl;
+
+/// \brief Logger Manager
+///
+/// The logger manager class exists to process the set of logger specifications
+/// and use them to set up the logging in the program appropriately.
+///
+/// To isolate the underlying implementation from basic processing, the
+/// LoggerManager is implemented using the "pimpl" idiom.
+
+class LoggerManager {
+public:
+    /// \brief Constructor
+    LoggerManager();
+
+    /// \brief Destructor
+    ~LoggerManager();
+
+    /// \brief Process Specifications
+    ///
+    /// Given a list of logger specifications, disables all current logging
+    /// and resets the properties of each logger to that given.
+    ///
+    /// \param start Iterator pointing to the start of the collection of
+    ///        logging specifications.
+    /// \param finish Iterator pointing to the end of the collection of
+    ///        logging specification.
+    template <typename T>
+    void process(T start, T finish) {
+        processInit();
+        for (T i = start; i != finish; ++i) {
+            processSpecification(*i);
+        }
+        processEnd();
+    }
+
+private:
+    /// \brief Initialize Processing
+    ///
+    /// Initializes the processing of a list of specifications by resetting all
+    /// loggers to their defaults.  Note that loggers aren't removed as unless
+    /// a previously-enabled logger is re-enabled, it becomes inactive.
+    void processInit();
+
+    /// \brief Process Logging Specification
+    ///
+    /// Processes the given specification.  It is assumed at this point that
+    /// either the logger does not exist or has been made inactive.
+    void processSpecification(const LoggerSpecification& spec);
+
+
+    /// \brief End Processing
+    ///
+    /// Place holder for finish processing.
+    /// TODO: Check that the root logger has something enabled
+    void processEnd();
+
+    // Members
+    LoggerManagerImpl*  impl_;      ///< Pointer to implementation
+};
+
+} // namespace log
+} // namespace isc
+
+
+#endif // __LOGGER_MANAGER_H
diff --git a/src/lib/log/logger_manager_impl.h b/src/lib/log/logger_manager_impl.h
new file mode 100644
index 0000000..e735f47
--- /dev/null
+++ b/src/lib/log/logger_manager_impl.h
@@ -0,0 +1,62 @@
+// 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_MANAGER_IMPL_H
+#define __LOGGER_MANAGER_IMPL_H
+
+#include <log/logger_specification.h>
+
+namespace isc {
+namespace log {
+
+/// \brief Logger Manager Implementation
+///
+/// This is the implementation of the logger manager for the log4cplus
+/// underlying logger.
+///
+/// As noted in logger_manager.h, the logger manager class exists to set up the
+/// logging given a set of specifications.  This class handles the processing
+/// of those specifications.
+
+class LoggerManagerImpl {
+public:
+
+    /// \brief Constructor
+    LoggerManagerImpl()
+    {}
+
+    /// \brief Initialize Processing
+    ///
+    /// This resets the hierachy of loggers back to their defaults.  This means
+    /// that all non-root loggers (if they exist) are set to NOT_SET, and the
+    /// root logger reset to logging informational messages.
+    void processInit();
+
+    /// \brief Process Specification
+    ///
+    /// Processes the specification for a single logger.
+    ///
+    /// \param spec Logging specification for this logger
+    void process(const LoggerSpecification& spec);
+
+    /// \brief End Processing
+    ///
+    /// Terminates the processing of the logging specifications.
+    void processEnd();
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_MANAGER_IMPL_H
diff --git a/src/lib/log/logger_specification.h b/src/lib/log/logger_specification.h
new file mode 100644
index 0000000..2fdcaf5
--- /dev/null
+++ b/src/lib/log/logger_specification.h
@@ -0,0 +1,154 @@
+// 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_SPECIFICATION_H
+#define __LOGGER_SPEC_IFICATIONH
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <log/logger_level.h>
+#include <log/output_option.h>
+
+/// \brief Logger Specification
+///
+/// The logging configuration options are a list of logger specifications, each
+/// of which represents a logger and the options for its appenders.
+///
+/// Unlike OutputOption (which is a struct), this contains a bit more
+/// structure and is concealed in a class.
+
+namespace isc {
+namespace log {
+
+class LoggerSpecification {
+public:
+    typedef std::vector<OutputOption>::iterator         iterator;
+    typedef std::vector<OutputOption>::const_iterator   const_iterator;
+
+    /// \brief Constructor
+    ///
+    /// \param name Name of the logger.
+    /// \param severity Severity at which this logger logs
+    /// \param dbglevel Debug level
+    /// \param additive true to cause message logged with this logger to be
+    ///        passed to the parent for logging.
+    LoggerSpecification(const std::string& name = "",
+                        isc::log::Severity severity = isc::log::INFO,
+                        int dbglevel = 0, bool additive = false) :
+        name_(name), severity_(severity), dbglevel_(dbglevel),
+        additive_(additive)
+    {}
+
+    /// \brief Set the name
+    ///
+    /// \param name Name of the logger .
+    void setName(const std::string& name) {
+        name_ = name;
+    }
+
+    /// \return Return logger name
+    std::string getName() const {
+        return name_;
+    }
+
+    /// \brief Set the severity
+    ///
+    /// \param severity New severity of the logger .
+    void setSeverity(isc::log::Severity severity) {
+        severity_ = severity;
+    }
+
+    /// \return Return logger severity
+    isc::log::Severity getSeverity() const {
+        return severity_;
+    }
+
+    /// \brief Set the debug level
+    ///
+    /// \param dbglevel New debug level of the logger .
+    void setDbglevel(int dbglevel) {
+        dbglevel_ = dbglevel;
+    }
+
+    /// \return Return logger debug level
+    int getDbglevel() const {
+        return dbglevel_;
+    }
+
+    /// \brief Set the additive flag
+    ///
+    /// \param additive New value of the additive flag
+    void setAdditive(bool additive) {
+        additive_ = additive;
+    }
+
+    /// \return Return additive flag
+    int getAdditive() const {
+        return additive_;
+    }
+
+    /// \brief Add output option
+    ///
+    /// \param Option to add to the list
+    void addOutputOption(const OutputOption& option) {
+        options_.push_back(option);
+    }
+
+    /// \return Iterator to start of output options
+    iterator begin() {
+        return options_.begin();
+    }
+
+    /// \return Iterator to start of output options
+    const_iterator begin() const {
+        return options_.begin();
+    }
+
+    /// \return Iterator to end of output options
+    iterator end() {
+        return options_.end();
+    }
+
+    /// \return Iterator to end of output options
+    const_iterator end() const {
+        return options_.end();
+    }
+
+    /// \return Number of output specification options
+    size_t optionCount() const {
+        return options_.size();
+    }
+
+    /// \brief Reset back to defaults
+    void reset() {
+        name_ = "";
+        severity_ = isc::log::INFO;
+        dbglevel_ = 0;
+        additive_ = false;
+        options_.clear();
+    }
+
+private:
+    std::string                 name_;          ///< Logger name
+    isc::log::Severity          severity_;      ///< Severity for this logger
+    int                         dbglevel_;      ///< Debug level
+    bool                        additive_;      ///< Chaining output 
+    std::vector<OutputOption>   options_;       ///< Logger options
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_SPEC_IFICATIONH
diff --git a/src/lib/log/output_option.h b/src/lib/log/output_option.h
new file mode 100644
index 0000000..79e9052
--- /dev/null
+++ b/src/lib/log/output_option.h
@@ -0,0 +1,81 @@
+// 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 __OUTPUT_OPTION_H
+#define __OUTPUT_OPTION_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string>
+
+/// \brief Logger Output Option
+///
+/// The logging configuration options are a list of logger specifications, each
+/// with one or more output options.  This class represents an output option;
+/// one or more of these are attached to a LoggerSpecification object which is
+/// then passed to the LoggerManager to configure the logger.
+///
+/// Although there are three distinct output types (console, file, syslog) and
+/// the options for each do not really overlap.  Although it is tempting to
+/// define a base OutputOption class and derive a class for each type
+/// (ConsoleOutputOptions etc.), it would be messy to use in practice.  At
+/// some point the exact class would have to be known to get the class-specific
+/// options and the (pointer to) the base class cast to the appropriate type.
+/// Instead, this "struct" contains the union of all output options; it is up
+/// to the caller to cherry-pick the members it needs.
+///
+/// One final note: this object holds data and does no computation.  For this
+/// reason, it is a "struct" and members are accessed directly instead of
+/// through methods.
+
+namespace isc {
+namespace log {
+
+struct OutputOption {
+
+    /// Destinations.  Prefixed "DEST_" to avoid problems with the C stdio.h
+    /// FILE type.
+    typedef enum {
+        DEST_CONSOLE = 0,
+        DEST_FILE = 1,
+        DEST_SYSLOG = 2
+    } Destination;
+
+    /// If console, stream on which messages are output
+    typedef enum {
+        STR_STDOUT = 0,
+        STR_STDERR = 1
+    } Stream;
+
+    /// \brief Constructor
+    OutputOption() : destination(DEST_CONSOLE), stream(STR_STDERR),
+                     flush(false), facility(""), filename(""), maxsize(0),
+                     maxver(0)
+    {}
+
+    /// Members. 
+
+    Destination     destination;        ///< Where the output should go
+    Stream          stream;             ///< stdout/stderr if console output
+    bool            flush;              ///< true to flush after each message
+    std::string     facility;           ///< syslog facility
+    std::string     filename;           ///< Filename if file output
+    size_t          maxsize;            ///< 0 if no maximum size
+    int             maxver;             ///< Maximum versions (none if <= 0)
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __OUTPUT_OPTION_H
diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am
index e996b88..ad00830 100644
--- a/src/lib/log/tests/Makefile.am
+++ b/src/lib/log/tests/Makefile.am
@@ -13,16 +13,19 @@ CLEANFILES = *.gcno *.gcda
 TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
-run_unittests_SOURCES  = root_logger_name_unittest.cc
-run_unittests_SOURCES += logger_unittest.cc
-run_unittests_SOURCES += logger_level_unittest.cc
+run_unittests_SOURCES  = run_unittests.cc
+run_unittests_SOURCES += log_formatter_unittest.cc
 run_unittests_SOURCES += logger_level_impl_unittest.cc
+run_unittests_SOURCES += logger_level_unittest.cc
+run_unittests_SOURCES += logger_manager_unittest.cc
+run_unittests_SOURCES += logger_unittest.cc
+run_unittests_SOURCES += logger_specification_unittest.cc
 run_unittests_SOURCES += message_dictionary_unittest.cc
-run_unittests_SOURCES += message_reader_unittest.cc
-run_unittests_SOURCES += message_initializer_unittest.cc
 run_unittests_SOURCES += message_initializer_unittest_2.cc
-run_unittests_SOURCES += run_unittests.cc
-run_unittests_SOURCES += log_formatter_unittest.cc
+run_unittests_SOURCES += message_initializer_unittest.cc
+run_unittests_SOURCES += message_reader_unittest.cc
+run_unittests_SOURCES += output_option_unittest.cc
+run_unittests_SOURCES += root_logger_name_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
diff --git a/src/lib/log/tests/logger_manager_unittest.cc b/src/lib/log/tests/logger_manager_unittest.cc
new file mode 100644
index 0000000..a601da7
--- /dev/null
+++ b/src/lib/log/tests/logger_manager_unittest.cc
@@ -0,0 +1,183 @@
+// 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 <stdio.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include <log/macros.h>
+#include <log/messagedef.h>
+#include <log/logger.h>
+#include <log/logger_level.h>
+#include <log/logger_manager.h>
+#include <log/logger_specification.h>
+#include <log/output_option.h>
+
+using namespace isc::log;
+using namespace std;
+
+/// \brief Derived logger
+///
+/// Only exists to make the protected static methods in Logger public for
+/// test purposes.
+
+class DerivedLogger : public isc::log::Logger {
+public:
+    DerivedLogger(std::string name) : isc::log::Logger(name)
+    {}
+    virtual ~DerivedLogger()
+    {}
+
+    static void reset() {
+        isc::log::Logger::reset();
+    }
+};
+
+/// \brief LoggerManager Test
+class LoggerManagerTest : public ::testing::Test {
+public:
+    LoggerManagerTest()
+    {}
+    ~LoggerManagerTest()
+    {
+        DerivedLogger::reset();
+    }
+};
+
+
+
+// Convenience class to create the specification for the logger "filelogger",
+// which, as the name suggests, logs to a file.  It remembers the file name and
+// deletes the file when instance of the class is destroyed.
+class SpecificationForFileLogger {
+public:
+
+    // Constructor - allocate file and create the specification object
+    SpecificationForFileLogger() : spec_(), name_(""), logname_("filelogger") {
+        OutputOption option;
+        option.destination = OutputOption::DEST_FILE;
+        name_ = option.filename = std::string(tmpnam(NULL));
+
+        spec_.setName(logname_);
+        spec_.addOutputOption(option);
+    }
+
+    // Destructor, remove the file.  This is only a test, so ignore failures
+    ~SpecificationForFileLogger() {
+        if (! name_.empty()) {
+            (void) unlink(name_.c_str());
+        }
+    }
+
+    // Return reference to the logging specification for this loggger
+    LoggerSpecification& getSpecification() {
+        return spec_;
+    }
+
+    // Return name of the logger
+    string getLoggerName() const {
+        return logname_;
+    }
+
+    // Return name of the file
+    string getFileName() const {
+        return name_;
+    }
+
+
+private:
+    LoggerSpecification     spec_;      // Specification for this file logger
+    string                  name_;      // Name of the output file
+    string                  logname_;   // Name of this logger
+};
+
+
+// Convenience function to read an output log file and check that each line
+// contains the expected message ID
+//
+// \param filename Name of the file to check
+// \param start Iterator pointing to first expected message ID
+// \param finish Iterator pointing to last expected message ID
+template <typename T>
+void checkFileContents(const std::string& filename, T start, T finish) {
+
+    // Access the file for input
+    ifstream infile(filename.c_str());
+    if (! infile.good()) {
+        FAIL() << "Unable to open the logging file " << filename;
+    }
+
+    // Iterate round the expected message IDs and check that they appear in
+    // the string.
+    string line;    // Line read from the file
+
+    T i = start;    // Iterator
+    getline(infile, line);
+    int lineno = 1;
+
+    while ((i != finish) && (infile.good())) {
+
+        // Check that the message ID appears in the line.
+        EXPECT_TRUE(line.find(string(*i)) != string::npos)
+            << "Expected to find " << string(*i) << " on line " << lineno
+            << " of logging file " << filename;
+
+        // Go for the next line
+        ++i;
+        getline(infile, line);
+        ++lineno;
+    }
+
+    // Why did the loop end?
+    EXPECT_TRUE(i == finish) << "Did not reach the end of the message ID list";
+    EXPECT_TRUE(infile.eof()) << "Did not reach the end of the logging file";
+
+    // File will close when the instream is deleted at the end of this
+    // function.
+}
+
+// Check that the logger correctly creates something logging to a file.
+TEST_F(LoggerManagerTest, FileLogger) {
+
+    // Create a specification for the file logger and use the manager to
+    // connect the "filelogger" logger to it.
+    SpecificationForFileLogger file_spec;
+    vector<LoggerSpecification> specVector(1, file_spec.getSpecification());
+    LoggerManager manager;
+    manager.process(specVector.begin(), specVector.end());
+
+    // Try logging to the file.  Local scope is set to ensure that the logger
+    // is destroyed before we reset the global logging.  We record what we
+    // put in the file for a later comparison.
+    vector<MessageID> ids;
+    {
+        Logger logger(file_spec.getLoggerName());
+
+        LOG_FATAL(logger, MSG_DUPMSGID).arg("test");
+        ids.push_back(MSG_DUPMSGID);
+
+        LOG_FATAL(logger, MSG_DUPLNS).arg("test");
+        ids.push_back(MSG_DUPLNS);
+    }
+    DerivedLogger::reset();
+
+    // At this point, the output file should contain two lines with messages
+    // LOGTEST_TEST1 and LOGTEST_TEST2 messages - test this.
+    checkFileContents(file_spec.getFileName(), ids.begin(), ids.end());
+}
diff --git a/src/lib/log/tests/logger_specification_unittest.cc b/src/lib/log/tests/logger_specification_unittest.cc
new file mode 100644
index 0000000..7f245a1
--- /dev/null
+++ b/src/lib/log/tests/logger_specification_unittest.cc
@@ -0,0 +1,106 @@
+// 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 <string>
+
+#include <gtest/gtest.h>
+
+#include <log/logger_specification.h>
+#include <log/output_option.h>
+
+using namespace isc::log;
+using namespace std;
+
+/// \brief LoggerSpecification Test
+class LoggerSpecificationTest : public ::testing::Test {
+public:
+    LoggerSpecificationTest()
+    {}
+    ~LoggerSpecificationTest()
+    {}
+};
+
+
+// Check default initialization.
+TEST_F(LoggerSpecificationTest, DefaultInitialization) {
+    LoggerSpecification spec;
+
+    EXPECT_EQ(string(""), spec.getName());
+    EXPECT_EQ(isc::log::INFO, spec.getSeverity());
+    EXPECT_EQ(0, spec.getDbglevel());
+    EXPECT_FALSE(spec.getAdditive());
+    EXPECT_EQ(0, spec.optionCount());
+}
+
+// Non-default initialization
+TEST_F(LoggerSpecificationTest, Initialization) {
+    LoggerSpecification spec("alpha", isc::log::ERROR, 42, true);
+
+    EXPECT_EQ(string("alpha"), spec.getName());
+    EXPECT_EQ(isc::log::ERROR, spec.getSeverity());
+    EXPECT_EQ(42, spec.getDbglevel());
+    EXPECT_TRUE(spec.getAdditive());
+    EXPECT_EQ(0, spec.optionCount());
+}
+
+// Get/Set tests
+TEST_F(LoggerSpecificationTest, SetGet) {
+    LoggerSpecification spec;
+
+    spec.setName("gamma");
+    EXPECT_EQ(string("gamma"), spec.getName());
+
+    spec.setSeverity(isc::log::FATAL);
+    EXPECT_EQ(isc::log::FATAL, spec.getSeverity());
+
+    spec.setDbglevel(7);
+    EXPECT_EQ(7, spec.getDbglevel());
+
+    spec.setAdditive(true);
+    EXPECT_TRUE(spec.getAdditive());
+
+    // Should not affect option count
+    EXPECT_EQ(0, spec.optionCount());
+}
+
+// Check option setting
+TEST_F(LoggerSpecificationTest, AddOption) {
+    OutputOption option1;
+    option1.destination = OutputOption::DEST_FILE;
+    option1.filename = "/tmp/example.log";
+    option1.maxsize = 123456;
+
+    OutputOption option2;
+    option2.destination = OutputOption::DEST_SYSLOG;
+    option2.facility = "LOCAL7";
+
+    LoggerSpecification spec;
+    spec.addOutputOption(option1);
+    spec.addOutputOption(option2);
+    EXPECT_EQ(2, spec.optionCount());
+
+    // Iterate through them
+    LoggerSpecification::const_iterator i = spec.begin();
+
+    EXPECT_EQ(OutputOption::DEST_FILE, i->destination);
+    EXPECT_EQ(string("/tmp/example.log"), i->filename);
+    EXPECT_EQ(123456, i->maxsize);
+
+    ++i;
+    EXPECT_EQ(OutputOption::DEST_SYSLOG, i->destination);
+    EXPECT_EQ(string("LOCAL7"), i->facility);
+
+    ++i;
+    EXPECT_TRUE(i == spec.end());
+}
diff --git a/src/lib/log/tests/output_option_unittest.cc b/src/lib/log/tests/output_option_unittest.cc
new file mode 100644
index 0000000..59154ff
--- /dev/null
+++ b/src/lib/log/tests/output_option_unittest.cc
@@ -0,0 +1,47 @@
+// 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 <string>
+
+#include <gtest/gtest.h>
+
+#include <log/output_option.h>
+
+using namespace isc::log;
+using namespace std;
+
+/// \brief OutputOption Test
+class OutputOptionTest : public ::testing::Test {
+public:
+    OutputOptionTest()
+    {}
+    ~OutputOptionTest()
+    {}
+};
+
+
+// As OutputOption is a struct, the only meaningful test is to check that it
+// initializes correctly.
+
+TEST_F(OutputOptionTest, Initialization) {
+    OutputOption option;
+
+    EXPECT_EQ(OutputOption::DEST_CONSOLE, option.destination);
+    EXPECT_EQ(OutputOption::STR_STDERR, option.stream);
+    EXPECT_FALSE(option.flush);
+    EXPECT_EQ(string(""), option.facility);
+    EXPECT_EQ(string(""), option.filename);
+    EXPECT_EQ(0, option.maxsize);
+    EXPECT_EQ(0, option.maxver);
+}




More information about the bind10-changes mailing list