diff options
Diffstat (limited to 'src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc')
-rw-r--r-- | src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc | 267 |
1 files changed, 264 insertions, 3 deletions
diff --git a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc index e42260386a..575a0b8e90 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2017 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 @@ -12,12 +12,14 @@ #include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet_id.h> #include <dhcpsrv/subnet_selector.h> +#include <testutils/test_to_element.h> #include <gtest/gtest.h> #include <string> using namespace isc; using namespace isc::asiolink; using namespace isc::dhcp; +using namespace isc::test; namespace { @@ -30,6 +32,82 @@ generateInterfaceId(const std::string& text) { return OptionPtr(new Option(Option::V6, D6O_INTERFACE_ID, buffer)); } +// This test verifies that specific subnet can be retrieved by specifying +// subnet identifier or subnet prefix. +TEST(CfgSubnets6Test, getSpecificSubnet) { + CfgSubnets6 cfg; + + // Create 3 subnets. + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4, + SubnetID(5))); + Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4, + SubnetID(8))); + Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4, + SubnetID(10))); + + // Store the subnets in a vector to make it possible to loop over + // all configured subnets. + std::vector<Subnet6Ptr> subnets; + subnets.push_back(subnet1); + subnets.push_back(subnet2); + subnets.push_back(subnet3); + + // Add all subnets to the configuration. + for (auto subnet = subnets.cbegin(); subnet != subnets.cend(); ++subnet) { + ASSERT_NO_THROW(cfg.add(*subnet)) << "failed to add subnet with id: " + << (*subnet)->getID(); + } + + // Iterate over all subnets and make sure they can be retrieved by + // subnet identifier. + for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) { + ConstSubnet6Ptr subnet_returned = cfg.getBySubnetId((*subnet)->getID()); + ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: " + << (*subnet)->getID(); + EXPECT_EQ((*subnet)->getID(), subnet_returned->getID()); + EXPECT_EQ((*subnet)->toText(), subnet_returned->toText()); + } + + // Repeat the previous test, but this time retrieve subnets by their + // prefixes. + for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) { + ConstSubnet6Ptr subnet_returned = cfg.getByPrefix((*subnet)->toText()); + ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: " + << (*subnet)->getID(); + EXPECT_EQ((*subnet)->getID(), subnet_returned->getID()); + EXPECT_EQ((*subnet)->toText(), subnet_returned->toText()); + } + + // Make sure that null pointers are returned for non-existing subnets. + EXPECT_FALSE(cfg.getBySubnetId(SubnetID(123))); + EXPECT_FALSE(cfg.getByPrefix("3000::/16")); +} + +// This test verifies that a single subnet can be removed from the configuration. +TEST(CfgSubnets6Test, deleteSubnet) { + CfgSubnets6 cfg; + + // Create 3 subnets. + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4)); + Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4)); + Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4)); + + ASSERT_NO_THROW(cfg.add(subnet1)); + ASSERT_NO_THROW(cfg.add(subnet2)); + ASSERT_NO_THROW(cfg.add(subnet3)); + + // There should be three subnets. + ASSERT_EQ(3, cfg.getAll()->size()); + // We're going to remove the subnet #2. Let's make sure it exists before + // we remove it. + ASSERT_TRUE(cfg.getByPrefix("2001:db8:2::/48")); + + // Remove the subnet and make sure it is gone. + ASSERT_NO_THROW(cfg.del(subnet2)); + ASSERT_EQ(2, cfg.getAll()->size()); + EXPECT_FALSE(cfg.getByPrefix("2001:db8:2::/48")); +} + // This test checks that the subnet can be selected using a relay agent's // link address. TEST(CfgSubnets6Test, selectSubnetByRelayAddress) { @@ -240,9 +318,9 @@ TEST(CfgSubnets6Test, selectSubnetByRelayAddressAndClassify) { EXPECT_FALSE(cfg.selectSubnet(selector)); } -// Test that client classes are considered when the subnet is selcted by the +// Test that client classes are considered when the subnet is selected by the // interface name. -TEST(CfgSubnets6Test, selectSubnetByInterfaceNameAndClaassify) { +TEST(CfgSubnets6Test, selectSubnetByInterfaceNameAndClassify) { CfgSubnets6 cfg; Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4)); @@ -342,4 +420,187 @@ TEST(CfgSubnets6Test, duplication) { EXPECT_THROW(cfg.add(subnet3), isc::dhcp::DuplicateSubnetID); } +// This test check if IPv6 subnets can be unparsed in a predictable way, +TEST(CfgSubnets6Test, unparseSubnet) { + CfgSubnets6 cfg; + + // Add some subnets. + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), + 48, 1, 2, 3, 4, 123)); + Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), + 48, 1, 2, 3, 4, 124)); + Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), + 48, 1, 2, 3, 4, 125)); + + OptionPtr ifaceid = generateInterfaceId("relay.eth0"); + subnet1->setInterfaceId(ifaceid); + subnet1->allowClientClass("foo"); + subnet2->setIface("lo"); + subnet2->setRelayInfo(IOAddress("2001:db8:ff::2")); + subnet3->setIface("eth1"); + + cfg.add(subnet1); + cfg.add(subnet2); + cfg.add(subnet3); + + // Unparse + std::string expected = "[\n" + "{\n" + " \"id\": 123,\n" + " \"subnet\": \"2001:db8:1::/48\",\n" + " \"relay\": { \"ip-address\": \"::\" },\n" + " \"interface-id\": \"relay.eth0\",\n" + " \"renew-timer\": 1,\n" + " \"rebind-timer\": 2,\n" + " \"preferred-lifetime\": 3,\n" + " \"valid-lifetime\": 4,\n" + " \"rapid-commit\": false,\n" + " \"reservation-mode\": \"all\",\n" + " \"client-class\": \"foo\",\n" + " \"pools\": [ ],\n" + " \"pd-pools\": [ ],\n" + " \"option-data\": [ ]\n" + "},{\n" + " \"id\": 124,\n" + " \"subnet\": \"2001:db8:2::/48\",\n" + " \"relay\": { \"ip-address\": \"2001:db8:ff::2\" },\n" + " \"interface\": \"lo\",\n" + " \"renew-timer\": 1,\n" + " \"rebind-timer\": 2,\n" + " \"preferred-lifetime\": 3,\n" + " \"valid-lifetime\": 4,\n" + " \"rapid-commit\": false,\n" + " \"reservation-mode\": \"all\",\n" + " \"pools\": [ ],\n" + " \"pd-pools\": [ ],\n" + " \"option-data\": [ ]\n" + "},{\n" + " \"id\": 125,\n" + " \"subnet\": \"2001:db8:3::/48\",\n" + " \"relay\": { \"ip-address\": \"::\" },\n" + " \"interface\": \"eth1\",\n" + " \"renew-timer\": 1,\n" + " \"rebind-timer\": 2,\n" + " \"preferred-lifetime\": 3,\n" + " \"valid-lifetime\": 4,\n" + " \"rapid-commit\": false,\n" + " \"reservation-mode\": \"all\",\n" + " \"pools\": [ ],\n" + " \"pd-pools\": [ ],\n" + " \"option-data\": [ ]\n" + "} ]\n"; + runToElementTest<CfgSubnets6>(expected, cfg); +} + +// This test check if IPv6 pools can be unparsed in a predictable way, +TEST(CfgSubnets6Test, unparsePool) { + CfgSubnets6 cfg; + + // Add a subnet with pools + Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), + 48, 1, 2, 3, 4, 123)); + Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, + IOAddress("2001:db8:1::100"), + IOAddress("2001:db8:1::199"))); + Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64)); + + subnet->addPool(pool1); + subnet->addPool(pool2); + cfg.add(subnet); + + // Unparse + std::string expected = "[\n" + "{\n" + " \"id\": 123,\n" + " \"subnet\": \"2001:db8:1::/48\",\n" + " \"relay\": { \"ip-address\": \"::\" },\n" + " \"renew-timer\": 1,\n" + " \"rebind-timer\": 2,\n" + " \"preferred-lifetime\": 3,\n" + " \"valid-lifetime\": 4,\n" + " \"rapid-commit\": false,\n" + " \"reservation-mode\": \"all\",\n" + " \"pools\": [\n" + " {\n" + " \"pool\": \"2001:db8:1::100-2001:db8:1::199\",\n" + " \"option-data\": [ ]\n" + " },{\n" + " \"pool\": \"2001:db8:1:1::/64\",\n" + " \"option-data\": [ ]\n" + " }\n" + " ],\n" + " \"pd-pools\": [ ],\n" + " \"option-data\": [ ]\n" + "} ]\n"; + runToElementTest<CfgSubnets6>(expected, cfg); +} + +// This test check if IPv6 prefix delegation pools can be unparsed +// in a predictable way, +TEST(CfgSubnets6Test, unparsePdPool) { + CfgSubnets6 cfg; + + // Add a subnet with pd-pools + Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), + 48, 1, 2, 3, 4, 123)); + Pool6Ptr pdpool1(new Pool6(Lease::TYPE_PD, + IOAddress("2001:db8:2::"), 48, 64)); + Pool6Ptr pdpool2(new Pool6(IOAddress("2001:db8:3::"), 48, 56, + IOAddress("2001:db8:3::"), 64)); + + subnet->addPool(pdpool1); + subnet->addPool(pdpool2); + cfg.add(subnet); + + // Unparse + std::string expected = "[\n" + "{\n" + " \"id\": 123,\n" + " \"subnet\": \"2001:db8:1::/48\",\n" + " \"relay\": { \"ip-address\": \"::\" },\n" + " \"renew-timer\": 1,\n" + " \"rebind-timer\": 2,\n" + " \"preferred-lifetime\": 3,\n" + " \"valid-lifetime\": 4,\n" + " \"rapid-commit\": false,\n" + " \"reservation-mode\": \"all\",\n" + " \"pools\": [ ],\n" + " \"pd-pools\": [\n" + " {\n" + " \"prefix\": \"2001:db8:2::\",\n" + " \"prefix-len\": 48,\n" + " \"delegated-len\": 64,\n" + " \"option-data\": [ ]\n" + " },{\n" + " \"prefix\": \"2001:db8:3::\",\n" + " \"prefix-len\": 48,\n" + " \"delegated-len\": 56,\n" + " \"excluded-prefix\": \"2001:db8:3::\",\n" + " \"excluded-prefix-len\": 64,\n" + " \"option-data\": [ ]\n" + " }\n" + " ],\n" + " \"option-data\": [ ]\n" + "} ]\n"; + runToElementTest<CfgSubnets6>(expected, cfg); +} + +// This test verifies that it is possible to retrieve a subnet using subnet-id. +TEST(CfgSubnets6Test, getSubnet) { + CfgSubnets6 cfg; + + // Let's configure 3 subnets + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4, 100)); + Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4, 200)); + Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4, 300)); + cfg.add(subnet1); + cfg.add(subnet2); + cfg.add(subnet3); + + EXPECT_EQ(subnet1, cfg.getSubnet(100)); + EXPECT_EQ(subnet2, cfg.getSubnet(200)); + EXPECT_EQ(subnet3, cfg.getSubnet(300)); + EXPECT_EQ(Subnet6Ptr(), cfg.getSubnet(400)); // no such subnet +} + } // end of anonymous namespace |