BIND 10 trac2974, updated. b63fddd9ded87b34a2f9072d118bbfaca420c045 [2974] Modifications as a result of review

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jun 13 16:14:17 UTC 2013


The branch, trac2974 has been updated
       via  b63fddd9ded87b34a2f9072d118bbfaca420c045 (commit)
      from  0df2936c8f985071e97fb17d9685266fc0d443a5 (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 b63fddd9ded87b34a2f9072d118bbfaca420c045
Author: Stephen Morris <stephen at isc.org>
Date:   Thu Jun 13 17:13:24 2013 +0100

    [2974] Modifications as a result of review

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

Summary of changes:
 src/lib/util/hooks/callout_handle.cc           |   18 +-
 src/lib/util/hooks/callout_handle.h            |   30 --
 src/lib/util/hooks/callout_manager.cc          |   67 ++--
 src/lib/util/hooks/callout_manager.h           |   18 +-
 src/lib/util/tests/callout_handle_unittest.cc  |    7 +-
 src/lib/util/tests/callout_manager_unittest.cc |  440 +++++++++++-------------
 src/lib/util/tests/handles_unittest.cc         |  190 +++++++++-
 7 files changed, 421 insertions(+), 349 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/util/hooks/callout_handle.cc b/src/lib/util/hooks/callout_handle.cc
index 5b6b3b2..8052823 100644
--- a/src/lib/util/hooks/callout_handle.cc
+++ b/src/lib/util/hooks/callout_handle.cc
@@ -34,12 +34,7 @@ CalloutHandle::CalloutHandle(const boost::shared_ptr<CalloutManager>& manager)
     // Call the "context_create" hook.  We should be OK doing this - although
     // the constructor has not finished running, all the member variables
     // have been created.
-    int status = manager_->callCallouts(ServerHooks::CONTEXT_CREATE, *this);
-    if (status > 0) {
-        isc_throw(ContextCreateFail, "error code of " << status << " returned "
-                  "from context_create callout during the creation of a "
-                  "ContextHandle object");
-    }
+    manager_->callCallouts(ServerHooks::CONTEXT_CREATE, *this);
 }
 
 // Destructor
@@ -48,16 +43,7 @@ CalloutHandle::~CalloutHandle() {
     // Call the "context_destroy" hook.  We should be OK doing this - although
     // the destructor is being called, all the member variables are still in
     // existence.
-    int status = manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
-    if (status > 0) {
-        // An exception is thrown on failure.  This may be severe, but if
-        // none is thrown a resource leak in a library (signalled by the
-        // context_destroy callout returning an error) may be difficult to
-        // trace.
-        isc_throw(ContextDestroyFail, "error code of " << status << " returned "
-                  "from context_destroy callout during the destruction of a "
-                  "ContextHandle object");
-    }
+    manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
 }
 
 // Return the name of all argument items.
diff --git a/src/lib/util/hooks/callout_handle.h b/src/lib/util/hooks/callout_handle.h
index ad3ef67..0033505 100644
--- a/src/lib/util/hooks/callout_handle.h
+++ b/src/lib/util/hooks/callout_handle.h
@@ -50,28 +50,6 @@ public:
         isc::Exception(file, line, what) {}
 };
 
-/// @brief Context creation failure
-///
-/// Thrown if, during the running of the constructor, the call to the
-/// context_create hook returns an error.
-
-class ContextCreateFail : public Exception {
-public:
-    ContextCreateFail(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-/// @brief Context destruction failure
-///
-/// Thrown if, during the running of the desstructor, the call to the
-/// context_destroy hook returns an error.
-
-class ContextDestroyFail : public Exception {
-public:
-    ContextDestroyFail(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
 // Forward declaration of the library handle and related collection classes.
 
 class CalloutManager;
@@ -109,14 +87,6 @@ class LibraryHandle;
 
 class CalloutHandle {
 public:
-    /// Callout success return status - the next callout in the list for the
-    /// hook will be called.
-    static const int SUCCESS = 0;
-
-    /// Callout complete return status - the callout has succeeded, but
-    /// remaining callouts on this hook (including any from other libraries)
-    /// should not be run.
-    static const int COMPLETE = 1;
 
     /// Typedef to allow abbreviation of iterator specification in methods.
     /// The std::string is the argument name and the "boost::any" is the
diff --git a/src/lib/util/hooks/callout_manager.cc b/src/lib/util/hooks/callout_manager.cc
index 32afc9f..af20619 100644
--- a/src/lib/util/hooks/callout_manager.cc
+++ b/src/lib/util/hooks/callout_manager.cc
@@ -63,7 +63,10 @@ CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
 bool
 CalloutManager::calloutsPresent(int hook_index) const {
     // Validate the hook index.
-    checkHookIndex(hook_index);
+    if ((hook_index < 0) || (hook_index >= hook_vector_.size())) {
+        isc_throw(NoSuchHook, "hook index " << hook_index <<
+                  " is not valid for the list of registered hooks");
+    }
 
     // Valid, so are there any callouts associated with that hook?
     return (!hook_vector_[hook_index].empty());
@@ -71,40 +74,40 @@ CalloutManager::calloutsPresent(int hook_index) const {
 
 // Call all the callouts for a given hook.
 
-int
+void
 CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
-    // Validate the hook index.
-    checkHookIndex(hook_index);
-
-    // Clear the "skip" flag so we don't carry state from a previous call.
-    callout_handle.setSkip(false);
-
-    // Duplicate the callout vector for this hook and work through that.
-    // This step is needed because we allow dynamic registration and
-    // deregistration of callouts.  If a callout attached to a hook modified
-    // the list of callouts, the underlying CalloutVector would change and
-    // potentially affect the iteration through that vector.
-    CalloutVector callouts(hook_vector_[hook_index]);
-
-    // Call all the callouts, stopping if a non SUCCESS status is returned.
-    int status = CalloutHandle::SUCCESS;
-    for (CalloutVector::const_iterator i = callouts.begin();
-         i != callouts.end() && (status == CalloutHandle::SUCCESS); ++i) {
-        // In case the callout tries to register or deregister a callout, set
-        // the current library index to the index associated with library
-        // that registered the callout being called.
-        current_library_ = i->first;
-
-        // Call the callout
-        status = (*i->second)(callout_handle);
-    }
-
-    // Reset the current library index to an invalid value to catch any
-    // programming errors.
-    current_library_ = -1;
 
+    // Only initialize and iterate if there are callouts present.  This check
+    // also catches the case of an invalid index.
+    if (calloutsPresent(hook_index)) {
+
+        // Clear the "skip" flag so we don't carry state from a previous call.
+        callout_handle.setSkip(false);
+
+        // Duplicate the callout vector for this hook and work through that.
+        // This step is needed because we allow dynamic registration and
+        // deregistration of callouts.  If a callout attached to a hook modified
+        // the list of callouts on that hook, the underlying CalloutVector would
+        // change and potentially affect the iteration through that vector.
+        CalloutVector callouts(hook_vector_[hook_index]);
+
+        // Call all the callouts.
+        for (CalloutVector::const_iterator i = callouts.begin();
+             i != callouts.end(); ++i) {
+            // In case the callout tries to register or deregister a callout,
+            // set the current library index to the index associated with the
+            // library that registered the callout being called.
+            current_library_ = i->first;
+
+            // Call the callout
+            // @todo Log the return status if non-zero
+            static_cast<void>((*i->second)(callout_handle));
+        }
 
-    return (status);
+        // Reset the current library index to an invalid value to catch any
+        // programming errors.
+        current_library_ = -1;
+    }
 }
 
 // Deregister a callout registered by the current library on a particular hook.
diff --git a/src/lib/util/hooks/callout_manager.h b/src/lib/util/hooks/callout_manager.h
index 542afd0..7a22433 100644
--- a/src/lib/util/hooks/callout_manager.h
+++ b/src/lib/util/hooks/callout_manager.h
@@ -182,9 +182,7 @@ public:
     /// @param hook_index Index of the hook to call.
     /// @param callout_handle Reference to the CalloutHandle object for the
     ///        current object being processed.
-    ///
-    /// @return Status return.
-    int callCallouts(int hook_index, CalloutHandle& callout_handle);
+    void callCallouts(int hook_index, CalloutHandle& callout_handle);
 
     /// @brief Get number of libraries
     ///
@@ -240,20 +238,6 @@ public:
     }
 
 private:
-    /// @brief Check hook index
-    ///
-    /// Ensures that the passed hook index is valid.
-    ///
-    /// @param index Hook index to test
-    ///
-    /// @throw NoSuchHook Hooks does not exist.
-    void checkHookIndex(int hook_index) const {
-        if ((hook_index < 0) || (hook_index >= hook_vector_.size())) {
-            isc_throw(NoSuchHook, "hook index " << hook_index <<
-                      " is not valid for the list of registered hooks");
-        }
-    }
-
     /// @brief Check library index
     ///
     /// Ensures that the current library index is valid.  This is called by
diff --git a/src/lib/util/tests/callout_handle_unittest.cc b/src/lib/util/tests/callout_handle_unittest.cc
index 635e570..76e18d8 100644
--- a/src/lib/util/tests/callout_handle_unittest.cc
+++ b/src/lib/util/tests/callout_handle_unittest.cc
@@ -225,14 +225,13 @@ TEST_F(CalloutHandleTest, ContextItemNames) {
     CalloutHandle handle(getCalloutManager());
 
     vector<string> expected_names;
-    int value = 42;
 
     expected_names.push_back("faith");
-    handle.setArgument("faith", value++);
+    handle.setArgument("faith", 42);
     expected_names.push_back("hope");
-    handle.setArgument("hope", value++);
+    handle.setArgument("hope", 43);
     expected_names.push_back("charity");
-    handle.setArgument("charity", value++);
+    handle.setArgument("charity", 44);
 
     // Get the names and check against the expected names.  We'll sort
     // both arrays to simplify the checking.
diff --git a/src/lib/util/tests/callout_manager_unittest.cc b/src/lib/util/tests/callout_manager_unittest.cc
index 8f35be3..ca9b8ad 100644
--- a/src/lib/util/tests/callout_manager_unittest.cc
+++ b/src/lib/util/tests/callout_manager_unittest.cc
@@ -54,10 +54,13 @@ public:
 
         // Set up the callout manager with these hooks.  Assume a maximum of
         // four libraries.
-        callout_manager_.reset(new CalloutManager(hooks_, 4));
+        callout_manager_.reset(new CalloutManager(hooks_, 10));
 
         // Set up the callout handle.
         callout_handle_.reset(new CalloutHandle(callout_manager_));
+
+        // Initialize the static variable.
+        callout_value_ = 0;
     }
 
     /// @brief Return the callout handle
@@ -110,59 +113,59 @@ int CalloutManagerTest::callout_value_ = 0;
 // Functions return a zero to indicate success.
 
 extern "C" {
-int manager_general(int number) {
+int callout_general(int number) {
     CalloutManagerTest::callout_value_ =
         10 * CalloutManagerTest::callout_value_ + number;
     return (0);
 }
 
-int manager_one(CalloutHandle&) {
-    return (manager_general(1));
+int callout_one(CalloutHandle&) {
+    return (callout_general(1));
 }
 
-int manager_two(CalloutHandle&) {
-    return (manager_general(2));
+int callout_two(CalloutHandle&) {
+    return (callout_general(2));
 }
 
-int manager_three(CalloutHandle&) {
-    return (manager_general(3));
+int callout_three(CalloutHandle&) {
+    return (callout_general(3));
 }
 
-int manager_four(CalloutHandle&) {
-    return (manager_general(4));
+int callout_four(CalloutHandle&) {
+    return (callout_general(4));
 }
 
-int manager_five(CalloutHandle&) {
-    return (manager_general(5));
+int callout_five(CalloutHandle&) {
+    return (callout_general(5));
 }
 
-int manager_six(CalloutHandle&) {
-    return (manager_general(6));
+int callout_six(CalloutHandle&) {
+    return (callout_general(6));
 }
 
-int manager_seven(CalloutHandle&) {
-    return (manager_general(7));
+int callout_seven(CalloutHandle&) {
+    return (callout_general(7));
 }
 
 // The next functions are duplicates of some of the above, but return an error.
 
-int manager_one_error(CalloutHandle& handle) {
-    (void) manager_one(handle);
+int callout_one_error(CalloutHandle& handle) {
+    (void) callout_one(handle);
     return (1);
 }
 
-int manager_two_error(CalloutHandle& handle) {
-    (void) manager_two(handle);
+int callout_two_error(CalloutHandle& handle) {
+    (void) callout_two(handle);
     return (1);
 }
 
-int manager_three_error(CalloutHandle& handle) {
-    (void) manager_three(handle);
+int callout_three_error(CalloutHandle& handle) {
+    (void) callout_three(handle);
     return (1);
 }
 
-int manager_four_error(CalloutHandle& handle) {
-    (void) manager_four(handle);
+int callout_four_error(CalloutHandle& handle) {
+    (void) callout_four(handle);
     return (1);
 }
 
@@ -210,15 +213,15 @@ TEST_F(CalloutManagerTest, CheckLibraryIndex) {
 
     // Check invalid ones
     EXPECT_THROW(getCalloutManager()->setLibraryIndex(-1), NoSuchLibrary);
-    EXPECT_THROW(getCalloutManager()->setLibraryIndex(5), NoSuchLibrary);
+    EXPECT_THROW(getCalloutManager()->setLibraryIndex(15), NoSuchLibrary);
 }
 
 // Check that we can only register callouts on valid hook names.
 
 TEST_F(CalloutManagerTest, ValidHookNames) {
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_NO_THROW(getCalloutManager()->registerCallout("alpha", manager_one));
-    EXPECT_THROW(getCalloutManager()->registerCallout("unknown", manager_one),
+    EXPECT_NO_THROW(getCalloutManager()->registerCallout("alpha", callout_one));
+    EXPECT_THROW(getCalloutManager()->registerCallout("unknown", callout_one),
                                                       NoSuchHook);
 }
 
@@ -233,9 +236,9 @@ TEST_F(CalloutManagerTest, RegisterCallout) {
     // Set up so that hooks "alpha" and "beta" have callouts attached from a
     // different libraries.
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
+    getCalloutManager()->registerCallout("alpha", callout_one);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", manager_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
 
     // Check all is as expected.
     EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
@@ -243,60 +246,48 @@ TEST_F(CalloutManagerTest, RegisterCallout) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Check that calling the callouts returns as expected. (This is also a
     // test of the callCallouts method.)
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1, callout_value_);
 
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
     EXPECT_EQ(2, callout_value_);
 
     // Register some more callouts from different libraries on hook "alpha".
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", manager_five);
+    getCalloutManager()->registerCallout("alpha", callout_five);
 
     // Check it is as expected.
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1345, callout_value_);
 
     // ... and check the additional callouts were not registered on the "beta"
     // hook.
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
     EXPECT_EQ(2, callout_value_);
 
     // Add another callout to hook "alpha" from library index 2 - this should
     // appear at the end of the callout list for that library.
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_six);
+    getCalloutManager()->registerCallout("alpha", callout_six);
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(13465, callout_value_);
 
     // Add a callout from library index 1 - this should appear between the
     // callouts from library index 0 and linrary index 2.
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_seven);
+    getCalloutManager()->registerCallout("alpha", callout_seven);
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(173465, callout_value_);
 }
 
@@ -315,15 +306,15 @@ TEST_F(CalloutManagerTest, CalloutsPresent) {
     // that some callouts are).  Chose the libraries for which the callouts
     // are registered randomly.
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
+    getCalloutManager()->registerCallout("alpha", callout_one);
 
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    getCalloutManager()->registerCallout("beta", manager_two);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
 
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("delta", manager_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("delta", callout_four);
 
     // Check all is as expected.
     EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
@@ -347,9 +338,7 @@ TEST_F(CalloutManagerTest, CallNoCallouts) {
                  
     // Call the callouts on an arbitrary hook and ensure that nothing happens.
     callout_value_ = 475;
-    int status = getCalloutManager()->callCallouts(alpha_index_,
-                                                   getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(475, callout_value_); // Unchanged
 }
 
@@ -364,42 +353,34 @@ TEST_F(CalloutManagerTest, CallCalloutsSuccess) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Each library contributes one callout on hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_one);
+    getCalloutManager()->registerCallout("alpha", callout_one);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_two);
+    getCalloutManager()->registerCallout("alpha", callout_two);
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_three);
+    getCalloutManager()->registerCallout("alpha", callout_three);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", manager_four);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1234, callout_value_);
 
     // Do a random selection of callouts on hook "beta".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("beta", manager_one);
-    getCalloutManager()->registerCallout("beta", manager_three);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->registerCallout("beta", callout_three);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", manager_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("beta", manager_four);
-    status = getCalloutManager()->callCallouts(beta_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
     EXPECT_EQ(1324, callout_value_);
 
     // Ensure that calling the callouts on a hook with no callouts works.
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(gamma_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
     EXPECT_EQ(0, callout_value_);
 }
 
@@ -416,76 +397,66 @@ TEST_F(CalloutManagerTest, CallCalloutsError) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Each library contributing one callout on hook "alpha". The first callout
     // returns an error (after adding its value to the result).
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one_error);
+    getCalloutManager()->registerCallout("alpha", callout_one_error);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_two);
+    getCalloutManager()->registerCallout("alpha", callout_two);
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_three);
+    getCalloutManager()->registerCallout("alpha", callout_three);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", manager_four);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(1, status);
-    EXPECT_EQ(1, callout_value_);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
 
     // Each library contributing multiple callouts on hook "beta". The last
     // callout on the first library returns an error.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("beta", manager_one);
-    getCalloutManager()->registerCallout("beta", manager_one_error);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->registerCallout("beta", callout_one_error);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", manager_two);
-    getCalloutManager()->registerCallout("beta", manager_two);
-    getCalloutManager()->registerCallout("beta", manager_three);
-    getCalloutManager()->registerCallout("beta", manager_three);
+    getCalloutManager()->registerCallout("beta", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->registerCallout("beta", callout_three);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("beta", manager_four);
-    getCalloutManager()->registerCallout("beta", manager_four);
-    status = getCalloutManager()->callCallouts(beta_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(1, status);
-    EXPECT_EQ(11, callout_value_);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(11223344, callout_value_);
 
     // A callout in a random position in the callout list returns an error.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("gamma", manager_one);
-    getCalloutManager()->registerCallout("gamma", manager_one);
+    getCalloutManager()->registerCallout("gamma", callout_one);
+    getCalloutManager()->registerCallout("gamma", callout_one);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("gamma", manager_two);
-    getCalloutManager()->registerCallout("gamma", manager_two);
+    getCalloutManager()->registerCallout("gamma", callout_two);
+    getCalloutManager()->registerCallout("gamma", callout_two);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("gamma", manager_four_error);
-    getCalloutManager()->registerCallout("gamma", manager_four);
-    status = getCalloutManager()->callCallouts(gamma_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(1, status);
-    EXPECT_EQ(11224, callout_value_);
+    getCalloutManager()->registerCallout("gamma", callout_four_error);
+    getCalloutManager()->registerCallout("gamma", callout_four);
+    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
+    EXPECT_EQ(112244, callout_value_);
 
     // The last callout on a hook returns an error.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("delta", manager_one);
-    getCalloutManager()->registerCallout("delta", manager_one);
+    getCalloutManager()->registerCallout("delta", callout_one);
+    getCalloutManager()->registerCallout("delta", callout_one);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("delta", manager_two);
-    getCalloutManager()->registerCallout("delta", manager_two);
+    getCalloutManager()->registerCallout("delta", callout_two);
+    getCalloutManager()->registerCallout("delta", callout_two);
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("delta", manager_three);
-    getCalloutManager()->registerCallout("delta", manager_three);
+    getCalloutManager()->registerCallout("delta", callout_three);
+    getCalloutManager()->registerCallout("delta", callout_three);
     getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("delta", manager_four);
-    getCalloutManager()->registerCallout("delta", manager_four_error);
-    status = getCalloutManager()->callCallouts(delta_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(1, status);
+    getCalloutManager()->registerCallout("delta", callout_four);
+    getCalloutManager()->registerCallout("delta", callout_four_error);
+    getCalloutManager()->callCallouts(delta_index_, getCalloutHandle());
     EXPECT_EQ(11223344, callout_value_);
 }
 
@@ -498,15 +469,11 @@ TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Add a callout to hook "alpha" and check it is added correctly.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(2, callout_value_);
 
     // Remove it and check that the no callouts are present.  We have to reset
@@ -514,7 +481,7 @@ TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
     // to callCallouts().
     getCalloutManager()->setLibraryIndex(0);
     EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
 }
 
@@ -528,37 +495,29 @@ TEST_F(CalloutManagerTest, DeregisterSingleCalloutSameLibrary) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Add multiple callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1234, callout_value_);
 
-    // Remove the manager_two callout.  We have to reset the current library
+    // Remove the callout_two callout.  We have to reset the current library
     // index here as it was invalidated by the call to callCallouts().
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(134, callout_value_);
 
     // Try removing it again.
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(134, callout_value_);
 
 }
@@ -572,60 +531,48 @@ TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsSameLibrary) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Each library contributes one callout on hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    getCalloutManager()->registerCallout("alpha", manager_one);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(12123434, callout_value_);
 
-    // Remove the manager_two callouts.  We have to reset the current library
+    // Remove the callout_two callouts.  We have to reset the current library
     // index here as it was invalidated by the call to callCallouts().
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(113434, callout_value_);
 
     // Try removing multiple callouts that includes one at the end of the
     // list of callouts.
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_four));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_four));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1133, callout_value_);
 
     // ... and from the start.
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_one));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_one));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(33, callout_value_);
 
     // ... and the remaining callouts.
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_three));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_three));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(0, callout_value_);
 
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
@@ -640,32 +587,26 @@ TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Each library contributes two callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
-    getCalloutManager()->registerCallout("alpha", manager_two);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_five);
-    getCalloutManager()->registerCallout("alpha", manager_two);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(123452, callout_value_);
 
-    // Remove the manager_two callout from library 0.  It should not affect
-    // the second manager_two callout registered by library 2.
+    // Remove the callout_two callout from library 0.  It should not affect
+    // the second callout_two callout registered by library 2.
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(13452, callout_value_);
 }
 
@@ -675,43 +616,90 @@ TEST_F(CalloutManagerTest, DeregisterAllCallouts) {
     // Ensure that no callouts are attached to hook one.
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
                  
-    int status = 0;
-
     // Each library contributes two callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", manager_one);
-    getCalloutManager()->registerCallout("alpha", manager_two);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
     getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", manager_three);
-    getCalloutManager()->registerCallout("alpha", manager_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
     getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", manager_five);
-    getCalloutManager()->registerCallout("alpha", manager_six);
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_six);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(123456, callout_value_);
 
     // Remove all callouts from library index 1.
     getCalloutManager()->setLibraryIndex(1);
     EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1256, callout_value_);
 
     // Remove all callouts from library index 2.
     getCalloutManager()->setLibraryIndex(2);
     EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(12, callout_value_);
 }
 
+// Check that we can register/deregister callouts on different libraries
+// and different hooks, and that the callout instances are regarded as
+// unique and do not affect one another.
+
+TEST_F(CalloutManagerTest, MultipleCalloutsLibrariesHooks) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Register callouts on the alpha hook.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+
+    // Register the same callouts on the beta hook, and check that those
+    // on the alpha hook are not affected.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("beta", callout_five);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(5143, callout_value_);
+
+    // Check that the order of callouts on the alpha hook has not been affected.
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+
+    // Remove callout four from beta and check that alpha is not affected.
+    getCalloutManager()->setLibraryIndex(2);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("beta", callout_four));
+
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(513, callout_value_);
+
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+}
+
 // Library handle tests.  As by inspection the LibraryHandle can be seen to be
 // little more than shell around CalloutManager, only a basic set of tests
 // is done concerning registration and deregistration of functions.
@@ -729,14 +717,14 @@ TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
     // different libraries.
     getCalloutManager()->setLibraryIndex(0);
     getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            manager_one);
+                                                            callout_one);
     getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            manager_two);
+                                                            callout_two);
     getCalloutManager()->setLibraryIndex(1);
     getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            manager_three);
+                                                            callout_three);
     getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            manager_four);
+                                                            callout_four);
 
     // Check all is as expected.
     EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
@@ -744,41 +732,31 @@ TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
                  
-    int status = 0;
-
     // Check that calling the callouts returns as expected. (This is also a
     // test of the callCallouts method.)
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1234, callout_value_);
 
     // Deregister a callout on library index 0 (after we check we can't
     // deregister it through library index 1).
     getCalloutManager()->setLibraryIndex(1);
-    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1234, callout_value_);
 
     getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", manager_two));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(134, callout_value_);
 
     // Deregister all callouts on library index 1.
     getCalloutManager()->setLibraryIndex(1);
     EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
     callout_value_ = 0;
-    status = getCalloutManager()->callCallouts(alpha_index_,
-                                               getCalloutHandle());
-    EXPECT_EQ(0, status);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
     EXPECT_EQ(1, callout_value_);
 }
 
diff --git a/src/lib/util/tests/handles_unittest.cc b/src/lib/util/tests/handles_unittest.cc
index 7bcc232..a8d2341 100644
--- a/src/lib/util/tests/handles_unittest.cc
+++ b/src/lib/util/tests/handles_unittest.cc
@@ -60,6 +60,9 @@ public:
 
         // Set up for three libraries.
         manager_.reset(new CalloutManager(hooks_, 3));
+
+        // Initialize remaining variables.
+        common_string_ = "";
     }
 
     /// @brief Return callout manager
@@ -73,6 +76,9 @@ public:
     int gamma_index_;
     int delta_index_;
 
+    /// String accessible by all callouts whatever the library
+    static std::string common_string_;
+
 private:
     /// Server hooks 
     boost::shared_ptr<ServerHooks> hooks_;
@@ -80,9 +86,12 @@ private:
     /// Callout manager.  Declared static so that the callout functions can
     /// access it.
     boost::shared_ptr<CalloutManager> manager_;
-
 };
 
+/// Define the common string
+std::string HandlesTest::common_string_;
+
+
 // The next set of functions define the callouts used by the tests.  They
 // manipulate the data in such a way that callouts called - and the order in
 // which they were called - can be determined.  The functions also check that
@@ -547,24 +556,6 @@ TEST_F(HandlesTest, ConstructionDestructionCallouts) {
 
     EXPECT_EQ("110120", resultCalloutString(0));
     EXPECT_EQ((110 + 120), resultCalloutInt(0));
-
-    // Test that the destructor throws an error if the context_destroy
-    // callout returns an error. (As the constructor and destructor will
-    // have implicitly run the CalloutManager's callCallouts method, we need
-    // to set the library index again.)
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("context_destroy", returnError);
-    callout_handle.reset(new CalloutHandle(getCalloutManager()));
-    EXPECT_THROW(callout_handle.reset(), ContextDestroyFail);
-
-    // We don't know what callout_handle is pointing to - it could be to a
-    // half-destroyed object - so use a new CalloutHandle to test construction
-    // failure.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("context_create", returnError);
-    boost::scoped_ptr<CalloutHandle> callout_handle2;
-    EXPECT_THROW(callout_handle2.reset(new CalloutHandle(getCalloutManager())),
-                 ContextCreateFail);
 }
 
 // Dynamic callout registration and deregistration.
@@ -765,6 +756,167 @@ TEST_F(HandlesTest, DynamicDeregistrationSameHook) {
     EXPECT_EQ("212782", resultCalloutString(1));
 }
 
+// Testing the operation of the "skip" flag.  Callouts print the value
+// they see in the flag and either leave it unchanged, set it or clear it.
+
+int
+calloutPrintSkip(CalloutHandle& handle) {
+    static const std::string YES("Y");
+    static const std::string NO("N");
+
+    HandlesTest::common_string_ = HandlesTest::common_string_ +
+        (handle.getSkip() ? YES : NO);
+    return (0);
+}
+
+int
+calloutSetSkip(CalloutHandle& handle) {
+    static_cast<void>(calloutPrintSkip(handle));
+    handle.setSkip(true);
+    return (0);
+}
+
+int
+calloutClearSkip(CalloutHandle& handle) {
+    static_cast<void>(calloutPrintSkip(handle));
+    handle.setSkip(false);
+    return (0);
+}
+
+// Do a series of tests, returning with the skip flag set "true".
+
+TEST_F(HandlesTest, ReturnSkipSet) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+
+    CalloutHandle callout_handle(getCalloutManager());
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check result.  For each of visual checking, the expected string is
+    // divided into sections corresponding to the blocks of callouts above.
+    EXPECT_EQ(std::string("NNYY" "NNYYN" "NNYN"), common_string_);
+
+    // ... and check that the skip flag on exit from callCallouts is set.
+    EXPECT_TRUE(callout_handle.getSkip());
+}
+
+// Repeat the test, returning with the skip flag clear.
+TEST_F(HandlesTest, ReturnSkipClear) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    CalloutHandle callout_handle(getCalloutManager());
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check result.  For each of visual checking, the expected string is
+    // divided into sections corresponding to the blocks of callouts above.
+    EXPECT_EQ(std::string("NYY" "NNYNYN" "NNNY"), common_string_);
+
+    // ... and check that the skip flag on exit from callCallouts is set.
+    EXPECT_FALSE(callout_handle.getSkip());
+}
+
+// The next set of callouts do a similar thing to the above "skip" tests,
+// but alter the value of a string argument.  This is for testing that the
+// a callout is able to change an argument and return it to the caller.
+
+const char* MODIFIED_ARG = "modified_arg";
+
+int
+calloutSetArgumentCommon(CalloutHandle& handle, const char* what) {
+    std::string modified_arg = "";
+
+    handle.getArgument(MODIFIED_ARG, modified_arg);
+    modified_arg = modified_arg + std::string(what);
+    handle.setArgument(MODIFIED_ARG, modified_arg);
+    return (0);
+}
+
+int
+calloutSetArgumentYes(CalloutHandle& handle) {
+    return (calloutSetArgumentCommon(handle, "Y"));
+}
+
+int
+calloutSetArgumentNo(CalloutHandle& handle) {
+    return (calloutSetArgumentCommon(handle, "N"));
+}
+
+// ... and a callout to just copy the argument to the "common_string_" variable
+// but otherwise not alter it.
+
+int
+calloutPrintArgument(CalloutHandle& handle) {
+    handle.getArgument(MODIFIED_ARG, HandlesTest::common_string_);
+    return (0);
+}
+
+TEST_F(HandlesTest, CheckModifiedArgument) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutPrintArgument);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+
+    // Create the argument with an initial empty string value.  Then call the
+    // sequence of callouts above.
+    CalloutHandle callout_handle(getCalloutManager());
+    std::string modified_arg = "";
+    callout_handle.setArgument(MODIFIED_ARG, modified_arg);
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check the intermediate and results.  For visual checking, the expected
+    // string is divided into sections corresponding to the blocks of callouts
+    // above.
+    EXPECT_EQ(std::string("YNN" "YY"), common_string_);
+
+    callout_handle.getArgument(MODIFIED_ARG, modified_arg);
+    EXPECT_EQ(std::string("YNN" "YYNN" "YNY"), modified_arg);
+}
+
 
 } // Anonymous namespace
 



More information about the bind10-changes mailing list