// Perform conditional initialization if nothing is loaded.
void
-HooksManager::conditionallyInitialize() {
- if (!lm_collection_) {
+HooksManager::performConditionalInitialization() {
- // Nothing present, so create the collection with any empty set of
- // libraries, and get the CalloutManager.
- vector<string> libraries;
- lm_collection_.reset(new LibraryManagerCollection(libraries));
- lm_collection_->loadLibraries();
+ // Nothing present, so create the collection with any empty set of
+ // libraries, and get the CalloutManager.
+ vector<string> libraries;
+ lm_collection_.reset(new LibraryManagerCollection(libraries));
+ lm_collection_->loadLibraries();
- callout_manager_ = lm_collection_->getCalloutManager();
- }
+ callout_manager_ = lm_collection_->getCalloutManager();
}
// Create a callout handle
return (getHooksManager().callCalloutsInternal(index, handle));
}
+// Load the libraries. This will delete the previously-loaded libraries
+// (if present) and load new ones.
+
+bool
+HooksManager::loadLibrariesInternal(const std::vector<std::string>& libraries) {
+ // Unload current set of libraries (if any are loaded).
+ unloadLibrariesInternal();
+
+ // Create the library manager and load the libraries.
+ lm_collection_.reset(new LibraryManagerCollection(libraries));
+ bool status = lm_collection_->loadLibraries();
+
+ // ... and obtain the callout manager for them.
+ callout_manager_ = lm_collection_->getCalloutManager();
+
+ return (status);
+}
+
+bool
+HooksManager::loadLibraries(const std::vector<std::string>& libraries) {
+ return (getHooksManager().loadLibrariesInternal(libraries));
+}
+
+// Unload the libraries. This just deletes all internal objects which will
+// cause the libraries to be unloaded.
+
+void
+HooksManager::unloadLibrariesInternal() {
+ // The order of deletion does not matter here, as each library manager
+ // holds its own pointer to the callout manager. However, we may as
+ // well delete the library managers first: if there are no other references
+ // to the callout manager, the second statement will delete it, which may
+ // ease debugging.
+ lm_collection_.reset();
+ callout_manager_.reset();
+}
+
+void HooksManager::unloadLibraries() {
+ getHooksManager().unloadLibrariesInternal();
+}
/// @return Reference to the singleton hooks manager.
static HooksManager& getHooksManager();
- /// @brief Reset hooks manager
- ///
- /// Resets the hooks manager to the initial state. This should only be
- /// called by test functions, so causes a warning message to be output.
- void reset() {}
-
/// @brief Load and reload libraries
///
/// Loads the list of libraries into the server address space. For each
/// @return true if all libraries loaded without a problem, false if one or
/// more libraries failed to load. In the latter case, message will
/// be logged that give the reason.
- bool loadLibraries(const std::vector<std::string>& /* libraries */) {return false;}
+ static bool loadLibraries(const std::vector<std::string>& libraries);
/// @brief Unload libraries
///
///
/// @return true if all libraries unloaded successfully, false on an error.
/// In the latter case, an error message will have been output.
- bool unloadLibraries() {return false;}
+ static void unloadLibraries();
/// @brief Are callouts present?
///
HooksManager();
//@{
- /// The following correspond to the each of the static methods above
- /// but operate on the current instance.
+ /// The following methods correspond to similarly-named static methods,
+ /// but actually do the work on the singleton instance of the HooksManager.
+ /// See the descriptions of the static methods for more details.
+
+ /// @brief Load and reload libraries
+ ///
+ /// @param libraries List of libraries to be loaded. The order is
+ /// important, as it determines the order that callouts on the same
+ /// hook will be called.
+ ///
+ /// @return true if all libraries loaded without a problem, false if one or
+ /// more libraries failed to load. In the latter case, message will
+ /// be logged that give the reason.
+ bool loadLibrariesInternal(const std::vector<std::string>& libraries);
+
+ /// @brief Unload libraries
+ void unloadLibrariesInternal();
/// @brief Are callouts present?
///
//@}
+ /// @brief Initialization to No Libraries
+ ///
+ /// Initializes the hooks manager with an "empty set" of libraries. This
+ /// method is called if conditionallyInitialize() determines that such
+ /// initialization is needed.
+ void performConditionalInitialization();
+
/// @brief Conditional initialization of the hooks manager
///
/// loadLibraries() performs the initialization of the HooksManager,
/// whenever any hooks execution function is invoked (checking callouts,
/// calling callouts or returning a callout handle). If the HooksManager
/// is unitialised, it will initialize it with an "empty set" of libraries.
- void conditionallyInitialize();
+ ///
+ /// For speed, the test of whether initialization is required is done
+ /// in-line here. The actual initialization is performed in
+ /// performConditionalInitialization().
+ void conditionallyInitialize() {
+ if (!lm_collection_) {
+ performConditionalInitialization();
+ }
+ }
// Members
/// Reset the hooks manager. The hooks manager is a singleton, so needs
/// to be reset for each test.
HooksManagerTest() {
- HooksManager::getHooksManager().reset();
+ HooksManager::unloadLibraries();
}
+ /// @brief Destructor
+ ///
+ /// Unload all libraries.
+ ~HooksManagerTest() {
+ HooksManager::unloadLibraries();
+ }
+
+
/// @brief Call callouts test
///
/// See the header for HooksCommonTestClass::execute for details.
}
};
-/*
+
// This is effectively the same test as for LibraryManager, but using the
-// LibraryManagerCollection object.
+// HooksManager object.
TEST_F(HooksManagerTest, LoadLibraries) {
library_names.push_back(std::string(FULL_CALLOUT_LIBRARY));
library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY));
- // Set up the library manager collection and get the callout manager we'll
- // be using.
- PublicLibraryManagerCollection lm_collection(library_names);
-
// Load the libraries.
- EXPECT_TRUE(lm_collection.loadLibraries());
- boost::shared_ptr<CalloutManager> manager =
- lm_collection.getCalloutManager();
+ EXPECT_TRUE(HooksManager::loadLibraries(library_names));
// Execute the callouts. The first library implements the calculation.
//
// r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
{
SCOPED_TRACE("Doing calculation with libraries loaded");
- executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183);
+ executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
}
// Try unloading the libraries.
- EXPECT_NO_THROW(lm_collection.unloadLibraries());
+ EXPECT_NO_THROW(HooksManager::unloadLibraries());
// Re-execute the calculation - callouts can be called but as nothing
// happens, the result should always be -1.
{
SCOPED_TRACE("Doing calculation with libraries not loaded");
- executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1);
+ executeCallCallouts(-1, 3, -1, 22, -1, 83, -1);
}
}
// an error when loaded. It is expected that the failing library will not be
// loaded, but others will be.
-TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
+TEST_F(HooksManagerTest, LoadLibrariesWithError) {
// Set up the list of libraries to be loaded.
std::vector<std::string> library_names;
library_names.push_back(std::string(INCORRECT_VERSION_LIBRARY));
library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY));
- // Set up the library manager collection and get the callout manager we'll
- // be using.
- PublicLibraryManagerCollection lm_collection(library_names);
-
- // Load the libraries. We expect a failure status to be returned as
- // one of the libraries failed to load.
- EXPECT_FALSE(lm_collection.loadLibraries());
- boost::shared_ptr<CalloutManager> manager =
- lm_collection.getCalloutManager();
-
- // Expect only two libraries were loaded.
- EXPECT_EQ(2, manager->getNumLibraries());
+ // Load the libraries. We expect a failure return because one of the
+ // libraries fails to load.
+ EXPECT_FALSE(HooksManager::loadLibraries(library_names));
// Execute the callouts. The first library implements the calculation.
//
// r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3
{
SCOPED_TRACE("Doing calculation with libraries loaded");
- executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183);
+ executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
}
// Try unloading the libraries.
- EXPECT_NO_THROW(lm_collection.unloadLibraries());
+ EXPECT_NO_THROW(HooksManager::unloadLibraries());
// Re-execute the calculation - callouts can be called but as nothing
// happens, the result should always be -1.
{
SCOPED_TRACE("Doing calculation with libraries not loaded");
- executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1);
+ executeCallCallouts(-1, 3, -1, 22, -1, 83, -1);
}
}
-*/
+
// Check that everything works even with no libraries loaded. First that
// calloutsPresent() always returns false.