custom values, referred to as ``binding-variables``,
within the lease's ``user-context``. Supported
in both kea-dhcp4 and kea-dhcp6.
- Gitlab #3463)
+ (Gitlab #3463)
provides a non-programmatic way to manage user contexts associated with
leases.
-As of Kea 2.7.7, the library also provides support for ``binding-varriables``. Binding
+As of Kea 2.7.7, the library also provides support for ``binding-variables``. Binding
variables allow the user to store custom values for each lease. They are discussed here:
:ref:`binding-variables`.
{
"hooks-libraries": [{
- "library": "lib/kea/hooks/libdhcp_lease_cmds.so",
+ "library": "/path/libdhcp_lease_cmds.so"
"parameters": {
"binding-variables": [{
"name": "opt-222",
- @b Arguments:
- name: @b query4, type: isc::dhcp::Pkt4Ptr, direction: <b>in</b>
+ - name: @b response4, type: isc::dhcp::Pkt4Ptr, direction: <b>in</b>
- name: @b leases4, type: isc::dhcp::Lease4CollectionPtr, direction: <b>in</b>
- name: @b deleted_leases4, type: isc::dhcp::Lease4CollectionPtr, direction: <b>in</b>
- @b Arguments:
- name: @b query4, type: isc::dhcp::Pkt4Ptr, direction: <b>in</b>
+ - name: @b response4, type: isc::dhcp::Pkt4Ptr, direction: <b>in</b>
- name: @b leases4, type: isc::dhcp::Lease4CollectionPtr, direction: <b>in</b>
- name: @b offer_lifetime, type: uint32_t, direction: <b>in</b>
- name: @b old_lease, type: isc::dhcp::Lease4Ptr, direction: <b>in</b>
DHCPDISCOVER from the client and the DHCPOFFER has been constructed but not
yet sent back. The argument "query4" contains a pointer to an isc::dhcp::Pkt4
object that contains all information regarding incoming DHCPDISCOVER packet.
+ The "response4" argument contains a pointer to an isc::dhcp::Pkt4 object that
+ contains all information regarding the outgoing::DHCPOFFER packet.
The "leases4" object will hold the pointer to the new candidate lease for this
client. The "offer_lifetime" argument comes from the context information for the
DHCPv4 lease allocation. If "offer_lifetime" is not zero, it indicates that temporary
- @b Arguments:
- name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in</b>
+ - name: @b response6, type: isc::dhcp::Pkt6Ptr, direction: <b>in</b>
- name: @b leases6, type: isc::dhcp::Lease6CollectionPtr, direction: <b>in</b>
- name: @b deleted_leases6, type: isc::dhcp::Lease6CollectionPtr, direction: <b>in</b>
const data::SimpleKeywords
BindingVariable::CONFIG_KEYWORDS =
{
- {"name", Element::string},
- {"expression", Element::string},
- {"source", Element::string}
+ { "name", Element::string },
+ { "expression", Element::string },
+ { "source", Element::string }
};
BindingVariablePtr
return (BaseStampedElement::getModificationTime());
}
-/// @brief Tag for the name index.
-//struct VariableNameTag { };
-
-/// @brief Tag for the source index.
-//struct VariableSourceTag { };
-
-
BindingVariableListPtr
BindingVariableCache::getAll() {
util::MultiThreadingLock lock(*mutex_);
const auto& index = variables_.get<VariableSequenceTag>();
for (auto const& variable : index) {
/// For now we'll return the pointer, w/o making a copy
- /// of the varaiable itself. We never updates variables
+ /// of the variable itself. We never updates variables
/// so we should be OK.
var_list->push_back(variable);
}
namespace isc {
namespace lease_cmds {
-
// Forward declaration for pointer.
class BindingVariable;
/// protocol family.
/// @throw BadValue if name if empty, or expression string fails
/// to parse.
- explicit BindingVariable(const std::string& name,
- const std::string& expression_str,
- const Source& source,
- uint32_t family);
+ BindingVariable(const std::string& name,
+ const std::string& expression_str,
+ const Source& source,
+ uint32_t family);
/// @brief Destructor
virtual ~BindingVariable() = default;
///
/// @param config Map Element containing parameters for a single binding variable.
/// @param family Protocol family of the variable, either AF_INET or AF_INET6.
- /// @return Pointer to the newly created BindingVariable instacne.
+ /// @return Pointer to the newly created BindingVariable instance.
/// @throw DhcpConfigError if configuration parameters are invalid.
static BindingVariablePtr parse(data::ConstElementPtr config, uint16_t family);
std::string,
&BindingVariable::getName>
>,
-
// Third index is by source.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<VariableSourceTag>,
/// @brief Defines a shared pointer to a BindingVariableCache.
typedef boost::shared_ptr<BindingVariableCache> BindingVariableCachePtr;
-/// @brief Singleton which warehouses the configuraed binding variables,
+/// @brief Singleton which warehouses the configured binding variables,
/// and evaluation of variables for a given lease and packet pair.
class BindingVariableMgr {
public:
///
/// @param family Protocol family of the expression, either
/// AF_INET or AF_INET6.
- explicit BindingVariableMgr(uint32_t family_);
+ explicit BindingVariableMgr(uint32_t family);
/// @brief Destructor;
~BindingVariableMgr() = default;
/// @param response Server response conveying the lease. Variables whose source
/// is "response" will be evaluated against this packet.
/// @param lease Lease whose use-context will be updated with the evaluation
- /// results. If the results of the evaluation are idnentical the the lease's
- /// exising binding-variables value, the lease is not altered. This allows
+ /// results. If the results of the evaluation are identical the the lease's
+ /// existing binding-variables value, the lease is not altered. This allows
/// a subsequent lease store update to only occur when needed.
/// @return True if the lease's user-context was udpated, false otherwise.
bool evaluateVariables(dhcp::PktPtr query, dhcp::PktPtr response,
/// user-context accordingly. This includes updating the lease in the lease
/// back end.
///
- /// @param handle Callout context - which is expected to contain the query4,
+ /// @param callout_handle Callout context - which is expected to contain the query4,
/// response4, leases4, offer_lifetime arguments.
/// @param mgr Pointer to the BindingVariableMgr singleton.
/// @throw Unexpected if there is no active lease or a processing error
/// user-context accordingly. This includes updating the lease in the lease
/// back end.
///
- /// @param handle Callout context - which is expected to contain the query4,
+ /// @param callout_handle Callout context - which is expected to contain the query4,
/// response4, and leases4 arguments.
/// @param mgr Pointer to the BindingVariableMgr singleton.
/// @throw Unexpected if a processing error occurs. LeaseCmdsConflict if the
/// user-context accordingly. This includes updating the leases in the lease
/// back end.
///
- /// @param handle Callout context - which is expected to contain the query6,
+ /// @param callout_handle Callout context - which is expected to contain the query6,
/// response6, and leases6 arguments.
/// @param mgr Pointer to the BindingVariableMgr singleton.
/// @throw Unexpected if there a processing error occurs. LeaseCmdsConflict
callout_handle.getArgument("response4", response);
callout_handle.getArgument("leases4", leases);
- if (leases->empty()) {
+ if (!leases || leases->empty() || !((*leases)[0])) {
isc_throw(Unexpected, "lease4Offer - no lease!");
}
}
Lease4Ptr lease = (*leases)[0];
+ if (!lease) {
+ isc_throw(Unexpected, "leases4Committed - no lease!");
+ }
+
try {
if (mgr->evaluateVariables(query, response, lease)) {
LeaseMgrFactory::instance().updateLease4(lease);
/// @brief lease4_offer hookpoint handler.
///
/// If the offer_lifetime callout argument is 0 the handler simply returns.
- /// Otherwise it will evaluate the binding variables (if any) and update
+ /// Otherwise it will evaluate the binding variables (if any) and update
/// the given lease's user-context accordingly. This includes updating the
/// lease in the lease back end.
///
- /// @param handle Callout context - which is expected to contain the query4, response4,
+ /// @param callout_handle Callout context - which is expected to contain the query4, response4,
/// leases4 arguments, and offer_lifetime.
/// @param mgr Pointer to the BindingVariableMgr singleton.
void
/// user-context accordingly. This includes updating the lease in the lease
/// back end.
///
- /// @param handle Callout context - which is expected to contain the query4, response4,
+ /// @param callout_handle Callout context - which is expected to contain the query4, response4,
/// and leases4 arguments.
/// @param mgr Pointer to the BindingVariableMgr singleton.
void
/// user-context accordingly. This includes updating the leases in the lease
/// back end.
///
- /// @param handle Callout context - which is expected to contain the query6, response6,
+ /// @param callout_handle Callout context - which is expected to contain the query6, response6,
/// and leases6 arguments.
/// @param mgr Pointer to the BindingVariableMgr singleton.
void
// Instantiate the binding-variables manager singleton.
binding_var_mgr.reset(new BindingVariableMgr(family));
- // Configure binding variable manager using the hook library's parameters.
- ConstElementPtr json = handle.getParameters();
- if (json) {
- binding_var_mgr->configure(json);
+ try {
+ // Configure binding variable manager using the hook library's parameters.
+ ConstElementPtr json = handle.getParameters();
+ if (json) {
+ binding_var_mgr->configure(json);
+ }
+ } catch (const std::exception& ex) {
+ LOG_ERROR(lease_cmds_logger, LEASE_CMDS_LOAD_ERROR)
+ .arg(ex.what());
+ return (1);
}
LOG_INFO(lease_cmds_logger, LEASE_CMDS_INIT_OK);
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_CONFLICT = "LEASE_CMDS_LEASES6_COMMITTED_CONFLICT";
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_FAILED = "LEASE_CMDS_LEASES6_COMMITTED_FAILED";
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_LEASE_ERROR = "LEASE_CMDS_LEASES6_COMMITTED_LEASE_ERROR";
+extern const isc::log::MessageID LEASE_CMDS_LOAD_ERROR = "LEASE_CMDS_LOAD_ERROR";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4 = "LEASE_CMDS_RESEND_DDNS4";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED = "LEASE_CMDS_RESEND_DDNS4_FAILED";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6 = "LEASE_CMDS_RESEND_DDNS6";
"LEASE_CMDS_LEASES6_COMMITTED_CONFLICT", "could not updating lease: %1 for: %2",
"LEASE_CMDS_LEASES6_COMMITTED_FAILED", "reason: %1",
"LEASE_CMDS_LEASES6_COMMITTED_LEASE_ERROR", "evaluating binding-variables for lease: %1 for: %2, reason: %3",
+ "LEASE_CMDS_LOAD_ERROR", "loading Lease Commands hooks library failed: %1",
"LEASE_CMDS_RESEND_DDNS4", "lease4-resend-ddns command successful: %1",
"LEASE_CMDS_RESEND_DDNS4_FAILED", "lease4-resend-ddns command failed: %1",
"LEASE_CMDS_RESEND_DDNS6", "lease6-resend-ddns command successful: %1",
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_CONFLICT;
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_FAILED;
extern const isc::log::MessageID LEASE_CMDS_LEASES6_COMMITTED_LEASE_ERROR;
+extern const isc::log::MessageID LEASE_CMDS_LOAD_ERROR;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6;
% LEASE_CMDS_WIPE6_FAILED lease6-wipe command failed (parameters: %1, reason: %2)
The lease6-wipe command has failed. Both the reason as well as the
parameters passed are logged.
+
+% LEASE_CMDS_LOAD_ERROR loading Lease Commands hooks library failed: %1
+This error message indicates an error loading the Lease Commands
+hooks library. The details of the error are provided as argument of
+the log message.
+
/// @brief Check that lease6-write works as expected.
void testLease6Write();
-
-#if 0
- /// @brief Check that leases6_committed handler works as expected with
- /// valid inputs.
- void testValidLeases6Committed();
-
- /// @brief Check that leases6_committed handler does not throw or alter
- /// leases under NOP conditions:
- /// 1. There is no repsonse packet
- /// 2. There are no leases
- /// 3. There are leases but none active
- void testNopLeases6Committed();
-
- void testLeases6CommittedErrors();
-#endif
};
void Lease6CmdsTest::testLease6AddMissingParams() {
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
-#if 0
-void
-Lease6CmdsTest::testValidLeases6Committed() {
- // Initialize lease manager (true = v6, true = add leases)
- initLeaseMgr(true, true);
-
- struct Scenario {
- uint32_t line_;
- std::string config_;
- std::string orig_context_;
- std::string exp_context_;
- };
-
- std::list<Scenario> scenarios = {
- {
- // No variables configured, nothing in lease context.
- __LINE__,
- R"({})",
- R"({})",
- R"({})"
- },
- {
- // Lease context has no binding-variables, two configured.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- },
- {
- "name": "sub-id",
- "expression": "hexstring(option[38].hex, ':')",
- "source": "response"
- }]})^",
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- },
- {
- // Lease context has binding-variables, none configured.
- // Current logic leaves lease untouched.
- __LINE__,
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- },
- {
- // Evaluated variable value is an empty string.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "my-var",
- "expression": "''",
- "source": "query"
- }]})^",
- R"({"ISC":{
- "binding-variables":{
- "my-var": "pre-existing value"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "my-var": ""
- }
- }})",
- }
- };
-
- // Create packet pair and lease.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- Pkt6Ptr response(new Pkt6(DHCPV6_REPLY, 7890));
- OptionPtr subscriber_id(new Option(Option::V6, D6O_SUBSCRIBER_ID,
- { 0x05, 0x06, 0x07, 0x08 }));
- response->addOption(subscriber_id);
-
- // Create a list of the lease addresses.
- std::list<IOAddress> lease_addrs;
- lease_addrs.push_back(IOAddress("2001:db8:1::1"));
- lease_addrs.push_back(IOAddress("2001:db8:1::2"));
- lease_addrs.push_back(IOAddress("2001:db8:2::2"));
-
- // Iterater over scenarios.
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(scenario.config_));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the lease and set its user-context to the original content.
- Lease6CollectionPtr orig_leases(new Lease6Collection());
- for (auto const& address : lease_addrs) {
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, address);
- ASSERT_TRUE(orig_lease);
- ASSERT_TRUE(orig_lease->valid_lft_ > 0);
-
- ConstElementPtr orig_context;
- ASSERT_NO_THROW_LOG(orig_context = Element::fromJSON(scenario.orig_context_));
- orig_lease->setContext(orig_context);
- ASSERT_NO_THROW_LOG(lmptr_->updateLease6(orig_lease));
- orig_leases->push_back(orig_lease);
- }
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", orig_leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases6Committed(*callout_handle, mgr));
-
- // Iterate over the leases and make sure the user-contexts are as expected.
- for (auto const& lease : *orig_leases) {
- // Fetch the lease.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, lease->addr_);
- ASSERT_TRUE(after_lease);
-
- // Context contents should match the expected context content.
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(scenario.exp_context_));
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- }
- }
-}
-
-void
-Lease6CmdsTest::testNopLeases6Committed() {
- // Initialize lease manager (true = v6, true = add leases)
- initLeaseMgr(true, true);
-
- struct Scenario {
- uint32_t line_;
- DHCPv6MessageType response_type_;
- bool send_lease_;
- uint32_t valid_lft_;
- };
-
- // Configure a single variable.
- std::string config =
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- }]})^";
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ASSERT_NO_THROW_LOG(mgr->configure(Element::fromJSON(config)));
-
- // Scenarios should all result in no change to the lease.
- std::list<Scenario> scenarios = {
- {
- // No leases.
- __LINE__,
- DHCPV6_REPLY,
- false,
- 0
- },
- {
- // No active leases.
- __LINE__,
- DHCPV6_REPLY,
- true,
- 0
- },
- {
- // No response.
- __LINE__,
- DHCPV6_NOTYPE,
- true,
- 1000
- }};
-
- // Create query packet.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- IOAddress na_addr("2001:db8:1::1");
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create the response packet, if one.
- Pkt6Ptr response;
- if (scenario.response_type_ != DHCPV6_NOTYPE) {
- response.reset(new Pkt6(scenario.response_type_, 1234));
- }
-
-
- // Fetch the lease and verify there is no context content.
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, na_addr);
- ASSERT_TRUE(orig_lease);
- ASSERT_FALSE(orig_lease->getContext());
- orig_lease->valid_lft_ = scenario.valid_lft_;
-
- Lease6CollectionPtr leases(new Lease6Collection());
- if (scenario.send_lease_) {
- leases->push_back(orig_lease);
- }
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases6Committed(*callout_handle, mgr));
-
- // Fetch the lease. Context should still be empty.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, na_addr);
- ASSERT_TRUE(after_lease);
- ASSERT_FALSE(after_lease->getContext());
- }
-}
-
-void
-Lease6CmdsTest::testLeases6CommittedErrors() {
- // Initialize lease manager (false = v4, true = add leases)
- initLeaseMgr(true, true);
-
- // Create a config with two binding variables.
- std::string config_str =
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- },
- {
- "name": "sub-id",
- "expression": "hexstring(option[38].hex, ':')",
- "source": "response"
- }]})^";
-
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(config_str));
-
- // Create the expected context contents.
- std::string exp_context_str =
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})";
-
-
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(exp_context_str));
-
- // Create packet pair and lease.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- Pkt6Ptr response(new Pkt6(DHCPV6_REPLY, 7890));
- OptionPtr subscriber_id(new Option(Option::V6, D6O_SUBSCRIBER_ID,
- { 0x05, 0x06, 0x07, 0x08 }));
- response->addOption(subscriber_id);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the leases.
- std::list<IOAddress> lease_addrs;
- lease_addrs.push_back(IOAddress("2001:db8:1::1"));
- lease_addrs.push_back(IOAddress("2001:db8:1::2"));
- lease_addrs.push_back(IOAddress("2001:db8:2::2"));
-
- Lease6CollectionPtr orig_leases(new Lease6Collection());
- for (auto const& address : lease_addrs) {
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, address);
- ASSERT_TRUE(orig_lease);
- orig_leases->push_back(orig_lease);
- }
-
- // Delete the middle lease from the back end. This should cause a conflict error.
- ASSERT_NO_THROW_LOG(lmptr_->deleteLease((*orig_leases)[1]));
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", orig_leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_THROW_MSG(cmds.leases6Committed(*callout_handle, mgr),
- Unexpected,
- "1 out of 3 leases failed to update for "
- "duid=[01:02:03:04], [no hwaddr info], tid=0x4d2");
-
- for (auto const& lease : *orig_leases) {
- // Fetch the lease.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, lease->addr_);
- if (after_lease) {
- // Context contents should match the expected context content.
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- } else {
- // Middle lease should not be found.
- EXPECT_EQ(lease->addr_, (*orig_leases)[1]->addr_);
- }
- }
-}
-#endif
-
TEST_F(Lease6CmdsTest, lease6AddMissingParams) {
testLease6AddMissingParams();
}
testLease6Write();
}
-#if 0
-TEST_F(Lease6CmdsTest, validLeases6Committed) {
- testValidLeases6Committed();
-}
-
-TEST_F(Lease6CmdsTest, validLeases6CommittedMultiThreading) {
- MultiThreadingTest mt(true);
- testValidLeases6Committed();
-}
-
-TEST_F(Lease6CmdsTest, nopLeases6Committed) {
- testNopLeases6Committed();
-}
-
-TEST_F(Lease6CmdsTest, nopLeases6CommittedMultiThreading) {
- MultiThreadingTest mt(true);
- testNopLeases6Committed();
-}
-
-TEST_F(Lease6CmdsTest, leases6CommittedErrors) {
- testLeases6CommittedErrors();
-}
-
-TEST_F(Lease6CmdsTest, leases6CommittedErrorsMultiThreading) {
- MultiThreadingTest mt(true);
- testLeases6CommittedErrors();
-}
-#endif
-
} // end of anonymous namespace
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/lease_cmds -I$(top_srcdir)/src/hooks/dhcp/lease_cmds
AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES)
-AM_CPPFLAGS += -DLEASE_CMDS_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/lease_cmds/.libs/libdhcp_lease_cmds.so\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
std::list<Scenario> scenarios = {
{
- __LINE__, "my-var", valid_v4_exp, BindingVariable::QUERY ,AF_INET
+ __LINE__, "my-var", valid_v4_exp, BindingVariable::QUERY, AF_INET
},
{
- __LINE__, "my-var", valid_v4_exp, BindingVariable::RESPONSE ,AF_INET
+ __LINE__, "my-var", valid_v4_exp, BindingVariable::RESPONSE, AF_INET
},
{
__LINE__, "my-var", valid_v6_exp, BindingVariable::QUERY, AF_INET6
EXPECT_GT(cache->getLastFlushTime(), ref_time);
}
-/// @brief Verifies cache behavior for handling duplicate
-/// entries.
+/// @brief Verifies cache behavior for handling duplicate entries.
TEST(BindingVariableCacheTest, duplicateEntries) {
// Create a new cache.
BindingVariableCachePtr cache(new BindingVariableCache());
ASSERT_TRUE(cache->getByName("four"));
}
-/// @brief Tests BindingVariableMgr::configure() with valid
+/// @brief Tests BindingVariableMgr::configure() with invalid
/// configuration scenarios.
TEST(BindingVariableMgrTest, invalidConfigure) {
struct Scenario {
ASSERT_NO_THROW_LOG(changed = mgr->evaluateVariables(query, response, lease));
// If the original and expected lease contexts the same the lease should
- // not have been changed, otherwse its context should have been updated.
+ // not have been changed, otherwise its context should have been updated.
if (*orig_context == *exp_context) {
ASSERT_FALSE(changed);
ASSERT_EQ(*lease->getContext(), *orig_context);
ASSERT_NO_THROW_LOG(changed = mgr->evaluateVariables(query, response, lease));
// If the original and expected lease contexts the same the lease should
- // not have been changed, otherwse its context should have been updated.
+ // not have been changed, otherwise its context should have been updated.
if (*orig_context == *exp_context) {
ASSERT_FALSE(changed);
ASSERT_EQ(*lease->getContext(), *orig_context);
}
}
-#if 0
-class BindingVariableHandlerTest : public ::testing::Test {
-public:
-
- /// @brief Pointer to the lease manager
- isc::dhcp::LeaseMgr* lmptr_;
-
- /// @brief Constructor
- BindingVariableHandlerTest() {
- isc::dhcp::LeaseMgrFactory::destroy();
- lmptr_ = 0;
- }
-
- /// @brief Destructor
- ///
- virtual ~BindingVariableHandlerTest() {
- isc::dhcp::LeaseMgrFactory::destroy();
- lmptr_ = 0;
- }
-
- /// @brief Creates an IPv4 lease
- ///
- /// Lease parameters: valid lifetime = 0xFFFFFFFE, cltt = 1923222072, fqdn-fwd = false,
- /// fqdn-rev = true, hostname = myhost.example.com
- ///
- /// @param ip_address IP address for the lease.
- /// @param subnet_id subnet identifier
- /// @param hw_address_pattern value to be used for generating HW address by repeating
- /// it 6 times.
- /// @param client_id_pattern value to be used for generating client identifier by
- /// repeating it 8 times.
- /// @param declined controls whether the lease should be in declined state.
- ///
- /// @return Returns the lease created
- isc::dhcp::Lease4Ptr createLease4(const std::string& ip_address,
- const isc::dhcp::SubnetID& subnet_id,
- const uint8_t hw_address_pattern,
- const uint8_t client_id_pattern,
- uint32_t pool_id = 0) {
- isc::dhcp::Lease4Ptr lease(new isc::dhcp::Lease4());
-
- lease->addr_ = isc::asiolink::IOAddress(ip_address);
-
- lease->hwaddr_.reset(new isc::dhcp::HWAddr(std::vector<uint8_t>(6, hw_address_pattern), isc::dhcp::HTYPE_ETHER));
- lease->client_id_ = isc::dhcp::ClientIdPtr(new isc::dhcp::ClientId(std::vector<uint8_t>(8, client_id_pattern)));
- lease->valid_lft_ = 2400;
- lease->updateCurrentExpirationTime();
- lease->subnet_id_ = subnet_id;
- lease->pool_id_ = pool_id;
- return (lease);
- }
-
- /// @brief Creates an IPv6 lease
- ///
- /// @param ip_address IP address for the lease.
- /// @param subnet_id subnet identifier
- /// @param duid_address_pattern value to be used for generating DUID by
- /// repeating it 8 times
- /// @param declined controls whether the lease should be in declined state.
- ///
- /// @return Returns the lease created
- isc::dhcp::Lease6Ptr createLease6(const std::string& ip_address,
- const isc::dhcp::SubnetID& subnet_id,
- const uint8_t duid_pattern,
- uint32_t pool_id = 0) {
- isc::dhcp::Lease6Ptr lease(new isc::dhcp::Lease6());
-
- lease->addr_ = isc::asiolink::IOAddress(ip_address);
- lease->type_ = isc::dhcp::Lease::TYPE_NA;
- lease->prefixlen_ = 128;
- lease->iaid_ = 42;
- lease->duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(std::vector<uint8_t>(8, duid_pattern)));
- lease->preferred_lft_ = 1800;
- lease->valid_lft_ = 2400;
- lease->subnet_id_ = subnet_id;
- lease->pool_id_ = pool_id;
-
- return (lease);
- }
-
- /// @brief Initializes lease manager (and optionally populates it with a lease)
- ///
- /// Creates a lease manager (memfile, trimmed down to keep everything in memory
- /// only) and optionally can create a lease, which is useful for leaseX-get and
- /// leaseX-del type of tests. For lease details, see @ref createLease4 and
- /// @ref createLease6.
- ///
- /// @param famiily protocol family AF_INET or AF_INET6
- /// @param insert_lease governs whether a lease should be pre-inserted
- /// @param declined governs whether a lease should be in declined state
- void initLeaseMgr(int family) {
- isc::dhcp::LeaseMgrFactory::destroy();
- if (family == AF_INET6) {
- isc::dhcp::LeaseMgrFactory::create("type=memfile persist=false "
- "universe=6 extended-info-tables=true");
- lmptr_ = &(isc::dhcp::LeaseMgrFactory::instance());
- ASSERT_TRUE(lmptr_);
- lmptr_->addLease(createLease6("2001:db8:1::1", 66, 0x42));
- lmptr_->addLease(createLease6("2001:db8:1::2", 66, 0x56));
- lmptr_->addLease(createLease6("2001:db8:2::1", 99, 0x42));
- lmptr_->addLease(createLease6("2001:db8:2::2", 99, 0x56));
- } else {
- isc::dhcp::LeaseMgrFactory::create("type=memfile persist=false universe=4");
- lmptr_ = &(isc::dhcp::LeaseMgrFactory::instance());
- ASSERT_TRUE(lmptr_);
- lmptr_->addLease(createLease4("192.0.2.1", 44, 0x08, 0x42));
- lmptr_->addLease(createLease4("192.0.2.2", 44, 0x09, 0x56));
- lmptr_->addLease(createLease4("192.0.3.1", 88, 0x08, 0x42));
- lmptr_->addLease(createLease4("192.0.3.2", 88, 0x09, 0x56));
- }
- }
-
-#if 0
- /// @brief Check that lease4_offer handler works as expected with
- /// valid inputs.
- void testValidLease4Offer();
-
- /// @brief Check that leases4_committed handler works as expected with
- /// valid inputs.
- void testValidLeases4Committed();
-
- /// @brief Check that leases4_committed handler does not throw or alter
- /// the lease under NOP conditions:
- /// 1. There is no repsonse packet
- /// 2. Response packet is a DHCPACK
- /// 3. There is no active lease
- void testNopLeases4Committed();
-#endif
-
- /// @brief Check that leases6_committed handler works as expected with
- /// valid inputs.
- void testValidLeases6Committed();
-
- /// @brief Check that leases6_committed handler does not throw or alter
- /// leases under NOP conditions:
- /// 1. There is no repsonse packet
- /// 2. There are no leases
- /// 3. There are leases but none active
- void testNopLeases6Committed();
-
- void testLeases6CommittedErrors();
-};
-
-#if 0
-void
-BindingVariableHandlerTest::testValidLease4Offer() {
- initLeaseMgr(AF_INET);
-
- struct Scenario {
- uint32_t line_;
- std::string config_;
- std::string orig_context_;
- std::string exp_context_;
- uint32_t offer_lifetime_;
- };
-
- std::list<Scenario> scenarios = {
- {
- // No variables configured, nothing in lease context.
- __LINE__,
- R"({})",
- R"({})",
- R"({})",
- 500
- },
- {
- // lease context has no binding-variables, two configured
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "hexstring(pkt4.mac,':')",
- "source": "query"
- },
- {
- "name": "yiaddr",
- "expression": "addrtotext(pkt4.yiaddr)",
- "source": "response"
- }]})^",
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- 500
- },
- {
- // lease context has no binding-variables, two configured
- // offer lifetime is 0.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "hexstring(pkt4.mac,':')",
- "source": "query"
- },
- {
- "name": "yiaddr",
- "expression": "addrtotext(pkt4.yiaddr)",
- "source": "response"
- }]})^",
- R"({})",
- R"({})",
- 0
- },
- {
- // lease context has binding-variables, none configured
- // Current logic leaves lease untouched.
- __LINE__,
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- 500
- },
- {
- // Evaluated variable value is an empty string.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "''",
- "source": "query"
- }]})^",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": ""
- }
- }})",
- 500
- }};
-
- // Create packet pair and lease.
- Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 1234));
- query->setHWAddr(1, 6, { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 });
-
- Pkt4Ptr response(new Pkt4(DHCPOFFER, 1234));
- IOAddress yiaddr("192.0.2.1");
- response->setYiaddr(yiaddr);
-
- // Iterater over scenarios.
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET)));
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(scenario.config_));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the lease and set its user-context to the original content.
- Lease4Ptr orig_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(orig_lease);
- ConstElementPtr orig_context;
- ASSERT_NO_THROW_LOG(orig_context = Element::fromJSON(scenario.orig_context_));
- orig_lease->setContext(orig_context);
- ASSERT_NO_THROW_LOG(lmptr_->updateLease4(orig_lease));
-
- Lease4CollectionPtr leases(new Lease4Collection());
- leases->push_back(orig_lease);
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query4", query);
- callout_handle->setArgument("response4", response);
- callout_handle->setArgument("leases4", leases);
- callout_handle->setArgument("offer_lifetime", scenario.offer_lifetime_);
-
- // Invoke the leases4Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.lease4Offer(*callout_handle, mgr));
-
- // Fetch the lease.
- Lease4Ptr after_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(after_lease);
-
- // Context contents should match the expected context content.
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(scenario.exp_context_));
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- }
-}
-
-void
-BindingVariableHandlerTest::testValidLeases4Committed() {
- initLeaseMgr(AF_INET);
-
- struct Scenario {
- uint32_t line_;
- std::string config_;
- std::string orig_context_;
- std::string exp_context_;
- };
-
- std::list<Scenario> scenarios = {
- {
- // No variables configured, nothing in lease context.
- __LINE__,
- R"({})",
- R"({})",
- R"({})"
- },
- {
- // lease context has no binding-variables, two configured
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "hexstring(pkt4.mac,':')",
- "source": "query"
- },
- {
- "name": "yiaddr",
- "expression": "addrtotext(pkt4.yiaddr)",
- "source": "response"
- }]})^",
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- },
- {
- // lease context has binding-variables, none configured
- // Current logic leaves lease untouched.
- __LINE__,
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06",
- "yiaddr": "192.0.2.1"
- }
- }})",
- },
- {
- // Evaluated variable value is an empty string.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "''",
- "source": "query"
- }]})^",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": "01:02:03:04:05:06"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "hwaddr": ""
- }
- }})",
- }};
-
- // Create packet pair and lease.
- Pkt4Ptr query(new Pkt4(DHCPREQUEST, 1234));
- query->setHWAddr(1, 6, { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 });
-
- Pkt4Ptr response(new Pkt4(DHCPACK, 1234));
- IOAddress yiaddr("192.0.2.1");
- response->setYiaddr(yiaddr);
-
- // Iterater over scenarios.
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET)));
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(scenario.config_));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the lease and set its user-context to the original content.
- Lease4Ptr orig_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(orig_lease);
- ConstElementPtr orig_context;
- ASSERT_NO_THROW_LOG(orig_context = Element::fromJSON(scenario.orig_context_));
- orig_lease->setContext(orig_context);
- ASSERT_NO_THROW_LOG(lmptr_->updateLease4(orig_lease));
-
- Lease4CollectionPtr leases(new Lease4Collection());
- leases->push_back(orig_lease);
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query4", query);
- callout_handle->setArgument("response4", response);
- callout_handle->setArgument("leases4", leases);
-
- // Invoke the leases4Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases4Committed(*callout_handle, mgr));
-
- // Fetch the lease.
- Lease4Ptr after_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(after_lease);
-
- // Context contents should match the expected context content.
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(scenario.exp_context_));
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- }
-}
-
-void
-BindingVariableHandlerTest::testNopLeases4Committed() {
- initLeaseMgr(AF_INET);
-
- struct Scenario {
- uint32_t line_;
- DHCPMessageType response_type_;
- bool send_lease_;
- };
-
- // Configure a single variable.
- std::string config =
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "hexstring(pkt4.mac,':')",
- "source": "query"
- }]})^";
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET)));
- ASSERT_NO_THROW_LOG(mgr->configure(Element::fromJSON(config)));
-
- // Scenarios should all result in no change to the lease.
- std::list<Scenario> scenarios = {
- {
- // Response is not a DHCPACK.
- __LINE__,
- DHCPNAK,
- true
- },
- {
- // No active lease.
- __LINE__,
- DHCPACK,
- false
- },
- {
- // No response.
- __LINE__,
- DHCP_NOTYPE,
- false
- }};
-
- // Create packet pair and lease.
- Pkt4Ptr query(new Pkt4(DHCPREQUEST, 1234));
- query->setHWAddr(1, 6, { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 });
- IOAddress yiaddr("192.0.2.1");
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- Pkt4Ptr response;
- if (scenario.response_type_ != DHCP_NOTYPE) {
- response.reset(new Pkt4(scenario.response_type_, 1234));
- }
-
- // Fetch the lease and set its user-context to the original content.
- Lease4Ptr orig_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(orig_lease);
- ASSERT_FALSE(orig_lease->getContext());
-
- Lease4CollectionPtr leases(new Lease4Collection());
- if (scenario.send_lease_) {
- leases->push_back(orig_lease);
- }
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query4", query);
- callout_handle->setArgument("response4", response);
- callout_handle->setArgument("leases4", leases);
-
- // Invoke the leases4Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases4Committed(*callout_handle, mgr));
-
- // Fetch the lease. Context should still be empty.
- Lease4Ptr after_lease = lmptr_->getLease4(yiaddr);
- ASSERT_TRUE(after_lease);
- ASSERT_FALSE(after_lease->getContext());
- }
-}
-#endif
-
-void
-BindingVariableHandlerTest::testValidLeases6Committed() {
- initLeaseMgr(AF_INET6);
-
- struct Scenario {
- uint32_t line_;
- std::string config_;
- std::string orig_context_;
- std::string exp_context_;
- };
-
- std::list<Scenario> scenarios = {
- {
- // No variables configured, nothing in lease context.
- __LINE__,
- R"({})",
- R"({})",
- R"({})"
- },
- {
- // Lease context has no binding-variables, two configured.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- },
- {
- "name": "sub-id",
- "expression": "hexstring(option[38].hex, ':')",
- "source": "response"
- }]})^",
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- },
- {
- // Lease context has binding-variables, none configured.
- // Current logic leaves lease untouched.
- __LINE__,
- R"({})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})",
- },
- {
- // Evaluated variable value is an empty string.
- __LINE__,
- R"^({"binding-variables":[
- {
- "name": "my-var",
- "expression": "''",
- "source": "query"
- }]})^",
- R"({"ISC":{
- "binding-variables":{
- "my-var": "pre-existing value"
- }
- }})",
- R"({"ISC":{
- "binding-variables":{
- "my-var": ""
- }
- }})",
- }
- };
-
- // Create packet pair and lease.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- Pkt6Ptr response(new Pkt6(DHCPV6_REPLY, 7890));
- OptionPtr subscriber_id(new Option(Option::V6, D6O_SUBSCRIBER_ID,
- { 0x05, 0x06, 0x07, 0x08 }));
- response->addOption(subscriber_id);
-
- // Create a list of the lease addresses.
- std::list<IOAddress> lease_addrs;
- lease_addrs.push_back(IOAddress("2001:db8:1::1"));
- lease_addrs.push_back(IOAddress("2001:db8:1::2"));
- lease_addrs.push_back(IOAddress("2001:db8:2::2"));
-
- // Iterater over scenarios.
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(scenario.config_));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the lease and set its user-context to the original content.
- Lease6CollectionPtr orig_leases(new Lease6Collection());
- for (auto const& address : lease_addrs) {
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, address);
- ASSERT_TRUE(orig_lease);
- ASSERT_TRUE(orig_lease->valid_lft_ > 0);
-
- ConstElementPtr orig_context;
- ASSERT_NO_THROW_LOG(orig_context = Element::fromJSON(scenario.orig_context_));
- orig_lease->setContext(orig_context);
- ASSERT_NO_THROW_LOG(lmptr_->updateLease6(orig_lease));
- orig_leases->push_back(orig_lease);
- }
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", orig_leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases6Committed(*callout_handle, mgr));
-
- // Iterate over the leases and make sure the user-contexts are as expected.
- for (auto const& lease : *orig_leases) {
- // Fetch the lease.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, lease->addr_);
- ASSERT_TRUE(after_lease);
-
- // Context contents should match the expected context content.
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(scenario.exp_context_));
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- }
- }
-}
-
-void
-BindingVariableHandlerTest::testNopLeases6Committed() {
- initLeaseMgr(AF_INET6);
-
- struct Scenario {
- uint32_t line_;
- DHCPv6MessageType response_type_;
- bool send_lease_;
- uint32_t valid_lft_;
- };
-
- // Configure a single variable.
- std::string config =
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- }]})^";
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ASSERT_NO_THROW_LOG(mgr->configure(Element::fromJSON(config)));
-
- // Scenarios should all result in no change to the lease.
- std::list<Scenario> scenarios = {
- {
- // No leases.
- __LINE__,
- DHCPV6_REPLY,
- false,
- 0
- },
- {
- // No active leases.
- __LINE__,
- DHCPV6_REPLY,
- true,
- 0
- },
- {
- // No response.
- __LINE__,
- DHCPV6_NOTYPE,
- true,
- 1000
- }};
-
- // Create query packet.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- IOAddress na_addr("2001:db8:1::1");
- for (auto const& scenario : scenarios) {
- SCOPED_LINE(scenario.line_);
-
- // Create the response packet, if one.
- Pkt6Ptr response;
- if (scenario.response_type_ != DHCPV6_NOTYPE) {
- response.reset(new Pkt6(scenario.response_type_, 1234));
- }
-
-
- // Fetch the lease and verify there is no context content.
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, na_addr);
- ASSERT_TRUE(orig_lease);
- ASSERT_FALSE(orig_lease->getContext());
- orig_lease->valid_lft_ = scenario.valid_lft_;
-
- Lease6CollectionPtr leases(new Lease6Collection());
- if (scenario.send_lease_) {
- leases->push_back(orig_lease);
- }
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_NO_THROW_LOG(cmds.leases6Committed(*callout_handle, mgr));
-
- // Fetch the lease. Context should still be empty.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, na_addr);
- ASSERT_TRUE(after_lease);
- ASSERT_FALSE(after_lease->getContext());
- }
-}
-
-void
-BindingVariableHandlerTest::testLeases6CommittedErrors() {
- initLeaseMgr(AF_INET6);
-
- // Create a config with two binding variables.
- std::string config_str =
- R"^({"binding-variables":[
- {
- "name": "duid",
- "expression": "hexstring(option[1].hex,':')",
- "source": "query"
- },
- {
- "name": "sub-id",
- "expression": "hexstring(option[38].hex, ':')",
- "source": "response"
- }]})^";
-
- ConstElementPtr config;
- ASSERT_NO_THROW_LOG(config = Element::fromJSON(config_str));
-
- // Create the expected context contents.
- std::string exp_context_str =
- R"({"ISC":{
- "binding-variables":{
- "duid": "01:02:03:04",
- "sub-id": "05:06:07:08"
- }
- }})";
-
-
- ConstElementPtr exp_context;
- ASSERT_NO_THROW_LOG(exp_context = Element::fromJSON(exp_context_str));
-
- // Create packet pair and lease.
- Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
- OptionPtr client_id(new Option(Option::V6, D6O_CLIENTID,
- { 0x01, 0x02, 0x03, 0x04 }));
- query->addOption(client_id);
-
- Pkt6Ptr response(new Pkt6(DHCPV6_REPLY, 7890));
- OptionPtr subscriber_id(new Option(Option::V6, D6O_SUBSCRIBER_ID,
- { 0x05, 0x06, 0x07, 0x08 }));
- response->addOption(subscriber_id);
-
- // Create and configure the manager.
- BindingVariableMgrPtr mgr;
- ASSERT_NO_THROW_LOG(mgr.reset(new BindingVariableMgr(AF_INET6)));
- ASSERT_NO_THROW_LOG(mgr->configure(config));
-
- // Fetch the leases.
- std::list<IOAddress> lease_addrs;
- lease_addrs.push_back(IOAddress("2001:db8:1::1"));
- lease_addrs.push_back(IOAddress("2001:db8:1::2"));
- lease_addrs.push_back(IOAddress("2001:db8:2::2"));
-
- Lease6CollectionPtr orig_leases(new Lease6Collection());
- for (auto const& address : lease_addrs) {
- Lease6Ptr orig_lease = lmptr_->getLease6(Lease::TYPE_NA, address);
- ASSERT_TRUE(orig_lease);
- orig_leases->push_back(orig_lease);
- }
-
- // Delete the middle lease from the back end. This should cause a conflict error.
- ASSERT_NO_THROW_LOG(lmptr_->deleteLease((*orig_leases)[1]));
-
- // Create a callout handle and add the expected arguments.
- CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
- callout_handle->setArgument("query6", query);
- callout_handle->setArgument("response6", response);
- callout_handle->setArgument("leases6", orig_leases);
-
- // Invoke the leases6Committed handler.
- LeaseCmds cmds;
- ASSERT_THROW_MSG(cmds.leases6Committed(*callout_handle, mgr),
- Unexpected,
- "1 out of 3 leases failed to update for "
- "duid=[01:02:03:04], [no hwaddr info], tid=0x4d2");
-
- for (auto const& lease : *orig_leases) {
- // Fetch the lease.
- Lease6Ptr after_lease = lmptr_->getLease6(Lease::TYPE_NA, lease->addr_);
- if (after_lease) {
- // Context contents should match the expected context content.
- ASSERT_EQ(*(after_lease->getContext()), *exp_context);
- } else {
- // Middle lease should not be found.
- EXPECT_EQ(lease->addr_, (*orig_leases)[1]->addr_);
- }
- }
-}
-
-TEST_F(BindingVariableHandlerTest, validLeases6Committed) {
- testValidLeases6Committed();
-}
-
-TEST_F(BindingVariableHandlerTest, validLeases6CommittedMultiThreading) {
- MultiThreadingTest mt(true);
- testValidLeases6Committed();
-}
-
-TEST_F(BindingVariableHandlerTest, nopLeases6Committed) {
- testNopLeases6Committed();
-}
-
-TEST_F(BindingVariableHandlerTest, nopLeases6CommittedMultiThreading) {
- MultiThreadingTest mt(true);
- testNopLeases6Committed();
-}
-
-TEST_F(BindingVariableHandlerTest, leases6CommittedErrors) {
- testLeases6CommittedErrors();
-}
-
-TEST_F(BindingVariableHandlerTest, leases6CommittedErrorsMultiThreading) {
- MultiThreadingTest mt(true);
- testLeases6CommittedErrors();
-}
-#endif
-
} // end of anonymous namespace
namespace {
-class LeaseCmdsFuncTest4 : public LeaseCmdsFuncTest {
+/// @brief DHCPv4 Test fixture for testing lease commands hook library
+/// functions and class methods.
+class LeaseCmdsFuncTest4 : public LeaseCmdsFuncTest {
public:
/// @brief Constructor
LeaseCmdsFuncTest4() = default;
/// @brief Destructor
- ///
virtual ~LeaseCmdsFuncTest4() = default;
/// @brief Creates an IPv4 lease
///
- /// Lease parameters: valid lifetime = 0xFFFFFFFE, cltt = 1923222072, fqdn-fwd = false,
- /// fqdn-rev = true, hostname = myhost.example.com
- ///
/// @param ip_address IP address for the lease.
/// @param subnet_id subnet identifier
/// @param hw_address_pattern value to be used for generating HW address by repeating
return (lease);
}
- /// @brief Initializes lease manager (and optionally populates it with a lease)
- ///
- /// Creates a lease manager and initial leases.
- /// only) and optionally can create a lease, which is useful for leaseX-get and
- /// leaseX-del type of tests. For lease details, see @ref createLease and
- /// @ref createLease6.
- ///
+ /// @brief Initializes the lease manager and populates it with test leases.
virtual void initLeaseMgr() {
LeaseMgrFactory::destroy();
LeaseMgrFactory::create("type=memfile persist=false universe=4");
void testValidLeases4Committed();
/// @brief Check that leases4_committed handler does not throw or alter
- /// the lease under NOP conditions:
- /// 1. There is no repsonse packet
- /// 2. Response packet is a DHCPACK
+ /// the lease under NOP conditions:
+ /// 1. There is no response packet
+ /// 2. Response packet is a DHCPACK
/// 3. There is no active lease
void testNopLeases4Committed();
};
IOAddress yiaddr("192.0.2.1");
response->setYiaddr(yiaddr);
- // Iterater over scenarios.
+ // Iterates over scenarios.
for (auto const& scenario : scenarios) {
SCOPED_LINE(scenario.line_);
callout_handle->setArgument("leases4", leases);
callout_handle->setArgument("offer_lifetime", scenario.offer_lifetime_);
- // Invoke the leases4Committed handler.
+ // Invoke the lease4Offer handler.
LeaseCmds cmds;
ASSERT_NO_THROW_LOG(cmds.lease4Offer(*callout_handle, mgr));
IOAddress yiaddr("192.0.2.1");
response->setYiaddr(yiaddr);
- // Iterater over scenarios.
+ // Iterates over scenarios.
for (auto const& scenario : scenarios) {
SCOPED_LINE(scenario.line_);
// Configure a single variable.
std::string config =
- R"^({"binding-variables":[
- {
- "name": "hwaddr",
- "expression": "hexstring(pkt4.mac,':')",
- "source": "query"
- }]})^";
+ R"^({"binding-variables":[
+ {
+ "name": "hwaddr",
+ "expression": "hexstring(pkt4.mac,':')",
+ "source": "query"
+ }]})^";
// Create and configure the manager.
BindingVariableMgrPtr mgr;
namespace {
-class LeaseCmdsFuncTest6 : public LeaseCmdsFuncTest {
+/// @brief DHCPv6 Test fixture for testing lease commands hook library
+/// functions and class methods.
+class LeaseCmdsFuncTest6 : public LeaseCmdsFuncTest {
public:
/// @brief Constructor
LeaseCmdsFuncTest6() = default;
/// @brief Destructor
virtual ~LeaseCmdsFuncTest6() = default;
- /// @brief Initializes lease manager (and optionally populates it with a lease)
+ /// @brief Initializes the lease manager and populates it with test leases.
void initLeaseMgr() {
LeaseMgrFactory::destroy();
- LeaseMgrFactory::create("type=memfile persist=false "
+ LeaseMgrFactory::create("type=memfile persist=false "
"universe=6 extended-info-tables=true");
lmptr_ = &(isc::dhcp::LeaseMgrFactory::instance());
ASSERT_TRUE(lmptr_);
/// @brief Check that leases6_committed handler does not throw or alter
/// leases under NOP conditions:
- /// 1. There is no repsonse packet
+ /// 1. There is no response packet
/// 2. There are no leases
/// 3. There are leases but none active
void testNopLeases6Committed();
lease_addrs.push_back(IOAddress("2001:db8:1::2"));
lease_addrs.push_back(IOAddress("2001:db8:2::2"));
- // Iterater over scenarios.
+ // Iterates over scenarios.
for (auto const& scenario : scenarios) {
SCOPED_LINE(scenario.line_);
namespace {
+/// @brief Macro around SCOPED_TRACE() for emitting a message including
+/// a source line number.
+/// @param line line number to emit
#define SCOPED_LINE(line) \
std::stringstream ss; \
ss << "Scenario at line: " << line; \
SCOPED_TRACE(ss.str());
-class LeaseCmdsFuncTest : public ::testing::Test {
+/// @brief Text fixture for testing lease command functions and
+/// class methods. Provides an intialized lease manager.
+class LeaseCmdsFuncTest : public ::testing::Test {
public:
/// @brief Constructor
LeaseCmdsFuncTest() {
lmptr_ = 0;
}
+ /// @brief Initializes the lease manager.
virtual void SetUp() {
initLeaseMgr();
}
/// @brief Destructor
- ///
virtual ~LeaseCmdsFuncTest() {
isc::dhcp::LeaseMgrFactory::destroy();
lmptr_ = 0;
/// @note This function in used internally by @ref closeCommandSockets and it
/// should not be used directly, except for unit tests.
///
- /// @param config Configuration information for the unix control socket.
+ /// @param info Configuration information for the unix control socket.
void closeCommandSocket(UnixSocketInfoPtr info = UnixSocketInfoPtr());
/// @brief Shuts down any open unix control sockets.
///
/// This method should be used only in tests.
///
- /// @param config Configuration information for the unix control socket.
+ /// @param info Configuration information for the unix control socket.
///
/// @return The file descriptor of the specified unix control socket.
int getControlSocketFD(UnixSocketInfoPtr info = UnixSocketInfoPtr());
/// Update the ISC entry in the lease's user-context
///
/// Adds or updates the named element within the "ISC" map
- /// with the lease's "user-context". The update occurs only if
+ /// with the lease's user context. The update occurs only if
/// the new value(s) are different than the existing values for the
/// element.
///