Browse Source

[3427] Configuration unit-tests written.

Tomek Mrugalski 10 years ago
parent
commit
4c99c52099

+ 2 - 0
src/lib/dhcpsrv/configuration.h

@@ -17,6 +17,8 @@
 
 #include <log/logger_level.h>
 #include <boost/shared_ptr.hpp>
+#include <vector>
+#include <stdint.h>
 
 namespace isc {
 namespace dhcp {

+ 1 - 1
src/lib/dhcpsrv/logging.h

@@ -43,7 +43,7 @@ public:
     /// Walks over specified logging configuration JSON structures and store
     /// parsed information in config_->logging_info_.
     ///
-    /// @param log_config JSON structures to be parsed
+    /// @param log_config JSON structures to be parsed (loggers list)
     void parseConfiguration(isc::data::ConstElementPtr log_config);
 
     /// @brief Applies stored configuration

+ 2 - 0
src/lib/dhcpsrv/tests/Makefile.am

@@ -55,6 +55,7 @@ libdhcpsrv_unittests_SOURCES  = run_unittests.cc
 libdhcpsrv_unittests_SOURCES += addr_utilities_unittest.cc
 libdhcpsrv_unittests_SOURCES += alloc_engine_unittest.cc
 libdhcpsrv_unittests_SOURCES += callout_handle_store_unittest.cc
+libdhcpsrv_unittests_SOURCES += configuration_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc
 libdhcpsrv_unittests_SOURCES += csv_lease_file4_unittest.cc
 libdhcpsrv_unittests_SOURCES += csv_lease_file6_unittest.cc
@@ -66,6 +67,7 @@ libdhcpsrv_unittests_SOURCES += lease_file_io.cc lease_file_io.h
 libdhcpsrv_unittests_SOURCES += lease_unittest.cc
 libdhcpsrv_unittests_SOURCES += lease_mgr_factory_unittest.cc
 libdhcpsrv_unittests_SOURCES += lease_mgr_unittest.cc
+libdhcpsrv_unittests_SOURCES += logging_unittest.cc
 libdhcpsrv_unittests_SOURCES += generic_lease_mgr_unittest.cc generic_lease_mgr_unittest.h
 libdhcpsrv_unittests_SOURCES += memfile_lease_mgr_unittest.cc
 libdhcpsrv_unittests_SOURCES += dhcp_parsers_unittest.cc

+ 10 - 0
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc

@@ -289,6 +289,16 @@ public:
     isc::dhcp::ClientClasses classify_;
 };
 
+// Checks that there is a configuration structure available and that
+// it is empty by default.
+TEST_F(CfgMgrTest, configuration) {
+
+    ConfigurationPtr configuration = CfgMgr::instance().getConfiguration();
+    ASSERT_TRUE(configuration);
+
+    EXPECT_TRUE(configuration->logging_info_.empty());
+}
+
 // This test verifies that multiple option definitions can be added
 // under different option spaces.
 TEST_F(CfgMgrTest, getOptionDefs) {

+ 63 - 0
src/lib/dhcpsrv/tests/configuration_unittest.cc

@@ -0,0 +1,63 @@
+// Copyright (C) 2012-2014 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 <config.h>
+
+#include <dhcpsrv/configuration.h>
+#include <gtest/gtest.h>
+
+using namespace isc::dhcp;
+
+// Those are the tests for Configuration storage. Right now they are minimal,
+// but the number is expected to grow significantly once we migrate more
+// parameters from CfgMgr storage to Configuration storage.
+
+namespace {
+
+// Check that by default there are no logging entries
+TEST(ConfigurationTest, basic) {
+    Configuration x;
+
+    EXPECT_TRUE(x.logging_info_.empty());
+}
+
+// Check that Configuration can store logging information.
+TEST(ConfigurationTest, loggingInfo) {
+
+    Configuration x;
+
+    LoggingInfo log1;
+    log1.name_ = "foo";
+    log1.severity_ = isc::log::WARN;
+    log1.debuglevel_ = 77;
+
+    LoggingDestination dest;
+    dest.output_ = "some-logfile.txt";
+    dest.maxver_ = 5;
+    dest.maxsize_ = 2097152;
+
+    log1.destinations_.push_back(dest);
+
+    x.logging_info_.push_back(log1);
+
+    EXPECT_EQ("foo", x.logging_info_[0].name_);
+    EXPECT_EQ(isc::log::WARN, x.logging_info_[0].severity_);
+    EXPECT_EQ(77, x.logging_info_[0].debuglevel_);
+
+    EXPECT_EQ("some-logfile.txt", x.logging_info_[0].destinations_[0].output_);
+    EXPECT_EQ(5, x.logging_info_[0].destinations_[0].maxver_);
+    EXPECT_EQ(2097152, x.logging_info_[0].destinations_[0].maxsize_);
+}
+
+} // end of anonymous namespace

+ 43 - 0
src/lib/dhcpsrv/tests/daemon_unittest.cc

@@ -15,10 +15,13 @@
 #include <config.h>
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/daemon.h>
+#include <dhcpsrv/logging.h>
+#include <cc/data.h>
 #include <gtest/gtest.h>
 
 using namespace isc;
 using namespace isc::dhcp;
+using namespace isc::data;
 
 namespace {
 
@@ -27,6 +30,46 @@ TEST(DaemonTest, noop) {
     EXPECT_NO_THROW(Daemon x);
 }
 
+// Checks that configureLogger method is behaving properly.
+// More dedicated tests are availablef for LogConfigParser class.
+// See logger_unittest.cc
+TEST(DaemonTest, parsingConsoleOutput) {
+
+    // Storage - parsed configuration will be stored here
+    ConfigurationPtr storage(new Configuration());
+
+    const char* config_txt =
+    "{ \"loggers\": ["
+    "    {"
+    "        \"name\": \"kea\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"stdout\""
+    "            }"
+    "        ],"
+    "        \"debuglevel\": 99,"
+    "        \"severity\": \"DEBUG\""
+    "    }"
+    "]}";
+    ConstElementPtr config = Element::fromJSON(config_txt);
+
+    // Spawn a daemon and tell it to configure logger
+    Daemon x;
+    EXPECT_NO_THROW(x.configureLogger(config, storage));
+
+    // The parsed configuration should be processed by the daemon and
+    // stored in configuration storage.
+    ASSERT_EQ(1, storage->logging_info_.size());
+
+    EXPECT_EQ("kea", storage->logging_info_[0].name_);
+    EXPECT_EQ(99, storage->logging_info_[0].debuglevel_);
+    EXPECT_EQ(isc::log::DEBUG, storage->logging_info_[0].severity_);
+
+    ASSERT_EQ(1, storage->logging_info_[0].destinations_.size());
+    EXPECT_EQ("stdout" , storage->logging_info_[0].destinations_[0].output_);
+}
+
+
 // More tests will appear here as we develop Daemon class.
 
 };

+ 126 - 0
src/lib/dhcpsrv/tests/logging_unittest.cc

@@ -0,0 +1,126 @@
+// Copyright (C) 2014 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 <config.h>
+#include <exceptions/exceptions.h>
+#include <cc/data.h>
+#include <dhcpsrv/logging.h>
+#include <gtest/gtest.h>
+
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::data;
+
+namespace {
+
+// Checks that contructor is able to process specified storage properly
+TEST(LoggingTest, constructor) {
+
+    ConfigurationPtr nullPtr;
+    EXPECT_THROW(LogConfigParser parser(nullPtr), InvalidOperation);
+
+    ConfigurationPtr nonnull(new Configuration());
+
+    EXPECT_NO_THROW(LogConfigParser parser(nonnull));
+}
+
+// Checks if the LogConfigParser class is able to transform JSON structures
+// into Configuration usable by log4cplus. This test checks for output
+// configured to stdout on debug level.
+TEST(LoggingTest, parsingConsoleOutput) {
+
+    const char* config_txt = 
+    "{ \"loggers\": ["
+    "    {"
+    "        \"name\": \"kea\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"stdout\""
+    "            }"
+    "        ],"
+    "        \"debuglevel\": 99,"
+    "        \"severity\": \"DEBUG\""
+    "    }"
+    "]}";
+
+    ConfigurationPtr storage(new Configuration());
+
+    LogConfigParser parser(storage);
+
+    // We need to parse properly formed JSON and then extract
+    // "loggers" element from it. For some reason fromJSON is
+    // throwing at opening square bracket 
+    ConstElementPtr config = Element::fromJSON(config_txt);
+    config = config->get("loggers");
+
+    EXPECT_NO_THROW(parser.parseConfiguration(config));
+
+    ASSERT_EQ(1, storage->logging_info_.size());
+
+    EXPECT_EQ("kea", storage->logging_info_[0].name_);
+    EXPECT_EQ(99, storage->logging_info_[0].debuglevel_);
+    EXPECT_EQ(isc::log::DEBUG, storage->logging_info_[0].severity_);
+
+    ASSERT_EQ(1, storage->logging_info_[0].destinations_.size());
+    EXPECT_EQ("stdout" , storage->logging_info_[0].destinations_[0].output_);
+}
+
+// Checks if the LogConfigParser class is able to transform JSON structures
+// into Configuration usable by log4cplus. This test checks for output
+// configured to a file on INFO level.
+TEST(LoggingTest, parsingFile) {
+
+    const char* config_txt = 
+    "{ \"loggers\": ["
+    "    {"
+    "        \"name\": \"kea\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"logfile.txt\""
+    "            }"
+    "        ],"
+    "        \"severity\": \"INFO\""
+    "    }"
+    "]}";
+
+    ConfigurationPtr storage(new Configuration());
+
+    LogConfigParser parser(storage);
+
+    // We need to parse properly formed JSON and then extract
+    // "loggers" element from it. For some reason fromJSON is
+    // throwing at opening square bracket 
+    ConstElementPtr config = Element::fromJSON(config_txt);
+    config = config->get("loggers");
+
+    EXPECT_NO_THROW(parser.parseConfiguration(config));
+
+    ASSERT_EQ(1, storage->logging_info_.size());
+
+    EXPECT_EQ("kea", storage->logging_info_[0].name_);
+    EXPECT_EQ(0, storage->logging_info_[0].debuglevel_);
+    EXPECT_EQ(isc::log::INFO, storage->logging_info_[0].severity_);
+
+    ASSERT_EQ(1, storage->logging_info_[0].destinations_.size());
+    EXPECT_EQ("logfile.txt" , storage->logging_info_[0].destinations_[0].output_);
+}
+
+// There is no easy way to test applyConfiguration() and defaultLogging().
+// To test them, it would require instrumenting log4cplus to actually fake
+// the logging set up. Alternatively, we could develop set of test suites
+// that check each logging destination spearately (e.g. configure log file, then
+// check if the file is indeed created or configure stdout destination, then
+// swap console file descriptors and check that messages are really logged.
+
+};