mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[#103,!277] Extended unit tests for databaseConfigApply in DHCPv4.
This commit is contained in:
@@ -149,35 +149,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Tests that a given global is in the staged configured globals
|
||||
///
|
||||
/// @param name name of the global parameter
|
||||
/// @param exp_value expected value of the global paramter as an Element
|
||||
void checkConfiguredGlobal(const std::string &name,
|
||||
ConstElementPtr exp_value) {
|
||||
SrvConfigPtr staging_cfg = CfgMgr::instance().getStagingCfg();
|
||||
ConstElementPtr globals = staging_cfg->getConfiguredGlobals();
|
||||
ConstElementPtr found_global = globals->get(name);
|
||||
ASSERT_TRUE(found_global) << "expected global: "
|
||||
<< name << " not found";
|
||||
|
||||
ASSERT_EQ(exp_value->getType(), found_global->getType())
|
||||
<< "expected global: " << name << " has wrong type";
|
||||
|
||||
ASSERT_EQ(*exp_value, *found_global)
|
||||
<< "expected global: " << name << " has wrong value";
|
||||
}
|
||||
|
||||
/// @brief Tests that a given global is in the staged configured globals
|
||||
///
|
||||
/// @param exp_global StampedValue representing the global value to verify
|
||||
///
|
||||
/// @todo At the point in time StampedVlaue carries type, exp_type should be
|
||||
/// replaced with exp_global->getType()
|
||||
void checkConfiguredGlobal(StampedValuePtr& exp_global) {
|
||||
checkConfiguredGlobal(exp_global->getName(), exp_global->getElementValue());
|
||||
}
|
||||
|
||||
boost::scoped_ptr<Dhcpv4Srv> srv_; ///< DHCP4 server under test
|
||||
int rcode_; ///< Return code from element parsing
|
||||
ConstElementPtr comment_; ///< Reason for parse fail
|
||||
@@ -247,14 +218,16 @@ TEST_F(Dhcp4CBTest, mergeGlobals) {
|
||||
EXPECT_EQ(86400, staging_cfg->getDeclinePeriod());
|
||||
|
||||
// Verify that the implicit globals from JSON are there.
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal("valid-lifetime", Element::create(1000)));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal("rebind-timer", Element::create(800)));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, "valid-lifetime",
|
||||
Element::create(1000)));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, "rebind-timer",
|
||||
Element::create(800)));
|
||||
|
||||
// Verify that the implicit globals from the backend are there.
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(server_hostname));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(calc_tee_times));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(t2_percent));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(renew_timer));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, server_hostname));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, calc_tee_times));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, t2_percent));
|
||||
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, renew_timer));
|
||||
}
|
||||
|
||||
// This test verifies that externally configured option definitions
|
||||
|
@@ -16,8 +16,7 @@ namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
void
|
||||
CBControlDHCPv4::databaseConfigApply(const ConfigPtr& srv_cfg,
|
||||
const db::BackendSelector& backend_selector,
|
||||
CBControlDHCPv4::databaseConfigApply(const db::BackendSelector& backend_selector,
|
||||
const db::ServerSelector& server_selector,
|
||||
const boost::posix_time::ptime& lb_modification_time,
|
||||
const db::AuditEntryCollection& audit_entries) {
|
||||
|
@@ -26,23 +26,17 @@ namespace dhcp {
|
||||
class CBControlDHCPv4 : public CBControlDHCP<ConfigBackendDHCPv4Mgr> {
|
||||
protected:
|
||||
|
||||
/// @brief Fetches the entire or partial configuration from the database.
|
||||
/// @brief DHCPv4 server specific method to apply fetch configuration
|
||||
/// into the local configuration.
|
||||
///
|
||||
/// This method is called by the starting up server to fetch and merge
|
||||
/// the entire configuration from the database or to fetch configuration
|
||||
/// updates periodically, e.g. as a result of triggering an interval
|
||||
/// timer callback.
|
||||
///
|
||||
/// @param srv_cfg pointer to the staging configuration that should
|
||||
/// hold the config backends list and other partial configuration read
|
||||
/// from the file in case the method is called upon the server's start
|
||||
/// up. It is a pointer to the current server configuration if the
|
||||
/// method is called to fetch configuration updates.
|
||||
/// @param fetch_updates_only boolean value indicating if the method is
|
||||
/// called upon the server start up (false) or it is called to fetch
|
||||
/// configuration updates (true).
|
||||
virtual void databaseConfigApply(const process::ConfigPtr& srv_cfg,
|
||||
const db::BackendSelector& backend_selector,
|
||||
/// @param backend_selector Backend selector.
|
||||
/// @param server_selector Server selector.
|
||||
/// @param lb_modification_time Lower bound modification time for the
|
||||
/// configuration elements to be fetched.
|
||||
/// @param audit_entries Audit entries fetched from the database since
|
||||
/// the last configuration update. This collection is empty if there
|
||||
/// were no updates.
|
||||
virtual void databaseConfigApply(const db::BackendSelector& backend_selector,
|
||||
const db::ServerSelector& server_selector,
|
||||
const boost::posix_time::ptime& lb_modification_time,
|
||||
const db::AuditEntryCollection& audit_entries);
|
||||
|
@@ -98,7 +98,8 @@ public:
|
||||
///
|
||||
/// @param desc descriptor
|
||||
OptionDescriptor(const OptionDescriptor& desc)
|
||||
: data::StampedElement(), option_(desc.option_),
|
||||
: data::StampedElement(desc),
|
||||
option_(desc.option_),
|
||||
persistent_(desc.persistent_),
|
||||
formatted_value_(desc.formatted_value_),
|
||||
space_name_(desc.space_name_) {
|
||||
|
@@ -6,27 +6,403 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <asiolink/io_address.h>
|
||||
#include <cc/stamped_value.h>
|
||||
#include <dhcp/option_string.h>
|
||||
#include <dhcpsrv/cb_ctl_dhcp4.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/testutils/generic_backend_unittest.h>
|
||||
#include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace isc::asiolink;
|
||||
using namespace isc::db;
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::dhcp::test;
|
||||
using namespace isc::process;
|
||||
|
||||
namespace {
|
||||
|
||||
/// @brief Test fixture class for @c CBControlDHCPv4 unit tests.
|
||||
class TestCBControlDHCPv4 : public CBControlDHCPv4 {
|
||||
/// @brief Base class for testing derivations of the CBControlDHCP.
|
||||
class CBControlDHCPTest : public GenericBackendTest {
|
||||
public:
|
||||
|
||||
/// @brief Constructor.
|
||||
CBControlDHCPTest()
|
||||
: timestamp_(), object_timestamp_(), audit_entries_() {
|
||||
CfgMgr::instance().clear();
|
||||
initTimestamps();
|
||||
}
|
||||
|
||||
/// @brief Destructor.
|
||||
virtual ~CBControlDHCPTest() {
|
||||
// Unregister the factory to be tidy.
|
||||
ConfigBackendDHCPv4Mgr::instance().unregisterBackendFactory("memfile");
|
||||
CfgMgr::instance().clear();
|
||||
}
|
||||
|
||||
/// @brief Creates new CREATE audit entry.
|
||||
///
|
||||
/// The audit entry is added to the @c audit_entries_ collection.
|
||||
///
|
||||
/// @param object_type Object type to be associated with the audit
|
||||
/// entry.
|
||||
void addCreateAuditEntry(const std::string& object_type) {
|
||||
AuditEntryPtr entry(new AuditEntry(object_type, 1234,
|
||||
AuditEntry::ModificationType::CREATE,
|
||||
"some log message"));
|
||||
audit_entries_.insert(entry);
|
||||
}
|
||||
|
||||
/// @brief Creates new DELETE audit entry.
|
||||
///
|
||||
/// The audit entry is added to the @c audit_entries_ collection.
|
||||
///
|
||||
/// @param object_type Object type to be associated with the audit
|
||||
/// entry.
|
||||
/// @param object_id Identifier of the object to be associated with
|
||||
/// the audit entry.
|
||||
void addDeleteAuditEntry(const std::string& object_type,
|
||||
const uint64_t object_id) {
|
||||
AuditEntryPtr entry(new AuditEntry(object_type, object_id,
|
||||
AuditEntry::ModificationType::DELETE,
|
||||
"some log message"));
|
||||
audit_entries_.insert(entry);
|
||||
}
|
||||
|
||||
/// @brief Initializes timestamps used in tests.
|
||||
void initTimestamps() {
|
||||
// Get the current timestamp and move it 30 seconds backwards.
|
||||
auto now = boost::posix_time::second_clock::local_time() -
|
||||
boost::posix_time::seconds(30);
|
||||
|
||||
// Initialize multiple timestamps from the base timestamp. The
|
||||
// values with indexes [-5, 0] are in the past. The remaining
|
||||
// four are in the future.
|
||||
for (int i = -5; i < 5; ++i) {
|
||||
timestamp_[i] = now + boost::posix_time::minutes(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Returns timestamp associated with a given index.
|
||||
///
|
||||
/// @param timestamp_index Index of the timestamp to be returned.
|
||||
boost::posix_time::ptime getTimestamp(const int timestamp_index) {
|
||||
return (timestamp_[timestamp_index]);
|
||||
}
|
||||
|
||||
/// @brief Returns timestamp to be associated with a given object type.
|
||||
///
|
||||
/// The object types correspond to the names of the SQL tables holding
|
||||
/// them, e.g. dhcp4_global_parameter, dhcp4_subnet etc.
|
||||
///
|
||||
/// @param object_type Object type.
|
||||
boost::posix_time::ptime getTimestamp(const std::string& object_type) {
|
||||
return (object_timestamp_[object_type]);
|
||||
}
|
||||
|
||||
/// @brief Associates object type with a timestamp.
|
||||
///
|
||||
/// When adding objects to the database, each one is associated with
|
||||
/// a modification time value. This value is setup by unit tests
|
||||
/// via this method.
|
||||
void setTimestamp(const std::string& object_type, const int timestamp_index) {
|
||||
object_timestamp_[object_type] = timestamp_[timestamp_index];
|
||||
}
|
||||
|
||||
/// @brief Sets timestamps for various object types to the same value.
|
||||
///
|
||||
/// @param timestamp_index Index of the timestamp to be set.
|
||||
virtual void setAllTimestamps(const int timestamp_index) = 0;
|
||||
|
||||
/// @brief Checks if @c databaseConfigApply should fetch updates for specified
|
||||
/// object types.
|
||||
///
|
||||
/// @param object_type Object type.
|
||||
bool fetchConfigElement(const std::string& object_type) const {
|
||||
if (!audit_entries_.empty()) {
|
||||
const auto& index = audit_entries_.get<AuditEntryObjectTypeTag>();
|
||||
auto range = index.equal_range(object_type);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
if (((*it)->getModificationType() != AuditEntry::ModificationType::DELETE)) {
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/// @brief Holds test timestamps.
|
||||
std::map<int, boost::posix_time::ptime> timestamp_;
|
||||
|
||||
/// @brief Holds mapping of the objects types to their timestamps.
|
||||
std::map<std::string, boost::posix_time::ptime> object_timestamp_;
|
||||
|
||||
/// @brief Collection of audit entries used in the unit tests.
|
||||
AuditEntryCollection audit_entries_;
|
||||
};
|
||||
|
||||
/// @brief Naked @c CBControlDHCPv4 class exposing protected methods.
|
||||
class TestCBControlDHCPv4 : public CBControlDHCPv4 {
|
||||
public:
|
||||
using CBControlDHCPv4::getInitialAuditEntryTime;
|
||||
using CBControlDHCPv4::databaseConfigApply;
|
||||
};
|
||||
|
||||
/// @brief Test fixture class for @c CBControlDHCPv4 unit tests.
|
||||
class CBControlDHCPv4Test : public CBControlDHCPTest {
|
||||
public:
|
||||
|
||||
// This test verifies that the configuration updates are
|
||||
// merged into the current configuration.
|
||||
TEST(CBControlDHCPv4Test, databaseConfigApplyUpdates) {
|
||||
TestCBControlDHCPv4 ctl;
|
||||
/// @todo implement the actual test.
|
||||
/// @brief Constructor.
|
||||
CBControlDHCPv4Test()
|
||||
: CBControlDHCPTest(), ctl_() {
|
||||
ConfigBackendDHCPv4Mgr::instance().registerBackendFactory("memfile",
|
||||
[](const DatabaseConnection::ParameterMap& params)
|
||||
-> ConfigBackendDHCPv4Ptr {
|
||||
return (TestConfigBackendDHCPv4Ptr(new TestConfigBackendDHCPv4(params)));
|
||||
});
|
||||
ConfigBackendDHCPv4Mgr::instance().addBackend("type=memfile");
|
||||
|
||||
// By default, set timestamps for all object types to -4. That leaves
|
||||
// us with the possibility to use index -5 (earlier) to use as lower
|
||||
// bound modification time so as all objects are fetched.
|
||||
setAllTimestamps(-4);
|
||||
}
|
||||
|
||||
/// @brief Sets timestamps of all DHCPv4 specific object types.
|
||||
///
|
||||
/// @param timestamp_index Index of the timestamp to be set.
|
||||
virtual void setAllTimestamps(const int timestamp_index) {
|
||||
setTimestamp("dhcp4_global_parameter", timestamp_index);
|
||||
setTimestamp("dhcp4_option_def", timestamp_index);
|
||||
setTimestamp("dhcp4_options", timestamp_index);
|
||||
setTimestamp("dhcp4_shared_network", timestamp_index);
|
||||
setTimestamp("dhcp4_subnet", timestamp_index);
|
||||
}
|
||||
|
||||
/// @brief Tests the @c CBControlDHCPv4::databaseConfigApply method.
|
||||
///
|
||||
/// This test inserts configuration elements of each type into the
|
||||
/// configuration database. Next, it calls the @c databaseConfigApply,
|
||||
/// which should merge each object from the database for which the
|
||||
/// CREATE or UPDATE audit entry is found. The test then verifies
|
||||
/// if the appropriate entries have been merged.
|
||||
///
|
||||
/// @param lb_modification_time Lower bound modification time to be
|
||||
/// passed to the @c databaseConfigApply.
|
||||
void testDatabaseConfigApply(const boost::posix_time::ptime& lb_modification_time) {
|
||||
auto& mgr = ConfigBackendDHCPv4Mgr::instance();
|
||||
|
||||
// Insert global parameter into a database.
|
||||
StampedValuePtr global_parameter = StampedValue::create("foo", "bar");
|
||||
global_parameter->setModificationTime(getTimestamp("dhcp4_global_parameter"));
|
||||
ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter4(BackendSelector::UNSPEC(),
|
||||
ServerSelector::ALL(),
|
||||
global_parameter));
|
||||
|
||||
// Insert option definition into the database.
|
||||
OptionDefinitionPtr def(new OptionDefinition("one", 101, "uint16"));
|
||||
def->setOptionSpaceName("isc");
|
||||
def->setModificationTime(getTimestamp("dhcp4_option_def"));
|
||||
ASSERT_NO_THROW(mgr.getPool()->createUpdateOptionDef4(BackendSelector::UNSPEC(),
|
||||
ServerSelector::ALL(),
|
||||
def));
|
||||
|
||||
// Insert global option into the database.
|
||||
OptionDescriptorPtr opt(new OptionDescriptor(createOption<OptionString>
|
||||
(Option::V4, DHO_HOST_NAME,
|
||||
true, false, "new.example.com")));
|
||||
opt->space_name_ = DHCP4_OPTION_SPACE;
|
||||
opt->setModificationTime(getTimestamp("dhcp4_options"));
|
||||
mgr.getPool()->createUpdateOption4(BackendSelector::UNSPEC(), ServerSelector::ALL(),
|
||||
opt);
|
||||
|
||||
// Insert shared network into the database.
|
||||
SharedNetwork4Ptr network(new SharedNetwork4("one"));
|
||||
network->setModificationTime(getTimestamp("dhcp4_shared_network"));
|
||||
|
||||
mgr.getPool()->createUpdateSharedNetwork4(BackendSelector::UNSPEC(),
|
||||
ServerSelector::ALL(),
|
||||
network);
|
||||
|
||||
// Insert subnet into the database.
|
||||
Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3, SubnetID(1)));
|
||||
subnet->setModificationTime(getTimestamp("dhcp4_subnet"));
|
||||
|
||||
mgr.getPool()->createUpdateSubnet4(BackendSelector::UNSPEC(), ServerSelector::ALL(),
|
||||
subnet);
|
||||
|
||||
ASSERT_FALSE(audit_entries_.empty())
|
||||
<< "Require at least one audit entry. The test is broken!";
|
||||
|
||||
ctl_.databaseConfigApply(BackendSelector::UNSPEC(), ServerSelector::ALL(),
|
||||
lb_modification_time, audit_entries_);
|
||||
|
||||
// The updates should have been merged into current configuration.
|
||||
auto srv_cfg = CfgMgr::instance().getCurrentCfg();
|
||||
|
||||
// If there is an audit entry for global parameter and the parameter
|
||||
// modification time is later than last audit entry time it should
|
||||
// be merged.
|
||||
if (fetchConfigElement("dhcp4_global_parameter") &&
|
||||
(global_parameter->getModificationTime() > lb_modification_time)) {
|
||||
checkConfiguredGlobal(srv_cfg, "foo", Element::create("bar"));
|
||||
|
||||
} else {
|
||||
// Otherwise it shouldn't exist.
|
||||
EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
|
||||
}
|
||||
|
||||
// If there is an audit entry for option definition and the definition
|
||||
// modification time is later than last audit entry time it should
|
||||
// be merged.
|
||||
auto found_def = srv_cfg->getCfgOptionDef()->get("isc", "one");
|
||||
if (fetchConfigElement("dhcp4_option_def") &&
|
||||
def->getModificationTime() > lb_modification_time) {
|
||||
ASSERT_TRUE(found_def);
|
||||
EXPECT_EQ(101, found_def->getCode());
|
||||
EXPECT_EQ(OptionDataType::OPT_UINT16_TYPE, found_def->getType());
|
||||
|
||||
} else {
|
||||
EXPECT_FALSE(found_def);
|
||||
}
|
||||
|
||||
// If there is an audit entry for an option and the option
|
||||
// modification time is later than last audit entry time it should
|
||||
// be merged.
|
||||
auto options = srv_cfg->getCfgOption();
|
||||
auto found_opt = options->get("dhcp4", DHO_HOST_NAME);
|
||||
if (fetchConfigElement("dhcp4_options") &&
|
||||
(opt->getModificationTime() > lb_modification_time)) {
|
||||
ASSERT_TRUE(found_opt.option_);
|
||||
EXPECT_EQ("new.example.com", found_opt.option_->toString());
|
||||
|
||||
} else {
|
||||
EXPECT_FALSE(found_opt.option_);
|
||||
}
|
||||
|
||||
// If there is an audit entry for a shared network and the network
|
||||
// modification time is later than last audit entry time it should
|
||||
// be merged.
|
||||
auto networks = srv_cfg->getCfgSharedNetworks4();
|
||||
auto found_network = networks->getByName("one");
|
||||
if (fetchConfigElement("dhcp4_shared_network") &&
|
||||
(network->getModificationTime() > lb_modification_time)) {
|
||||
EXPECT_TRUE(found_network);
|
||||
|
||||
} else {
|
||||
EXPECT_FALSE(found_network);
|
||||
}
|
||||
|
||||
// If there is an audit entry for a subnet and the subnet modification
|
||||
// time is later than last audit entry time it should be merged.
|
||||
auto subnets = srv_cfg->getCfgSubnets4();
|
||||
auto found_subnet = subnets->getSubnet(1);
|
||||
if (fetchConfigElement("dhcp4_subnet") &&
|
||||
(subnet->getModificationTime() > lb_modification_time)) {
|
||||
EXPECT_TRUE(found_subnet);
|
||||
|
||||
} else {
|
||||
EXPECT_FALSE(found_subnet);
|
||||
}
|
||||
}
|
||||
|
||||
TestCBControlDHCPv4 ctl_;
|
||||
};
|
||||
|
||||
|
||||
// This test verifies that the configuration updates for all object
|
||||
// types are merged into the current configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyAll) {
|
||||
|
||||
addCreateAuditEntry("dhcp4_global_parameter");
|
||||
addCreateAuditEntry("dhcp4_option_def");
|
||||
addCreateAuditEntry("dhcp4_options");
|
||||
addCreateAuditEntry("dhcp4_shared_network");
|
||||
addCreateAuditEntry("dhcp4_subnet");
|
||||
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that only a global parameter is merged into
|
||||
// the current configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyGlobal) {
|
||||
addCreateAuditEntry("dhcp4_global_parameter");
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that global parameter is not fetched from the
|
||||
// database when the modification time is earlier than the last
|
||||
// fetched audit entry.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyGlobalNotFetched) {
|
||||
addCreateAuditEntry("dhcp4_global_parameter");
|
||||
testDatabaseConfigApply(getTimestamp(-3));
|
||||
}
|
||||
|
||||
// This test verifies that only an option definition is merged into
|
||||
// the current configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionDef) {
|
||||
addCreateAuditEntry("dhcp4_option_def");
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that option definition is not fetched from the
|
||||
// database when the modification time is earlier than the last
|
||||
// fetched audit entry.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionDefNotFetched) {
|
||||
addCreateAuditEntry("dhcp4_option_def");
|
||||
testDatabaseConfigApply(getTimestamp(-3));
|
||||
}
|
||||
|
||||
// This test verifies that only a DHCPv4 option is merged into the
|
||||
// current configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyOption) {
|
||||
addCreateAuditEntry("dhcp4_options");
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that DHCPv4 option is not fetched from the
|
||||
// database when the modification time is earlier than the last
|
||||
// fetched audit entry.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionNotFetched) {
|
||||
addCreateAuditEntry("dhcp4_options");
|
||||
testDatabaseConfigApply(getTimestamp(-3));
|
||||
}
|
||||
|
||||
// This test verifies that only a shared network is merged into the
|
||||
// current configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplySharedNetwork) {
|
||||
addCreateAuditEntry("dhcp4_shared_network");
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that shared network is not fetched from the
|
||||
// database when the modification time is earlier than the last
|
||||
// fetched audit entry.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplySharedNetworkNotFetched) {
|
||||
addCreateAuditEntry("dhcp4_shared_network");
|
||||
testDatabaseConfigApply(getTimestamp(-3));
|
||||
}
|
||||
|
||||
// This test verifies that only a subnet is merged into the current
|
||||
// configuration.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplySubnet) {
|
||||
addCreateAuditEntry("dhcp4_subnet");
|
||||
testDatabaseConfigApply(getTimestamp(-5));
|
||||
}
|
||||
|
||||
// This test verifies that subnet is not fetched from the database
|
||||
// when the modification time is earlier than the last fetched audit
|
||||
// entry.
|
||||
TEST_F(CBControlDHCPv4Test, databaseConfigApplySubnetNotFetched) {
|
||||
addCreateAuditEntry("dhcp4_subnet");
|
||||
testDatabaseConfigApply(getTimestamp(-3));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include <util/buffer.h>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace isc::data;
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
namespace test {
|
||||
@@ -99,6 +101,28 @@ GenericBackendTest::testOptionsEquivalent(const OptionDescriptor& ref_option,
|
||||
EXPECT_EQ(ref_option.space_name_, tested_option.space_name_);
|
||||
}
|
||||
|
||||
void
|
||||
GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
|
||||
const std::string &name,
|
||||
ConstElementPtr exp_value) {
|
||||
ConstElementPtr globals = srv_cfg->getConfiguredGlobals();
|
||||
ConstElementPtr found_global = globals->get(name);
|
||||
ASSERT_TRUE(found_global) << "expected global: "
|
||||
<< name << " not found";
|
||||
|
||||
ASSERT_EQ(exp_value->getType(), found_global->getType())
|
||||
<< "expected global: " << name << " has wrong type";
|
||||
|
||||
ASSERT_EQ(*exp_value, *found_global)
|
||||
<< "expected global: " << name << " has wrong value";
|
||||
}
|
||||
|
||||
void
|
||||
GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
|
||||
StampedValuePtr& exp_global) {
|
||||
checkConfiguredGlobal(srv_cfg, exp_global->getName(), exp_global->getElementValue());
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace isc::dhcp::test
|
||||
} // end of namespace isc::dhcp
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2018-2019 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
|
||||
@@ -8,8 +8,10 @@
|
||||
#define GENERIC_BACKEND_UNITTEST_H
|
||||
|
||||
#include <asiolink/io_address.h>
|
||||
#include <cc/stamped_value.h>
|
||||
#include <dhcp/option.h>
|
||||
#include <dhcpsrv/cfg_option.h>
|
||||
#include <dhcpsrv/srv_config.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdint>
|
||||
@@ -242,6 +244,26 @@ public:
|
||||
/// @param tested_option Option returned by the backend to be tested.
|
||||
void testOptionsEquivalent(const OptionDescriptor& ref_option,
|
||||
const OptionDescriptor& tested_option) const;
|
||||
|
||||
/// @brief Tests that a given global is in the configured globals
|
||||
///
|
||||
/// @param srv_cfg server config where the global should be checked.
|
||||
/// @param name name of the global parameter
|
||||
/// @param exp_value expected value of the global paramter as an Element
|
||||
void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
|
||||
const std::string &name,
|
||||
data::ConstElementPtr exp_value);
|
||||
|
||||
/// @brief Tests that a given global is in the configured globals
|
||||
///
|
||||
/// @param srv_cfg server config where the global should be checked.
|
||||
/// @param exp_global StampedValue representing the global value to verify
|
||||
///
|
||||
/// @todo At the point in time StampedVlaue carries type, exp_type should be
|
||||
/// replaced with exp_global->getType()
|
||||
void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
|
||||
data::StampedValuePtr& exp_global);
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace isc::dhcp::test
|
||||
|
@@ -211,7 +211,7 @@ public:
|
||||
// into the given configuration.
|
||||
if (!fetch_updates_only || !audit_entries.empty()) {
|
||||
try {
|
||||
databaseConfigApply(srv_cfg, backend_selector, server_selector,
|
||||
databaseConfigApply(backend_selector, server_selector,
|
||||
lb_modification_time, audit_entries);
|
||||
} catch (...) {
|
||||
// Revert last audit entry time so as we can retry from the
|
||||
@@ -280,7 +280,6 @@ protected:
|
||||
/// - Merge the fetched configuration into the local server's
|
||||
/// configuration.
|
||||
///
|
||||
/// @pararm srv_cfg Pointer to the local server configuration.
|
||||
/// @param backend_selector Backend selector.
|
||||
/// @param server_selector Server selector.
|
||||
/// @param lb_modification_time Lower bound modification time for the
|
||||
@@ -288,8 +287,7 @@ protected:
|
||||
/// @param audit_entries Audit entries fetched from the database since
|
||||
/// the last configuration update. This collection is empty if there
|
||||
/// were no updates.
|
||||
virtual void databaseConfigApply(const ConfigPtr& srv_cfg,
|
||||
const db::BackendSelector& backend_selector,
|
||||
virtual void databaseConfigApply(const db::BackendSelector& backend_selector,
|
||||
const db::ServerSelector& server_selector,
|
||||
const boost::posix_time::ptime& lb_modification_time,
|
||||
const db::AuditEntryCollection& audit_entries) = 0;
|
||||
|
@@ -245,8 +245,7 @@ public:
|
||||
/// @param backend_selector Backend selector.
|
||||
/// @param server_selector Server selector.
|
||||
/// @param audit_entries Collection of audit entries.
|
||||
virtual void databaseConfigApply(const ConfigPtr& srv_cfg,
|
||||
const BackendSelector& backend_selector,
|
||||
virtual void databaseConfigApply(const BackendSelector& backend_selector,
|
||||
const ServerSelector& server_selector,
|
||||
const boost::posix_time::ptime&,
|
||||
const AuditEntryCollection& audit_entries) {
|
||||
|
Reference in New Issue
Block a user