Commit 7d63012c authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3562] Added more tests for HostReservationParser class.

parent 228c2228
......@@ -30,7 +30,7 @@ void
IPv6Resrv::set(const asiolink::IOAddress& prefix, const uint8_t prefix_len) {
if (!prefix.isV6() || prefix.isV6Multicast()) {
isc_throw(isc::BadValue, "invalid prefix '" << prefix
<< " for new IPv6 reservation");
<< "' for new IPv6 reservation");
} else if (prefix_len > 128) {
isc_throw(isc::BadValue, "invalid prefix length '"
......@@ -61,12 +61,16 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
ipv6_subnet_id_(ipv6_subnet_id),
ipv4_reservation_(asiolink::IOAddress("0.0.0.0")),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_len, identifier_type);
// Validate and set IPv4 address reservation.
setIPv4Reservation(ipv4_reservation);
}
Host::Host(const std::string& identifier, const std::string& identifier_name,
......@@ -76,12 +80,16 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
ipv6_subnet_id_(ipv6_subnet_id),
ipv4_reservation_(asiolink::IOAddress("0.0.0.0")),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_name);
// Validate and set IPv4 address reservation.
setIPv4Reservation(ipv4_reservation);
}
const std::vector<uint8_t>&
......@@ -138,6 +146,16 @@ Host::setIdentifier(const std::string& identifier, const std::string& name) {
}
}
void
Host::setIPv4Reservation(const asiolink::IOAddress& address) {
if (!address.isV4()) {
isc_throw(isc::BadValue, "address '" << address << "' is not a valid"
" IPv4 address");
}
ipv4_reservation_ = address;
}
void
Host::addReservation(const IPv6Resrv& reservation) {
ipv6_reservations_.insert(IPv6ResrvTuple(reservation.getType(),
......
......@@ -316,9 +316,9 @@ public:
/// The new reservation removes a previous reservation.
///
/// @param address Address to be reserved for the client.
void setIPv4Reservation(const asiolink::IOAddress& address) {
ipv4_reservation_ = address;
}
///
/// @throw isc::BadValue if the provided address is not an IPv4 address.
void setIPv4Reservation(const asiolink::IOAddress& address);
/// @brief Returns reserved IPv4 address.
///
......
......@@ -101,7 +101,8 @@ HostReservationParser4::build(isc::data::ConstElementPtr reservation_data) {
BOOST_FOREACH(ConfigPair element, reservation_data->mapValue()) {
try {
if (element.first == "ip-address") {
host_->setIPv4Reservation(IOAddress(element.second->stringValue()));
host_->setIPv4Reservation(IOAddress(element.second->
stringValue()));
}
}
catch (const std::exception& ex) {
......
......@@ -241,15 +241,21 @@ TEST_F(CfgHostsTest, get6) {
// Add hosts.
for (int i = 0; i < 25; ++i) {
// Add host identified by HW address.
cfg.add(HostPtr(new Host(hwaddrs_[i]->toText(false),
"hw-address",
SubnetID(10), SubnetID(1 + i % 2),
increase(IOAddress("2001:db8:1::1"), i))));
HostPtr host = HostPtr(new Host(hwaddrs_[i]->toText(false),
"hw-address",
SubnetID(10), SubnetID(1 + i % 2),
IOAddress("0.0.0.0")));
host->addReservation(IPv6Resrv(increase(IOAddress("2001:db8:1::1"),
i)));
cfg.add(host);
// Add host identified by DUID.
cfg.add(HostPtr(new Host(duids_[i]->toText(), "duid",
SubnetID(10), SubnetID(1 + i % 2),
increase(IOAddress("2001:db8:2::1"), i))));
host = HostPtr(new Host(duids_[i]->toText(), "duid",
SubnetID(10), SubnetID(1 + i % 2),
IOAddress("0.0.0.0")));
host->addReservation(IPv6Resrv(increase(IOAddress("2001:db8:2::1"),
i)));
cfg.add(host);
}
for (int i = 0; i < 25; ++i) {
......@@ -260,8 +266,11 @@ TEST_F(CfgHostsTest, get6) {
hwaddrs_[i]);
ASSERT_TRUE(host);
EXPECT_EQ(1 + i % 2, host->getIPv6SubnetID());
IPv6ResrvRange reservations =
host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(1, std::distance(reservations.first, reservations.second));
EXPECT_EQ(increase(IOAddress("2001:db8:1::1"), i),
host->getIPv4Reservation());
reservations.first->second.getPrefix());
// Retrieve host by DUID. The HW address is non-null but there is no
// reservation made for the HW address so the reservation is returned
......@@ -269,8 +278,10 @@ TEST_F(CfgHostsTest, get6) {
host = cfg.get6(SubnetID(1 + i % 2), duids_[i], hwaddrs_[i + 25]);
ASSERT_TRUE(host);
EXPECT_EQ(1 + i % 2, host->getIPv6SubnetID());
reservations = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(1, std::distance(reservations.first, reservations.second));
EXPECT_EQ(increase(IOAddress("2001:db8:2::1"), i),
host->getIPv4Reservation());
reservations.first->second.getPrefix());
}
// Also check that when the get6 finds multiple Host objects that fulfil
......
......@@ -62,6 +62,9 @@ protected:
return (false);
}
void
expectFailure(const HostReservationParser& parser,
const std::string& config) const;
/// @brief HW Address object used by tests.
HWAddrPtr hwaddr_;
......@@ -138,6 +141,43 @@ TEST_F(HostReservationParserTest, dhcp4DUID) {
EXPECT_TRUE(hosts[0]->getHostname().empty());
}
// This test verifies that the configuration parser for host reservations
// throws an exception when IPv6 address is specified for IPv4 address
// reservation.
TEST_F(HostReservationParserTest, dhcp4IPv6Address) {
std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
"\"ip-address\": \"2001:db8:1::1\" }";
ElementPtr config_element = Element::fromJSON(config);
HostReservationParser4 parser(SubnetID(10));
EXPECT_THROW(parser.build(config_element), DhcpConfigError);
}
// This test verifies that the configuration parser for host reservations
// throws an exception when no HW address nor DUID is specified.
TEST_F(HostReservationParserTest, noIdentifier) {
std::string config = "{ \"ip-address\": \"192.0.2.112\","
"\"hostname\": \"\" }";
ElementPtr config_element = Element::fromJSON(config);
HostReservationParser4 parser(SubnetID(10));
EXPECT_THROW(parser.build(config_element), DhcpConfigError);
}
// This test verifies that the configuration parser for host reservations
// throws an exception when invalid IP address is specified.
TEST_F(HostReservationParserTest, malformedAddress) {
std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
"\"ip-address\": \"192.0.2.bogus\" }";
ElementPtr config_element = Element::fromJSON(config);
HostReservationParser4 parser(SubnetID(10));
EXPECT_THROW(parser.build(config_element), DhcpConfigError);
}
// This test verfies that the parser can parse the IPv6 reservation entry for
// which hw-address is a host identifier.
TEST_F(HostReservationParserTest, dhcp6HWaddr) {
......@@ -218,5 +258,18 @@ TEST_F(HostReservationParserTest, dhcp6DUID) {
ASSERT_EQ(0, std::distance(prefixes.first, prefixes.second));
}
// This test verifies that the configuration parser throws an exception
// when IPv4 address is specified for IPv6 reservation.
TEST_F(HostReservationParserTest, dhcp6IPv4Address) {
std::string config = "{ \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
"\"ip-addresses\": [ \"192.0.2.3\", \"2001:db8:1::200\" ],"
"\"prefixes\": [ ] }";
ElementPtr config_element = Element::fromJSON(config);
HostReservationParser6 parser(SubnetID(12));
EXPECT_THROW(parser.build(config_element), DhcpConfigError);
}
} // end of anonymous namespace
......@@ -380,6 +380,10 @@ TEST(HostTest, setValues) {
EXPECT_EQ(234, host->getIPv6SubnetID());
EXPECT_EQ("10.0.0.1", host->getIPv4Reservation().toText());
EXPECT_EQ("other-host.example.org", host->getHostname());
// An IPv6 address can't be used for IPv4 reservations.
EXPECT_THROW(host->setIPv4Reservation(IOAddress("2001:db8:1::1")),
isc::BadValue);
}
// Test that Host constructors initialize client classes from string.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment