From: Stephen Morris Date: Thu, 13 Jun 2013 16:13:24 +0000 (+0100) Subject: [2974] Modifications as a result of review X-Git-Tag: bind10-1.2.0beta1-release~402^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b63fddd9ded87b34a2f9072d118bbfaca420c045;p=thirdparty%2Fkea.git [2974] Modifications as a result of review --- diff --git a/src/lib/util/hooks/callout_handle.cc b/src/lib/util/hooks/callout_handle.cc index 5b6b3b221a..8052823a02 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& 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 ad3ef673b6..00335058ed 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 32afc9fec1..af20619197 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((*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 542afd040c..7a224332f1 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 635e570db1..76e18d8f8b 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 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 8f35be3aff..ca9b8adbcd 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 7bcc232aef..a8d23417fc 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 hooks_; @@ -80,9 +86,12 @@ private: /// Callout manager. Declared static so that the callout functions can /// access it. boost::shared_ptr 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 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(calloutPrintSkip(handle)); + handle.setSkip(true); + return (0); +} + +int +calloutClearSkip(CalloutHandle& handle) { + static_cast(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