diff options
Diffstat (limited to 'src/lib/hooks/tests/library_manager_collection_unittest.cc')
-rw-r--r-- | src/lib/hooks/tests/library_manager_collection_unittest.cc | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/src/lib/hooks/tests/library_manager_collection_unittest.cc b/src/lib/hooks/tests/library_manager_collection_unittest.cc new file mode 100644 index 0000000..9b30cb3 --- /dev/null +++ b/src/lib/hooks/tests/library_manager_collection_unittest.cc @@ -0,0 +1,314 @@ +// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <hooks/callout_handle.h> +#include <hooks/callout_manager.h> +#include <hooks/library_manager.h> +#include <hooks/library_manager_collection.h> +#include <hooks/libinfo.h> + +#include <hooks/tests/common_test_class.h> +#include <hooks/tests/test_libraries.h> + +#include <boost/shared_ptr.hpp> +#include <gtest/gtest.h> + +#include <algorithm> +#include <string> + + +using namespace isc; +using namespace isc::hooks; +using namespace std; + +namespace { + +/// @brief Library manager collection test class + +class LibraryManagerCollectionTest : public ::testing::Test, + public HooksCommonTestClass { +private: + + /// To avoid unused variable errors + std::string dummy(int i) { + if (i == 0) { + return (MARKER_FILE); + } else if (i > 0) { + return (LOAD_CALLOUT_LIBRARY); + } else { + return (LOAD_ERROR_CALLOUT_LIBRARY); + } + } +}; + +} // namespace + +namespace isc { +namespace hooks { +/// @brief Public library manager collection class +/// +/// This is an instance of the LibraryManagerCollection class but with the +/// protected methods made public for test purposes. + +class PublicLibraryManagerCollection : public LibraryManagerCollection { +public: + /// @brief Constructor + /// + /// @param List of libraries that this collection will manage. The order + /// of the libraries is important. + PublicLibraryManagerCollection(const HookLibsCollection& libraries) + : LibraryManagerCollection(libraries) { + } + + /// Public methods that call protected methods on the superclass. + using LibraryManagerCollection::unloadLibraries; +}; + +} // namespace hooks +} // namespace isc + +namespace { +// This is effectively the same test as for LibraryManager, but using the +// LibraryManagerCollection object. + +TEST_F(LibraryManagerCollectionTest, LoadLibraries) { + + // Set up the list of libraries to be loaded. + HookLibsCollection library_names; + library_names.push_back(make_pair(std::string(FULL_CALLOUT_LIBRARY), + data::ConstElementPtr())); + library_names.push_back(make_pair(std::string(BASIC_CALLOUT_LIBRARY), + data::ConstElementPtr())); + + // 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()); + EXPECT_EQ(2, lm_collection.getLoadedLibraryCount()); + + // Execute the callouts. The first library implements the calculation. + // + // r3 = (7 * d1 - d2) * d3 + // + // The last-loaded library implements the calculation + // + // r3 = (10 + d1) * d2 - d3 + // + // Putting the processing for each library together in the appropriate + // order, we get: + // + // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3 + boost::shared_ptr<CalloutManager> manager = + lm_collection.getCalloutManager(); + { + SCOPED_TRACE("Doing calculation with libraries loaded"); + executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183); + } + + // Try unloading the libraries. + EXPECT_NO_THROW(lm_collection.unloadLibraries()); + EXPECT_EQ(0, lm_collection.getLoadedLibraryCount()); + + // 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); + } +} + +// This is effectively the same test as above, but with a library generating +// an error when loaded. It is expected that no libraries will be loaded. + +TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) { + + // Set up the list of libraries to be loaded. + HookLibsCollection library_names; + library_names.push_back(make_pair(std::string(FULL_CALLOUT_LIBRARY), + data::ConstElementPtr())); + library_names.push_back(make_pair(std::string(INCORRECT_VERSION_LIBRARY), + data::ConstElementPtr())); + library_names.push_back(make_pair(std::string(BASIC_CALLOUT_LIBRARY), + data::ConstElementPtr())); + + // 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()); + + // Expect no libraries were loaded. + EXPECT_EQ(0, lm_collection.getLoadedLibraryCount()); +} + +// Check that everything works even with no libraries loaded. + +TEST_F(LibraryManagerCollectionTest, NoLibrariesLoaded) { + // Set up the list of libraries to be loaded. + HookLibsCollection library_names; + + // Set up the library manager collection and get the callout manager we'll + // be using. + LibraryManagerCollection lm_collection(library_names); + EXPECT_TRUE(lm_collection.loadLibraries()); + EXPECT_EQ(0, lm_collection.getLoadedLibraryCount()); + boost::shared_ptr<CalloutManager> manager = + lm_collection.getCalloutManager(); + + // Execute the calculation - callouts can be called but as nothing + // happens, the result should always be -1. + executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1); +} + +// Check that we can get the names of the libraries. + +TEST_F(LibraryManagerCollectionTest, LibraryNames) { + + // Set up the list of libraries to be loaded. + HookLibsCollection libraries; + libraries.push_back(make_pair(std::string(FULL_CALLOUT_LIBRARY), + data::ConstElementPtr())); + libraries.push_back(make_pair(std::string(BASIC_CALLOUT_LIBRARY), + data::ConstElementPtr())); + + // Set up the library manager collection and get the callout manager we'll + // be using. + PublicLibraryManagerCollection lm_collection(libraries); + + // Check the names before the libraries are loaded. + std::vector<std::string> collection_names = lm_collection.getLibraryNames(); + EXPECT_TRUE(extractNames(libraries) == collection_names); + + // Load the libraries and check the names again. + EXPECT_TRUE(lm_collection.loadLibraries()); + EXPECT_EQ(2, lm_collection.getLoadedLibraryCount()); + collection_names = lm_collection.getLibraryNames(); + EXPECT_TRUE(extractNames(libraries) == collection_names); +} + +// Test the library validation function. + +TEST_F(LibraryManagerCollectionTest, validateLibraries) { + // Vector of libraries that failed validation + std::vector<std::string> failed; + + // Test different vectors of libraries. + + // No libraries should return a success. + std::vector<std::string> libraries; + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed.empty()); + + // Single valid library should validate. + libraries.clear(); + libraries.push_back(BASIC_CALLOUT_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed.empty()); + + // Multiple valid libraries should succeed. + libraries.clear(); + libraries.push_back(BASIC_CALLOUT_LIBRARY); + libraries.push_back(FULL_CALLOUT_LIBRARY); + libraries.push_back(UNLOAD_CALLOUT_LIBRARY); + libraries.push_back(CALLOUT_PARAMS_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed.empty()); + + // Single invalid library should fail. + libraries.clear(); + libraries.push_back(NOT_PRESENT_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed == libraries); + + // Multiple invalid libraries should fail. + libraries.clear(); + libraries.push_back(INCORRECT_VERSION_LIBRARY); + libraries.push_back(NO_VERSION_LIBRARY); + libraries.push_back(FRAMEWORK_EXCEPTION_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed == libraries); + + // Combination of valid and invalid (first one valid) should fail. + libraries.clear(); + libraries.push_back(FULL_CALLOUT_LIBRARY); + libraries.push_back(INCORRECT_VERSION_LIBRARY); + libraries.push_back(NO_VERSION_LIBRARY); + + std::vector<std::string> expected_failures; + expected_failures.push_back(INCORRECT_VERSION_LIBRARY); + expected_failures.push_back(NO_VERSION_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed == expected_failures); + + // Combination of valid and invalid (first one invalid) should fail. + libraries.clear(); + libraries.push_back(NO_VERSION_LIBRARY); + libraries.push_back(FULL_CALLOUT_LIBRARY); + libraries.push_back(INCORRECT_VERSION_LIBRARY); + + expected_failures.clear(); + expected_failures.push_back(NO_VERSION_LIBRARY); + expected_failures.push_back(INCORRECT_VERSION_LIBRARY); + + failed = LibraryManagerCollection::validateLibraries(libraries); + EXPECT_TRUE(failed == expected_failures); +} + +// This test verifies if getLibraryNames and getLibraryInfo are returning +// expected values if there are no libraries configured. +TEST_F(LibraryManagerCollectionTest, libraryGetEmpty) { + + HookLibsCollection empty; + boost::shared_ptr<LibraryManagerCollection> mgr; + + // Instantiate library manager collection with no libraries + EXPECT_NO_THROW(mgr.reset(new LibraryManagerCollection(empty))); + + // Check that getLibraryInfo returns empty list properly. + HookLibsCollection returned = mgr->getLibraryInfo(); + EXPECT_TRUE(returned.empty()); + + // Check that getLibraryNames return empty list, too. + vector<string> names(3, "rubbish"); // just put something in it. + EXPECT_NO_THROW(names = mgr->getLibraryNames()); + EXPECT_TRUE(names.empty()); +} + +// This test verifies if getLibraryNames and getLibraryInfo are returning +// expected values when there are libraries configured. +TEST_F(LibraryManagerCollectionTest, libraryGet) { + using namespace data; + + HookLibsCollection libs; + ElementPtr param1(Element::fromJSON("{ \"param1\": \"foo\" }")); + ElementPtr param2(Element::fromJSON("{ \"param2\": \"bar\" }")); + libs.push_back(make_pair("libone", param1)); + libs.push_back(make_pair("libtwo", param2)); + + boost::shared_ptr<LibraryManagerCollection> mgr; + EXPECT_NO_THROW(mgr.reset(new LibraryManagerCollection(libs))); + EXPECT_TRUE(libs == mgr->getLibraryInfo()); + + vector<string> exp_names; + exp_names.push_back("libone"); + exp_names.push_back("libtwo"); + + EXPECT_TRUE(exp_names == mgr->getLibraryNames()); +} + +} // Anonymous namespace |