Browse Source

[4297] Unit-tests for parameters implemented.

Tomek Mrugalski 9 years ago
parent
commit
656b5e1541

+ 7 - 1
src/lib/hooks/hooks_manager.cc

@@ -131,6 +131,12 @@ HooksManager::getLibraryNamesInternal() const {
                            : std::vector<std::string>());
 }
 
+HookLibsCollection
+HooksManager::getLibraryInfoInternal() const {
+    return (lm_collection_ ? lm_collection_->getLibraryInfo()
+            : HookLibsCollection());
+}
+
 std::vector<std::string>
 HooksManager::getLibraryNames() {
     return (getHooksManager().getLibraryNamesInternal());
@@ -138,7 +144,7 @@ HooksManager::getLibraryNames() {
 
 HookLibsCollection
 HooksManager::getLibraryInfo() {
-    return (getHooksManager().getLibraryInfo());
+    return (getHooksManager().getLibraryInfoInternal());
 }
 
 // Perform conditional initialization if nothing is loaded.

+ 3 - 0
src/lib/hooks/hooks_manager.h

@@ -274,6 +274,9 @@ private:
     /// @return List of loaded library names.
     std::vector<std::string> getLibraryNamesInternal() const;
 
+    /// @brief Return a collection of library names with parameters.
+    HookLibsCollection getLibraryInfoInternal() const;
+
     //@}
 
     /// @brief Initialization to No Libraries

+ 15 - 0
src/lib/hooks/library_handle.cc

@@ -6,6 +6,7 @@
 
 #include <hooks/callout_manager.h>
 #include <hooks/library_handle.h>
+#include <hooks/hooks_manager.h>
 
 namespace isc {
 namespace hooks {
@@ -64,5 +65,19 @@ LibraryHandle::deregisterAllCallouts(const std::string& name) {
     return (status);
 }
 
+isc::data::ConstElementPtr
+LibraryHandle::getParameter(const std::string& name) {
+    HookLibsCollection libinfo = HooksManager::getHooksManager().getLibraryInfo();
+
+    if ((index_ >= libinfo.size()) || (index_ < 0)) {
+        // Something is very wrong here. However, this is user facing
+        // interface, so we should not throw here.
+        return (isc::data::ConstElementPtr());
+    }
+
+    // Try to find appropriate parameter. May return NULL
+    return (libinfo[index_].second->get(name));
+}
+
 } // namespace util
 } // namespace isc

+ 62 - 0
src/lib/hooks/library_handle.h

@@ -8,6 +8,7 @@
 #define LIBRARY_HANDLE_H
 
 #include <string>
+#include <cc/data.h>
 
 namespace isc {
 namespace hooks {
@@ -107,6 +108,67 @@ public:
     /// @throw NoSuchHook Thrown if the hook name is unrecognized.
     bool deregisterAllCallouts(const std::string& name);
 
+
+    /// @brief Returns configuration parameter for the library.
+    ///
+    /// This method returns configuration parameters specified in the
+    /// configuration file. Here's the example. Let's assume that there
+    /// are two hook libraries configured:
+    ///
+    /// "hooks-libraries": [
+    ///     {
+    ///        "library": "/opt/charging.so",
+    ///        "parameters": {}
+    ///    },
+    ///    {
+    ///        "library": "/opt/local/notification.so",
+    ///        "parameters": {
+    ///            "mail": "alarm@example.com",
+    ///            "floor": 42,
+    ///            "debug": false,
+    ///            "users": [ "alice", "bob", "charlie" ],
+    ///            "header": {
+    ///                "french": "bonjour",
+    ///                "klingon": "yl'el"
+    ///            }
+    ///        }
+    ///    }
+    ///]
+    ///
+    /// The first library has no parameters, so regardles of the name
+    /// specified, for that library getParameter will always return NULL.
+    ///
+    /// For the second paramter, depending the following calls will return:
+    /// - x = getParameter("mail") will return instance of
+    ///   isc::data::StringElement. The content can be accessed with
+    ///   x->stringValue() and will return std::string.
+    /// - x = getParameter("floor") will return an instance of isc::data::IntElement.
+    ///   The content can be accessed with x->intValue() and will return int.
+    /// - x = getParameter("debug") will return an instance of isc::data::BoolElement.
+    ///   Its value can be accessed with x->boolValue() and will return bool.
+    /// - x = getParameter("users") will return an instance of ListElement.
+    ///   Its content can be accessed with the following methods:
+    ///   x->size(), x->get(index)
+    /// - x = getParameter("watch-list") will return an instance of isc::data::MapElement.
+    ///   Its content can be accessed with the following methods:
+    ///   x->find("klingon"), x->contains("french"), x->size()
+    ///
+    /// For more examples and complete API, see documentation for
+    /// @ref isc::data::Element class and its derivatives:
+    /// - @ref isc::data::IntElement
+    /// - @ref isc::data::DoubleElement
+    /// - @ref isc::data::BoolElement
+    /// - @ref isc::data::StringElement
+    /// - @ref isc::data::ListElement
+    /// - @ref isc::data::MapElement
+    ///
+    /// Another good way to learn how to use Element interface is to look at the
+    /// unittests in data_unittests.cc.
+    ///
+    /// @param name text name of the parameter.
+    isc::data::ConstElementPtr
+    getParameter(const std::string& name);
+
 private:
     /// @brief Copy constructor
     ///

+ 8 - 1
src/lib/hooks/tests/Makefile.am

@@ -47,7 +47,7 @@ if HAVE_GTEST
 # ignored for unit tests built here.
 
 noinst_LTLIBRARIES = libnvl.la  libivl.la libfxl.la libbcl.la liblcl.la \
-                     liblecl.la libucl.la libfcl.la
+                     liblecl.la libucl.la libfcl.la libpcl.la
 
 # -rpath /nowhere is a hack to trigger libtool to not create a
 # convenience archive, resulting in shared modules
@@ -102,6 +102,13 @@ libfcl_la_CXXFLAGS = $(AM_CXXFLAGS)
 libfcl_la_CPPFLAGS = $(AM_CPPFLAGS)
 libfcl_la_LDFLAGS  = -avoid-version -export-dynamic -module -rpath /nowhere
 
+# The parameters checking callout library - expects
+libpcl_la_SOURCES  = callout_params_library.cc
+libpcl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libpcl_la_CPPFLAGS = $(AM_CPPFLAGS)
+libpcl_la_LDFLAGS  = -avoid-version -export-dynamic -module -rpath /nowhere
+libpcl_la_LDFLAGS += $(top_builddir)/src/lib/util/libkea-util.la
+
 TESTS += run_unittests
 run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += callout_handle_unittest.cc

+ 28 - 1
src/lib/hooks/tests/hooks_manager_unittest.cc

@@ -10,6 +10,7 @@
 
 #include <hooks/tests/common_test_class.h>
 #include <hooks/tests/test_libraries.h>
+#include <cc/data.h>
 
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
@@ -17,9 +18,9 @@
 #include <algorithm>
 #include <string>
 
-
 using namespace isc;
 using namespace isc::hooks;
+using namespace isc::data;
 using namespace std;
 
 namespace {
@@ -538,5 +539,31 @@ TEST_F(HooksManagerTest, validateLibraries) {
     EXPECT_TRUE(failed == expected_failures);
 }
 
+// This test verifies that the specified parameters are accessed properly.
+TEST_F(HooksManagerTest, LibraryParameters) {
+
+    // Prepare paramters for the callout parameters library.
+    ElementPtr params = Element::createMap();
+    params->set("svalue", Element::create("string value"));
+    params->set("ivalue", Element::create(42));
+    params->set("bvalue", Element::create(true));
+
+    // Set up the list of libraries to be loaded.
+    HookLibsCollection library_names;
+    library_names.push_back(make_pair(std::string(BASIC_CALLOUT_LIBRARY),
+                                      data::ConstElementPtr()));
+    library_names.push_back(make_pair(std::string(CALLOUT_PARAMS_LIBRARY),
+                                      params));
+
+    // Load the libraries. Note that callout params library checks if
+    // all mandatory parameters are there, so if anything is missing, its
+    // load() function will return error, thus causing the library to not
+    // load.
+    EXPECT_TRUE(HooksManager::loadLibraries(library_names));
+
+    // Try unloading the libraries.
+    EXPECT_NO_THROW(HooksManager::unloadLibraries());
+}
+
 
 } // Anonymous namespace

+ 1 - 0
src/lib/hooks/tests/library_manager_collection_unittest.cc

@@ -213,6 +213,7 @@ TEST_F(LibraryManagerCollectionTest, validateLibraries) {
     libraries.push_back(BASIC_CALLOUT_LIBRARY);
     libraries.push_back(FULL_CALLOUT_LIBRARY);
     libraries.push_back(UNLOAD_CALLOUT_LIBRARY);
+    libraries.push_back(CALLOUT_PARAMS_LIBRARY);
 
     failed = LibraryManagerCollection::validateLibraries(libraries);
     EXPECT_TRUE(failed.empty());

+ 1 - 0
src/lib/hooks/tests/library_manager_unittest.cc

@@ -560,6 +560,7 @@ TEST_F(LibraryManagerTest, validateLibraries) {
     EXPECT_FALSE(LibraryManager::validateLibrary(NOT_PRESENT_LIBRARY));
     EXPECT_FALSE(LibraryManager::validateLibrary(NO_VERSION_LIBRARY));
     EXPECT_TRUE(LibraryManager::validateLibrary(UNLOAD_CALLOUT_LIBRARY));
+    EXPECT_TRUE(LibraryManager::validateLibrary(CALLOUT_PARAMS_LIBRARY));
 }
 
 // Check that log messages are properly registered and unregistered.

+ 3 - 0
src/lib/hooks/tests/test_libraries.h.in

@@ -46,6 +46,9 @@ static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
 // Library where there is an unload() function.
 static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
 
+// Library where parameters are checked.
+static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/.libs/libpcl.so";
+
 } // anonymous namespace