Parcourir la source

[2980] LibraryManager basic unit tests written

Stephen Morris il y a 12 ans
Parent
commit
03db051a72

+ 1 - 0
configure.ac

@@ -1402,6 +1402,7 @@ AC_OUTPUT([doc/version.ent
            src/lib/cc/session_config.h.pre
            src/lib/cc/session_config.h.pre
            src/lib/cc/tests/session_unittests_config.h
            src/lib/cc/tests/session_unittests_config.h
            src/lib/datasrc/datasrc_config.h.pre
            src/lib/datasrc/datasrc_config.h.pre
+           src/lib/hooks/tests/library_manager_unittest.cc
            src/lib/log/tests/console_test.sh
            src/lib/log/tests/console_test.sh
            src/lib/log/tests/destination_test.sh
            src/lib/log/tests/destination_test.sh
            src/lib/log/tests/init_logger_test.sh
            src/lib/log/tests/init_logger_test.sh

+ 2 - 0
src/lib/hooks/Makefile.am

@@ -16,7 +16,9 @@ lib_LTLIBRARIES = libb10-hooks.la
 libb10_hooks_la_SOURCES  =
 libb10_hooks_la_SOURCES  =
 libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
 libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
 libb10_hooks_la_SOURCES += callout_manager.cc callout_manager.h
 libb10_hooks_la_SOURCES += callout_manager.cc callout_manager.h
+libb10_hooks_la_SOURCES += hooks.h
 libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
 libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
+libb10_hooks_la_SOURCES += library_manager.h
 libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
 libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
 
 
 libb10_hooks_la_CXXFLAGS = $(AM_CXXFLAGS)
 libb10_hooks_la_CXXFLAGS = $(AM_CXXFLAGS)

+ 24 - 0
src/lib/hooks/hooks.h

@@ -0,0 +1,24 @@
+// Copyright (C) 2013  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 HOOKS_H
+#define HOOKS_H
+
+#include <hooks/callout_handle.h>
+#include <hooks/library_handle.h>
+
+// Version 1.0
+static const int BIND10_HOOKS_VERSION = (1 << 16 + 0);
+
+#endif  // HOOKS_H

+ 91 - 0
src/lib/hooks/library_manager.h

@@ -0,0 +1,91 @@
+// Copyright (C) 2013  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 LIBRARY_MANAGER_H
+#define LIBRARY_MANAGER_H
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace isc {
+namespace hooks {
+
+class CalloutManager;
+
+/// @brief Library manager
+///
+/// This class handles the loading and unloading of a specific library.
+///
+/// On loading, it opens the library using dlopen and checks the version (set
+/// with the "version" method.  If all is OK, it iterates through the list of
+/// known hooks and locates their symbols, registering each callout as it
+/// does so.  Finally it locates the "load" and "unload" functions (if present),
+/// calling the "load" callouts if present.
+///
+/// On unload, it calls the "unload" method if one was located, clears the
+/// callouts from all hooks and closes the library.
+
+class LibraryManager {
+public:
+    /// @brief Constructor
+    ///
+    /// Stores the library name.  The actual loading is done in loadLibrary().
+    ///
+    /// @param name Name of the library to load.  This should be an absolute
+    ///        path name.
+    /// @param index Index of this library
+    /// @param manager CalloutManager object
+    LibraryManager(const std::string& name, int index,
+                   const boost::shared_ptr<CalloutManager>& manager)
+        : dl_handle_(NULL), index_(index), manager_(manager), name_(name),
+          load_func_(NULL), unload_func_(NULL),
+          version_func_(NULL)
+    {}
+
+    /// @brief Loads a library
+    ///
+    /// Open the library and check the version.  If all is OK, load all
+    /// standard symbols then call "load" if present.
+    void loadLibrary() {}
+
+    /// @brief Unloads a library
+    ///
+    /// Calls the libraries "unload" function if present, the closes the
+    /// library.
+    void unloadLibrary() {}
+
+    /// @brief Return library name
+    ///
+    /// @return Name of this library
+    std::string getName() const {
+        return (name_);
+    }
+
+private:
+    void*       dl_handle_;     ///< Handle returned by dlopen
+    int         index_;         ///< Index associated with this library
+    boost::shared_ptr<CalloutManager> manager_;
+                                ///< Callout manager for registration
+    std::string name_;          ///< Name of the library
+
+    void*       load_func_;     ///< Pointer to the "load" function
+    void*       unload_func_;   ///< Pointer to the "unload" function
+    void*       version_func_;  ///< Pointer to the "version" function
+};
+
+} // namespace hooks
+} // namespace isc
+
+#endif  // LIBRARY_MANAGER_H

+ 12 - 0
src/lib/hooks/tests/Makefile.am

@@ -24,6 +24,17 @@ CLEANFILES = *.gcno *.gcda
 TESTS_ENVIRONMENT = \
 TESTS_ENVIRONMENT = \
 	$(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
 	$(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
 
 
+# Build shared libraries for testing.  The Basic Callout Library
+lib_LTLIBRARIES = libbco.la
+libbco_la_SOURCES  = basic_callout_library.cc
+libbco_la_CXXFLAGS = $(AM_CXXFLAGS)
+libbco_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+libbco_la_LIBADD  =
+libbco_la_LIBADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
+libbco_la_LIBADD += $(top_builddir)/src/lib/log/libb10-log.la
+libbco_la_LIBADD += $(top_builddir)/src/lib/util/libb10-util.la
+libbco_la_LIBADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+
 TESTS =
 TESTS =
 if HAVE_GTEST
 if HAVE_GTEST
 TESTS += run_unittests
 TESTS += run_unittests
@@ -31,6 +42,7 @@ run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += callout_handle_unittest.cc
 run_unittests_SOURCES += callout_handle_unittest.cc
 run_unittests_SOURCES += callout_manager_unittest.cc
 run_unittests_SOURCES += callout_manager_unittest.cc
 run_unittests_SOURCES += handles_unittest.cc
 run_unittests_SOURCES += handles_unittest.cc
+run_unittests_SOURCES += library_manager_unittest.cc
 run_unittests_SOURCES += server_hooks_unittest.cc
 run_unittests_SOURCES += server_hooks_unittest.cc
 
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)

+ 96 - 0
src/lib/hooks/tests/basic_callout_library.cc

@@ -0,0 +1,96 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Basic Callout Library
+///
+/// This file is built into a shared library and is loaded by the LibraryManager
+/// test.  The characteristics of this library are:
+///
+/// - Only the "version" framework function is supplied.  The other callouts
+///   are assumed to be "standard" callouts.
+///
+/// - A context_create callout is supplied.
+///
+/// - Three other callouts are supplied.  Two do some trivial calculations
+///   on the arguments supplied to it and the context variables.  The
+///   third returns the results through the "result" argument, and this is
+///   checked by the test program.
+
+#include <hooks/hooks.h>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+int
+version() {
+    return (BIND10_HOOKS_VERSION);
+}
+
+// Callouts
+
+int
+context_create(CalloutHandle& handle) {
+    handle.setContext("result", static_cast<int>(10));
+    return (0);
+}
+
+// First callout adds the passed "data_1" argument to the initialized context
+// value of 10.
+
+int basic_one(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_1", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result += data;
+    handle.setContext("result", result);
+
+    return (0);
+}
+
+// Second callout multiplies the current context value by the "data_2"
+// argument.
+
+int
+basic_two(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_2", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result *= data;
+    handle.setContext("result", result);
+
+    return (0);
+}
+
+// Final callout returns the value in the context through the "result"
+// argument.
+
+int
+basic_three(CalloutHandle& handle) {
+    int result;
+    handle.getContext("result", result);
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+};
+

+ 78 - 0
src/lib/hooks/tests/library_manager_unittest.cc.in

@@ -0,0 +1,78 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_manager.h>
+#include <hooks/server_hooks.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+// Names of the libraries used in these tests
+static const char* BASIC_CALLOUT_LIBRARY = "@builddir@/.libs/libbco.so";
+
+
+namespace {
+
+// Checks the basic functionality - loads a library where the callouts are
+// named after the hooks, calls the callouts and checks the results.
+
+TEST(LibraryManagerTest, BasicCalloutTest) {
+    // Set up the hooks we expect.
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+    int one_index = hooks.registerHook("basic_one");
+    int two_index = hooks.registerHook("basic_two");
+    int three_index = hooks.registerHook("basic_three");
+
+    // Set up the callout manager with one library.
+    boost::shared_ptr<CalloutManager> co_manager(new CalloutManager(1));
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    LibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                               0, co_manager);
+    EXPECT_NO_THROW(lib_manager.loadLibrary());
+
+    // Create the callout handle...
+    CalloutHandle callout_handle(co_manager);
+
+    // Now execute the callouts in the order expected.  context_create
+    // always comes first.  This sets the context value to 10.
+    co_manager->callCallouts(ServerHooks::CONTEXT_CREATE, callout_handle);
+
+    // First callout adds 5 to the context value.
+    callout_handle.setArgument("data_1", static_cast<int>(5));
+    co_manager->callCallouts(one_index, callout_handle);
+
+    // Second callout multiples the context value by 7
+    callout_handle.setArgument("data_2", static_cast<int>(7));
+    co_manager->callCallouts(two_index, callout_handle);
+
+    // Third callour retrieves the context value.
+    co_manager->callCallouts(three_index, callout_handle);
+    int result;
+    callout_handle.getArgument("result", result);
+    EXPECT_EQ(105, result);
+}
+
+} // Anonymous namespace