summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorPiotrek Zadroga <piotrek@isc.org>2023-11-22 15:36:49 +0100
committerPiotrek Zadroga <piotrek@isc.org>2024-01-09 11:40:04 +0100
commit3203d257a357676aadf1a93a1ff1711c7d361373 (patch)
tree1ccf2494f0e1d7acac0161fe01e42da51f8b2454 /src/lib
parent[#3074] option example update (diff)
downloadkea-3203d257a357676aadf1a93a1ff1711c7d361373.tar.xz
kea-3203d257a357676aadf1a93a1ff1711c7d361373.zip
[#3074] UTs updated
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dhcp/option_data_types.cc2
-rw-r--r--src/lib/dhcp/tests/option_classless_static_route_unittest.cc22
-rw-r--r--src/lib/dhcp/tests/option_definition_unittest.cc88
3 files changed, 98 insertions, 14 deletions
diff --git a/src/lib/dhcp/option_data_types.cc b/src/lib/dhcp/option_data_types.cc
index 934ff5478a..4e2a17b964 100644
--- a/src/lib/dhcp/option_data_types.cc
+++ b/src/lib/dhcp/option_data_types.cc
@@ -50,6 +50,7 @@ OptionDataTypeUtil::OptionDataTypeUtil() {
data_types_["string"] = OPT_STRING_TYPE;
data_types_["tuple"] = OPT_TUPLE_TYPE;
data_types_["fqdn"] = OPT_FQDN_TYPE;
+ data_types_["custom"] = OPT_CUSTOM_TYPE;
data_types_["record"] = OPT_RECORD_TYPE;
data_type_names_[OPT_EMPTY_TYPE] = "empty";
@@ -68,6 +69,7 @@ OptionDataTypeUtil::OptionDataTypeUtil() {
data_type_names_[OPT_STRING_TYPE] = "string";
data_type_names_[OPT_TUPLE_TYPE] = "tuple";
data_type_names_[OPT_FQDN_TYPE] = "fqdn";
+ data_type_names_[OPT_CUSTOM_TYPE] = "custom";
data_type_names_[OPT_RECORD_TYPE] = "record";
// The "unknown" data type is declared here so as
// it can be returned by reference by a getDataTypeName
diff --git a/src/lib/dhcp/tests/option_classless_static_route_unittest.cc b/src/lib/dhcp/tests/option_classless_static_route_unittest.cc
index f65d9730a8..cabb1ca803 100644
--- a/src/lib/dhcp/tests/option_classless_static_route_unittest.cc
+++ b/src/lib/dhcp/tests/option_classless_static_route_unittest.cc
@@ -287,12 +287,11 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDataTruncated) {
// Only one static route is defined.
TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithOneRoute) {
// Prepare data to decode - one route with mask width = 8.
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
8, // mask width
10, // significant subnet octet for 10.0.0.0/8
- 10, 198, 122, 1 // router IP address
+ 10, 45, 122, 1 // router IP address
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option;
@@ -304,7 +303,7 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithOneRoute) {
// Verify toText() is working fine.
EXPECT_EQ("type=121(CLASSLESS_STATIC_ROUTE), len=6, Route 1 (subnet 10.0.0.0/8,"
- " router IP 10.198.122.1)",
+ " router IP 10.45.122.1)",
option->toText());
}
@@ -313,7 +312,7 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithOneRoute) {
// 3 static routes are defined.
TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithMoreRoutes) {
// Prepare data to decode - 3 static routes
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
0, // mask width
10, 17, 0, 1, // router IP address
25, // mask width
@@ -323,7 +322,6 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithMoreRoutes) {
10, 27, 129, // significant subnet octets for 10.27.129.0/24
10, 27, 129, 1 // router IP address
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option;
@@ -346,12 +344,11 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorWithMoreRoutes) {
// when data in the buffer is truncated.
TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorDataTruncated) {
// Prepare data to decode - truncated data
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
8, // mask width
10, // significant subnet octet for 10.0.0.0/8
10, // router IP address truncated
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws OutOfRange during Unpack.
OptionClasslessStaticRoutePtr option;
@@ -364,13 +361,12 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorDataTruncated) {
// when data of the second static route in the buffer is truncated.
TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorSecondRouteDataTruncated) {
// Prepare data to decode - truncated data
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
0, // mask width
10, 17, 0, 1, // router IP address
25, // mask width
10, 229 // significant subnet octets truncated
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws OutOfRange during Unpack.
OptionClasslessStaticRoutePtr option;
@@ -383,14 +379,13 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorSecondRouteDataTruncated)
// when data of the second static route in the buffer contains bad subnet width.
TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorSecondRouteBadSubnetWidth) {
// Prepare data to decode - truncated data
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
0, // mask width
10, 17, 0, 1, // router IP address
125, // bad mask width
10, 229, 0, 128, // significant subnet octets for 10.229.0.128/25
10, 229, 0, 1 // router IP address
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option;
@@ -402,7 +397,7 @@ TEST(OptionClasslessStaticRouteTest, wireDatabufferCtorSecondRouteBadSubnetWidth
// This test verifies toText() method
TEST(OptionClasslessStaticRouteTest, toText) {
// Prepare data to decode - 3 static routes
- const uint8_t buf_data[] = {
+ const OptionBuffer buf = {
0, // mask width
10, 17, 0, 1, // router IP address
25, // mask width
@@ -412,7 +407,6 @@ TEST(OptionClasslessStaticRouteTest, toText) {
10, 27, 129, // significant subnet octets for 10.27.129.0/24
10, 27, 129, 1 // router IP address
};
- OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option;
diff --git a/src/lib/dhcp/tests/option_definition_unittest.cc b/src/lib/dhcp/tests/option_definition_unittest.cc
index e19523f7b0..c58071af69 100644
--- a/src/lib/dhcp/tests/option_definition_unittest.cc
+++ b/src/lib/dhcp/tests/option_definition_unittest.cc
@@ -15,6 +15,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option4_dnr.h>
#include <dhcp/option6_dnr.h>
+#include <dhcp/option_classless_static_route.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_definition.h>
#include <dhcp/option_int.h>
@@ -2105,4 +2106,91 @@ TEST_F(OptionDefinitionTest, tuple6ArrayTokenized) {
EXPECT_EQ("world", tuple2.getText());
}
+// The purpose of this test is to verify creation of OPT_CUSTOM_TYPE option
+// definition. OptionFactory is used which takes vector of string values as
+// data for the option. This is special case for OPT_CUSTOM_TYPE because it means
+// that custom data is provided in string values. Custom parsing is verified in this test.
+TEST_F(OptionDefinitionTest, customOptionTypeString) {
+ OptionDefinition opt_def("classless-static-route", DHO_CLASSLESS_STATIC_ROUTE,
+ DHCP4_OPTION_SPACE, "custom", false);
+
+ OptionPtr option;
+
+ // Specify option's static routes.
+ std::vector<std::string> values;
+ values.push_back("0.0.0.0/0-10.17.0.1");
+ values.push_back("10.229.0.128/25-10.229.0.1");
+ values.push_back("10.27.129.0/24-10.27.129.1");
+
+ // Create an instance of this option using the definition.
+ ASSERT_NO_THROW(option = opt_def.optionFactory(Option::V4, DHO_CLASSLESS_STATIC_ROUTE, values););
+
+ // Make sure that the returned option class is correct.
+ const Option* optptr = option.get();
+ ASSERT_TRUE(optptr);
+ ASSERT_TRUE(typeid(*optptr) == typeid(OptionClasslessStaticRoute));
+
+ // Validate that option's fields were correctly parsed from strings.
+ OptionClasslessStaticRoutePtr option_cast = boost::dynamic_pointer_cast<OptionClasslessStaticRoute>(option);
+
+ // Expected len: 2 (option code + option len headers) + 5 (1 dest descriptor + 4 router addr)
+ // + 9 (5 dest descriptor + 4 router addr) + 8 (4 dest descriptor + 4 router addr).
+ EXPECT_EQ(24, option_cast->len());
+
+ // Verify toText() is working fine.
+ EXPECT_EQ("type=121(CLASSLESS_STATIC_ROUTE), len=22, "
+ "Route 1 (subnet 0.0.0.0/0, router IP 10.17.0.1), "
+ "Route 2 (subnet 10.229.0.128/25, router IP 10.229.0.1), "
+ "Route 3 (subnet 10.27.129.0/24, router IP 10.27.129.1)",
+ option_cast->toText());
+}
+
+// The purpose of this test is to verify creation of OPT_CUSTOM_TYPE option
+// definition. OptionFactory is used which takes OptionBuffer as
+// data for the option. Binary data unpack is verified in this test.
+TEST_F(OptionDefinitionTest, customOptionTypeBinary) {
+ OptionDefinition opt_def("classless-static-route", DHO_CLASSLESS_STATIC_ROUTE,
+ DHCP4_OPTION_SPACE, "custom", false);
+
+ OptionPtr option;
+
+ // Create a buffer holding static routes on-wire data
+ const OptionBuffer buf = {
+ 0, // mask width
+ 10, 17, 0, 1, // router IP address
+ 25, // mask width
+ 10, 229, 0, 128, // significant subnet octets for 10.229.0.128/25
+ 10, 229, 0, 1, // router IP address
+ 24, // mask width
+ 10, 27, 129, // significant subnet octets for 10.27.129.0/24
+ 10, 27, 129, 1 // router IP address
+ };
+
+ // Create an instance of this option using the definition.
+ ASSERT_NO_THROW(option = opt_def.optionFactory(Option::V4, DHO_CLASSLESS_STATIC_ROUTE, buf););
+
+ // Make sure that the returned option class is correct.
+ const Option* optptr = option.get();
+ ASSERT_TRUE(optptr);
+ ASSERT_TRUE(typeid(*optptr) == typeid(OptionClasslessStaticRoute));
+
+ // Sanity check on universe and header length.
+ EXPECT_EQ(Option::V4, option->getUniverse());
+ EXPECT_EQ(2, option->getHeaderLen());
+
+ // Validate parsed values.
+ OptionClasslessStaticRoutePtr option_cast = boost::dynamic_pointer_cast<OptionClasslessStaticRoute>(option);
+
+ // Expected len: 2 (option code + option len headers) + 5 (1 dest descriptor + 4 router addr)
+ // + 9 (5 dest descriptor + 4 router addr) + 8 (4 dest descriptor + 4 router addr).
+ EXPECT_EQ(24, option_cast->len());
+
+ // Verify toText() is working fine.
+ EXPECT_EQ("type=121(CLASSLESS_STATIC_ROUTE), len=22, "
+ "Route 1 (subnet 0.0.0.0/0, router IP 10.17.0.1), "
+ "Route 2 (subnet 10.229.0.128/25, router IP 10.229.0.1), "
+ "Route 3 (subnet 10.27.129.0/24, router IP 10.27.129.1)",
+ option_cast->toText());
+}
+
} // anonymous namespace