summaryrefslogtreecommitdiffstats
path: root/src/lib/yang/tests/adaptor_pool_unittests.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/yang/tests/adaptor_pool_unittests.cc')
-rw-r--r--src/lib/yang/tests/adaptor_pool_unittests.cc274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/lib/yang/tests/adaptor_pool_unittests.cc b/src/lib/yang/tests/adaptor_pool_unittests.cc
new file mode 100644
index 0000000..dd70716
--- /dev/null
+++ b/src/lib/yang/tests/adaptor_pool_unittests.cc
@@ -0,0 +1,274 @@
+// Copyright (C) 2018-2021 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 <testutils/gtest_utils.h>
+#include <yang/adaptor_pool.h>
+#include <yang/yang_models.h>
+
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::data;
+using namespace isc::yang;
+
+namespace {
+
+// Verifies that canonizePool does not touch a prefix without space.
+TEST(AdaptorPoolTest, canonizePoolPrefixNoSpace) {
+ string config = "{\n"
+ " \"pool\": \"192.0.2.128/28\"\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ EXPECT_NO_THROW(AdaptorPool::canonizePool(json));
+ EXPECT_TRUE(copied->equals(*json));
+}
+
+// Verifies that canonizePool does not touch a canonical range.
+TEST(AdaptorPoolTest, canonizePoolRange) {
+ string config = "{\n"
+ " \"pool\": \"192.0.2.1 - 192.0.2.200\"\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ EXPECT_NO_THROW(AdaptorPool::canonizePool(json));
+ EXPECT_TRUE(copied->equals(*json));
+}
+
+// Verifies that canonizePool removes spaces from a prefix.
+TEST(AdaptorPoolTest, canonizePoolPrefixSpaces) {
+ string config = "{\n"
+ " \"pool\": \"192.0.2.128 /\t28\"\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ EXPECT_NO_THROW(AdaptorPool::canonizePool(json));
+ EXPECT_FALSE(copied->equals(*json));
+ ConstElementPtr pool = json->get("pool");
+ ASSERT_TRUE(pool);
+ ASSERT_EQ(Element::string, pool->getType());
+ EXPECT_EQ("192.0.2.128/28", pool->stringValue());
+}
+
+// Verifies that canonizePool adds two spaces from a range.
+TEST(AdaptorPoolTest, canonizePoolRangeNoSpace) {
+ string config = "{\n"
+ " \"pool\": \"192.0.2.1-192.0.2.200\"\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ EXPECT_NO_THROW(AdaptorPool::canonizePool(json));
+ EXPECT_FALSE(copied->equals(*json));
+ ConstElementPtr pool = json->get("pool");
+ ASSERT_TRUE(pool);
+ ASSERT_EQ(Element::string, pool->getType());
+ EXPECT_EQ("192.0.2.1 - 192.0.2.200", pool->stringValue());
+}
+
+// Verifies that canonizePool removes extra spaces from a range.
+TEST(AdaptorPoolTest, canonizePoolRangeExtraSpaces) {
+ string config = "{\n"
+ " \"pool\": \"192.0.2.1 - 192.0.2.200\"\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ EXPECT_NO_THROW(AdaptorPool::canonizePool(json));
+ EXPECT_FALSE(copied->equals(*json));
+ ConstElementPtr pool = json->get("pool");
+ ASSERT_TRUE(pool);
+ ASSERT_EQ(Element::string, pool->getType());
+ EXPECT_EQ("192.0.2.1 - 192.0.2.200", pool->stringValue());
+}
+
+// Verifies that fromSubnet is specific to ietf-dhcpv6-server model.
+TEST(AdaptorPoolTest, fromSubnetKea) {
+ string config = "{\n"
+ " \"subnet\": \"192.0.2.0/24\",\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
+ " },{\n"
+ " \"pool\": \"192.0.2.101 - 192.0.2.200\"\n"
+ " } ],\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ ConstElementPtr pools = json->get("pools");
+
+ // This should be no-op for kea-dhcp4-server and kea-dhcp6-server models
+ EXPECT_NO_THROW(AdaptorPool::fromSubnet(KEA_DHCP4_SERVER, json, pools));
+ EXPECT_TRUE(copied->equals(*json));
+ // The model is checked first.
+ EXPECT_NO_THROW(AdaptorPool::fromSubnet(KEA_DHCP6_SERVER, json, pools));
+ EXPECT_TRUE(copied->equals(*json));
+
+ // Check that the model name is actually checked.
+ EXPECT_THROW(AdaptorPool::fromSubnet("non-existent-module", json, pools),
+ NotImplemented);
+}
+
+// Verifies that fromSubnet works as expected.
+TEST(AdaptorPoolTest, fromSubnet) {
+ string config = "{\n"
+ " \"subnet\": \"2001:db8:1::/64\",\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"2001:db8:1::/80\"\n"
+ " },{\n"
+ " \"pool\": \"2001:db8:1:0:1::/80\"\n"
+ " } ],\n"
+ " \"preferred-lifetime\": 3000,\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ ConstElementPtr pools = json->get("pools");
+ EXPECT_NO_THROW(AdaptorPool::fromSubnet(IETF_DHCPV6_SERVER, json, pools));
+ EXPECT_FALSE(copied->equals(*json));
+ pools = json->get("pools");
+ ASSERT_TRUE(pools);
+ ASSERT_EQ(2, pools->size());
+ ConstElementPtr pool = pools->get(0);
+ ASSERT_TRUE(pool);
+ string expected = "{"
+ " \"pool\": \"2001:db8:1::/80\","
+ " \"preferred-lifetime\": 3000,"
+ " \"rebind-timer\": 2000,"
+ " \"renew-timer\": 1000,"
+ " \"valid-lifetime\": 4000 }";
+ EXPECT_EQ(expected, pool->str());
+ pool = pools->get(1);
+ ASSERT_TRUE(pool);
+ expected = "{"
+ " \"pool\": \"2001:db8:1:0:1::/80\","
+ " \"preferred-lifetime\": 3000,"
+ " \"rebind-timer\": 2000,"
+ " \"renew-timer\": 1000,"
+ " \"valid-lifetime\": 4000 }";
+ EXPECT_EQ(expected, pool->str());
+}
+
+// Verifies that toSubnet is specific to ietf-dhcpv6-server model.
+TEST(AdaptorPoolTest, toSubnetKea) {
+ string config = "{\n"
+ " \"subnet\": \"192.0.2.0/24\",\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
+ " },{\n"
+ " \"pool\": \"192.0.2.101 - 192.0.2.200\"\n"
+ " } ],\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ ConstElementPtr pools = json->get("pools");
+ EXPECT_NO_THROW(AdaptorPool::toSubnet(KEA_DHCP4_SERVER, json, pools));
+ EXPECT_TRUE(copied->equals(*json));
+ // The model is checked first.
+ EXPECT_NO_THROW(AdaptorPool::toSubnet(KEA_DHCP6_SERVER, json, pools));
+ EXPECT_TRUE(copied->equals(*json));
+ // Model name is not free: an error is raised if it is not expected.
+ EXPECT_THROW(AdaptorPool::toSubnet("keatest-module", json, pools),
+ NotImplemented);
+}
+
+// Verifies that toSubnet works as expected.
+TEST(AdaptorPoolTest, toSubnet) {
+ string config = "{\n"
+ " \"subnet\": \"2001:db8:1::/64\",\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"2001:db8:1::/80\",\n"
+ " \"preferred-lifetime\": 3000,\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ " },{\n"
+ " \"pool\": \"2001:db8:1:0:1::/80\",\n"
+ " \"preferred-lifetime\": 3000,\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ " } ]\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr copied = copy(json);
+ ConstElementPtr pools = json->get("pools");
+ EXPECT_NO_THROW(AdaptorPool::toSubnet(IETF_DHCPV6_SERVER, json, pools));
+ EXPECT_FALSE(copied->equals(*json));
+ // Check timers.
+ ConstElementPtr timer = json->get("valid-lifetime");
+ ASSERT_TRUE(timer);
+ EXPECT_EQ("4000", timer->str());
+ timer = json->get("preferred-lifetime");
+ ASSERT_TRUE(timer);
+ EXPECT_EQ("3000", timer->str());
+ timer = json->get("renew-timer");
+ ASSERT_TRUE(timer);
+ EXPECT_EQ("1000", timer->str());
+ timer = json->get("rebind-timer");
+ ASSERT_TRUE(timer);
+ EXPECT_EQ("2000", timer->str());
+ // Timers must be removed as they are not allowed here in Kea.
+ pools = json->get("pools");
+ ASSERT_TRUE(pools);
+ ASSERT_EQ(2, pools->size());
+ ConstElementPtr pool = pools->get(0);
+ ASSERT_TRUE(pool);
+ EXPECT_EQ("{ \"pool\": \"2001:db8:1::/80\" }", pool->str());
+ pool = pools->get(1);
+ ASSERT_TRUE(pool);
+ EXPECT_EQ("{ \"pool\": \"2001:db8:1:0:1::/80\" }", pool->str());
+}
+
+// Verifies that toSubnet fails on inconsistent input.
+TEST(AdaptorPoolTest, toSubnetBad) {
+ // Changed last rebind-timer to a different value.
+ string config = "{\n"
+ " \"subnet\": \"2001:db8:1::/64\",\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"2001:db8:1::/80\",\n"
+ " \"preferred-lifetime\": 3000,\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 2000\n"
+ " },{\n"
+ " \"pool\": \"2001:db8:1:0:1::/80\",\n"
+ " \"preferred-lifetime\": 3000,\n"
+ " \"valid-lifetime\": 4000,\n"
+ " \"renew-timer\": 1000,\n"
+ " \"rebind-timer\": 20\n"
+ " } ]\n"
+ "}";
+ ElementPtr json;
+ ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
+ ConstElementPtr pools = json->get("pools");
+ EXPECT_THROW(AdaptorPool::toSubnet(IETF_DHCPV6_SERVER, json, pools),
+ BadValue);
+}
+
+}; // end of anonymous namespace