Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
aac023f8
Commit
aac023f8
authored
Jul 25, 2013
by
Stephen Morris
Browse files
[2981] Added libreload functionality to DHCPv6 server
parent
c7b293f6
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
View file @
aac023f8
...
...
@@ -137,7 +137,7 @@ TEST_F(CtrlDhcpv4SrvTest, libreload) {
ConstElementPtr
result
=
ControlledDhcpv4Srv
::
execDhcpv4ServerCommand
(
"libreload"
,
params
);
ConstElementPtr
comment
=
parseAnswer
(
rcode
,
result
);
EXPECT_EQ
(
0
,
rcode
);
//
e
xpect success
EXPECT_EQ
(
0
,
rcode
);
//
E
xpect success
// Check that the libraries have unloaded and reloaded. The libraries are
// unloaded in the reverse order to which they are loaded. When they load,
...
...
src/bin/dhcp6/ctrl_dhcp6_srv.cc
View file @
aac023f8
...
...
@@ -26,16 +26,20 @@
#include
<dhcp6/dhcp6_log.h>
#include
<dhcp6/spec_config.h>
#include
<exceptions/exceptions.h>
#include
<hooks/hooks_manager.h>
#include
<util/buffer.h>
#include
<cassert>
#include
<iostream>
#include
<string>
#include
<vector>
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
cc
;
using
namespace
isc
::
config
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
hooks
;
using
namespace
isc
::
log
;
using
namespace
isc
::
util
;
using
namespace
std
;
...
...
@@ -142,7 +146,19 @@ ControlledDhcpv6Srv::dhcp6CommandHandler(const string& command, ConstElementPtr
"Shutting down."
);
return
(
answer
);
}
else
if
(
command
==
"libreload"
)
{
// TODO - add library reloading
// TODO delete any stored CalloutHandles referring to the old libraries
// Get list of currently loaded libraries and reload them.
vector
<
string
>
loaded
=
HooksManager
::
getLibraryNames
();
bool
status
=
HooksManager
::
loadLibraries
(
loaded
);
if
(
!
status
)
{
LOG_ERROR
(
dhcp6_logger
,
DHCP6_RELOAD_FAIL
);
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Failed to reload hooks libraries."
);
return
(
answer
);
}
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Hooks libraries successfully reloaded."
);
return
(
answer
);
}
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
...
...
src/bin/dhcp6/dhcp6_messages.mes
View file @
aac023f8
...
...
@@ -246,6 +246,11 @@ mandatory client-id option. This is most likely caused by a buggy client
(or a relay that malformed forwarded message). This request will not be
processed and a response with error status code will be sent back.
% DHCP6_RELOAD_FAIL reload of hooks libraries failed
A "libreload" command was issued to reload the hooks libraries but for
some reason the reload failed. Other error messages issued from the
hooks framework will indicate the nature of the problem.
% DHCP6_RENEW_UNKNOWN_SUBNET RENEW message received from client on unknown subnet (duid=%1, iaid=%2)
A warning message indicating that a client is attempting to renew his lease,
but the server does not have any information about the subnet this client belongs
...
...
src/bin/dhcp6/tests/Makefile.am
View file @
aac023f8
...
...
@@ -61,6 +61,7 @@ dhcp6_unittests_SOURCES = dhcp6_unittests.cc
dhcp6_unittests_SOURCES
+=
dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
ctrl_dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
config_parser_unittest.cc
dhcp6_unittests_SOURCES
+=
marker_file.cc
dhcp6_unittests_SOURCES
+=
../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES
+=
../dhcp6_log.h ../dhcp6_log.cc
dhcp6_unittests_SOURCES
+=
../ctrl_dhcp6_srv.cc
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
aac023f8
...
...
@@ -47,6 +47,7 @@ using namespace isc::asiolink;
using
namespace
isc
::
config
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
dhcp
::
test
;
using
namespace
isc
::
hooks
;
using
namespace
std
;
...
...
@@ -323,61 +324,6 @@ public:
expected_data_len
));
}
/// @brief Check marker file
///
/// Marker files are used by the load/unload functions in the hooks
/// libraries in these tests to signal whether they have been loaded or
/// unloaded. The file (if present) contains a single line holding
/// a set of characters.
///
/// This convenience function checks the file to see if the characters
/// are those expected.
///
/// @param name Name of the marker file.
/// @param expected Characters expected. If a marker file is present,
/// it is expected to contain characters. Therefore a value of NULL
/// is used to signify that the marker file is not expected to be
/// present.
///
/// @return true if all tests pass, false if not (in which case a failure
/// will have been logged).
bool
checkMarkerFile
(
const
char
*
name
,
const
char
*
expected
)
{
// Open the file for input
fstream
file
(
name
,
fstream
::
in
);
// Is it open?
if
(
!
file
.
is_open
())
{
// No. This is OK if we don't expected is to be present but is
// a failure otherwise.
if
(
expected
==
NULL
)
{
return
(
true
);
}
ADD_FAILURE
()
<<
"Unable to open "
<<
name
<<
". It was expected "
<<
"to be present and to contain the string '"
<<
expected
<<
"'"
;
return
(
false
);
}
else
if
(
expected
==
NULL
)
{
// File is open but we don't expect it to be present.
ADD_FAILURE
()
<<
"Opened "
<<
name
<<
" but it is not expected to "
<<
"be present."
;
return
(
false
);
}
// OK, is open, so read the data and see what we have. Compare it
// against what is expected.
string
content
;
getline
(
file
,
content
);
string
expected_str
(
expected
);
EXPECT_EQ
(
expected_str
,
content
)
<<
"Data was read from "
<<
name
;
file
.
close
();
return
(
expected_str
==
content
);
}
int
rcode_
;
///< Return code (see @ref isc::config::parseAnswer)
Dhcpv6Srv
srv_
;
///< Instance of the Dhcp6Srv used during tests
ConstElementPtr
comment_
;
///< Comment (see @ref isc::config::parseAnswer)
...
...
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
View file @
aac023f8
...
...
@@ -14,30 +14,37 @@
#include
<config.h>
#include
<config/ccsession.h>
#include
<dhcp/dhcp6.h>
#include
<dhcp6/ctrl_dhcp6_srv.h>
#include
<config/ccsession.h>
#include
<hooks/hooks_manager.h>
#include
"marker_file.h"
#include
"test_libraries.h"
#include
<boost/scoped_ptr.hpp>
#include
<gtest/gtest.h>
#include
<iostream>
#include
<fstream>
#include
<iostream>
#include
<sstream>
#include
<arpa/inet.h>
#include
<unistd.h>
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
data
;
using
namespace
isc
::
config
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
dhcp
::
test
;
using
namespace
isc
::
hooks
;
namespace
{
class
NakedControlledDhcpv6Srv
:
public
ControlledDhcpv6Srv
{
// "
n
aked" DHCPv6 server, exposes internal fields
// "
N
aked" DHCPv6 server, exposes internal fields
public:
NakedControlledDhcpv6Srv
()
:
ControlledDhcpv6Srv
(
DHCP6_SERVER_PORT
+
10000
)
{
}
};
...
...
@@ -45,10 +52,25 @@ public:
class
CtrlDhcpv6SrvTest
:
public
::
testing
::
Test
{
public:
CtrlDhcpv6SrvTest
()
{
reset
();
}
~
CtrlDhcpv6SrvTest
()
{
reset
();
};
/// @brief Reset hooks data
///
/// Resets the data for the hooks-related portion of the test by ensuring
/// that no libraries are loaded and that any marker files are deleted.
void
reset
()
{
// Unload any previously-loaded libraries.
HooksManager
::
unloadLibraries
();
// Get rid of any marker files.
static_cast
<
void
>
(
unlink
(
LOAD_MARKER_FILE
));
static_cast
<
void
>
(
unlink
(
UNLOAD_MARKER_FILE
));
}
};
TEST_F
(
CtrlDhcpv6SrvTest
,
commands
)
{
...
...
@@ -62,12 +84,12 @@ TEST_F(CtrlDhcpv6SrvTest, commands) {
ElementPtr
params
(
new
isc
::
data
::
MapElement
());
int
rcode
=
-
1
;
//
c
ase 1: send bogus command
//
C
ase 1: send bogus command
ConstElementPtr
result
=
ControlledDhcpv6Srv
::
execDhcpv6ServerCommand
(
"blah"
,
params
);
ConstElementPtr
comment
=
parseAnswer
(
rcode
,
result
);
EXPECT_EQ
(
1
,
rcode
);
// expect failure (no such command as blah)
//
c
ase 2: send shutdown command without any parameters
//
C
ase 2: send shutdown command without any parameters
result
=
ControlledDhcpv6Srv
::
execDhcpv6ServerCommand
(
"shutdown"
,
params
);
comment
=
parseAnswer
(
rcode
,
result
);
EXPECT_EQ
(
0
,
rcode
);
// expect success
...
...
@@ -76,10 +98,52 @@ TEST_F(CtrlDhcpv6SrvTest, commands) {
ConstElementPtr
x
(
new
isc
::
data
::
IntElement
(
pid
));
params
->
set
(
"pid"
,
x
);
//
c
ase 3: send shutdown command with 1 parameter: pid
//
C
ase 3: send shutdown command with 1 parameter: pid
result
=
ControlledDhcpv6Srv
::
execDhcpv6ServerCommand
(
"shutdown"
,
params
);
comment
=
parseAnswer
(
rcode
,
result
);
EXPECT_EQ
(
0
,
rcode
);
// Expect success
}
}
// end of anonymous namespace
// Check that the "libreload" command will reload libraries
TEST_F
(
CtrlDhcpv6SrvTest
,
libreload
)
{
// Ensure no marker files to start with.
ASSERT_FALSE
(
checkMarkerFileExists
(
LOAD_MARKER_FILE
));
ASSERT_FALSE
(
checkMarkerFileExists
(
UNLOAD_MARKER_FILE
));
// Load two libraries
std
::
vector
<
std
::
string
>
libraries
;
libraries
.
push_back
(
CALLOUT_LIBRARY_1
);
libraries
.
push_back
(
CALLOUT_LIBRARY_2
);
HooksManager
::
loadLibraries
(
libraries
);
// Check they are loaded.
std
::
vector
<
std
::
string
>
loaded_libraries
=
HooksManager
::
getLibraryNames
();
ASSERT_TRUE
(
libraries
==
loaded_libraries
);
// ... which also included checking that the marker file created by the
// load functions exists.
EXPECT_TRUE
(
checkMarkerFile
(
LOAD_MARKER_FILE
,
"12"
));
EXPECT_FALSE
(
checkMarkerFileExists
(
UNLOAD_MARKER_FILE
));
// Now execute the "libreload" command. This should cause the libraries
// to unload and to reload.
// Use empty parameters list
ElementPtr
params
(
new
isc
::
data
::
MapElement
());
int
rcode
=
-
1
;
ConstElementPtr
result
=
ControlledDhcpv6Srv
::
execDhcpv6ServerCommand
(
"libreload"
,
params
);
ConstElementPtr
comment
=
parseAnswer
(
rcode
,
result
);
EXPECT_EQ
(
0
,
rcode
);
// Expect success
// Check that the libraries have unloaded and reloaded. The libraries are
// unloaded in the reverse order to which they are loaded. When they load,
// they should append information to the loading marker file.
EXPECT_TRUE
(
checkMarkerFile
(
UNLOAD_MARKER_FILE
,
"21"
));
EXPECT_TRUE
(
checkMarkerFile
(
LOAD_MARKER_FILE
,
"1212"
));
}
}
// End of anonymous namespace
src/bin/dhcp6/tests/marker_file.cc
0 → 100644
View file @
aac023f8
// 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
"marker_file.h"
#include
<gtest/gtest.h>
#include
<fstream>
#include
<string>
namespace
isc
{
namespace
dhcp
{
namespace
test
{
using
namespace
std
;
// Check the marker file.
bool
checkMarkerFile
(
const
char
*
name
,
const
char
*
expected
)
{
// Open the file for input
fstream
file
(
name
,
fstream
::
in
);
// Is it open?
if
(
!
file
.
is_open
())
{
// No. This is OK if we don't expected is to be present but is
// a failure otherwise.
if
(
expected
==
NULL
)
{
return
(
true
);
}
ADD_FAILURE
()
<<
"Unable to open "
<<
name
<<
". It was expected "
<<
"to be present and to contain the string '"
<<
expected
<<
"'"
;
return
(
false
);
}
else
if
(
expected
==
NULL
)
{
// File is open but we don't expect it to be present.
ADD_FAILURE
()
<<
"Opened "
<<
name
<<
" but it is not expected to "
<<
"be present."
;
return
(
false
);
}
// OK, is open, so read the data and see what we have. Compare it
// against what is expected.
string
content
;
getline
(
file
,
content
);
string
expected_str
(
expected
);
EXPECT_EQ
(
expected_str
,
content
)
<<
"Data was read from "
<<
name
;
file
.
close
();
return
(
expected_str
==
content
);
}
// Check if the marker file exists - this is a wrapper for "access(2)" and
// really tests if the file exists and is accessible
bool
checkMarkerFileExists
(
const
char
*
name
)
{
return
(
access
(
name
,
F_OK
)
==
0
);
}
}
// namespace test
}
// namespace dhcp
}
// namespace isc
src/bin/dhcp6/tests/marker_file.h.in
View file @
aac023f8
...
...
@@ -17,16 +17,55 @@
/// @file
/// Define a marker file that is used in tests to prove that an "unload"
/// function has been called
.
/// function has been called
namespace {
const char* LOAD_MARKER_FILE = "@abs_builddir@/load_marker.txt";
const char* UNLOAD_MARKER_FILE = "@abs_builddir@/unload_marker.txt";
const char*
const
LOAD_MARKER_FILE = "@abs_builddir@/load_marker.txt";
const char*
const
UNLOAD_MARKER_FILE = "@abs_builddir@/unload_marker.txt";
}
namespace isc {
namespace dhcp {
namespace test {
/// @brief Check marker file
///
/// This function is used in some of the DHCP server tests.
///
/// Marker files are used by the load/unload functions in the hooks
/// libraries in these tests to signal whether they have been loaded or
/// unloaded. The file (if present) contains a single line holding
/// a set of characters.
///
/// This convenience function checks the file to see if the characters
/// are those expected.
///
/// @param name Name of the marker file.
/// @param expected Characters expected. If a marker file is present,
/// it is expected to contain characters. Therefore a value of NULL
/// is used to signify that the marker file is not expected to be
/// present.
///
/// @return true if all tests pass, false if not (in which case a failure
/// will have been logged).
bool
checkMarkerFile(const char* name, const char* expected);
/// @brief Check marker file exists
///
/// This function is used in some of the DHCP server tests.
///
/// Checkes that the specified file does NOT exist.
///
/// @param name Name of the marker file.
///
/// @return true if file exists, false if not.
bool
checkMarkerFileExists(const char* name);
} // namespace test
} // namespace dhcp
} // namespace isc
#endif // MARKER_FILE_H
src/bin/dhcp6/tests/test_libraries.h.in
View file @
aac023f8
...
...
@@ -37,13 +37,13 @@ namespace {
// Library with load/unload functions creating marker files to check their
// operation.
static
const char* CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1"
const char*
const
CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1"
DLL_SUFFIX;
static
const char* CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2"
const char*
const
CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2"
DLL_SUFFIX;
// Name of a library which is not present.
static
const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere"
const char*
const
NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere"
DLL_SUFFIX;
} // anonymous namespace
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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