123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736 |
- // Copyright (C) 2014-2016 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 <dhcpsrv/host.h>
- #include <boost/scoped_ptr.hpp>
- #include <gtest/gtest.h>
- using namespace isc;
- using namespace isc::dhcp;
- using namespace isc::asiolink;
- namespace {
- // This test verifies that it is possible to create IPv6 address
- // reservation.
- TEST(IPv6ResrvTest, constructorAddress) {
- IPv6Resrv resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::cafe"));
- EXPECT_EQ("2001:db8:1::cafe", resrv.getPrefix().toText());
- EXPECT_EQ(128, resrv.getPrefixLen());
- EXPECT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
- }
- // This test verifies that it is possible to create IPv6 prefix
- // reservation.
- TEST(IPv6ResrvTest, constructorPrefix) {
- IPv6Resrv resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64);
- EXPECT_EQ("2001:db8:1::", resrv.getPrefix().toText());
- EXPECT_EQ(64, resrv.getPrefixLen());
- EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
- }
- // This test verifies that the toText() function prints correctly.
- TEST(IPv6ResrvTest, toText) {
- IPv6Resrv resrv_prefix(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64);
- EXPECT_EQ("2001:db8:1::/64", resrv_prefix.toText());
- IPv6Resrv resrv_address(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:111::23"));
- EXPECT_EQ("2001:db8:111::23", resrv_address.toText());
- }
- // This test verifies that invalid prefix is rejected.
- TEST(IPv6ResrvTest, constructorInvalidPrefix) {
- // IPv4 address is invalid for IPv6 reservation.
- EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("10.0.0.1"), 128),
- isc::BadValue);
- // Multicast address is invalid for IPv6 reservation.
- EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("ff02:1::2"), 128),
- isc::BadValue);
- }
- // This test verifies that invalid prefix length is rejected.
- TEST(IPv6ResrvTest, constructiorInvalidPrefixLength) {
- ASSERT_NO_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"),
- 128));
- EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 129),
- isc::BadValue);
- EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 244),
- isc::BadValue);
- EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::"), 64),
- isc::BadValue);
- }
- // This test verifies that it is possible to modify prefix and its
- // length in an existing reservation.
- TEST(IPv6ResrvTest, setPrefix) {
- // Create a reservation using an address and prefix length 128.
- IPv6Resrv resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::1"));
- ASSERT_EQ("2001:db8:1::1", resrv.getPrefix().toText());
- ASSERT_EQ(128, resrv.getPrefixLen());
- ASSERT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
- // Modify the reservation to use a prefix having a length of 48.
- ASSERT_NO_THROW(resrv.set(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
- EXPECT_EQ("2001:db8::", resrv.getPrefix().toText());
- EXPECT_EQ(48, resrv.getPrefixLen());
- EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
- // IPv4 address is invalid for IPv6 reservation.
- EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_NA, IOAddress("10.0.0.1"), 128),
- isc::BadValue);
- // IPv6 multicast address is invalid for IPv6 reservation.
- EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_NA, IOAddress("ff02::1:2"), 128),
- isc::BadValue);
- // Prefix length greater than 128 is invalid.
- EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 129),
- isc::BadValue);
- }
- // This test checks that the equality operators work fine.
- TEST(IPv6ResrvTest, equal) {
- EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) ==
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64));
- EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) !=
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64));
- EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) ==
- IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")));
- EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) !=
- IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")));
- EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) ==
- IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2")));
- EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) !=
- IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2")));
- EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) ==
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
- EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) !=
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
- EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1"), 128) ==
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::1"), 128));
- EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1"), 128) !=
- IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::1"), 128));
- }
- // This test verfies that it is possible to create a Host object
- // using hardware address in the textual format.
- TEST(HostTest, createFromHWAddrString) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "somehost.example.org")));
- // The HW address should be set to non-null.
- HWAddrPtr hwaddr = host->getHWAddress();
- ASSERT_TRUE(hwaddr);
- EXPECT_EQ("hwtype=1 01:02:03:04:05:06", hwaddr->toText());
- // DUID should be null if hardware address is in use.
- EXPECT_FALSE(host->getDuid());
- EXPECT_EQ(1, host->getIPv4SubnetID());
- EXPECT_EQ(2, host->getIPv6SubnetID());
- EXPECT_EQ("192.0.2.3", host->getIPv4Reservation().toText());
- EXPECT_EQ("somehost.example.org", host->getHostname());
- // Use invalid identifier name
- EXPECT_THROW(Host("01:02:03:04:05:06", "bogus", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"), "somehost.example.org"),
- isc::BadValue);
- // Use invalid HW address.
- EXPECT_THROW(Host("010203040506", "hw-address", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"), "somehost.example.org"),
- isc::BadValue);
- }
- // This test verifies that it is possible to create Host object using
- // a DUID in the textual format.
- TEST(HostTest, createFromDUIDString) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("a1:b2:c3:d4:e5:06", "duid",
- SubnetID(10), SubnetID(20),
- IOAddress("192.0.2.5"),
- "me.example.org")));
- // DUID should be set to non-null value.
- DuidPtr duid = host->getDuid();
- ASSERT_TRUE(duid);
- EXPECT_EQ("a1:b2:c3:d4:e5:06", duid->toText());
- // Hardware address must be null if DUID is in use.
- EXPECT_FALSE(host->getHWAddress());
- EXPECT_EQ(10, host->getIPv4SubnetID());
- EXPECT_EQ(20, host->getIPv6SubnetID());
- EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
- EXPECT_EQ("me.example.org", host->getHostname());
- // Use invalid DUID.
- EXPECT_THROW(Host("bogus", "duid", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"), "somehost.example.org"),
- isc::BadValue);
- // Empty DUID is also not allowed.
- EXPECT_THROW(Host("", "duid", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"), "somehost.example.org"),
- isc::BadValue);
- }
- // This test verifies that it is possible to create Host object using
- // hardware address in the binary format.
- TEST(HostTest, createFromHWAddrBinary) {
- boost::scoped_ptr<Host> host;
- // Prepare the hardware address in binary format.
- const uint8_t hwaddr_data[] = {
- 0xaa, 0xab, 0xca, 0xda, 0xbb, 0xee
- };
- ASSERT_NO_THROW(host.reset(new Host(hwaddr_data,
- sizeof(hwaddr_data),
- Host::IDENT_HWADDR,
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "somehost.example.org")));
- // Hardware address should be non-null.
- HWAddrPtr hwaddr = host->getHWAddress();
- ASSERT_TRUE(hwaddr);
- EXPECT_EQ("hwtype=1 aa:ab:ca:da:bb:ee", hwaddr->toText());
- // DUID should be null if hardware address is in use.
- EXPECT_FALSE(host->getDuid());
- EXPECT_EQ(1, host->getIPv4SubnetID());
- EXPECT_EQ(2, host->getIPv6SubnetID());
- EXPECT_EQ("192.0.2.3", host->getIPv4Reservation().toText());
- EXPECT_EQ("somehost.example.org", host->getHostname());
- }
- // This test verifies that it is possible to create a Host object using
- // DUID in the binary format.
- TEST(HostTest, createFromDuidBinary) {
- boost::scoped_ptr<Host> host;
- // Prepare DUID binary.
- const uint8_t duid_data[] = {
- 1, 2, 3, 4, 5, 6
- };
- ASSERT_NO_THROW(host.reset(new Host(duid_data,
- sizeof(duid_data),
- Host::IDENT_DUID,
- SubnetID(10), SubnetID(20),
- IOAddress("192.0.2.5"),
- "me.example.org")));
- // DUID should be non null.
- DuidPtr duid = host->getDuid();
- ASSERT_TRUE(duid);
- EXPECT_EQ("01:02:03:04:05:06", duid->toText());
- // Hardware address should be null if DUID is in use.
- EXPECT_FALSE(host->getHWAddress());
- EXPECT_EQ(10, host->getIPv4SubnetID());
- EXPECT_EQ(20, host->getIPv6SubnetID());
- EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
- EXPECT_EQ("me.example.org", host->getHostname());
- }
- // Test that it is possible to replace an identifier for a particular
- // Host instance (HW address -> DUID and vice versa) with a new
- // indentifier in the textual format.
- TEST(HostTest, setIdentifierString) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "me.example.com")));
- // Initially, there should be a HW address, but not a DUID set.
- ASSERT_TRUE(host->getHWAddress());
- ASSERT_FALSE(host->getDuid());
- // Now, use a DUID as identifier.
- ASSERT_NO_THROW(host->setIdentifier("aabbccddee", "duid"));
- // Verify that the DUID is correct.
- DuidPtr duid = host->getDuid();
- ASSERT_TRUE(duid);
- EXPECT_EQ("aa:bb:cc:dd:ee", duid->toText());
- // HW address should be not set.
- EXPECT_FALSE(host->getHWAddress());
- // Now, let's do another way around.
- ASSERT_NO_THROW(host->setIdentifier("09:08:07:06:05:04", "hw-address"));
- // Verify that HW address is correct.
- HWAddrPtr hw_addr = host->getHWAddress();
- ASSERT_TRUE(hw_addr);
- EXPECT_EQ("hwtype=1 09:08:07:06:05:04", hw_addr->toText());
- // DUID should be not set.
- EXPECT_FALSE(host->getDuid());
- }
- // Test that it is possible to replace an identifier for a particular
- // Host instance (HW address -> DUID and vice versa) with the new
- // identifier in the binary format.
- TEST(HostTest, setIdentifierBinary) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "me.example.com")));
- // Initially, there should be a HW address, but not a DUID set.
- ASSERT_TRUE(host->getHWAddress());
- ASSERT_FALSE(host->getDuid());
- // Now, use a DUID as identifier.
- const uint8_t duid_data[] = {
- 0xaa, 0xbb, 0xcc, 0xdd, 0xee
- };
- ASSERT_NO_THROW(host->setIdentifier(duid_data, sizeof(duid_data),
- Host::IDENT_DUID));
- // Verify that the DUID is correct.
- DuidPtr duid = host->getDuid();
- ASSERT_TRUE(duid);
- EXPECT_EQ("aa:bb:cc:dd:ee", duid->toText());
- // HW address should be not set.
- EXPECT_FALSE(host->getHWAddress());
- // Now, let's do another way around.
- const uint8_t hwaddr_data[] = {
- 9, 8, 7, 6, 5, 4
- };
- ASSERT_NO_THROW(host->setIdentifier(hwaddr_data, sizeof(hwaddr_data),
- Host::IDENT_HWADDR));
- // Verify that HW address is correct.
- HWAddrPtr hw_addr = host->getHWAddress();
- ASSERT_TRUE(hw_addr);
- EXPECT_EQ("hwtype=1 09:08:07:06:05:04", hw_addr->toText());
- // DUID should be not set.
- EXPECT_FALSE(host->getDuid());
- }
- /// @brief Checks if the reservation is in the range of reservations.
- ///
- /// @param resrv Reservation to be searched for.
- /// @param range Range of reservations returned by the @c Host object
- /// in which the reservation will be searched.
- bool
- reservationExists(const IPv6Resrv& resrv, const IPv6ResrvRange& range) {
- for (IPv6ResrvIterator it = range.first; it != range.second;
- ++it) {
- if (resrv == it->second) {
- return (true);
- }
- }
- return (false);
- }
- // This test verifies that the IPv6 reservations of a different type can
- // be added for the host.
- TEST(HostTest, addReservations) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"))));
- EXPECT_FALSE(host->hasIPv6Reservation());
- // Add 4 reservations: 2 for NAs, 2 for PDs.
- ASSERT_NO_THROW(
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::cafe")));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:1::"), 64));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:2::"), 64));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::1")));
- );
- EXPECT_TRUE(host->hasIPv6Reservation());
- // Check that reservations exist.
- EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::cafe"))));
- EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:1::"),
- 64)));
- EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:2::"),
- 64)));
- EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::1"))));
- // Get only NA reservations.
- IPv6ResrvRange addresses = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
- ASSERT_EQ(2, std::distance(addresses.first, addresses.second));
- EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::cafe")),
- addresses));
- EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::1")),
- addresses));
- // Get only PD reservations.
- IPv6ResrvRange prefixes = host->getIPv6Reservations(IPv6Resrv::TYPE_PD);
- ASSERT_EQ(2, std::distance(prefixes.first, prefixes.second));
- EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:1::"), 64),
- prefixes));
- EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:2::"), 64),
- prefixes));
- }
- // This test checks that various modifiers may be used to replace the current
- // values of the Host class.
- TEST(HostTest, setValues) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "some-host.example.org")));
- ASSERT_EQ(1, host->getIPv4SubnetID());
- ASSERT_EQ(2, host->getIPv6SubnetID());
- ASSERT_EQ("192.0.2.3", host->getIPv4Reservation().toText());
- ASSERT_EQ("some-host.example.org", host->getHostname());
- host->setIPv4SubnetID(SubnetID(123));
- host->setIPv6SubnetID(SubnetID(234));
- host->setIPv4Reservation(IOAddress("10.0.0.1"));
- host->setHostname("other-host.example.org");
- EXPECT_EQ(123, host->getIPv4SubnetID());
- EXPECT_EQ(234, host->getIPv6SubnetID());
- EXPECT_EQ("10.0.0.1", host->getIPv4Reservation().toText());
- EXPECT_EQ("other-host.example.org", host->getHostname());
- // Remove IPv4 reservation.
- host->removeIPv4Reservation();
- EXPECT_EQ(IOAddress::IPV4_ZERO_ADDRESS(), host->getIPv4Reservation());
- // An IPv6 address can't be used for IPv4 reservations.
- EXPECT_THROW(host->setIPv4Reservation(IOAddress("2001:db8:1::1")),
- isc::BadValue);
- // Zero address can't be set, the removeIPv4Reservation should be
- // used intead.
- EXPECT_THROW(host->setIPv4Reservation(IOAddress::IPV4_ZERO_ADDRESS()),
- isc::BadValue);
- // Broadcast address can't be set.
- EXPECT_THROW(host->setIPv4Reservation(IOAddress::IPV4_BCAST_ADDRESS()),
- isc::BadValue);
- }
- // Test that Host constructors initialize client classes from string.
- TEST(HostTest, clientClassesFromConstructor) {
- boost::scoped_ptr<Host> host;
- // Prepare the hardware address in binary format.
- const uint8_t hwaddr_data[] = {
- 0xaa, 0xab, 0xca, 0xda, 0xbb, 0xee
- };
- // Try the "from binary" constructor.
- ASSERT_NO_THROW(host.reset(new Host(hwaddr_data,
- sizeof(hwaddr_data),
- Host::IDENT_HWADDR,
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "somehost.example.org",
- "alpha, , beta",
- "gamma")));
- EXPECT_TRUE(host->getClientClasses4().contains("alpha"));
- EXPECT_TRUE(host->getClientClasses4().contains("beta"));
- EXPECT_FALSE(host->getClientClasses4().contains("gamma"));
- EXPECT_TRUE(host->getClientClasses6().contains("gamma"));
- EXPECT_FALSE(host->getClientClasses6().contains("alpha"));
- EXPECT_FALSE(host->getClientClasses6().contains("beta"));
- // Try the "from string" constructor.
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "somehost.example.org",
- "alpha, beta, gamma",
- "beta, gamma")));
- EXPECT_TRUE(host->getClientClasses4().contains("alpha"));
- EXPECT_TRUE(host->getClientClasses4().contains("beta"));
- EXPECT_TRUE(host->getClientClasses4().contains("gamma"));
- EXPECT_FALSE(host->getClientClasses6().contains("alpha"));
- EXPECT_TRUE(host->getClientClasses6().contains("beta"));
- EXPECT_TRUE(host->getClientClasses6().contains("gamma"));
- }
- // Test that new client classes can be added for the Host.
- TEST(HostTest, addClientClasses) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"))));
- EXPECT_FALSE(host->getClientClasses4().contains("foo"));
- EXPECT_FALSE(host->getClientClasses6().contains("foo"));
- EXPECT_FALSE(host->getClientClasses4().contains("bar"));
- EXPECT_FALSE(host->getClientClasses6().contains("bar"));
- host->addClientClass4("foo");
- host->addClientClass6("bar");
- EXPECT_TRUE(host->getClientClasses4().contains("foo"));
- EXPECT_FALSE(host->getClientClasses6().contains("foo"));
- EXPECT_FALSE(host->getClientClasses4().contains("bar"));
- EXPECT_TRUE(host->getClientClasses6().contains("bar"));
- host->addClientClass4("bar");
- host->addClientClass6("foo");
- EXPECT_TRUE(host->getClientClasses4().contains("foo"));
- EXPECT_TRUE(host->getClientClasses6().contains("foo"));
- EXPECT_TRUE(host->getClientClasses4().contains("bar"));
- EXPECT_TRUE(host->getClientClasses6().contains("bar"));
- }
- // This test checks that it is possible to add DHCPv4 options for a host.
- TEST(HostTest, addOptions4) {
- Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"));
- // Differentiate options by their codes (100-109)
- for (uint16_t code = 100; code < 110; ++code) {
- OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "dhcp4"));
- }
- // Add 7 options to another option space. The option codes partially overlap
- // with option codes that we have added to dhcp4 option space.
- for (uint16_t code = 105; code < 112; ++code) {
- OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "isc"));
- }
- // Get options from the Subnet and check if all 10 are there.
- OptionContainerPtr options = host.getCfgOption4()->getAll("dhcp4");
- ASSERT_TRUE(options);
- ASSERT_EQ(10, options->size());
- // It should be possible to retrieve DHCPv6 options but the container
- // should be empty.
- OptionContainerPtr options6 = host.getCfgOption6()->getAll("dhcp6");
- ASSERT_TRUE(options6);
- EXPECT_TRUE(options6->empty());
- // Also make sure that for dhcp4 option space no DHCPv6 options are
- // returned. This is to check that containers for DHCPv4 and DHCPv6
- // options do not share information.
- options6 = host.getCfgOption6()->getAll("dhcp4");
- ASSERT_TRUE(options6);
- EXPECT_TRUE(options6->empty());
- // Validate codes of options added to dhcp4 option space.
- uint16_t expected_code = 100;
- for (OptionContainer::const_iterator option_desc = options->begin();
- option_desc != options->end(); ++option_desc) {
- ASSERT_TRUE(option_desc->option_);
- EXPECT_EQ(expected_code, option_desc->option_->getType());
- ++expected_code;
- }
- options = host.getCfgOption4()->getAll("isc");
- ASSERT_TRUE(options);
- ASSERT_EQ(7, options->size());
- // Validate codes of options added to isc option space.
- expected_code = 105;
- for (OptionContainer::const_iterator option_desc = options->begin();
- option_desc != options->end(); ++option_desc) {
- ASSERT_TRUE(option_desc->option_);
- EXPECT_EQ(expected_code, option_desc->option_->getType());
- ++expected_code;
- }
- // Try to get options from a non-existing option space.
- options = host.getCfgOption4()->getAll("abcd");
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
- }
- // This test checks that it is possible to add DHCPv6 options for a host.
- TEST(HostTest, addOptions6) {
- Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"));
- // Differentiate options by their codes (100-109)
- for (uint16_t code = 100; code < 110; ++code) {
- OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "dhcp6"));
- }
- // Add 7 options to another option space. The option codes partially overlap
- // with option codes that we have added to dhcp6 option space.
- for (uint16_t code = 105; code < 112; ++code) {
- OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "isc"));
- }
- // Get options from the Subnet and check if all 10 are there.
- OptionContainerPtr options = host.getCfgOption6()->getAll("dhcp6");
- ASSERT_TRUE(options);
- ASSERT_EQ(10, options->size());
- // It should be possible to retrieve DHCPv4 options but the container
- // should be empty.
- OptionContainerPtr options4 = host.getCfgOption4()->getAll("dhcp4");
- ASSERT_TRUE(options4);
- EXPECT_TRUE(options4->empty());
- // Also make sure that for dhcp6 option space no DHCPv4 options are
- // returned. This is to check that containers for DHCPv4 and DHCPv6
- // options do not share information.
- options4 = host.getCfgOption4()->getAll("dhcp6");
- ASSERT_TRUE(options4);
- EXPECT_TRUE(options4->empty());
- // Validate codes of options added to dhcp6 option space.
- uint16_t expected_code = 100;
- for (OptionContainer::const_iterator option_desc = options->begin();
- option_desc != options->end(); ++option_desc) {
- ASSERT_TRUE(option_desc->option_);
- EXPECT_EQ(expected_code, option_desc->option_->getType());
- ++expected_code;
- }
- options = host.getCfgOption6()->getAll("isc");
- ASSERT_TRUE(options);
- ASSERT_EQ(7, options->size());
- // Validate codes of options added to isc option space.
- expected_code = 105;
- for (OptionContainer::const_iterator option_desc = options->begin();
- option_desc != options->end(); ++option_desc) {
- ASSERT_TRUE(option_desc->option_);
- EXPECT_EQ(expected_code, option_desc->option_->getType());
- ++expected_code;
- }
- // Try to get options from a non-existing option space.
- options = host.getCfgOption6()->getAll("abcd");
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
- }
- // This test verifies that it is possible to retrieve a textual
- // representation of the host identifier.
- TEST(HostTest, getIdentifierAsText) {
- Host host1("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"));
- EXPECT_EQ("hwaddr=010203040506", host1.getIdentifierAsText());
- Host host2("0a:0b:0c:0d:0e:0f:ab:cd:ef", "duid",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"));
- EXPECT_EQ("duid=0A0B0C0D0E0FABCDEF",
- host2.getIdentifierAsText());
- }
- // This test checks that Host object is correctly described in the
- // textual format using the toText method.
- TEST(HostTest, toText) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "myhost.example.com")));
- // Add 4 reservations: 2 for NAs, 2 for PDs.
- ASSERT_NO_THROW(
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::cafe")));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:1::"), 64));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
- IOAddress("2001:db8:1:2::"), 64));
- host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
- IOAddress("2001:db8:1::1")));
- );
- // Make sure that the output is correct,
- EXPECT_EQ("hwaddr=010203040506 ipv4_subnet_id=1 ipv6_subnet_id=2"
- " hostname=myhost.example.com"
- " ipv4_reservation=192.0.2.3"
- " ipv6_reservation0=2001:db8:1::cafe"
- " ipv6_reservation1=2001:db8:1::1"
- " ipv6_reservation2=2001:db8:1:1::/64"
- " ipv6_reservation3=2001:db8:1:2::/64",
- host->toText());
- // Reset some of the data and make sure that the output is affected.
- host->setHostname("");
- host->removeIPv4Reservation();
- host->setIPv4SubnetID(0);
- EXPECT_EQ("hwaddr=010203040506 ipv6_subnet_id=2"
- " hostname=(empty) ipv4_reservation=(no)"
- " ipv6_reservation0=2001:db8:1::cafe"
- " ipv6_reservation1=2001:db8:1::1"
- " ipv6_reservation2=2001:db8:1:1::/64"
- " ipv6_reservation3=2001:db8:1:2::/64",
- host->toText());
- // Create host identified by DUID, instead of HWADDR, with a very
- // basic configuration.
- ASSERT_NO_THROW(host.reset(new Host("11:12:13:14:15", "duid",
- SubnetID(0), SubnetID(0),
- IOAddress::IPV4_ZERO_ADDRESS(),
- "myhost")));
- EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)"
- " ipv6_reservations=(none)", host->toText());
- // Add some classes.
- host->addClientClass4("modem");
- host->addClientClass4("router");
- EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)"
- " ipv6_reservations=(none)"
- " dhcp4_class0=modem dhcp4_class1=router",
- host->toText());
- host->addClientClass6("hub");
- host->addClientClass6("device");
- EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)"
- " ipv6_reservations=(none)"
- " dhcp4_class0=modem dhcp4_class1=router"
- " dhcp6_class0=device dhcp6_class1=hub",
- host->toText());
- }
- // Test verifies if the host can store HostId properly.
- TEST(HostTest, hostId) {
- boost::scoped_ptr<Host> host;
- ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
- SubnetID(1), SubnetID(2),
- IOAddress("192.0.2.3"),
- "myhost.example.com")));
- EXPECT_EQ(0, host->getHostId());
- EXPECT_NO_THROW(host->setHostId(12345));
- EXPECT_EQ(12345, host->getHostId());
- }
- } // end of anonymous namespace
|