Commit b4bf719a authored by Stephen Morris's avatar Stephen Morris
Browse files

[2980] Added HooksManager load/unload libraries methods

parent 49ee4eaf
......@@ -49,17 +49,15 @@ HooksManager::getHooksManager() {
// 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
......@@ -102,6 +100,46 @@ HooksManager::callCallouts(int index, CalloutHandle& 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();
}
......
......@@ -47,12 +47,6 @@ public:
/// @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
......@@ -73,7 +67,7 @@ public:
/// @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
///
......@@ -88,7 +82,7 @@ public:
///
/// @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?
///
......@@ -168,8 +162,23 @@ private:
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?
///
......@@ -196,6 +205,13 @@ private:
//@}
/// @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,
......@@ -204,7 +220,15 @@ private:
/// 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
......
......@@ -41,9 +41,17 @@ public:
/// 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.
......@@ -91,9 +99,9 @@ public:
}
};
/*
// This is effectively the same test as for LibraryManager, but using the
// LibraryManagerCollection object.
// HooksManager object.
TEST_F(HooksManagerTest, LoadLibraries) {
......@@ -102,14 +110,8 @@ 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.
//
......@@ -125,17 +127,17 @@ TEST_F(HooksManagerTest, LoadLibraries) {
// 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);
}
}
......@@ -143,7 +145,7 @@ TEST_F(HooksManagerTest, LoadLibraries) {
// 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;
......@@ -151,18 +153,9 @@ TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
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.
//
......@@ -178,20 +171,20 @@ TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
// 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.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment