Skip to content
GitLab
Menu
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
aff6b06b
Commit
aff6b06b
authored
Aug 15, 2013
by
Stephen Morris
Browse files
[master] Merge branch 'trac2981'
parents
abdd9be8
f73cd9bc
Changes
34
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
aff6b06b
...
...
@@ -1413,6 +1413,10 @@ AC_OUTPUT([doc/version.ent
src/bin/dbutil/run_dbutil.sh
src/bin/dbutil/tests/dbutil_test.sh
src/bin/ddns/ddns.py
src/bin/dhcp4/tests/marker_file.h
src/bin/dhcp4/tests/test_libraries.h
src/bin/dhcp6/tests/marker_file.h
src/bin/dhcp6/tests/test_libraries.h
src/bin/xfrin/tests/xfrin_test
src/bin/xfrin/xfrin.py
src/bin/xfrin/run_b10-xfrin.sh
...
...
@@ -1458,6 +1462,7 @@ AC_OUTPUT([doc/version.ent
src/bin/d2/tests/test_data_files_config.h
src/bin/tests/process_rename_test.py
src/lib/config/tests/data_def_unittests_config.h
src/lib/dhcpsrv/tests/test_libraries.h
src/lib/python/isc/config/tests/config_test
src/lib/python/isc/cc/tests/cc_test
src/lib/python/isc/notify/tests/notify_out_test
...
...
src/bin/dhcp4/config_parser.cc
View file @
aff6b06b
...
...
@@ -364,6 +364,8 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
globalContext
()
->
string_values_
);
}
else
if
(
config_id
.
compare
(
"lease-database"
)
==
0
)
{
parser
=
new
DbAccessParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"hooks-libraries"
)
==
0
)
{
parser
=
new
HooksLibrariesParser
(
config_id
);
}
else
{
isc_throw
(
NotImplemented
,
"Parser error: Global configuration parameter not supported: "
...
...
@@ -399,6 +401,11 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
ParserPtr
option_parser
;
ParserPtr
iface_parser
;
// Some of the parsers alter the state of the system in a way that can't
// easily be undone. (Or alter it in a way such that undoing the change has
// the same risk of failure as doing the change.)
ParserPtr
hooks_parser_
;
// The subnet parsers implement data inheritance by directly
// accessing global storage. For this reason the global data
// parsers must store the parsed data into global storages
...
...
@@ -434,6 +441,12 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
// parser and can be run here before any other parsers.
iface_parser
=
parser
;
parser
->
build
(
config_pair
.
second
);
}
else
if
(
config_pair
.
first
==
"hooks-libraries"
)
{
// Executing commit will alter currently-loaded hooks
// libraries. Check if the supplied libraries are valid,
// but defer the commit until everything else has committed.
hooks_parser_
=
parser
;
parser
->
build
(
config_pair
.
second
);
}
else
{
// Those parsers should be started before other
// parsers so we can call build straight away.
...
...
@@ -493,6 +506,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
if
(
iface_parser
)
{
iface_parser
->
commit
();
}
// This occurs last as if it succeeds, there is no easy way
// revert it. As a result, the failure to commit a subsequent
// change causes problems when trying to roll back.
if
(
hooks_parser_
)
{
hooks_parser_
->
commit
();
}
}
catch
(
const
isc
::
Exception
&
ex
)
{
LOG_ERROR
(
dhcp4_logger
,
DHCP4_PARSER_COMMIT_FAIL
).
arg
(
ex
.
what
());
...
...
src/bin/dhcp4/ctrl_dhcp4_srv.cc
View file @
aff6b06b
...
...
@@ -19,24 +19,28 @@
#include <cc/session.h>
#include <config/ccsession.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp4/config_parser.h>
#include <dhcp4/ctrl_dhcp4_srv.h>
#include <dhcp4/dhcp4_log.h>
#include <dhcp4/spec_config.h>
#include <dhcp4/config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <exceptions/exceptions.h>
#include <hooks/hooks_manager.h>
#include <util/buffer.h>
#include <cassert>
#include <iostream>
#include <sstream>
#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
;
...
...
@@ -141,6 +145,21 @@ ControlledDhcpv4Srv::dhcp4CommandHandler(const string& command, ConstElementPtr
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Shutting down."
);
return
(
answer
);
}
else
if
(
command
==
"libreload"
)
{
// 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
(
dhcp4_logger
,
DHCP4_HOOKS_LIBS_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/dhcp4/dhcp4.spec
View file @
aff6b06b
...
...
@@ -3,6 +3,20 @@
"module_name": "Dhcp4",
"module_description": "DHCPv4 server daemon",
"config_data": [
{
"item_name": "hooks-libraries",
"item_type": "list",
"item_optional": true,
"item_default": [],
"list_item_spec":
{
"item_name": "hooks-library",
"item_type": "string",
"item_optional": false,
"item_default": ""
}
},
{ "item_name": "interfaces",
"item_type": "list",
"item_optional": false,
...
...
@@ -272,7 +286,14 @@
"item_optional": true
}
]
},
{
"command_name": "libreload",
"command_description": "Reloads the current hooks libraries.",
"command_args": []
}
]
}
}
src/bin/dhcp4/dhcp4_messages.mes
View file @
aff6b06b
...
...
@@ -89,6 +89,11 @@ point, the setting of the flag instructs the server not to choose a
subnet, an action that severely limits further processing; the server
will be only able to offer global options - no addresses will be assigned.
% DHCP4_HOOKS_LIBS_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.
% DHCP4_LEASE_ADVERT lease %1 advertised (client client-id %2, hwaddr %3)
This debug message indicates that the server successfully advertised
a lease. It is up to the client to choose one server out of othe advertised
...
...
src/bin/dhcp4/tests/Makefile.am
View file @
aff6b06b
...
...
@@ -32,6 +32,7 @@ AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/dhcp6/tests\"
AM_CPPFLAGS
+=
-DINSTALL_PROG
=
\"
$(abs_top_srcdir)
/install-sh
\"
CLEANFILES
=
$(builddir)
/interfaces.txt
$(builddir)
/logger_lockfile
CLEANFILES
+=
$(builddir)
/load_marker.txt
$(builddir)
/unload_marker.txt
AM_CXXFLAGS
=
$(B10_CXXFLAGS)
if
USE_CLANGPP
...
...
@@ -48,6 +49,16 @@ TESTS_ENVIRONMENT = \
TESTS
=
if
HAVE_GTEST
# Build shared libraries for testing.
lib_LTLIBRARIES
=
libco1.la libco2.la
libco1_la_SOURCES
=
callout_library_1.cc callout_library_common.h
libco1_la_CXXFLAGS
=
$(AM_CXXFLAGS)
libco1_la_CPPFLAGS
=
$(AM_CPPFLAGS)
libco2_la_SOURCES
=
callout_library_2.cc callout_library_common.h
libco2_la_CXXFLAGS
=
$(AM_CXXFLAGS)
libco2_la_CPPFLAGS
=
$(AM_CPPFLAGS)
TESTS
+=
dhcp4_unittests
...
...
@@ -58,7 +69,9 @@ dhcp4_unittests_SOURCES += dhcp4_unittests.cc
dhcp4_unittests_SOURCES
+=
dhcp4_srv_unittest.cc
dhcp4_unittests_SOURCES
+=
ctrl_dhcp4_srv_unittest.cc
dhcp4_unittests_SOURCES
+=
config_parser_unittest.cc
dhcp4_unittests_SOURCES
+=
marker_file.cc
nodist_dhcp4_unittests_SOURCES
=
../dhcp4_messages.h ../dhcp4_messages.cc
nodist_dhcp4_unittests_SOURCES
+=
marker_file.h test_libraries.h
dhcp4_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
dhcp4_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
...
...
src/bin/dhcp4/tests/callout_library_1.cc
0 → 100644
View file @
aff6b06b
// 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.
/// @file
/// @brief Marker file callout library
///
/// This is the source of a test library for the DHCP parser and configuration
/// tests. See callout_common.cc for details.
static
const
int
LIBRARY_NUMBER
=
1
;
#include "callout_library_common.h"
src/bin/dhcp4/tests/callout_library_2.cc
0 → 100644
View file @
aff6b06b
// 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.
/// @file
/// @brief Marker file callout library
///
/// This is the source of a test library for the DHCP parser and configuration
/// tests. See callout_common.cc for details.
static
const
int
LIBRARY_NUMBER
=
2
;
#include "callout_library_common.h"
src/bin/dhcp4/tests/callout_library_common.h
0 → 100644
View file @
aff6b06b
// 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.
/// @file
/// @brief Marker file callout library
///
/// This is the source of a test library for the DHCP parser and configuration
/// tests.
///
/// To check that they libraries are loaded and unloaded correctly, the load
/// and unload functions in this library maintain two marker files - the load
/// marker file and the unload marker file. The functions append a single
/// line to the file, creating the file if need be. In this way, the test code
/// can determine whether the load/unload functions have been run and, if so,
/// in what order.
///
/// This file is the common library file for the tests. It will not compile
/// by itself - it is included into each callout library which specifies the
/// missing constant LIBRARY_NUMBER before the inclusion.
#include <hooks/hooks.h>
#include "marker_file.h"
#include <fstream>
using
namespace
isc
::
hooks
;
using
namespace
std
;
extern
"C"
{
/// @brief Append digit to marker file
///
/// If the marker file does not exist, create it. Then append the single
/// digit (given by the constant LIBRARY_NUMBER) defined earlier to it and
/// close the file.
///
/// @param name Name of the file to open
///
/// @return 0 on success, non-zero on error.
int
appendDigit
(
const
char
*
name
)
{
// Open the file and check if successful.
fstream
file
(
name
,
fstream
::
out
|
fstream
::
app
);
if
(
!
file
.
good
())
{
return
(
1
);
}
// Add the library number to it and close.
file
<<
LIBRARY_NUMBER
;
file
.
close
();
return
(
0
);
}
// Framework functions
int
version
()
{
return
(
BIND10_HOOKS_VERSION
);
}
int
load
(
LibraryHandle
&
)
{
return
(
appendDigit
(
LOAD_MARKER_FILE
));
}
int
unload
()
{
return
(
appendDigit
(
UNLOAD_MARKER_FILE
));
}
};
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
aff6b06b
...
...
@@ -25,6 +25,10 @@
#include <dhcp/option_int.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfgmgr.h>
#include <hooks/hooks_manager.h>
#include "marker_file.h"
#include "test_libraries.h"
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
...
...
@@ -34,12 +38,14 @@
#include <sstream>
#include <limits.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
;
using
namespace
std
;
namespace
{
...
...
@@ -54,6 +60,15 @@ public:
CfgMgr
::
instance
().
deleteActiveIfaces
();
}
// Check that no hooks libraries are loaded. This is a pre-condition for
// a number of tests, so is checked in one place. As this uses an
// ASSERT call - and it is not clear from the documentation that Gtest
// predicates can be used in a constructor - the check is placed in SetUp.
void
SetUp
()
{
std
::
vector
<
std
::
string
>
libraries
=
HooksManager
::
getLibraryNames
();
ASSERT_TRUE
(
libraries
.
empty
());
}
// Checks if global parameter of name have expected_value
void
checkGlobalUint32
(
string
name
,
uint32_t
expected_value
)
{
const
Uint32StoragePtr
uint32_defaults
=
...
...
@@ -78,6 +93,10 @@ public:
~
Dhcp4ParserTest
()
{
resetConfiguration
();
// ... and delete the hooks library marker files if present
unlink
(
LOAD_MARKER_FILE
);
unlink
(
UNLOAD_MARKER_FILE
);
};
/// @brief Create the simple configuration with single option.
...
...
@@ -236,56 +255,81 @@ public:
expected_data_len
));
}
/// @brief
Reset
configuration
database.
/// @brief
Parse and Execute
configuration
///
/// This function resets configuration data base by
/// removing all subnets and option-data. Reset must
/// be performed after each test to make sure that
/// contents of the database do not affect result of
/// subsequent tests.
void
resetConfiguration
()
{
/// Parses a configuration and executes a configuration of the server.
/// If the operation fails, the current test will register a failure.
///
/// @param config Configuration to parse
/// @param operation Operation being performed. In the case of an error,
/// the error text will include the string "unable to <operation>.".
///
/// @return true if the configuration succeeded, false if not. In the
/// latter case, a failure will have been added to the current test.
bool
executeConfiguration
(
const
std
::
string
&
config
,
const
char
*
operation
)
{
ConstElementPtr
status
;
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000, "
"
\"
subnet4
\"
: [ ], "
"
\"
option-def
\"
: [ ], "
"
\"
option-data
\"
: [ ] }"
;
try
{
ElementPtr
json
=
Element
::
fromJSON
(
config
);
status
=
configureDhcp4Server
(
*
srv_
,
json
);
}
catch
(
const
std
::
exception
&
ex
)
{
FAIL
()
<<
"Fatal error: unable to reset configuration database"
<<
" after the test. The following configuration was used"
<<
" to reset database: "
<<
std
::
endl
ADD_FAILURE
()
<<
"Unable to "
<<
operation
<<
". "
<<
"The following configuration was used: "
<<
std
::
endl
<<
config
<<
std
::
endl
<<
" and the following error message was returned:"
<<
ex
.
what
()
<<
std
::
endl
;
return
(
false
);
}
// status object must not be NULL
//
The
status object must not be NULL
if
(
!
status
)
{
FAIL
()
<<
"
Fatal error: unable to reset configuration database
"
<<
"
after the test. C
onfiguration function returned
"
<<
" NULL pointer"
<<
std
::
endl
;
ADD_
FAIL
URE
()
<<
"
Unable to "
<<
operation
<<
".
"
<<
"
The c
onfiguration function returned
a null pointer."
;
return
(
false
)
;
}
// Store the answer if we need it.
// Returned value should be 0 (configuration success)
comment_
=
parseAnswer
(
rcode_
,
status
);
// returned value should be 0 (configuration success)
if
(
rcode_
!=
0
)
{
FAIL
()
<<
"Fatal error: unable to reset configuration database"
<<
" after the test. Configuration function returned"
<<
" error code "
<<
rcode_
<<
std
::
endl
;
string
reason
=
""
;
if
(
comment_
)
{
reason
=
string
(
" ("
)
+
comment_
->
stringValue
()
+
string
(
")"
);
}
ADD_FAILURE
()
<<
"Unable to "
<<
operation
<<
". "
<<
"The configuration function returned error code "
<<
rcode_
<<
reason
;
return
(
false
);
}
return
(
true
);
}
/// @brief Reset configuration database.
///
/// This function resets configuration data base by
/// removing all subnets and option-data. Reset must
/// be performed after each test to make sure that
/// contents of the database do not affect result of
/// subsequent tests.
void
resetConfiguration
()
{
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
hooks-libraries
\"
: [ ], "
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000, "
"
\"
subnet4
\"
: [ ], "
"
\"
option-def
\"
: [ ], "
"
\"
option-data
\"
: [ ] }"
;
static_cast
<
void
>
(
executeConfiguration
(
config
,
"reset configuration database"
));
}
boost
::
scoped_ptr
<
Dhcpv4Srv
>
srv_
;
int
rcode_
;
ConstElementPtr
comment_
;
boost
::
scoped_ptr
<
Dhcpv4Srv
>
srv_
;
// DHCP4 server under test
int
rcode_
;
// Return code from element parsing
ConstElementPtr
comment_
;
// Reason for parse fail
};
// Goal of this test is a verification if a very simple config update
...
...
@@ -1750,6 +1794,147 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
EXPECT_FALSE
(
desc
.
option
->
getOption
(
3
));
}
// Tests of the hooks libraries configuration. All tests have the pre-
// condition (checked in the test fixture's SetUp() method) that no hooks
// libraries are loaded at the start of the tests.
// Helper function to return a configuration containing an arbitrary number
// of hooks libraries.
std
::
string
buildHooksLibrariesConfig
(
const
std
::
vector
<
std
::
string
>&
libraries
)
{
const
string
quote
(
"
\"
"
);
// Create the first part of the configuration string.
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
hooks-libraries
\"
: ["
;
// Append the libraries (separated by commas if needed)
for
(
int
i
=
0
;
i
<
libraries
.
size
();
++
i
)
{
if
(
i
>
0
)
{
config
+=
string
(
", "
);
}
config
+=
(
quote
+
libraries
[
i
]
+
quote
);
}
// Append the remainder of the configuration.
config
+=
string
(
"],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
"
\"
name
\"
:
\"
dhcp-message
\"
,"
"
\"
space
\"
:
\"
dhcp4
\"
,"
"
\"
code
\"
: 56,"
"
\"
data
\"
:
\"
AB CDEF0105
\"
,"
"
\"
csv-format
\"
: False"
" },"
" {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
code
\"
: 56,"
"
\"
data
\"
:
\"
1234
\"
,"
"
\"
csv-format
\"
: True"
" } ],"
"
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
code
\"
: 56,"
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ],"
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.2.1 - 192.0.2.100
\"
],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
"
" } ]"
"}"
);
return
(
config
);
}
// Convenience function for creating hooks library configuration with one or
// two character string constants.
std
::
string
buildHooksLibrariesConfig
(
const
char
*
library1
=
NULL
,
const
char
*
library2
=
NULL
)
{
std
::
vector
<
std
::
string
>
libraries
;
if
(
library1
!=
NULL
)
{
libraries
.
push_back
(
string
(
library1
));
if
(
library2
!=
NULL
)
{
libraries
.
push_back
(
string
(
library2
));
}
}
return
(
buildHooksLibrariesConfig
(
libraries
));
}
// The goal of this test is to verify the configuration of hooks libraries if
// none are specified.
TEST_F
(
Dhcp4ParserTest
,
NoHooksLibraries
)
{
// Parse a configuration containing no names.
string
config
=
buildHooksLibrariesConfig
();
if
(
!
executeConfiguration
(
config
,
"set configuration with no hooks libraries"
))
{
FAIL
()
<<
"Unable to execute configuration"
;
}
else
{
// No libraries should be loaded at the end of the test.
std
::
vector
<
std
::
string
>
libraries
=
HooksManager
::
getLibraryNames
();
EXPECT_TRUE
(
libraries
.
empty
());
}
}
// Verify parsing fails with one library that will fail validation.
TEST_F
(
Dhcp4ParserTest
,
InvalidLibrary
)
{
// Parse a configuration containing a failing library.
string
config
=
buildHooksLibrariesConfig
(
NOT_PRESENT_LIBRARY
);
ConstElementPtr
status
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
ASSERT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
// The status object must not be NULL
ASSERT_TRUE
(
status
);
// Returned value should not be 0
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_NE
(
0
,
rcode_
);
}
// Verify the configuration of hooks libraries with two being specified.
TEST_F
(
Dhcp4ParserTest
,
LibrariesSpecified
)
{
// Marker files should not be present.