Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
49ee4eaf
Commit
49ee4eaf
authored
Jun 21, 2013
by
Stephen Morris
Browse files
[2980] Checkpoint - HooksManager class partially working
parent
db3f2d81
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/lib/hooks/Makefile.am
View file @
49ee4eaf
...
...
@@ -31,6 +31,7 @@ libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
libb10_hooks_la_SOURCES
+=
callout_manager.cc callout_manager.h
libb10_hooks_la_SOURCES
+=
hooks.h
libb10_hooks_la_SOURCES
+=
hooks_log.cc hooks_log.h
libb10_hooks_la_SOURCES
+=
hooks_manager.cc hooks_manager.h
libb10_hooks_la_SOURCES
+=
library_handle.cc library_handle.h
libb10_hooks_la_SOURCES
+=
library_manager.cc library_manager.h
libb10_hooks_la_SOURCES
+=
library_manager_collection.cc library_manager_collection.h
...
...
src/lib/hooks/callout_handle.h
View file @
49ee4eaf
...
...
@@ -356,7 +356,7 @@ private:
/// A shared pointer to a CalloutHandle object.
typedef
boost
::
shared_ptr
<
CalloutHandle
>
CalloutHandlePtr
;
}
// namespace
util
}
// namespace
hooks
}
// namespace isc
...
...
src/lib/hooks/hooks_manager.cc
0 → 100644
View file @
49ee4eaf
// 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.
// TODO - This is a temporary implementation of the hooks manager - it is
// likely to be completely rewritte
#include <hooks/callout_handle.h>
#include <hooks/callout_manager.h>
#include <hooks/callout_manager.h>
#include <hooks/library_handle.h>
#include <hooks/library_manager_collection.h>
#include <hooks/hooks_manager.h>
#include <hooks/server_hooks.h>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
using
namespace
std
;
namespace
isc
{
namespace
hooks
{
// Constructor
HooksManager
::
HooksManager
()
{
}
// Return reference to singleton hooks manager.
HooksManager
&
HooksManager
::
getHooksManager
()
{
static
HooksManager
manager
;
return
(
manager
);
}
// Perform conditional initialization if nothing is loaded.
void
HooksManager
::
conditionallyInitialize
()
{
if
(
!
lm_collection_
)
{
// 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
();
}
}
// Create a callout handle
boost
::
shared_ptr
<
CalloutHandle
>
HooksManager
::
createCalloutHandleInternal
()
{
conditionallyInitialize
();
return
(
boost
::
shared_ptr
<
CalloutHandle
>
(
new
CalloutHandle
(
callout_manager_
)));
}
boost
::
shared_ptr
<
CalloutHandle
>
HooksManager
::
createCalloutHandle
()
{
return
(
getHooksManager
().
createCalloutHandleInternal
());
}
// Are callouts present?
bool
HooksManager
::
calloutsPresentInternal
(
int
index
)
{
conditionallyInitialize
();
return
(
callout_manager_
->
calloutsPresent
(
index
));
}
bool
HooksManager
::
calloutsPresent
(
int
index
)
{
return
(
getHooksManager
().
calloutsPresentInternal
(
index
));
}
// Call the callouts
void
HooksManager
::
callCalloutsInternal
(
int
index
,
CalloutHandle
&
handle
)
{
conditionallyInitialize
();
return
(
callout_manager_
->
callCallouts
(
index
,
handle
));
}
void
HooksManager
::
callCallouts
(
int
index
,
CalloutHandle
&
handle
)
{
return
(
getHooksManager
().
callCalloutsInternal
(
index
,
handle
));
}
}
// namespace util
}
// namespace isc
src/lib/hooks/hooks_manager.h
0 → 100644
View file @
49ee4eaf
// 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 HOOKS_MANAGER_H
#define HOOKS_MANAGER_H
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
namespace
isc
{
namespace
hooks
{
// Forward declarations
class
CalloutHandle
;
class
CalloutManager
;
class
LibraryHandle
;
class
LibraryManagerCollection
;
/// @brief Hooks Manager
///
/// This is the overall manager of the hooks framework and is the main class
/// used by a BIND 10 module when handling hooks. It is responsible for the
/// loading and unloading of user libraries, and for calling the callouts on
/// each hook point.
///
/// The class is a singleton, the single instance of the object being accessed
/// through the static getHooksManager() method.
class
HooksManager
:
boost
::
noncopyable
{
public:
/// @brief Get singleton hooks manager
///
/// @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
/// library, the "standard" functions (ones with the same names as the
/// hook points) are configured and the libraries' "load" function
/// called.
///
/// If libraries are already loaded, they are unloaded and the new
/// libraries loaded.
///
/// If any library fails to load, an error message will be logged. The
/// remaining libraries will be loaded if possible.
///
/// @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
loadLibraries
(
const
std
::
vector
<
std
::
string
>&
/* libraries */
)
{
return
false
;}
/// @brief Unload libraries
///
/// Unloads the loaded libraries and leaves the hooks subsystem in the
/// state it was after construction but before loadLibraries() is called.
///
/// @note: This method should be used with caution - see the notes for
/// the class LibraryManager for pitfalls. In general, a server
/// should not call this method: library unloading will automatically
/// take place when new libraries are loaded, and when appropriate
/// objects are destroyed.
///
/// @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
;}
/// @brief Are callouts present?
///
/// Checks loaded libraries and returns true if at lease one callout
/// has been registered by them for the given hook.
///
/// @param index Hooks index for which callouts are checked.
///
/// @return true if callouts are present, false if not.
/// @throw NoSuchHook Given index does not correspond to a valid hook.
static
bool
calloutsPresent
(
int
index
);
/// @brief Calls the callouts for a given hook
///
/// Iterates through the libray handles and calls the callouts associated
/// with the given hook index.
///
/// @note This method invalidates the current library index set with
/// setLibraryIndex().
///
/// @param index Index of the hook to call.
/// @param handle Reference to the CalloutHandle object for the current
/// object being processed.
static
void
callCallouts
(
int
index
,
CalloutHandle
&
handle
);
/// @brief Return pre-callouts library handle
///
/// Returns a library handle that can be used by the server to register
/// callouts on a hook that are called _before_ any callouts belonging
/// to a library.
///
/// @note This library handle is valid only after loadLibraries() is
/// called and before another call to loadLibraries(). Its use
/// at any other time may cause severe problems.
///
/// TODO: This is also invalidated by a call to obtaining the
/// post-callout function.
///
/// @return Shared pointer to library handle associated with pre-library
/// callout registration.
boost
::
shared_ptr
<
LibraryHandle
>
preCalloutLibraryHandle
()
const
;
/// @brief Return post-callouts library handle
///
/// Returns a library handle that can be used by the server to register
/// callouts on a hook that are called _after any callouts belonging
/// to a library.
///
/// @note This library handle is valid only after loadLibraries() is
/// called and before another call to loadLibraries(). Its use
/// at any other time may cause severe problems.
///
/// TODO: This is also invalidated by a call to obtaining the
/// pret-callout function.
///
/// @return Shared pointer to library handle associated with post-library
/// callout registration.
boost
::
shared_ptr
<
LibraryHandle
>
postCalloutLibraryHandle
()
const
;
/// @brief Return callout handle
///
/// Returns a callout handle to be associated with a request passed round
/// the system.
///
/// @note This handle is valid only after a loadLibraries() call and then
/// only up to the next loadLibraries() call.
///
/// @return Shared pointer to a CalloutHandle object.
static
boost
::
shared_ptr
<
CalloutHandle
>
createCalloutHandle
();
private:
/// @brief Constructor
///
/// This is private as the object is a singleton and can only be addessed
/// through the getHooksManager() static method.
HooksManager
();
//@{
/// The following correspond to the each of the static methods above
/// but operate on the current instance.
/// @brief Are callouts present?
///
/// @param index Hooks index for which callouts are checked.
///
/// @return true if callouts are present, false if not.
/// @throw NoSuchHook Given index does not correspond to a valid hook.
bool
calloutsPresentInternal
(
int
index
);
/// @brief Calls the callouts for a given hook
///
/// @param index Index of the hook to call.
/// @param handle Reference to the CalloutHandle object for the current
/// object being processed.
void
callCalloutsInternal
(
int
index
,
CalloutHandle
&
handle
);
/// @brief Return callout handle
///
/// @note This handle is valid only after a loadLibraries() call and then
/// only up to the next loadLibraries() call.
///
/// @return Shared pointer to a CalloutHandle object.
boost
::
shared_ptr
<
CalloutHandle
>
createCalloutHandleInternal
();
//@}
/// @brief Conditional initialization of the hooks manager
///
/// loadLibraries() performs the initialization of the HooksManager,
/// setting up the internal structures and loading libraries. However,
/// in some cases, server authors may not do that. This method is called
/// 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
();
// Members
/// Set of library managers.
boost
::
shared_ptr
<
LibraryManagerCollection
>
lm_collection_
;
/// Callout manager for the set of library managers.
boost
::
shared_ptr
<
CalloutManager
>
callout_manager_
;
};
}
// namespace util
}
// namespace hooks
#endif // HOOKS_MANAGER_H
src/lib/hooks/tests/Makefile.am
View file @
49ee4eaf
...
...
@@ -73,10 +73,14 @@ run_unittests_SOURCES += callout_handle_unittest.cc
run_unittests_SOURCES
+=
callout_manager_unittest.cc
run_unittests_SOURCES
+=
common_test_class.h
run_unittests_SOURCES
+=
handles_unittest.cc
run_unittests_SOURCES
+=
hooks_manager_unittest.cc
run_unittests_SOURCES
+=
library_manager_collection_unittest.cc
run_unittests_SOURCES
+=
library_manager_unittest.cc
run_unittests_SOURCES
+=
server_hooks_unittest.cc
nodist_run_unittests_SOURCES
=
marker_file.h
nodist_run_unittests_SOURCES
+=
test_libraries.h
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
run_unittests_LDADD
=
$(AM_LDADD)
$(GTEST_LDADD)
...
...
src/lib/hooks/tests/hooks_manager_unittest.cc
0 → 100644
View file @
49ee4eaf
// 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/hooks_manager.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 Hooks manager collection test class
class
HooksManagerTest
:
public
::
testing
::
Test
,
public
HooksCommonTestClass
{
public:
/// @brief Constructor
///
/// Reset the hooks manager. The hooks manager is a singleton, so needs
/// to be reset for each test.
HooksManagerTest
()
{
HooksManager
::
getHooksManager
().
reset
();
}
/// @brief Call callouts test
///
/// See the header for HooksCommonTestClass::execute for details.
///
/// @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"
;
// Get a CalloutHandle for the calculation.
CalloutHandlePtr
handle
=
HooksManager
::
createCalloutHandle
();
// 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.
int
result
=
-
1
;
handle
->
setArgument
(
RESULT
,
result
);
// Seed the calculation.
HooksManager
::
callCallouts
(
isc
::
hooks
::
ServerHooks
::
CONTEXT_CREATE
,
*
handle
);
handle
->
getArgument
(
RESULT
,
result
);
EXPECT_EQ
(
r0
,
result
)
<<
"context_create"
<<
COMMON_TEXT
;
// Perform the first calculation.
handle
->
setArgument
(
"data_1"
,
d1
);
HooksManager
::
callCallouts
(
lm_one_index_
,
*
handle
);
handle
->
getArgument
(
RESULT
,
result
);
EXPECT_EQ
(
r1
,
result
)
<<
"lm_one"
<<
COMMON_TEXT
;
// ... the second ...
handle
->
setArgument
(
"data_2"
,
d2
);
HooksManager
::
callCallouts
(
lm_two_index_
,
*
handle
);
handle
->
getArgument
(
RESULT
,
result
);
EXPECT_EQ
(
r2
,
result
)
<<
"lm_two"
<<
COMMON_TEXT
;
// ... and the third.
handle
->
setArgument
(
"data_3"
,
d3
);
HooksManager
::
callCallouts
(
lm_three_index_
,
*
handle
);
handle
->
getArgument
(
RESULT
,
result
);
EXPECT_EQ
(
r3
,
result
)
<<
"lm_three"
<<
COMMON_TEXT
;
}
};
/*
// This is effectively the same test as for LibraryManager, but using the
// LibraryManagerCollection object.
TEST_F(HooksManagerTest, 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());
boost::shared_ptr<CalloutManager> 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(manager, 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(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 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());
boost::shared_ptr<CalloutManager> manager =
lm_collection.getCalloutManager();
// Expect only two libraries were loaded.
EXPECT_EQ(2, 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(manager, 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(manager, -1, 3, -1, 22, -1, 83, -1);
}
}
*/
// Check that everything works even with no libraries loaded. First that
// calloutsPresent() always returns false.
TEST_F
(
HooksManagerTest
,
NoLibrariesCalloutsPresent
)
{
// No callouts should be present on any hooks.
EXPECT_FALSE
(
HooksManager
::
calloutsPresent
(
lm_one_index_
));
EXPECT_FALSE
(
HooksManager
::
calloutsPresent
(
lm_two_index_
));
EXPECT_FALSE
(
HooksManager
::
calloutsPresent
(
lm_three_index_
));
}
TEST_F
(
HooksManagerTest
,
NoLibrariesCallCallouts
)
{
executeCallCallouts
(
-
1
,
3
,
-
1
,
22
,
-
1
,
83
,
-
1
);
}
}
// Anonymous namespace
src/lib/hooks/tests/library_manager_collection_unittest.cc
View file @
49ee4eaf
...
...
@@ -16,10 +16,8 @@
#include <hooks/callout_manager.h>
#include <hooks/library_manager.h>
#include <hooks/library_manager_collection.h>
#include <hooks/server_hooks.h>
#include <hooks/tests/common_test_class.h>
#include <hooks/tests/marker_file.h>
#include <hooks/tests/test_libraries.h>
#include <boost/shared_ptr.hpp>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment