BIND 10 trac2980, updated. db3f2d81e975c2c82e575ba2947340f520f763a9 [2980] Rationalised the tests a but by extracting a common class

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Jun 21 16:46:44 UTC 2013


The branch, trac2980 has been updated
       via  db3f2d81e975c2c82e575ba2947340f520f763a9 (commit)
       via  cc8e7feaf34f1028438854453b4811d7283852c0 (commit)
       via  8b7ae5faff5a12fb2841e8b35b43253c0d67c22f (commit)
      from  7c20771f4296820b7efc22b19a0783e7d226736a (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 db3f2d81e975c2c82e575ba2947340f520f763a9
Author: Stephen Morris <stephen at isc.org>
Date:   Fri Jun 21 17:46:10 2013 +0100

    [2980] Rationalised the tests a but by extracting a common class

commit cc8e7feaf34f1028438854453b4811d7283852c0
Author: Stephen Morris <stephen at isc.org>
Date:   Fri Jun 21 16:45:42 2013 +0100

    [2980] Abstracted names of test libraries into a common header file

commit 8b7ae5faff5a12fb2841e8b35b43253c0d67c22f
Author: Stephen Morris <stephen at isc.org>
Date:   Fri Jun 21 16:24:10 2013 +0100

    [2980] Added the LibraryManagerCollection object
    
    This manages LibraryManagers created for the libraries loaded.

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

Summary of changes:
 configure.ac                                       |    2 +-
 src/lib/hooks/Makefile.am                          |    1 +
 src/lib/hooks/callout_handle.h                     |    3 +
 src/lib/hooks/callout_manager.cc                   |   12 ++
 src/lib/hooks/callout_manager.h                    |   29 +--
 src/lib/hooks/library_manager.h                    |    1 +
 src/lib/hooks/tests/Makefile.am                    |    4 +-
 src/lib/hooks/tests/callout_manager_unittest.cc    |   13 +-
 src/lib/hooks/tests/common_test_class.h            |  138 +++++++++++++++
 .../tests/library_manager_collection_unittest.cc   |  186 ++++++++++++++++++++
 ..._unittest.cc.in => library_manager_unittest.cc} |  139 ++++-----------
 src/lib/hooks/tests/test_libraries.h.in            |   55 ++++++
 12 files changed, 468 insertions(+), 115 deletions(-)
 create mode 100644 src/lib/hooks/tests/common_test_class.h
 create mode 100644 src/lib/hooks/tests/library_manager_collection_unittest.cc
 rename src/lib/hooks/tests/{library_manager_unittest.cc.in => library_manager_unittest.cc} (77%)
 create mode 100644 src/lib/hooks/tests/test_libraries.h.in

-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index ff54312..1b9ce60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1402,8 +1402,8 @@ AC_OUTPUT([doc/version.ent
            src/lib/cc/session_config.h.pre
            src/lib/cc/tests/session_unittests_config.h
            src/lib/datasrc/datasrc_config.h.pre
-           src/lib/hooks/tests/library_manager_unittest.cc
            src/lib/hooks/tests/marker_file.h
+           src/lib/hooks/tests/test_libraries.h
            src/lib/log/tests/console_test.sh
            src/lib/log/tests/destination_test.sh
            src/lib/log/tests/init_logger_test.sh
diff --git a/src/lib/hooks/Makefile.am b/src/lib/hooks/Makefile.am
index eee2a72..75b3daf 100644
--- a/src/lib/hooks/Makefile.am
+++ b/src/lib/hooks/Makefile.am
@@ -33,6 +33,7 @@ libb10_hooks_la_SOURCES += hooks.h
 libb10_hooks_la_SOURCES += hooks_log.cc hooks_log.h
 libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
 libb10_hooks_la_SOURCES += library_manager.cc library_manager.h
+libb10_hooks_la_SOURCES += library_manager_collection.cc library_manager_collection.h
 libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
 
 nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h
diff --git a/src/lib/hooks/callout_handle.h b/src/lib/hooks/callout_handle.h
index 9603f5c..81cfb5f 100644
--- a/src/lib/hooks/callout_handle.h
+++ b/src/lib/hooks/callout_handle.h
@@ -353,6 +353,9 @@ private:
     bool skip_;
 };
 
+/// A shared pointer to a CalloutHandle object.
+typedef boost::shared_ptr<CalloutHandle> CalloutHandlePtr;
+
 } // namespace util
 } // namespace isc
 
diff --git a/src/lib/hooks/callout_manager.cc b/src/lib/hooks/callout_manager.cc
index 69027ae..0547a19 100644
--- a/src/lib/hooks/callout_manager.cc
+++ b/src/lib/hooks/callout_manager.cc
@@ -27,6 +27,18 @@ using namespace std;
 namespace isc {
 namespace hooks {
 
+// Set the number of libraries handles by the CalloutManager.
+
+void
+CalloutManager::setNumLibraries(int num_libraries) {
+    if (num_libraries < 0) {
+        isc_throw(isc::BadValue, "number of libraries passed to the "
+                  "CalloutManager must be >= 0");
+    }
+
+    num_libraries_ = num_libraries;
+}
+
 // Register a callout for the current library.
 
 void
diff --git a/src/lib/hooks/callout_manager.h b/src/lib/hooks/callout_manager.h
index f28bc1c..39e374e 100644
--- a/src/lib/hooks/callout_manager.h
+++ b/src/lib/hooks/callout_manager.h
@@ -96,17 +96,15 @@ public:
     ///
     /// @throw isc::BadValue if the number of libraries is less than or equal
     ///        to 0, or if the pointer to the server hooks object is empty.
-    CalloutManager(int num_libraries)
-        : current_hook_(-1), current_library_(-1), hook_vector_(),
+    CalloutManager(int num_libraries = 0)
+        : current_hook_(-1), current_library_(-1),
+          hook_vector_(ServerHooks::getServerHooks().getCount()),
           library_handle_(this), num_libraries_(num_libraries)
     {
-        if (num_libraries <= 0) {
-            isc_throw(isc::BadValue, "number of libraries passed to the "
-                      "CalloutManager must be >= 0");
-        }
-
-        // Parameters OK, do operations that depend on them.
-        hook_vector_.resize(ServerHooks::getServerHooks().getCount());
+        // Check that the number of libraries is OK.  (This does a redundant
+        // set of the number of libraries, but it's only a single assignment
+        // and avoids the need for a separate "check" method.
+        setNumLibraries(num_libraries);
     }
 
     /// @brief Register a callout on a hook for the current library
@@ -187,12 +185,23 @@ public:
         return (current_hook_);
     }
 
+    /// @brief Set number of libraries
+    ///
+    /// Sets the number of libraries.  Although the value is passed to the
+    /// constructor, in some cases that is only an estimate and the number
+    /// can only be determined after the CalloutManager is created.
+    ///
+    /// @param num_libraries Number of libraries served by this CalloutManager.
+    ///
+    /// @throw BadValue Number of libraries must be >= 0.
+    void setNumLibraries(int num_libraries);
+
     /// @brief Get number of libraries
     ///
     /// Returns the number of libraries that this CalloutManager is expected
     /// to serve.  This is the number passed to its constructor.
     ///
-    /// @return Number of libraries server by this CalloutManager.
+    /// @return Number of libraries served by this CalloutManager.
     int getNumLibraries() const {
         return (num_libraries_);
     }
diff --git a/src/lib/hooks/library_manager.h b/src/lib/hooks/library_manager.h
index 1014f00..4120cdf 100644
--- a/src/lib/hooks/library_manager.h
+++ b/src/lib/hooks/library_manager.h
@@ -23,6 +23,7 @@ namespace isc {
 namespace hooks {
 
 class CalloutManager;
+class LibraryHandle;
 class LibraryManager;
 
 /// @brief Library manager
diff --git a/src/lib/hooks/tests/Makefile.am b/src/lib/hooks/tests/Makefile.am
index 39c37b6..05364aa 100644
--- a/src/lib/hooks/tests/Makefile.am
+++ b/src/lib/hooks/tests/Makefile.am
@@ -71,7 +71,9 @@ TESTS += run_unittests
 run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += callout_handle_unittest.cc
 run_unittests_SOURCES += callout_manager_unittest.cc
+run_unittests_SOURCES += common_test_class.h
 run_unittests_SOURCES += handles_unittest.cc
+run_unittests_SOURCES += library_manager_collection_unittest.cc
 run_unittests_SOURCES += library_manager_unittest.cc
 run_unittests_SOURCES += server_hooks_unittest.cc
 
@@ -88,4 +90,4 @@ endif
 
 noinst_PROGRAMS = $(TESTS)
 
-EXTRA_DIST = library_manager_unittest.cc.in marker_file.h.in
+EXTRA_DIST = marker_file.h.in test_libraries.h.in
diff --git a/src/lib/hooks/tests/callout_manager_unittest.cc b/src/lib/hooks/tests/callout_manager_unittest.cc
index 22bb3d1..f57d17d 100644
--- a/src/lib/hooks/tests/callout_manager_unittest.cc
+++ b/src/lib/hooks/tests/callout_manager_unittest.cc
@@ -177,22 +177,31 @@ TEST_F(CalloutManagerTest, BadConstructorParameters) {
     boost::scoped_ptr<CalloutManager> cm;
 
     // Invalid number of libraries
-    EXPECT_THROW(cm.reset(new CalloutManager(0)), BadValue);
     EXPECT_THROW(cm.reset(new CalloutManager(-1)), BadValue);
 }
 
 // Check the number of libraries is reported successfully.
 
-TEST_F(CalloutManagerTest, GetNumLibraries) {
+TEST_F(CalloutManagerTest, NumberOfLibraries) {
     boost::scoped_ptr<CalloutManager> cm;
 
     // Check two valid values of number of libraries to ensure that the
     // GetNumLibraries() returns the value set.
+    EXPECT_NO_THROW(cm.reset(new CalloutManager()));
+    EXPECT_EQ(0, cm->getNumLibraries());
+
+    EXPECT_NO_THROW(cm.reset(new CalloutManager(0)));
+    EXPECT_EQ(0, cm->getNumLibraries());
+
     EXPECT_NO_THROW(cm.reset(new CalloutManager(4)));
     EXPECT_EQ(4, cm->getNumLibraries());
 
     EXPECT_NO_THROW(cm.reset(new CalloutManager(42)));
     EXPECT_EQ(42, cm->getNumLibraries());
+
+    // Check that setting the number of libraries alterns the number reported.
+    EXPECT_NO_THROW(cm->setNumLibraries(27));
+    EXPECT_EQ(27, cm->getNumLibraries());
 }
 
 // Check that we can only set the current library index to the correct values.
diff --git a/src/lib/hooks/tests/common_test_class.h b/src/lib/hooks/tests/common_test_class.h
new file mode 100644
index 0000000..bcb8e56
--- /dev/null
+++ b/src/lib/hooks/tests/common_test_class.h
@@ -0,0 +1,138 @@
+// 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 COMMON_HOOKS_TEST_CLASS_H
+#define COMMON_HOOKS_TEST_CLASS_H
+
+#include <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/server_hooks.h>
+#include <hooks/tests/marker_file.h>
+
+#include <boost/shared_ptr.hpp>
+#include <gtest/gtest.h>
+
+/// @brief Common hooks test class
+///
+/// This class is a shared parent of the test fixture class in the tests of the
+/// higher-level hooks classes (LibraryManager, LibraryManagerCollection and
+/// HooksManager).  It
+///
+/// - sets the the ServerHooks object with three hooks and stores their
+///   indexes.
+/// - executes the callouts (which are assumed to perform a calculation)
+///   and checks the results.
+
+class HooksCommonTestClass {
+public:
+    /// @brief Constructor
+    HooksCommonTestClass() {
+
+        // Set up the server hooks.  ServerHooks is a singleton, so we reset it
+        // between each test.
+        isc::hooks::ServerHooks& hooks =
+            isc::hooks::ServerHooks::getServerHooks();
+        hooks.reset();
+        lm_one_index_ = hooks.registerHook("lm_one");
+        lm_two_index_ = hooks.registerHook("lm_two");
+        lm_three_index_ = hooks.registerHook("lm_three");
+    }
+
+    /// @brief Call callouts test
+    ///
+    /// All of the loaded libraries for which callouts are called register four
+    /// callouts: a context_create callout and three callouts that are attached
+    /// to hooks lm_one, lm_two and lm_three.  These four callouts, executed
+    /// in sequence, perform a series of calculations. Data is passed between
+    /// callouts in the argument list, in a variable named "result".
+    ///
+    /// context_create initializes the calculation by setting a seed
+    /// value, called r0 here.  This value is dependent on the library being
+    /// loaded.  Prior to that, the argument "result" is initialized to -1,
+    /// the purpose being to avoid exceptions when running this test with no
+    /// libraries loaded.
+    ///
+    /// Callout lm_one is passed a value d1 and performs a simple arithmetic
+    /// operation on it and r0 yielding a result r1.  Hence we can say that
+    /// @f[ r1 = lm1(r0, d1) @f]
+    ///
+    /// Callout lm_two is passed a value d2 and peforms another simple
+    /// arithmetic operation on it and d2, yielding r2, i.e.
+    /// @f[ r2 = lm2(d1, d2) @f]
+    ///
+    /// lm_three does a similar operation giving @f[ r3 = lm3(r2, d3) @f].
+    ///
+    /// The details of the operations lm1, lm2 and lm3 depend on the library.
+    /// However the sequence of calls needed to do this set of calculations
+    /// is identical regardless of the exact functions. This method performs
+    /// those operations and checks the results of each step.
+    ///
+    /// It is assumed that callout_manager_ has been set up appropriately.
+    ///
+    /// @note The CalloutHandle used in the calls is declared locally here.
+    ///       The advantage of this (apart from scope reduction) is that on
+    ///       exit, it is destroyed.  This removes any references to memory
+    ///       allocated by loaded libraries while they are still loaded.
+    ///
+    /// @param manager CalloutManager to use for the test
+    /// @param r0...r3, d1..d3 Values and intermediate values expected.  They
+    ///        are ordered so that the variables appear in the argument list in
+    ///        the order they are used.
+    void executeCallCallouts(
+            const boost::shared_ptr<isc::hooks::CalloutManager>& manager,
+            int r0, int d1, int r1, int d2, int r2, int d3, int r3) {
+        static const char* COMMON_TEXT = " callout returned the wong value";
+        static const char* RESULT = "result";
+
+        int result;
+
+        // Set up a callout handle for the calls.
+        isc::hooks::CalloutHandle handle(manager);
+
+        // Initialize the argument RESULT.  This simplifies testing by
+        // eliminating the generation of an exception when we try the unload
+        // test.  In that case, RESULT is unchanged.
+        handle.setArgument(RESULT, -1);
+
+        // Seed the calculation.
+        manager->callCallouts(isc::hooks::ServerHooks::CONTEXT_CREATE, handle);
+        handle.getArgument(RESULT, result);
+        EXPECT_EQ(r0, result) << "context_create" << COMMON_TEXT;
+
+        // Perform the first calculation.
+        handle.setArgument("data_1", d1);
+        manager->callCallouts(lm_one_index_, handle);
+        handle.getArgument(RESULT, result);
+        EXPECT_EQ(r1, result) << "lm_one" << COMMON_TEXT;
+
+        // ... the second ...
+        handle.setArgument("data_2", d2);
+        manager->callCallouts(lm_two_index_, handle);
+        handle.getArgument(RESULT, result);
+        EXPECT_EQ(r2, result) << "lm_two" << COMMON_TEXT;
+
+        // ... and the third.
+        handle.setArgument("data_3", d3);
+        manager->callCallouts(lm_three_index_, handle);
+        handle.getArgument(RESULT, result);
+        EXPECT_EQ(r3, result) << "lm_three" << COMMON_TEXT;
+    }
+
+    /// Hook indexes.  These are are made public for ease of reference.
+    int lm_one_index_;
+    int lm_two_index_;
+    int lm_three_index_;
+};
+
+#endif // COMMON_HOOKS_TEST_CLASS_H
diff --git a/src/lib/hooks/tests/library_manager_collection_unittest.cc b/src/lib/hooks/tests/library_manager_collection_unittest.cc
new file mode 100644
index 0000000..a9295d0
--- /dev/null
+++ b/src/lib/hooks/tests/library_manager_collection_unittest.cc
@@ -0,0 +1,186 @@
+// 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/library_manager_collection.h>
+#include <hooks/server_hooks.h>
+
+#include <hooks/tests/common_test_class.h>
+#include <hooks/tests/marker_file.h>
+#include <hooks/tests/test_libraries.h>
+
+#include <boost/shared_ptr.hpp>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <string>
+
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+/// @brief Library manager collection test class
+
+class LibraryManagerCollectionTest : public ::testing::Test,
+                                     public HooksCommonTestClass {
+};
+
+/// @brief Public library manager collection class
+///
+/// This is an instance of the LibraryManagerCollection class but with the
+/// protected methods made public for test purposes.
+
+class PublicLibraryManagerCollection
+                : public isc::hooks::LibraryManagerCollection {
+public:
+    /// @brief Constructor
+    ///
+    /// @param List of libraries that this collection will manage.  The order
+    ///        of the libraries is important.
+    PublicLibraryManagerCollection(const std::vector<std::string>& libraries)
+        : LibraryManagerCollection(libraries)
+    {}
+
+    /// Public methods that call protected methods on the superclass.
+    using LibraryManagerCollection::unloadLibraries;
+};
+
+
+// This is effectively the same test as for LibraryManager, but using the
+// LibraryManagerCollection object.
+
+TEST_F(LibraryManagerCollectionTest, LoadLibraries) {
+
+    // Set up the list of libraries to be loaded.
+    std::vector<std::string> library_names;
+    library_names.push_back(std::string(FULL_CALLOUT_LIBRARY));
+    library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY));
+
+    // Set up the library manager collection and get the callout manager we'll
+    // be using.
+    PublicLibraryManagerCollection lm_collection(library_names);
+
+    // Load the libraries.
+    EXPECT_TRUE(lm_collection.loadLibraries());
+    boost::shared_ptr<CalloutManager> manager =
+                                      lm_collection.getCalloutManager();
+
+    // Execute the callouts.  The first library implements the calculation.
+    //
+    // r3 = (7 * d1 - d2) * d3
+    // 
+    // The last-loaded library implements the calculation
+    //
+    // r3 = (10 + d1) * d2 - d3
+    //
+    // Putting the processing for each library together in the appropriate
+    // order, we get:
+    //
+    // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
+    {
+        SCOPED_TRACE("Doing calculation with libraries loaded");
+        executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183);
+    }
+
+    // Try unloading the libraries.
+    EXPECT_NO_THROW(lm_collection.unloadLibraries());
+
+    // Re-execute the calculation - callouts can be called but as nothing
+    // happens, the result should always be -1.
+    {
+        SCOPED_TRACE("Doing calculation with libraries not loaded");
+        executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1);
+    }
+}
+
+// This is effectively the same test as above, but with a library generating
+// an error when loaded. It is expected that the failing library will not be
+// loaded, but others will be.
+
+TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
+
+    // Set up the list of libraries to be loaded.
+    std::vector<std::string> library_names;
+    library_names.push_back(std::string(FULL_CALLOUT_LIBRARY));
+    library_names.push_back(std::string(INCORRECT_VERSION_LIBRARY));
+    library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY));
+
+    // Set up the library manager collection and get the callout manager we'll
+    // be using.
+    PublicLibraryManagerCollection lm_collection(library_names);
+
+    // Load the libraries.  We expect a failure status to be returned as
+    // one of the libraries failed to load.
+    EXPECT_FALSE(lm_collection.loadLibraries());
+    boost::shared_ptr<CalloutManager> manager =
+                                      lm_collection.getCalloutManager();
+
+    // Expect only two libraries were loaded.
+    EXPECT_EQ(2, manager->getNumLibraries());
+
+    // Execute the callouts.  The first library implements the calculation.
+    //
+    // r3 = (7 * d1 - d2) * d3
+    // 
+    // The last-loaded library implements the calculation
+    //
+    // r3 = (10 + d1) * d2 - d3
+    //
+    // Putting the processing for each library together in the appropriate
+    // order, we get:
+    //
+    // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
+    {
+        SCOPED_TRACE("Doing calculation with libraries loaded");
+        executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183);
+    }
+
+    // Try unloading the libraries.
+    EXPECT_NO_THROW(lm_collection.unloadLibraries());
+
+    // Re-execute the calculation - callouts can be called but as nothing
+    // happens, the result should always be -1.
+    {
+        SCOPED_TRACE("Doing calculation with libraries not loaded");
+        executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1);
+    }
+}
+
+// Check that everything works even with no libraries loaded.
+
+TEST_F(LibraryManagerCollectionTest, NoLibrariesLoaded) {
+    // Set up the list of libraries to be loaded.
+    std::vector<std::string> library_names;
+
+    // Set up the library manager collection and get the callout manager we'll
+    // be using.
+    LibraryManagerCollection lm_collection(library_names);
+    EXPECT_TRUE(lm_collection.loadLibraries());
+    boost::shared_ptr<CalloutManager> manager =
+                                      lm_collection.getCalloutManager();
+
+    // Load the libraries.
+    EXPECT_TRUE(lm_collection.loadLibraries());
+
+    // Eecute the calculation - callouts can be called but as nothing
+    // happens, the result should always be -1.
+    executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1);
+}
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/library_manager_unittest.cc b/src/lib/hooks/tests/library_manager_unittest.cc
new file mode 100644
index 0000000..0ddfbc4
--- /dev/null
+++ b/src/lib/hooks/tests/library_manager_unittest.cc
@@ -0,0 +1,504 @@
+// 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 <hooks/tests/common_test_class.h>
+#include <hooks/tests/marker_file.h>
+#include <hooks/tests/test_libraries.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <fstream>
+#include <string>
+
+#include <unistd.h>
+
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+/// @brief Library manager test class
+
+class LibraryManagerTest : public ::testing::Test,
+                           public HooksCommonTestClass {
+public:
+    /// @brief Constructor
+    ///
+    /// Initializes the CalloutManager object used in the tests.  It sets it
+    /// up with the hooks initialized in the HooksCommonTestClass object and
+    /// with four libraries.
+    LibraryManagerTest() {
+        callout_manager_.reset(new CalloutManager(4));
+
+        // Ensure the marker file is not present at the start of a test.
+        static_cast<void>(unlink(MARKER_FILE));
+    }
+
+    /// @brief Destructor
+    ///
+    /// Ensures a marker file is removed after each test.
+    ~LibraryManagerTest() {
+        static_cast<void>(unlink(MARKER_FILE));
+    }
+
+    /// @brief Marker file present
+    ///
+    /// Convenience function to check whether a marker file is present.  It
+    /// does this by opening the file.
+    ///
+    /// @return true if the marker file is present.
+    bool markerFilePresent() const {
+
+        // Try to open it.
+        std::fstream marker;
+        marker.open(MARKER_FILE, std::fstream::in);
+
+        // Check if it is open and close it if so.
+        bool exists = marker.is_open();
+        if (exists) {
+            marker.close();
+        }
+
+        return (exists);
+    }
+
+    /// @brief Call callouts test
+    ///
+    /// A wrapper around the method of the same name in the HooksCommonTestClass
+    /// object, this passes this class's CalloutManager to that method.
+    ///
+    /// @param r0...r3, d1..d3 Values and intermediate values expected.  They
+    ///        are ordered so that the variables appear in the argument list in
+    ///        the order they are used.  See HooksCommonTestClass::execute for
+    ///        a full description.
+    void executeCallCallouts(int r0, int d1, int r1, int d2, int r2, int d3,
+                             int r3) {
+        HooksCommonTestClass::executeCallCallouts(callout_manager_, r0, d1,
+                                                  r1, d2, r2, d3, r3);
+    }
+
+    /// Callout manager used for the test.
+    boost::shared_ptr<CalloutManager> callout_manager_;
+};
+
+/// @brief Library manager class
+///
+/// This is an instance of the LibraryManager class but with the protected
+/// methods made public for test purposes.
+
+class PublicLibraryManager : public isc::hooks::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.  For all these tests, it will be
+    ///        zero, as we are only using one library.
+    /// @param manager CalloutManager object
+    PublicLibraryManager(const std::string& name, int index,
+                         const boost::shared_ptr<CalloutManager>& manager)
+        : LibraryManager(name, index, manager)
+    {}
+
+    /// Public methods that call protected methods on the superclass.
+    using LibraryManager::openLibrary;
+    using LibraryManager::closeLibrary;
+    using LibraryManager::checkVersion;
+    using LibraryManager::registerStandardCallouts;
+    using LibraryManager::runLoad;
+    using LibraryManager::runUnload;
+};
+
+
+// Check that openLibrary() reports an error when it can't find the specified
+// library.
+
+TEST_F(LibraryManagerTest, NoLibrary) {
+    PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_FALSE(lib_manager.openLibrary());
+}
+
+// Check that the openLibrary() and closeLibrary() methods work.
+
+TEST_F(LibraryManagerTest, OpenClose) {
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+
+    // Open and close the library
+    EXPECT_TRUE(lib_manager.openLibrary());
+    EXPECT_TRUE(lib_manager.closeLibrary());
+
+    // Check that a second close on an already closed library does not report
+    // an error.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check that the code handles the case of a library with no version function.
+
+TEST_F(LibraryManagerTest, NoVersion) {
+    PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should fail.
+    EXPECT_FALSE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check that the code handles the case of a library with a version function
+// that returns an incorrect version number.
+
+TEST_F(LibraryManagerTest, WrongVersion) {
+    PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should fail.
+    EXPECT_FALSE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Tests that checkVersion() function succeeds in the case of a library with a
+// version function that returns the correct version number.
+
+TEST_F(LibraryManagerTest, CorrectVersionReturned) {
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should succeed.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Checks the registration of standard callouts.
+
+TEST_F(LibraryManagerTest, RegisterStandardCallouts) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                               0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check the version of the library.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Load the standard callouts
+    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
+
+    // Now execute the callouts in the order expected.  The library performs
+    // the calculation:
+    //
+    // r3 = (10 + d1) * d2 - d3
+    executeCallCallouts(10, 5, 15, 7, 105, 17, 88);
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Test that the "load" function is called correctly.
+
+TEST_F(LibraryManagerTest, CheckLoadCalled) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check the version of the library.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Load the standard callouts
+    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
+
+    // Check that only context_create and lm_one have callouts registered.
+    EXPECT_TRUE(callout_manager_->calloutsPresent(
+                ServerHooks::CONTEXT_CREATE));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(
+                 ServerHooks::CONTEXT_DESTROY));
+
+    // Call the runLoad() method to run the load() function.
+    EXPECT_TRUE(lib_manager.runLoad());
+    EXPECT_TRUE(callout_manager_->calloutsPresent(
+                ServerHooks::CONTEXT_CREATE));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(
+                 ServerHooks::CONTEXT_DESTROY));
+
+    // Now execute the callouts in the order expected.  The library performs
+    // the calculation:
+    //
+    // r3 = (5 * d1 + d2) * d3
+    executeCallCallouts(5, 5, 25, 7, 32, 10, 320);
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check handling of a "load" function that returns an error.
+
+TEST_F(LibraryManagerTest, CheckLoadError) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that we catch a load error
+    EXPECT_FALSE(lib_manager.runLoad());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// No unload function
+
+TEST_F(LibraryManagerTest, CheckNoUnload) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that no unload function returns true.
+    EXPECT_TRUE(lib_manager.runUnload());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Unload function returns an error
+
+TEST_F(LibraryManagerTest, CheckUnloadError) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that unload function returning an error returns false.
+    EXPECT_FALSE(lib_manager.runUnload());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check that the case of the library's unload() function returning a
+// success is handled correcty.
+
+TEST_F(LibraryManagerTest, CheckUnload) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(UNLOAD_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+
+    // Check that the marker file is not present (at least that the file
+    // open fails).
+    EXPECT_FALSE(markerFilePresent());
+
+    // Check that unload function runs and returns a success
+    EXPECT_TRUE(lib_manager.runUnload());
+
+    // Check that the marker file was created.
+    EXPECT_TRUE(markerFilePresent());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Test the operation of unloadLibrary().  We load a library with a set
+// of callouts then unload it.  We need to check that the callouts have been
+// removed.  We'll also check that the library's unload() function was called
+// as well.
+
+TEST_F(LibraryManagerTest, LibUnload) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(FULL_CALLOUT_LIBRARY),
+                               0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check the version of the library.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // No callouts should be registered at the moment.
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+
+    // Load the single standard callout and check it is registered correctly.
+    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+
+    // Call the load function to load the other callouts.
+    EXPECT_TRUE(lib_manager.runLoad());
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
+
+    // Unload the library and check that the callouts have been removed from
+    // the CalloutManager.
+    lib_manager.unloadLibrary();
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+}
+
+// Now come the loadLibrary() tests that make use of all the methods tested
+// above.  These tests are really to make sure that the methods have been
+// tied toget correctly.
+
+// First test the basic error cases - no library, no version function, version
+// function returning an error.
+
+TEST_F(LibraryManagerTest, LoadLibraryNoLibrary) {
+    LibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY), 0,
+                                           callout_manager_);
+    EXPECT_FALSE(lib_manager.loadLibrary());
+}
+
+// Check that the code handles the case of a library with no version function.
+
+TEST_F(LibraryManagerTest, LoadLibraryNoVersion) {
+    LibraryManager lib_manager(std::string(NO_VERSION_LIBRARY), 0,
+                                           callout_manager_);
+    EXPECT_FALSE(lib_manager.loadLibrary());
+}
+
+// Check that the code handles the case of a library with a version function
+// that returns an incorrect version number.
+
+TEST_F(LibraryManagerTest, LoadLibraryWrongVersion) {
+    LibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY), 0,
+                                           callout_manager_);
+    EXPECT_FALSE(lib_manager.loadLibrary());
+}
+
+// Check that the full loadLibrary call works.
+
+TEST_F(LibraryManagerTest, LoadLibrary) {
+    LibraryManager lib_manager(std::string(FULL_CALLOUT_LIBRARY), 0,
+                                           callout_manager_);
+    EXPECT_TRUE(lib_manager.loadLibrary());
+
+    // Now execute the callouts in the order expected.  The library performs
+    // the calculation:
+    //
+    // r3 = (7 * d1 - d2) * d3
+    executeCallCallouts(7, 5, 35, 9, 26, 3, 78);
+
+    EXPECT_TRUE(lib_manager.unloadLibrary());
+
+    // Check that the callouts have been removed from the callout manager.
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+}
+
+// Now test for multiple libraries.  We'll load the full callout library
+// first, then load some of the libraries with missing framework functions.
+// This will check that when searching for framework functions, only the
+// specified library is checked, not other loaded libraries. We will
+// load a second library with suitable callouts and check that the callouts
+// are added correctly. Finally, we'll unload one of the libraries and
+// check that only the callouts belonging to that library were removed.
+
+TEST_F(LibraryManagerTest, LoadMultipleLibraries) {
+    // Load a library with all framework functions.
+    LibraryManager lib_manager_1(std::string(FULL_CALLOUT_LIBRARY), 0,
+                                 callout_manager_);
+    EXPECT_TRUE(lib_manager_1.loadLibrary());
+
+    // Attempt to load a library with no version() function.  We should detect
+    // this and not end up calling the function from the already loaded
+    // library.
+    LibraryManager lib_manager_2(std::string(NO_VERSION_LIBRARY), 1,
+                                 callout_manager_);
+    EXPECT_FALSE(lib_manager_2.loadLibrary());
+
+    // Attempt to load the library with an incorrect version.  This should
+    // be detected.
+    LibraryManager lib_manager_3(std::string(INCORRECT_VERSION_LIBRARY), 1,
+                                 callout_manager_);
+    EXPECT_FALSE(lib_manager_3.loadLibrary());
+
+    // Load the basic callout library.  This only has standard callouts so,
+    // if the first library's load() function gets called, some callouts
+    // will be registered twice and lead to incorrect results.
+    LibraryManager lib_manager_4(std::string(BASIC_CALLOUT_LIBRARY), 1,
+                                 callout_manager_);
+    EXPECT_TRUE(lib_manager_4.loadLibrary());
+
+    // Execute the callouts.  The first library implements the calculation.
+    //
+    // r3 = (7 * d1 - d2) * d3
+    // 
+    // The last-loaded library implements the calculation
+    //
+    // r3 = (10 + d1) * d2 - d3
+    //
+    // Putting the processing for each library together in the appropriate
+    // order, we get:
+    //
+    // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
+    executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
+
+    // All done, so unload the first library.
+    EXPECT_TRUE(lib_manager_1.unloadLibrary());
+
+    // Now execute the callouts again and check that the results are as
+    // expected for the new calculation.
+    executeCallCallouts(10, 5, 15, 7, 105, 17, 88);
+
+    // ... and tidy up.
+    EXPECT_TRUE(lib_manager_4.unloadLibrary());
+}
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/library_manager_unittest.cc.in b/src/lib/hooks/tests/library_manager_unittest.cc.in
deleted file mode 100644
index da73517..0000000
--- a/src/lib/hooks/tests/library_manager_unittest.cc.in
+++ /dev/null
@@ -1,567 +0,0 @@
-// 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 <hooks/tests/marker_file.h>
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <fstream>
-#include <string>
-
-#include <unistd.h>
-
-
-using namespace isc;
-using namespace isc::hooks;
-using namespace std;
-
-namespace {
-
-/// @brief Library manager test class
-
-class LibraryManagerTest : public ::testing::Test {
-public:
-    /// @brief Constructor
-    ///
-    /// Sets up a collection of three LibraryHandle objects to use in the test.
-    LibraryManagerTest() {
-
-        // Set up the server hooks.  ServerHooks is a singleton, so we reset it
-        // between each test.
-        ServerHooks& hooks = ServerHooks::getServerHooks();
-        hooks.reset();
-        lm_one_index_ = hooks.registerHook("lm_one");
-        lm_two_index_ = hooks.registerHook("lm_two");
-        lm_three_index_ = hooks.registerHook("lm_three");
-
-        // Set up the callout manager with these hooks.  Assume a maximum of
-        // four libraries.
-        callout_manager_.reset(new CalloutManager(4));
-
-        // Ensure the marker file is not present at the start of a test.
-        static_cast<void>(unlink(MARKER_FILE));
-    }
-
-    /// @brief Destructor
-    ///
-    /// Ensures a marker file is removed after each test.
-    ~LibraryManagerTest() {
-        static_cast<void>(unlink(MARKER_FILE));
-    }
-
-    /// @brief Call callouts test
-    ///
-    /// All of the loaded libraries for which callouts are called register four
-    /// callouts: a context_create callout and three callouts that are attached
-    /// to hooks lm_one, lm_two and lm_three.  These four callouts, executed
-    /// in sequence, perform a series of calculations. Data is passed between
-    /// callouts in the argument list, in a variable named "result".
-    ///
-    /// context_create initializes the calculation by setting a seed
-    /// value, called r0 here.
-    ///
-    /// Callout lm_one is passed a value d1 and performs a simple arithmetic
-    /// operation on it and r0 yielding a result r1.  Hence we can say that
-    /// @f[ r1 = lm1(r0, d1) @f]
-    ///
-    /// Callout lm_two is passed a value d2 and peforms another simple
-    /// arithmetic operation on it and d2, yielding r2, i.e.
-    /// @f[ r2 = lm2(d1, d2) @f]
-    ///
-    /// lm_three does a similar operation giving @f[ r3 = lm3(r2, d3) @f].
-    ///
-    /// The details of the operations lm1, lm2 and lm3 depend on the library.
-    /// However the sequence of calls needed to do this set of calculations
-    /// is identical regardless of the exact functions. This method performs
-    /// those operations and checks the results of each step.
-    ///
-    /// It is assumed that callout_manager_ has been set up appropriately.
-    ///
-    /// @note The CalloutHandle used in the calls is declared locally here.
-    ///       The advantage of this (apart from scope reduction) is that on
-    ///       exit, it is destroyed.  This removes any references to memory
-    ///       allocated by loaded libraries while they are still loaded.
-    ///
-    /// @param r0...r3, d1..d3 Values and intermediate values expected.  They
-    ///        are ordered so that the variables appear in the argument list in
-    ///        the order they are used.
-    void executeCallCallouts(int r0, int d1, int r1, int d2, int r2, int d3,
-                             int r3) {
-        static const char* COMMON_TEXT = " callout returned the wong value";
-        int result;
-
-        // Set up a callout handle for the calls.
-        CalloutHandle callout_handle(callout_manager_);
-
-        // Seed the calculation.
-        callout_manager_->callCallouts(ServerHooks::CONTEXT_CREATE,
-                                       callout_handle);
-        callout_handle.getArgument("result", result);
-        EXPECT_EQ(r0, result) << "context_create" << COMMON_TEXT;
-
-        // Perform the first calculation.
-        callout_handle.setArgument("data_1", d1);
-        callout_manager_->callCallouts(lm_one_index_, callout_handle);
-        callout_handle.getArgument("result", result);
-        EXPECT_EQ(r1, result) << "lm_one" << COMMON_TEXT;
-
-        // ... the second ...
-        callout_handle.setArgument("data_2", d2);
-        callout_manager_->callCallouts(lm_two_index_, callout_handle);
-        callout_handle.getArgument("result", result);
-        EXPECT_EQ(r2, result) << "lm_two" << COMMON_TEXT;
-
-        // ... and the third.
-        callout_handle.setArgument("data_3", d3);
-        callout_manager_->callCallouts(lm_three_index_, callout_handle);
-        callout_handle.getArgument("result", result);
-        EXPECT_EQ(r3, result) << "lm_three" << COMMON_TEXT;
-    }
-
-    /// Hook indexes.  These are are made public for ease of reference.
-    int lm_one_index_;
-    int lm_two_index_;
-    int lm_three_index_;
-
-    /// Callout manager used for the test.
-    boost::shared_ptr<CalloutManager> callout_manager_;
-};
-
-
-/// @brief Library manager class
-///
-/// This is an instance of the LibraryManager class but with the protected
-/// methods made public for test purposes.
-
-class PublicLibraryManager : public isc::hooks::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.  For all these tests, it will be
-    ///        zero, as we are only using one library.
-    /// @param manager CalloutManager object
-    PublicLibraryManager(const std::string& name, int index,
-                         const boost::shared_ptr<CalloutManager>& manager)
-        : LibraryManager(name, index, manager)
-    {}
-
-    /// Public methods that call protected methods on the superclass.
-    using LibraryManager::openLibrary;
-    using LibraryManager::closeLibrary;
-    using LibraryManager::checkVersion;
-    using LibraryManager::registerStandardCallouts;
-    using LibraryManager::runLoad;
-    using LibraryManager::runUnload;
-};
-
-// Names of the libraries used in these tests.  These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file.  Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
-static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl.so";
-static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
-static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
-static const char* LOAD_ERROR_CALLOUT_LIBRARY =
-    "@abs_builddir@/.libs/liblecl.so";
-static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
-static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
-static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
-
-
-// Check that openLibrary() reports an error when it can't find the specified
-// library.
-
-TEST_F(LibraryManagerTest, NoLibrary) {
-    PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_FALSE(lib_manager.openLibrary());
-}
-
-// Check that the openLibrary() and closeLibrary() methods work.
-
-TEST_F(LibraryManagerTest, OpenClose) {
-    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-
-    // Open and close the library
-    EXPECT_TRUE(lib_manager.openLibrary());
-    EXPECT_TRUE(lib_manager.closeLibrary());
-
-    // Check that a second close on an already closed library does not report
-    // an error.
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Check that the code handles the case of a library with no version function.
-
-TEST_F(LibraryManagerTest, NoVersion) {
-    PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
-                                     0, callout_manager_);
-    // Open should succeed.
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Version check should fail.
-    EXPECT_FALSE(lib_manager.checkVersion());
-
-    // Tidy up.
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Check that the code handles the case of a library with a version function
-// that returns an incorrect version number.
-
-TEST_F(LibraryManagerTest, WrongVersion) {
-    PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
-                                     0, callout_manager_);
-    // Open should succeed.
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Version check should fail.
-    EXPECT_FALSE(lib_manager.checkVersion());
-
-    // Tidy up.
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Tests that checkVersion() function succeeds in the case of a library with a
-// version function that returns the correct version number.
-
-TEST_F(LibraryManagerTest, CorrectVersionReturned) {
-    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    // Open should succeed.
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Version check should succeed.
-    EXPECT_TRUE(lib_manager.checkVersion());
-
-    // Tidy up.
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Checks the registration of standard callouts.
-
-TEST_F(LibraryManagerTest, RegisterStandardCallouts) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                               0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check the version of the library.
-    EXPECT_TRUE(lib_manager.checkVersion());
-
-    // Load the standard callouts
-    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
-
-    // Now execute the callouts in the order expected.  The library performs
-    // the calculation:
-    //
-    // r3 = (10 + d1) * d2 - d3
-    executeCallCallouts(10, 5, 15, 7, 105, 17, 88);
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Test that the "load" function is called correctly.
-
-TEST_F(LibraryManagerTest, CheckLoadCalled) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(LOAD_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check the version of the library.
-    EXPECT_TRUE(lib_manager.checkVersion());
-
-    // Load the standard callouts
-    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
-
-    // Check that only context_create and lm_one have callouts registered.
-    EXPECT_TRUE(callout_manager_->calloutsPresent(
-                ServerHooks::CONTEXT_CREATE));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(
-                 ServerHooks::CONTEXT_DESTROY));
-
-    // Call the runLoad() method to run the load() function.
-    EXPECT_TRUE(lib_manager.runLoad());
-    EXPECT_TRUE(callout_manager_->calloutsPresent(
-                ServerHooks::CONTEXT_CREATE));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(
-                 ServerHooks::CONTEXT_DESTROY));
-
-    // Now execute the callouts in the order expected.  The library performs
-    // the calculation:
-    //
-    // r3 = (5 * d1 + d2) * d3
-    executeCallCallouts(5, 5, 25, 7, 32, 10, 320);
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Check handling of a "load" function that returns an error.
-
-TEST_F(LibraryManagerTest, CheckLoadError) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check that we catch a load error
-    EXPECT_FALSE(lib_manager.runLoad());
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// No unload function
-
-TEST_F(LibraryManagerTest, CheckNoUnload) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check that no unload function returns true.
-    EXPECT_TRUE(lib_manager.runUnload());
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Unload function returns an error
-
-TEST_F(LibraryManagerTest, CheckUnloadError) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check that unload function returning an error returns false.
-    EXPECT_FALSE(lib_manager.runUnload());
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Check that the case of the library's unload() function returning a
-// success is handled correcty.
-
-TEST_F(LibraryManagerTest, CheckUnload) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(UNLOAD_CALLOUT_LIBRARY),
-                                     0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check that the marker file is not present (at least that the file
-    // open fails).
-    fstream marker;
-    marker.open(MARKER_FILE, fstream::in);
-    EXPECT_TRUE(marker.fail());
-
-    // Check that unload function runs and returns a success
-    EXPECT_TRUE(lib_manager.runUnload());
-
-    // Check that the open succeeded
-    marker.open(MARKER_FILE, fstream::in);
-    EXPECT_TRUE(marker.is_open());
-
-    // Tidy up
-    marker.close();
-
-    // Tidy up
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Test the operation of unloadLibrary().  We load a library with a set
-// of callouts then unload it.  We need to check that the callouts have been
-// removed.  We'll also check that the library's unload() function was called
-// as well.
-
-TEST_F(LibraryManagerTest, LibUnload) {
-
-    // Load the only library, specifying the index of 0 as it's the only
-    // library.  This should load all callouts.
-    PublicLibraryManager lib_manager(std::string(FULL_CALLOUT_LIBRARY),
-                               0, callout_manager_);
-    EXPECT_TRUE(lib_manager.openLibrary());
-
-    // Check the version of the library.
-    EXPECT_TRUE(lib_manager.checkVersion());
-
-    // No callouts should be registered at the moment.
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
-
-    // Load the single standard callout and check it is registered correctly.
-    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
-
-    // Call the load function to load the other callouts.
-    EXPECT_TRUE(lib_manager.runLoad());
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
-
-    // Unload the library and check that the callouts have been removed from
-    // the CalloutManager.
-    lib_manager.unloadLibrary();
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
-}
-
-// Now come the loadLibrary() tests that make use of all the methods tested
-// above.  These tests are really to make sure that the methods have been
-// tied toget correctly.
-
-// First test the basic error cases - no library, no version function, version
-// function returning an error.
-
-TEST_F(LibraryManagerTest, LoadLibraryNoLibrary) {
-    LibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY), 0,
-                                           callout_manager_);
-    EXPECT_FALSE(lib_manager.loadLibrary());
-}
-
-// Check that the code handles the case of a library with no version function.
-
-TEST_F(LibraryManagerTest, LoadLibraryNoVersion) {
-    LibraryManager lib_manager(std::string(NO_VERSION_LIBRARY), 0,
-                                           callout_manager_);
-    EXPECT_FALSE(lib_manager.loadLibrary());
-}
-
-// Check that the code handles the case of a library with a version function
-// that returns an incorrect version number.
-
-TEST_F(LibraryManagerTest, LoadLibraryWrongVersion) {
-    LibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY), 0,
-                                           callout_manager_);
-    EXPECT_FALSE(lib_manager.loadLibrary());
-}
-
-// Check that the full loadLibrary call works.
-
-TEST_F(LibraryManagerTest, LoadLibrary) {
-    LibraryManager lib_manager(std::string(FULL_CALLOUT_LIBRARY), 0,
-                                           callout_manager_);
-    EXPECT_TRUE(lib_manager.loadLibrary());
-
-    // Now execute the callouts in the order expected.  The library performs
-    // the calculation:
-    //
-    // r3 = (7 * d1 - d2) * d3
-    executeCallCallouts(7, 5, 35, 9, 26, 3, 78);
-
-    EXPECT_TRUE(lib_manager.unloadLibrary());
-
-    // Check that the callouts have been removed from the callout manager.
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
-}
-
-// Now test for multiple libraries.  We'll load the full callout library
-// first, then load some of the libraries with missing framework functions.
-// This will check that when searching for framework functions, only the
-// specified library is checked, not other loaded libraries. We will
-// load a second library with suitable callouts and check that the callouts
-// are added correctly. Finally, we'll unload one of the libraries and
-// check that only the callouts belonging to that library were removed.
-
-TEST_F(LibraryManagerTest, LoadMultipleLibraries) {
-    // Load a library with all framework functions.
-    LibraryManager lib_manager_1(std::string(FULL_CALLOUT_LIBRARY), 0,
-                                 callout_manager_);
-    EXPECT_TRUE(lib_manager_1.loadLibrary());
-
-    // Attempt to load a library with no version() function.  We should detect
-    // this and not end up calling the function from the already loaded
-    // library.
-    LibraryManager lib_manager_2(std::string(NO_VERSION_LIBRARY), 1,
-                                 callout_manager_);
-    EXPECT_FALSE(lib_manager_2.loadLibrary());
-
-    // Attempt to load the library with an incorrect version.  This should
-    // be detected.
-    LibraryManager lib_manager_3(std::string(INCORRECT_VERSION_LIBRARY), 1,
-                                 callout_manager_);
-    EXPECT_FALSE(lib_manager_3.loadLibrary());
-
-    // Load the basic callout library.  This only has standard callouts so,
-    // if the first library's load() function gets called, some callouts
-    // will be registered twice and lead to incorrect results.
-    LibraryManager lib_manager_4(std::string(BASIC_CALLOUT_LIBRARY), 1,
-                                 callout_manager_);
-    EXPECT_TRUE(lib_manager_4.loadLibrary());
-
-    // Execute the callouts.  The first library implements the calculation.
-    //
-    // r3 = (7 * d1 - d2) * d3
-    // 
-    // The last-loaded library implements the calculation
-    //
-    // r3 = (10 + d1) * d2 - d3
-    //
-    // Putting the processing for each library together in the appropriate
-    // order, we get:
-    //
-    // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
-    executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
-
-    // All done, so unload the first library.
-    EXPECT_TRUE(lib_manager_1.unloadLibrary());
-
-    // Now execute the callouts again and check that the results are as
-    // expected for the new calculation.
-    executeCallCallouts(10, 5, 15, 7, 105, 17, 88);
-
-    // ... and tidy up.
-    EXPECT_TRUE(lib_manager_4.unloadLibrary());
-}
-
-} // Anonymous namespace
diff --git a/src/lib/hooks/tests/test_libraries.h.in b/src/lib/hooks/tests/test_libraries.h.in
new file mode 100644
index 0000000..ffc08c8
--- /dev/null
+++ b/src/lib/hooks/tests/test_libraries.h.in
@@ -0,0 +1,55 @@
+// 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 TEST_LIBRARIES_H
+#define TEST_LIBRARIES_H
+
+namespace {
+
+// Names of the libraries used in these tests.  These libraries are built using
+// libtool, so we need to look in the hidden ".libs" directory to locate the
+// .so file.  Note that we access the .so file - libtool creates this as a
+// like to the real shared library.
+
+// Basic library with context_create and three "standard" callouts.
+static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
+
+// Library with context_create and three "standard" callouts, as well as
+// load() and unload() functions.
+static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl.so";
+
+// Library where the version() function returns an incorrect result.
+static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
+
+// Library where some of the callout registration is done with the load()
+// function.
+static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
+
+// Library where the load() function returns an error.
+static const char* LOAD_ERROR_CALLOUT_LIBRARY =
+    "@abs_builddir@/.libs/liblecl.so";
+
+// Name of a library which is not present.
+static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+
+// Library that does not include a version function.
+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";
+
+} // anonymous namespace
+
+
+#endif // TEST_LIBRARIES_H



More information about the bind10-changes mailing list