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

[2980] Abstracted names of test libraries into a common header file

parent 8b7ae5fa
......@@ -1402,9 +1402,8 @@ AC_OUTPUT([doc/version.ent
src/lib/cc/session_config.h.pre
src/lib/cc/tests/session_unittests_config.h
src/lib/datasrc/datasrc_config.h.pre
src/lib/hooks/tests/library_manager_collection_unittest.cc
src/lib/hooks/tests/library_manager_unittest.cc
src/lib/hooks/tests/marker_file.h
src/lib/hooks/tests/test_libraries.h
src/lib/log/tests/console_test.sh
src/lib/log/tests/destination_test.sh
src/lib/log/tests/init_logger_test.sh
......
......@@ -89,4 +89,4 @@ endif
noinst_PROGRAMS = $(TESTS)
EXTRA_DIST = library_manager_unittest.cc.in marker_file.h.in
EXTRA_DIST = marker_file.h.in test_libraries.h.in
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <hooks/callout_handle.h>
#include <hooks/callout_manager.h>
#include <hooks/library_manager.h>
#include <hooks/library_manager_collection.h>
#include <hooks/server_hooks.h>
#include <hooks/tests/marker_file.h>
#include <hooks/tests/test_libraries.h>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
#include <algorithm>
#include <fstream>
#include <string>
#include <unistd.h>
using namespace isc;
using namespace isc::hooks;
using namespace std;
namespace {
/// @brief Library manager collection test class
class LibraryManagerCollectionTest : public ::testing::Test {
public:
/// @brief Constructor
LibraryManagerCollectionTest() {
// Set up the server hooks. ServerHooks is a singleton, so we reset it
// between each test.
ServerHooks& hooks = ServerHooks::getServerHooks();
hooks.reset();
lm_one_index_ = hooks.registerHook("lm_one");
lm_two_index_ = hooks.registerHook("lm_two");
lm_three_index_ = hooks.registerHook("lm_three");
// Ensure the marker file is not present at the start of a test.
static_cast<void>(unlink(MARKER_FILE));
}
/// @brief Destructor
///
/// Ensures a marker file is removed after each test.
~LibraryManagerCollectionTest() {
static_cast<void>(unlink(MARKER_FILE));
}
/// @brief Call callouts test
///
/// All of the loaded libraries for which callouts are called register four
/// callouts: a context_create callout and three callouts that are attached
/// to hooks lm_one, lm_two and lm_three. These four callouts, executed
/// in sequence, perform a series of calculations. Data is passed between
/// callouts in the argument list, in a variable named "result".
///
/// context_create initializes the calculation by setting a seed
/// value, called r0 here. This value is dependent on the library being
/// loaded. Prior to that, the argument "result" is initialized to -1,
/// the purpose being to avoid exceptions when running this test with no
/// libraries loaded.
///
/// Callout lm_one is passed a value d1 and performs a simple arithmetic
/// operation on it and r0 yielding a result r1. Hence we can say that
/// @f[ r1 = lm1(r0, d1) @f]
///
/// Callout lm_two is passed a value d2 and peforms another simple
/// arithmetic operation on it and d2, yielding r2, i.e.
/// @f[ r2 = lm2(d1, d2) @f]
///
/// lm_three does a similar operation giving @f[ r3 = lm3(r2, d3) @f].
///
/// The details of the operations lm1, lm2 and lm3 depend on the library.
/// However the sequence of calls needed to do this set of calculations
/// is identical regardless of the exact functions. This method performs
/// those operations and checks the results of each step.
///
/// It is assumed that callout_manager_ has been set up appropriately.
///
/// @note The CalloutHandle used in the calls is declared locally here.
/// The advantage of this (apart from scope reduction) is that on
/// exit, it is destroyed. This removes any references to memory
/// allocated by loaded libraries while they are still loaded.
///
/// @param r0...r3, d1..d3 Values and intermediate values expected. They
/// are ordered so that the variables appear in the argument list in
/// the order they are used.
void executeCallCallouts(int r0, int d1, int r1, int d2, int r2, int d3,
int r3) {
static const char* COMMON_TEXT = " callout returned the wong value";
static const char* RESULT = "result";
int result;
// Set up a callout handle for the calls.
CalloutHandle callout_handle(callout_manager_);
// Initialize the argument RESULT. This simplifies testing by
// eliminating the generation of an exception when we try the unload
// test. In that case, RESULT is unchanged.
callout_handle.setArgument(RESULT, -1);
// Seed the calculation.
callout_manager_->callCallouts(ServerHooks::CONTEXT_CREATE,
callout_handle);
callout_handle.getArgument(RESULT, result);
EXPECT_EQ(r0, result) << "context_create" << COMMON_TEXT;
// Perform the first calculation.
callout_handle.setArgument("data_1", d1);
callout_manager_->callCallouts(lm_one_index_, callout_handle);
callout_handle.getArgument(RESULT, result);
EXPECT_EQ(r1, result) << "lm_one" << COMMON_TEXT;
// ... the second ...
callout_handle.setArgument("data_2", d2);
callout_manager_->callCallouts(lm_two_index_, callout_handle);
callout_handle.getArgument(RESULT, result);
EXPECT_EQ(r2, result) << "lm_two" << COMMON_TEXT;
// ... and the third.
callout_handle.setArgument("data_3", d3);
callout_manager_->callCallouts(lm_three_index_, callout_handle);
callout_handle.getArgument(RESULT, result);
EXPECT_EQ(r3, result) << "lm_three" << COMMON_TEXT;
}
/// Hook indexes. These are are made public for ease of reference.
int lm_one_index_;
int lm_two_index_;
int lm_three_index_;
/// Callout manager used in the executeCallCallouts() call.
boost::shared_ptr<CalloutManager> callout_manager_;
};
/// @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 isc::hooks::LibraryManagerCollection {
public:
/// @brief Constructor
///
/// @param List of libraries that this collection will manage. The order
/// of the libraries is important.
PublicLibraryManagerCollection(const std::vector<std::string>& libraries)
: LibraryManagerCollection(libraries)
{}
/// Public methods that call protected methods on the superclass.
using LibraryManagerCollection::unloadLibraries;
};
// 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.
std::vector<std::string> library_names;
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());
callout_manager_ = lm_collection.getCalloutManager();
// 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
{
SCOPED_TRACE("Doing calculation with libraries loaded");
executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
}
// Try unloading the libraries.
EXPECT_NO_THROW(lm_collection.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(-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 the failing library will not be
// loaded, but others will be.
TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
// Set up the list of libraries to be loaded.
std::vector<std::string> library_names;
library_names.push_back(std::string(FULL_CALLOUT_LIBRARY));
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());
callout_manager_ = lm_collection.getCalloutManager();
// Expect only two libraries were loaded.
EXPECT_EQ(2, callout_manager_->getNumLibraries());
// 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
{
SCOPED_TRACE("Doing calculation with libraries loaded");
executeCallCallouts(10, 3, 33, 2, 62, 3, 183);
}
// Try unloading the libraries.
EXPECT_NO_THROW(lm_collection.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(-1, 3, -1, 22, -1, 83, -1);
}
}
// Check that everything works even with no libraries loaded.
TEST_F(LibraryManagerCollectionTest, NoLibrariesLoaded) {
// Set up the list of libraries to be loaded.
std::vector<std::string> 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());
callout_manager_ = lm_collection.getCalloutManager();
// Load the libraries.
EXPECT_TRUE(lm_collection.loadLibraries());
// Eecute the calculation - callouts can be called but as nothing
// happens, the result should always be -1.
executeCallCallouts(-1, 3, -1, 22, -1, 83, -1);
}
} // Anonymous namespace
......@@ -16,7 +16,9 @@
#include <hooks/callout_manager.h>
#include <hooks/library_manager.h>
#include <hooks/server_hooks.h>
#include <hooks/tests/marker_file.h>
#include <hooks/tests/test_libraries.h>
#include <gtest/gtest.h>
......@@ -33,20 +35,6 @@ using namespace std;
namespace {
// Names of the libraries used in these tests. These libraries are built using
// libtool, so we need to look in the hidden ".libs" directory to locate the
// .so file. Note that we access the .so file - libtool creates this as a
// like to the real shared library.
static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl.so";
static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
static const char* LOAD_ERROR_CALLOUT_LIBRARY =
"@abs_builddir@/.libs/liblecl.so";
static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
/// @brief Library manager test class
class LibraryManagerTest : public ::testing::Test {
......
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef TEST_LIBRARIES_H
#define TEST_LIBRARIES_H
namespace {
// Names of the libraries used in these tests. These libraries are built using
// libtool, so we need to look in the hidden ".libs" directory to locate the
// .so file. Note that we access the .so file - libtool creates this as a
// like to the real shared library.
// Basic library with context_create and three "standard" callouts.
static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
// Library with context_create and three "standard" callouts, as well as
// load() and unload() functions.
static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl.so";
// Library where the version() function returns an incorrect result.
static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
// Library where some of the callout registration is done with the load()
// function.
static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
// Library where the load() function returns an error.
static const char* LOAD_ERROR_CALLOUT_LIBRARY =
"@abs_builddir@/.libs/liblecl.so";
// Name of a library which is not present.
static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
// Library that does not include a version function.
static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
// Library where there is an unload() function.
static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
} // anonymous namespace
#endif // TEST_LIBRARIES_H
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