mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#1405] added parser class
This commit is contained in:
@@ -4853,7 +4853,15 @@ following can be used:
|
||||
"valid-lifetime": 600,
|
||||
"subnet4": [ {
|
||||
"subnet": "10.0.0.0/24",
|
||||
"reservation-mode": "global",
|
||||
# It is deprecated by the "reservation-modes" map.
|
||||
# "reservation-mode": "global",
|
||||
# Reservation modes specifying server's mode of operation when it
|
||||
# fetches host reservations.
|
||||
"reservation-modes": {
|
||||
"global": True,
|
||||
"in-subnet": False,
|
||||
"out-of-pool": False
|
||||
},
|
||||
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ]
|
||||
} ]
|
||||
}
|
||||
@@ -4956,7 +4964,15 @@ following example:
|
||||
"hw-address": "aa:bb:cc:dd:ee:fe",
|
||||
"client-classes": [ "reserved_class" ]
|
||||
}],
|
||||
"reservation-mode": "global",
|
||||
# It is deprecated by the "reservation-modes" map.
|
||||
# "reservation-mode": "global",
|
||||
# Reservation modes specifying server's mode of operation when it
|
||||
# fetches host reservations.
|
||||
"reservation-modes": {
|
||||
"global": True,
|
||||
"in-subnet": False,
|
||||
"out-of-pool": False
|
||||
},
|
||||
"shared-networks": [{
|
||||
"subnet4": [
|
||||
{
|
||||
|
@@ -4294,7 +4294,15 @@ following can be used:
|
||||
"valid-lifetime": 600,
|
||||
"subnet4": [ {
|
||||
"subnet": "2001:db8:1::/64",
|
||||
"reservation-mode": "global",
|
||||
# It is deprecated by the "reservation-modes" map.
|
||||
# "reservation-mode": "global",
|
||||
# Reservation modes specifying server's mode of operation when it
|
||||
# fetches host reservations.
|
||||
"reservation-modes": {
|
||||
"global": True,
|
||||
"in-subnet": False,
|
||||
"out-of-pool": False
|
||||
},
|
||||
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ]
|
||||
} ]
|
||||
}
|
||||
@@ -4397,7 +4405,15 @@ following example:
|
||||
"hw-address": "aa:bb:cc:dd:ee:fe",
|
||||
"client-classes": [ "reserved_class" ]
|
||||
}],
|
||||
"reservation-mode": "global",
|
||||
# It is deprecated by the "reservation-modes" map.
|
||||
# "reservation-mode": "global",
|
||||
# Reservation modes specifying server's mode of operation when it
|
||||
# fetches host reservations.
|
||||
"reservation-modes": {
|
||||
"global": True,
|
||||
"in-subnet": False,
|
||||
"out-of-pool": False
|
||||
},
|
||||
"shared-networks": [{
|
||||
"subnet6": [
|
||||
{
|
||||
|
@@ -2655,7 +2655,15 @@ An example response could look as follows:
|
||||
"ip-address": "0.0.0.0"
|
||||
},
|
||||
"renew-timer": 60,
|
||||
"reservation-mode": "all",
|
||||
# It is deprecated by the "reservation-modes" map.
|
||||
# "reservation-mode": "all",
|
||||
# Reservation modes specifying server's mode of operation when it
|
||||
# fetches host reservations.
|
||||
"reservation-modes": {
|
||||
"global": False,
|
||||
"in-subnet": True,
|
||||
"out-of-pool": True
|
||||
},
|
||||
"subnet4": [
|
||||
{
|
||||
"subnet": "192.0.2.0/24",
|
||||
|
@@ -564,6 +564,15 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||
if (reservation_mode) {
|
||||
reservation_mode = mutable_cfg->get("reservation-modes");
|
||||
if (reservation_mode) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and 'reservation-modes' parameters");
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
||||
if (config_control) {
|
||||
parameter_name = "config-control";
|
||||
@@ -628,6 +637,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
(config_pair.first == "boot-file-name") ||
|
||||
(config_pair.first == "server-tag") ||
|
||||
(config_pair.first == "reservation-mode") ||
|
||||
(config_pair.first == "reservation-modes") ||
|
||||
(config_pair.first == "calculate-tee-times") ||
|
||||
(config_pair.first == "t1-percent") ||
|
||||
(config_pair.first == "t2-percent") ||
|
||||
|
@@ -184,6 +184,8 @@ Parser4Context::contextName()
|
||||
return ("subnet4");
|
||||
case RESERVATION_MODE:
|
||||
return ("reservation-mode");
|
||||
case RESERVATION_MODES:
|
||||
return ("reservation-modes");
|
||||
case OPTION_DEF:
|
||||
return ("option-def");
|
||||
case OPTION_DATA:
|
||||
|
@@ -84,7 +84,7 @@ public:
|
||||
/// This will parse the input as hooks-library.
|
||||
PARSER_HOOKS_LIBRARY,
|
||||
|
||||
/// This will parse the input as dhcp-ddns.
|
||||
/// This will parse the input as dhcp-ddns. (D2 client config)
|
||||
PARSER_DHCP_DDNS,
|
||||
|
||||
/// This will parse the input as reservation-modes.
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
/// Check if a required parameter is present in the map at the top
|
||||
/// of the stack and raise an error when it is not.
|
||||
///
|
||||
/// @param name name of the parameter to check
|
||||
/// @param name name of the parameter expected to be present
|
||||
/// @param open_loc location of the opening curly bracket
|
||||
/// @param close_loc location of the closing curly bracket
|
||||
/// @throw Dhcp4ParseError
|
||||
|
@@ -688,6 +688,15 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||
if (reservation_mode) {
|
||||
reservation_mode = mutable_cfg->get("reservation-modes");
|
||||
if (reservation_mode) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and 'reservation-modes' parameters");
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
||||
if (config_control) {
|
||||
parameter_name = "config-control";
|
||||
@@ -761,6 +770,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
(config_pair.first == "dhcp4o6-port") ||
|
||||
(config_pair.first == "server-tag") ||
|
||||
(config_pair.first == "reservation-mode") ||
|
||||
(config_pair.first == "reservation-modes") ||
|
||||
(config_pair.first == "calculate-tee-times") ||
|
||||
(config_pair.first == "t1-percent") ||
|
||||
(config_pair.first == "t2-percent") ||
|
||||
|
@@ -181,6 +181,8 @@ Parser6Context::contextName()
|
||||
return ("subnet6");
|
||||
case RESERVATION_MODE:
|
||||
return ("reservation-mode");
|
||||
case RESERVATION_MODES:
|
||||
return ("reservation-modes");
|
||||
case OPTION_DEF:
|
||||
return ("option-def");
|
||||
case OPTION_DATA:
|
||||
|
@@ -360,7 +360,7 @@
|
||||
// specific options.
|
||||
//
|
||||
// When using reservations, it is useful to configure
|
||||
// reservation-mode (subnet specific parameter) and
|
||||
// reservation-modes (subnet specific parameter) and
|
||||
// host-reservation-identifiers (global parameter).
|
||||
{
|
||||
"client-id": "01:12:23:34:45:56:67",
|
||||
|
@@ -45,6 +45,8 @@ EXTRA_DIST += parsers/ifaces_config_parser.h
|
||||
EXTRA_DIST += parsers/multi_threading_config_parser.cc
|
||||
EXTRA_DIST += parsers/multi_threading_config_parser.h
|
||||
EXTRA_DIST += parsers/option_data_parser.h
|
||||
EXTRA_DIST += parsers/reservation_modes_parser.cc
|
||||
EXTRA_DIST += parsers/reservation_modes_parser.h
|
||||
EXTRA_DIST += parsers/sanity_checks_parser.cc
|
||||
EXTRA_DIST += parsers/sanity_checks_parser.h
|
||||
EXTRA_DIST += parsers/simple_parser4.cc
|
||||
@@ -178,6 +180,8 @@ libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.cc
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.h
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.cc
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.h
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.cc
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.h
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.cc
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.h
|
||||
libkea_dhcpsrv_la_SOURCES += parsers/shared_network_parser.cc
|
||||
@@ -408,6 +412,7 @@ libkea_dhcpsrv_parsers_include_HEADERS = \
|
||||
parsers/multi_threading_config_parser.h \
|
||||
parsers/option_data_parser.h \
|
||||
parsers/dhcp_queue_control_parser.h \
|
||||
parsers/reservation_modes_parser.h \
|
||||
parsers/sanity_checks_parser.h \
|
||||
parsers/shared_network_parser.h \
|
||||
parsers/shared_networks_list_parser.h \
|
||||
|
@@ -155,7 +155,7 @@ public:
|
||||
|
||||
/// @brief Specifies allowed host reservation mode.
|
||||
///
|
||||
typedef enum {
|
||||
typedef enum : uint8_t {
|
||||
|
||||
/// None - host reservation is disabled. No reservation types
|
||||
/// are allowed.
|
||||
@@ -181,7 +181,10 @@ public:
|
||||
/// AllocEngine code has to check whether there are reservations, even
|
||||
/// when dealing with reservations from within the dynamic pools.
|
||||
HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL
|
||||
} HRMode;
|
||||
} HRModeFlag;
|
||||
|
||||
/// @brief Bitset used to store @ref HRModeFlag flags.
|
||||
typedef uint8_t HRMode;
|
||||
|
||||
/// @brief Inheritance "mode" used when fetching an optional @c Network
|
||||
/// parameter.
|
||||
@@ -811,14 +814,39 @@ protected:
|
||||
template<typename ReturnType>
|
||||
ReturnType getGlobalProperty(ReturnType property,
|
||||
const std::string& global_name) const {
|
||||
if (!global_name.empty() && fetch_globals_fn_) {
|
||||
std::string member_name;
|
||||
std::string search_name = global_name;
|
||||
auto found = global_name.find('.');
|
||||
if (found != std::string::npos) {
|
||||
if (std::count(global_name.begin(), global_name.end(), '.') > 1) {
|
||||
isc_throw(BadValue, "more than one level of indirection found in: "
|
||||
<< global_name);
|
||||
}
|
||||
member_name = global_name.substr(found + 1, global_name.length() - found - 1);
|
||||
search_name = global_name.substr(0, found);
|
||||
}
|
||||
if (!search_name.empty() && fetch_globals_fn_) {
|
||||
data::ConstElementPtr globals = fetch_globals_fn_();
|
||||
if (globals && (globals->getType() == data::Element::map)) {
|
||||
data::ConstElementPtr global_param = globals->get(global_name);
|
||||
data::ConstElementPtr global_param = globals->get(search_name);
|
||||
if (global_param) {
|
||||
// If there is a global parameter, convert it to the
|
||||
// optional value of the given type and return.
|
||||
return (data::ElementValue<typename ReturnType::ValueType>()(global_param));
|
||||
if (!member_name.empty()) {
|
||||
if (global_param->getType() != data::Element::map) {
|
||||
isc_throw(BadValue, "the parameter: " << global_name
|
||||
<< " must be a map");
|
||||
}
|
||||
auto member_element = global_param->get(member_name);
|
||||
if (member_element) {
|
||||
// If there is a global parameter with the specified
|
||||
// member, convert the member to the optional value
|
||||
// of the given type and return.
|
||||
return (data::ElementValue<typename ReturnType::ValueType>()(member_element));
|
||||
}
|
||||
} else {
|
||||
// If there is a global parameter, convert it to the
|
||||
// optional value of the given type and return.
|
||||
return (data::ElementValue<typename ReturnType::ValueType>()(global_param));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <config.h>
|
||||
#include <dhcpsrv/triplet.h>
|
||||
#include <dhcpsrv/parsers/base_network_parser.h>
|
||||
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||
#include <util/optional.h>
|
||||
#include <util/strutil.h>
|
||||
|
||||
@@ -201,6 +202,10 @@ void
|
||||
BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
if (network_data->contains("reservation-mode")) {
|
||||
if (network_data->contains("reservation-modes")) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and 'reservation-modes' parameters");
|
||||
}
|
||||
try {
|
||||
std::string hr_mode = getString(network_data, "reservation-mode");
|
||||
network->setHostReservationMode(Network::hrModeFromString(hr_mode));
|
||||
@@ -212,6 +217,27 @@ BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseNetworkParser::parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
if (network_data->contains("reservation-modes")) {
|
||||
if (network_data->contains("reservation-mode")) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and 'reservation-modes' parameters");
|
||||
}
|
||||
try {
|
||||
auto reservation_modes = network_data->get("reservation-modes");
|
||||
HostReservationModesParser parser;
|
||||
Network::HRMode flags = parser.parse(reservation_modes);
|
||||
network->setHostReservationMode(flags);
|
||||
} catch (const BadValue& ex) {
|
||||
isc_throw(DhcpConfigError, "invalid reservation-modes parameter: "
|
||||
<< ex.what() << " (" << getPosition("reservation-modes",
|
||||
network_data) << ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
|
@@ -80,6 +80,9 @@ protected:
|
||||
|
||||
/// @brief Parses host reservation mode.
|
||||
///
|
||||
/// @note Configuring 'reservation-mode' is deprecated. The new map
|
||||
/// 'reservation-modes' should be used.
|
||||
///
|
||||
/// @param network_data Data element holding shared network
|
||||
/// configuration to be parsed.
|
||||
/// @param [out] network Pointer to a network in which parsed data is
|
||||
@@ -87,6 +90,15 @@ protected:
|
||||
void parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network);
|
||||
|
||||
/// @brief Parses host reservation modes.
|
||||
///
|
||||
/// @param network_data Data element holding shared network
|
||||
/// configuration to be parsed.
|
||||
/// @param [out] network Pointer to a network in which parsed data is
|
||||
/// to be stored.
|
||||
void parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network);
|
||||
|
||||
/// @brief Parses parameters pertaining to DDNS behavior.
|
||||
///
|
||||
/// The parsed parameters are:
|
||||
|
@@ -859,7 +859,11 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
}
|
||||
}
|
||||
|
||||
// Let's set host reservation mode.
|
||||
// reservation-modes
|
||||
parseHostReservationModes(params, network);
|
||||
|
||||
// Let's set host reservation mode. If not specified, the default value of
|
||||
// all will be used.
|
||||
parseHostReservationMode(params, network);
|
||||
|
||||
// Try setting up client class.
|
||||
@@ -1330,6 +1334,9 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
subnet6->setIface(iface);
|
||||
}
|
||||
|
||||
// reservation-modes
|
||||
parseHostReservationModes(params, network);
|
||||
|
||||
// Let's set host reservation mode. If not specified, the default value of
|
||||
// all will be used.
|
||||
parseHostReservationMode(params, network);
|
||||
|
59
src/lib/dhcpsrv/parsers/reservation_modes_parser.cc
Normal file
59
src/lib/dhcpsrv/parsers/reservation_modes_parser.cc
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2015-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 <cc/data.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/dhcpsrv_log.h>
|
||||
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
using namespace isc::data;
|
||||
using namespace isc::util;
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
Network::HRMode
|
||||
HostReservationModesParser::parse(const ConstElementPtr& control_elem) {
|
||||
if (control_elem->getType() != Element::map) {
|
||||
isc_throw(DhcpConfigError, "reservation-modes must be a map");
|
||||
}
|
||||
|
||||
ConstElementPtr elem;
|
||||
uint8_t flags = 0;
|
||||
|
||||
elem = control_elem->get("global");
|
||||
if (elem) {
|
||||
bool value = elem->boolValue();
|
||||
if (value) {
|
||||
flags |= Network::HR_GLOBAL;
|
||||
}
|
||||
}
|
||||
|
||||
elem = control_elem->get("in-subnet");
|
||||
if (elem) {
|
||||
bool value = elem->boolValue();
|
||||
if (value) {
|
||||
flags |= Network::HR_IN_SUBNET;
|
||||
}
|
||||
}
|
||||
|
||||
elem = control_elem->get("out-of-pool");
|
||||
if (elem) {
|
||||
bool value = elem->boolValue();
|
||||
if (value) {
|
||||
flags |= Network::HR_OUT_OF_POOL;
|
||||
}
|
||||
}
|
||||
|
||||
return (static_cast<Network::HRMode>(flags));
|
||||
}
|
||||
|
||||
} // end of namespace isc::dhcp
|
||||
} // end of namespace isc
|
46
src/lib/dhcpsrv/parsers/reservation_modes_parser.h
Normal file
46
src/lib/dhcpsrv/parsers/reservation_modes_parser.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2018 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/.
|
||||
|
||||
#ifndef RESERVATION_MODES_PARSER_H
|
||||
#define RESERVATION_MODES_PARSER_H
|
||||
|
||||
#include <cc/data.h>
|
||||
#include <cc/simple_parser.h>
|
||||
#include <dhcpsrv/network.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// @brief Parser for the configuration of DHCP packet queue controls
|
||||
///
|
||||
/// This parser parses the "reservation-modes" parameter which holds the
|
||||
/// the configurable parameters that tailor host reservation modes.
|
||||
///
|
||||
/// This parser is used in both DHCPv4 and DHCPv6, and also inside subnet and
|
||||
/// shared networks.
|
||||
class HostReservationModesParser : public isc::data::SimpleParser {
|
||||
public:
|
||||
|
||||
/// @brief Constructor
|
||||
///
|
||||
HostReservationModesParser(){};
|
||||
|
||||
/// @brief Parses content of the "reservation-modes".
|
||||
///
|
||||
/// @param control_elem MapElement containing the host reservation modes
|
||||
/// values to parse
|
||||
///
|
||||
/// @return Host reservation modes flags.
|
||||
///
|
||||
/// @throw DhcpConfigError if any of the values are invalid.
|
||||
Network::HRMode parse(const isc::data::ConstElementPtr& control_elem);
|
||||
};
|
||||
|
||||
}
|
||||
} // end of namespace isc
|
||||
|
||||
#endif // RESERVATION_MODES_PARSER_H
|
@@ -185,6 +185,9 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
// reservation-modes
|
||||
parseHostReservationModes(shared_network_data, network);
|
||||
|
||||
// reservation-mode
|
||||
parseHostReservationMode(shared_network_data, network);
|
||||
|
||||
@@ -351,6 +354,9 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
// reservation-modes
|
||||
parseHostReservationModes(shared_network_data, network);
|
||||
|
||||
// reservation-mode
|
||||
parseHostReservationMode(shared_network_data, network);
|
||||
|
||||
|
@@ -87,6 +87,7 @@ libdhcpsrv_unittests_SOURCES += csv_lease_file6_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += dhcp_queue_control_parser_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += reservation_modes_parser_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += dhcp4o6_ipc_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += duid_config_parser_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += expiration_config_parser_unittest.cc
|
||||
|
@@ -48,7 +48,7 @@ DHCPQueueControlParserTest::TearDown() {
|
||||
}
|
||||
|
||||
// Verifies that DHCPQueueControlParser handles
|
||||
// expected valid dhcp-queue-control contet
|
||||
// expected valid dhcp-queue-control content
|
||||
TEST_F(DHCPQueueControlParserTest, validContent) {
|
||||
struct Scenario {
|
||||
std::string description_;
|
||||
@@ -153,9 +153,8 @@ TEST_F(DHCPQueueControlParserTest, invalidContent) {
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over the valid scenarios and verify they succeed.
|
||||
// Iterate over the invalid scenarios and verify they throw exception.
|
||||
ConstElementPtr config_elems;
|
||||
ConstElementPtr queue_control;
|
||||
for (auto scenario : scenarios) {
|
||||
SCOPED_TRACE(scenario.description_);
|
||||
{
|
||||
|
165
src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc
Normal file
165
src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright (C) 2018-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 <cc/data.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||
#include <testutils/test_to_element.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::test;
|
||||
using namespace isc::util;
|
||||
|
||||
namespace {
|
||||
|
||||
/// @brief Test fixture class for @c HostReservationModesParser
|
||||
class HostReservationModesParserTest : public ::testing::Test {
|
||||
protected:
|
||||
|
||||
/// @brief Setup for each test.
|
||||
///
|
||||
/// Clears the configuration in the @c CfgMgr.
|
||||
virtual void SetUp();
|
||||
|
||||
/// @brief Cleans up after each test.
|
||||
///
|
||||
/// Clears the configuration in the @c CfgMgr.
|
||||
virtual void TearDown();
|
||||
|
||||
};
|
||||
|
||||
void
|
||||
HostReservationModesParserTest::SetUp() {
|
||||
CfgMgr::instance().clear();
|
||||
}
|
||||
|
||||
void
|
||||
HostReservationModesParserTest::TearDown() {
|
||||
CfgMgr::instance().clear();
|
||||
}
|
||||
|
||||
// Verifies that HostReservationModesParser handles
|
||||
// expected valid reservation-modes content
|
||||
TEST_F(HostReservationModesParserTest, validContent) {
|
||||
struct Scenario {
|
||||
std::string description_;
|
||||
std::string json_;
|
||||
};
|
||||
|
||||
std::vector<Scenario> scenarios = {
|
||||
{
|
||||
"queue disabled",
|
||||
"{ \n"
|
||||
" \"enable-queue\": false \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"queue disabled, arbitrary content allowed",
|
||||
"{ \n"
|
||||
" \"enable-queue\": false, \n"
|
||||
" \"foo\": \"bogus\", \n"
|
||||
" \"random-int\" : 1234 \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"queue enabled, with queue-type",
|
||||
"{ \n"
|
||||
" \"enable-queue\": true, \n"
|
||||
" \"queue-type\": \"some-type\" \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"queue enabled with queue-type and arbitrary content",
|
||||
"{ \n"
|
||||
" \"enable-queue\": true, \n"
|
||||
" \"queue-type\": \"some-type\", \n"
|
||||
" \"foo\": \"bogus\", \n"
|
||||
" \"random-int\" : 1234 \n"
|
||||
"} \n"
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over the valid scenarios and verify they succeed.
|
||||
ConstElementPtr config_elems;
|
||||
Network::HRMode reservation_modes;
|
||||
for (auto scenario : scenarios) {
|
||||
SCOPED_TRACE(scenario.description_);
|
||||
{
|
||||
// Construct the config JSON
|
||||
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
|
||||
<< "invalid JSON, test is broken";
|
||||
|
||||
// Parsing config into a reservation modes parser should succeed.
|
||||
HostReservationModesParser parser;
|
||||
try {
|
||||
reservation_modes = parser.parse(config_elems);
|
||||
} catch (const std::exception& ex) {
|
||||
ADD_FAILURE() << "parser threw an exception: " << ex.what();
|
||||
}
|
||||
|
||||
// Verify the resultant reservation-modes.
|
||||
ASSERT_TRUE(reservation_modes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that HostReservationModesParser correctly catches
|
||||
// invalid reservation-modes content
|
||||
TEST_F(HostReservationModesParserTest, invalidContent) {
|
||||
struct Scenario {
|
||||
std::string description_;
|
||||
std::string json_;
|
||||
};
|
||||
|
||||
std::vector<Scenario> scenarios = {
|
||||
{
|
||||
"enable-queue missing",
|
||||
"{ \n"
|
||||
" \"enable-type\": \"some-type\" \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"enable-queue not boolean",
|
||||
"{ \n"
|
||||
" \"enable-queue\": \"always\" \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"queue enabled, type missing",
|
||||
"{ \n"
|
||||
" \"enable-queue\": true \n"
|
||||
"} \n"
|
||||
},
|
||||
{
|
||||
"queue enabled, type not a string",
|
||||
"{ \n"
|
||||
" \"enable-queue\": true, \n"
|
||||
" \"queue-type\": 7777 \n"
|
||||
"} \n"
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over the invalid scenarios and verify they throw exception.
|
||||
ConstElementPtr config_elems;
|
||||
for (auto scenario : scenarios) {
|
||||
SCOPED_TRACE(scenario.description_);
|
||||
{
|
||||
// Construct the config JSON
|
||||
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
|
||||
<< "invalid JSON, test is broken";
|
||||
|
||||
// Parsing config into a reservation modes parser should succeed.
|
||||
HostReservationModesParser parser;
|
||||
EXPECT_THROW(parser.parse(config_elems), DhcpConfigError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // anonymous namespace
|
Reference in New Issue
Block a user