Browse Source

[2980] Basic library manager functionality added

Also started to add logging.
Stephen Morris 12 years ago
parent
commit
390c1a763d

+ 17 - 1
src/lib/hooks/Makefile.am

@@ -10,17 +10,33 @@ AM_CXXFLAGS  = $(B10_CXXFLAGS)
 # But older GCC compilers don't have the flag.
 AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
 
-CLEANFILES = *.gcno *.gcda
+
+# Define rule to build logging source files from message file
+hooks_messages.h hooks_messages.cc: hooks_messages.mes
+	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/hooks/hooks_messages.mes
+
+# Tell automake that the message files are built as part of the build process
+# (so that they are built before the main library is built).
+BUILT_SOURCES = hooks_messages.h hooks_messages.cc
+
+# Ensure that the message file is included in the distribution
+EXTRA_DIST = hooks_messages.mes
+
+# Get rid of generated message files on a clean
+CLEANFILES = *.gcno *.gcda hooks_messages.h hooks_messages.cc
 
 lib_LTLIBRARIES = libb10-hooks.la
 libb10_hooks_la_SOURCES  =
 libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
 libb10_hooks_la_SOURCES += callout_manager.cc callout_manager.h
 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 += server_hooks.cc server_hooks.h
 
+nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h
+
 libb10_hooks_la_CXXFLAGS = $(AM_CXXFLAGS)
 libb10_hooks_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
 libb10_hooks_la_LDFLAGS  = $(AM_LDFLAGS) -ldl

+ 26 - 0
src/lib/hooks/hooks_log.cc

@@ -0,0 +1,26 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+/// Defines the logger used by the NSAS
+
+#include "hooks/hooks_log.h"
+
+namespace isc {
+namespace hooks {
+
+isc::log::Logger hooks_logger("hooks");
+
+} // namespace hooks
+} // namespace isc
+

+ 50 - 0
src/lib/hooks/hooks_log.h

@@ -0,0 +1,50 @@
+// 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_LOG_H
+#define HOOKS_LOG_H
+
+#include <log/macros.h>
+#include <hooks/hooks_messages.h>
+
+namespace isc {
+namespace hooks {
+
+/// \brief Hooks system Logging
+///
+/// Defines the levels used to output debug messages in the Hooks framework.
+/// Note that higher numbers equate to more verbose (and detailed) output.
+
+// The first level traces normal operations,
+const int HOOKS_DBG_TRACE = DBGLVL_TRACE_BASIC;
+
+// The next level traces each call to hook code.
+const int HOOKS_DBG_CALLS = DBGLVL_TRACE_BASIC_DATA;
+
+// Additional information on the calls.  Report each call to a callout (even
+// if there are multiple callouts on a hook) and each status return.
+const int HOOKS_DBG_EXTENDED_CALLS = DBGLVL_TRACE_DETAIL_DATA;
+
+
+/// \brief HOOKS Logger
+///
+/// Define the logger used to log messages.  We could define it in multiple
+/// modules, but defining in a single module and linking to it saves time and
+/// space.
+extern isc::log::Logger hooks_logger;    // isc::hooks::logger is the HOOKS logger
+
+} // namespace hooks
+} // namespace isc
+
+#endif // HOOKS_LOG_H

+ 47 - 0
src/lib/hooks/hooks_messages.mes

@@ -0,0 +1,47 @@
+# 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.
+
+$NAMESPACE isc::hooks
+
+% HOOKS_CLOSE_ERROR failed to close hook library %1: %2
+BIND 10 has failed to close the named hook library for the stated reason.
+Although this is an error, this should not affect the running system other
+than as a loss of resources.  If this error persists, you should restart
+BIND 10.
+
+% HOOKS_INCORRECT_VERSION hook library %1 is at version %2, require version %3
+BIND 10 has detected that the named hook library has been built against
+a version of BIND 10 that is incompatible with the version of BIND 10
+running on your system.  It has not loaded the library.
+
+This is most likely due to the installation of a new version of BIND 10
+without rebuilding the hook library.  A rebuild and re-install of the library
+should fix the problem in most cases.
+
+% HOOKS_NO_VERSION no version() function found in hook library %1
+The shared library named in the message was found and successfully loaded, but
+BIND 10 did not find a function named 'version' in it.  This function is
+required and should return the version of BIND 10 against which the library
+was built.  The value is used to check that the library was built against a
+compatible version of BIND 10.  The library has not been loaded.
+
+% HOOKS_OPEN_ERROR failed to open hook library %1: %2
+BIND 10 failed to open the specified hook library for the stated reason. The
+library has not been loaded.  BIND 10 will continue to function, but without
+the services offered by the library.
+
+% HOOKS_REGISTER_CALLOUT library %1 has registered a callout for hook %2
+This is a debug message, output when the library loading function has located
+a standard callout (a callout with the same name as a hook point) and
+registered it.

+ 7 - 1
src/lib/hooks/library_manager.h

@@ -109,7 +109,6 @@ protected:
     ///         when this method was called.
     bool closeLibrary();
 
-
     /// @brief Check library version
     ///
     /// With the library open, accesses the "version()" function and, if
@@ -122,6 +121,13 @@ protected:
     /// @return bool true if the check succeeded
     bool checkVersion() const;
 
+    /// @brief Register standard callouts
+    ///
+    /// Loops through the list of hook names and searches the library for
+    /// functions with those names.  Any that are found are registered as
+    /// callouts for that hook.
+    void registerStandardCallouts();
+
 private:
     void*       dl_handle_;     ///< Handle returned by dlopen
     int         index_;         ///< Index associated with this library

+ 16 - 9
src/lib/hooks/tests/basic_callout_library.cc

@@ -25,12 +25,12 @@
 ///
 /// - 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.
+/// - Three other callouts are supplied.  All do some trivial calculationsll
+///   on the arguments supplied to it and the context variables, returning
+///   intermediate results through the "result" argument.
 
 #include <hooks/hooks.h>
+#include <iostream>
 
 using namespace isc::hooks;
 
@@ -46,13 +46,14 @@ version() {
 int
 context_create(CalloutHandle& handle) {
     handle.setContext("result", static_cast<int>(10));
+    handle.setArgument("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 lm_one(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_1", data);
 
@@ -61,6 +62,7 @@ int basic_one(CalloutHandle& handle) {
 
     result += data;
     handle.setContext("result", result);
+    handle.setArgument("result", result);
 
     return (0);
 }
@@ -69,7 +71,7 @@ int basic_one(CalloutHandle& handle) {
 // argument.
 
 int
-basic_two(CalloutHandle& handle) {
+lm_two(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_2", data);
 
@@ -78,17 +80,22 @@ basic_two(CalloutHandle& handle) {
 
     result *= data;
     handle.setContext("result", result);
+    handle.setArgument("result", result);
 
     return (0);
 }
 
-// Final callout returns the value in the context through the "result"
-// argument.
+// Final callout subtracts the result in "data_3" and.
 
 int
-basic_three(CalloutHandle& handle) {
+lm_three(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_3", data);
+
     int result;
     handle.getContext("result", result);
+
+    result -= data;
     handle.setArgument("result", result);
 
     return (0);

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

@@ -1,241 +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 <gtest/gtest.h>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-using namespace isc;
-using namespace isc::hooks;
-using namespace std;
-
-/// @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.  There is sone singleton for all tests,
-        // so reset it and explicitly set up the hooks for the test.
-        ServerHooks& hooks = ServerHooks::getServerHooks();
-        hooks.reset();
-        alpha_index_ = hooks.registerHook("alpha");
-        beta_index_ = hooks.registerHook("beta");
-        gamma_index_ = hooks.registerHook("gamma");
-
-        // Set up the callout manager with these hooks.  Assume a maximum of
-        // four libraries.
-        callout_manager_.reset(new CalloutManager(1));
-
-        // Set up the callout handle.
-        callout_handle_.reset(new CalloutHandle(callout_manager_));
-    }
-
-    /// @brief Return the callout handle
-    CalloutHandle& getCalloutHandle() {
-        return (*callout_handle_);
-    }
-
-    /// @brief Return the callout manager
-    boost::shared_ptr<CalloutManager> getCalloutManager() {
-        return (callout_manager_);
-    }
-
-    /// Hook indexes.  These are somewhat ubiquitous, so are made public for
-    /// ease of reference instead of being accessible by a function.
-    int alpha_index_;
-    int beta_index_;
-    int gamma_index_;
-
-private:
-    /// Callout handle used in calls
-    boost::shared_ptr<CalloutHandle> callout_handle_;
-
-    /// 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
-    /// @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
-    //@{
-    /// @brief Open library
-    ///
-    /// Opens the library associated with this LibraryManager.  A message is
-    /// logged on an error.
-    ///
-    /// @return true if the library opened successfully, false otherwise.
-    bool openLibrary() {
-        return (LibraryManager::openLibrary());
-    }
-
-    /// @brief Close library
-    ///
-    /// Closes the library associated with this LibraryManager.  A message is
-    /// logged on an error.
-    ///
-    /// @return true if the library closed successfully, false otherwise.
-    bool closeLibrary() {
-        return (LibraryManager::closeLibrary());
-    }
-
-
-    /// @brief Check library version
-    ///
-    /// With the library open, accesses the "version()" function and, if
-    /// present, checks the returned value against the hooks version symbol
-    /// for the currently running BIND 10.
-    ///
-    /// If there is no version() function, or if there is a mismatch in
-    /// version number, a message logged.
-    ///
-    /// @return bool true if the check succeeded
-    bool checkVersion() const {
-        return (LibraryManager::checkVersion());
-    }
-
-    //@}
-};
-
-// 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* NOT_PRESENT_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libnothere.so";
-static const char* NO_VERSION_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libnv.so";
-static const char* INCORRECT_VERSION_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libiv.so";
-static const char* BASIC_CALLOUT_LIBRARY = "/home/stephen/bind10/src/lib/hooks/tests/.libs/libbco.so";
-
-
-namespace {
-
-// Tests that OpenLibrary reports an error for an unknown library.
-
-TEST_F(LibraryManagerTest, NonExistentLibrary) {
-    // Check that opening a non-existent library fails.
-    PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
-                                     0, getCalloutManager());
-    EXPECT_FALSE(lib_manager.openLibrary());
-}
-
-// Tests that OpenLibrary handles the case of no version present.
-
-TEST_F(LibraryManagerTest, NoVersionFunction) {
-    PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
-                                     0, getCalloutManager());
-    // 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 OpenLibrary reports an error for an unknown library.
-
-TEST_F(LibraryManagerTest, IncorrectVersionReturned) {
-    PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
-                                     0, getCalloutManager());
-    // 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 the openLibrary() and closeLibrary() methods work.
-
-TEST_F(LibraryManagerTest, OpenClose) {
-
-    // Create the library manager.
-    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                                     0, getCalloutManager());
-
-    // Open and close the library
-    EXPECT_TRUE(lib_manager.openLibrary());
-    EXPECT_TRUE(lib_manager.closeLibrary());
-
-    // Check that closing an already closed library causes no problems.
-    EXPECT_TRUE(lib_manager.closeLibrary());
-}
-
-// Checks the basic functionality - loads a library where the callouts are
-// named after the hooks, calls the callouts and checks the results.
-
-TEST_F(LibraryManagerTest, BasicCalloutTest) {
-
-    // 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, getCalloutManager());
-    EXPECT_NO_THROW(lib_manager.loadLibrary());
-
-    // Set up abbreviations...
-    boost::shared_ptr<CalloutManager> co_manager = getCalloutManager();
-    CalloutHandle& callout_handle = getCalloutHandle();
-
-    // 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(alpha_index_, callout_handle);
-
-    // Second callout multiples the context value by 7
-    callout_handle.setArgument("data_2", static_cast<int>(7));
-    co_manager->callCallouts(beta_index_, callout_handle);
-
-    // Third callour retrieves the context value.
-    co_manager->callCallouts(gamma_index_, callout_handle);
-    int result;
-    callout_handle.getArgument("result", result);
-    EXPECT_EQ(105, result);
-}
-
-} // Anonymous namespace

+ 83 - 85
src/lib/hooks/tests/library_manager_unittest.cc.in

@@ -23,6 +23,8 @@
 #include <string>
 #include <vector>
 
+#include <iostream>
+
 using namespace isc;
 using namespace isc::hooks;
 using namespace std;
@@ -40,9 +42,9 @@ public:
         // so reset it and explicitly set up the hooks for the test.
         ServerHooks& hooks = ServerHooks::getServerHooks();
         hooks.reset();
-        alpha_index_ = hooks.registerHook("alpha");
-        beta_index_ = hooks.registerHook("beta");
-        gamma_index_ = hooks.registerHook("gamma");
+        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.
@@ -52,23 +54,12 @@ public:
         callout_handle_.reset(new CalloutHandle(callout_manager_));
     }
 
-    /// @brief Return the callout handle
-    CalloutHandle& getCalloutHandle() {
-        return (*callout_handle_);
-    }
-
-    /// @brief Return the callout manager
-    boost::shared_ptr<CalloutManager> getCalloutManager() {
-        return (callout_manager_);
-    }
-
     /// Hook indexes.  These are somewhat ubiquitous, so are made public for
     /// ease of reference instead of being accessible by a function.
-    int alpha_index_;
-    int beta_index_;
-    int gamma_index_;
+    int lm_one_index_;
+    int lm_two_index_;
+    int lm_three_index_;
 
-private:
     /// Callout handle used in calls
     boost::shared_ptr<CalloutHandle> callout_handle_;
 
@@ -90,51 +81,26 @@ public:
     ///
     /// @param name Name of the library to load.  This should be an absolute
     ///        path name.
-    /// @param index Index of this library
+    /// @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
-    //@{
-    /// @brief Open library
-    ///
-    /// Opens the library associated with this LibraryManager.  A message is
-    /// logged on an error.
-    ///
-    /// @return true if the library opened successfully, false otherwise.
-    bool openLibrary() {
-        return (LibraryManager::openLibrary());
-    }
-
-    /// @brief Close library
-    ///
-    /// Closes the library associated with this LibraryManager.  A message is
-    /// logged on an error.
-    ///
-    /// @return true if the library closed successfully, false otherwise.
-    bool closeLibrary() {
-        return (LibraryManager::closeLibrary());
-    }
-
-
-    /// @brief Check library version
-    ///
-    /// With the library open, accesses the "version()" function and, if
-    /// present, checks the returned value against the hooks version symbol
-    /// for the currently running BIND 10.
+    /// @brief Destructor
     ///
-    /// If there is no version() function, or if there is a mismatch in
-    /// version number, a message logged.
-    ///
-    /// @return bool true if the check succeeded
-    bool checkVersion() const {
-        return (LibraryManager::checkVersion());
+    /// Ensures that the library is closed after the test.
+    ~PublicLibraryManager() {
+        static_cast<void>(closeLibrary());
     }
 
-    //@}
+    /// Public methods that call protected methods on the superclass.
+    using LibraryManager::openLibrary;
+    using LibraryManager::closeLibrary;
+    using LibraryManager::checkVersion;
+    using LibraryManager::registerStandardCallouts;
 };
 
 // Names of the libraries used in these tests.  These libraries are built using
@@ -152,17 +118,30 @@ namespace {
 // Tests that OpenLibrary reports an error for an unknown library.
 
 TEST_F(LibraryManagerTest, NonExistentLibrary) {
-    // Check that opening a non-existent library fails.
     PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
-                                     0, getCalloutManager());
+                                     0, callout_manager_);
     EXPECT_FALSE(lib_manager.openLibrary());
 }
 
-// Tests that OpenLibrary handles the case of no version present.
+// Tests 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 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, NoVersionFunction) {
     PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
-                                     0, getCalloutManager());
+                                     0, callout_manager_);
     // Open should succeed.
     EXPECT_TRUE(lib_manager.openLibrary());
 
@@ -173,11 +152,12 @@ TEST_F(LibraryManagerTest, NoVersionFunction) {
     EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
-// Tests that OpenLibrary reports an error for an unknown library.
+// Check that the code handles the case of a library with a version function
+// that returns an incorrect version number.
 
 TEST_F(LibraryManagerTest, IncorrectVersionReturned) {
     PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
-                                     0, getCalloutManager());
+                                     0, callout_manager_);
     // Open should succeed.
     EXPECT_TRUE(lib_manager.openLibrary());
 
@@ -188,51 +168,69 @@ TEST_F(LibraryManagerTest, IncorrectVersionReturned) {
     EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
-// Tests that the openLibrary() and closeLibrary() methods work.
-
-TEST_F(LibraryManagerTest, OpenClose) {
+// Tests that checkVersion() function succeeds in the case of a library with a
+// version function that returns the correct version number.
 
-    // Create the library manager.
+TEST_F(LibraryManagerTest, CorrectVersionReturned) {
     PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
-                                     0, getCalloutManager());
-
-    // Open and close the 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 basic functionality - loads a library where the callouts are
-// named after the hooks, calls the callouts and checks the results.
+// Checks the registration of standard callouts.
 
-TEST_F(LibraryManagerTest, BasicCalloutTest) {
+TEST_F(LibraryManagerTest, RegisterStandardCallouts) {
 
     // 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, getCalloutManager());
-    EXPECT_NO_THROW(lib_manager.loadLibrary());
+    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());
 
-    // Set up abbreviations...
-    boost::shared_ptr<CalloutManager> co_manager = getCalloutManager();
-    CalloutHandle& callout_handle = getCalloutHandle();
+    int result = 0;
 
     // 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);
+    callout_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(alpha_index_, callout_handle);
+    callout_handle_->setArgument("data_1", static_cast<int>(5));
+    callout_manager_->callCallouts(lm_one_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(15, result);
 
     // Second callout multiples the context value by 7
-    callout_handle.setArgument("data_2", static_cast<int>(7));
-    co_manager->callCallouts(beta_index_, callout_handle);
-
-    // Third callour retrieves the context value.
-    co_manager->callCallouts(gamma_index_, callout_handle);
-    int result;
-    callout_handle.getArgument("result", result);
+    callout_handle_->setArgument("data_2", static_cast<int>(7));
+    callout_manager_->callCallouts(lm_two_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
     EXPECT_EQ(105, result);
+
+    // Third callout subtracts 17.
+    callout_handle_->setArgument("data_3", static_cast<int>(17));
+    callout_manager_->callCallouts(lm_three_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(88, result);
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
 } // Anonymous namespace