Commit 3886d117 authored by Marcin Siodelski's avatar Marcin Siodelski

[2314] Added the test to check that standard V4 option can be encapsulated.

parent 3f1577b5
......@@ -21,6 +21,8 @@
#include <dhcp4/dhcp4_srv.h>
#include <dhcp4/config_parser.h>
#include <dhcp/option4_addrlst.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfgmgr.h>
#include <boost/foreach.hpp>
......@@ -67,6 +69,7 @@ public:
void checkResult(ConstElementPtr status, int expected_code) {
ASSERT_TRUE(status);
comment_ = parseAnswer(rcode_, status);
std::cout << comment_->str() << std::endl;
EXPECT_EQ(expected_code, rcode_);
}
......@@ -1589,4 +1592,165 @@ TEST_F(Dhcp4ParserTest, DISABLED_Uint32Parser) {
checkResult(status, 1);
}
// The goal of this test is to verify that the standard option can
// be configured to encapsulate multiple other options.
TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
// The configuration is two stage process in this test.
// In the first stahe we create definitions of suboptions
// that we will add to the base option.
// Let's create some dummy options: foo and foo2.
string config = "{ \"interface\": [ \"all\" ],"
"\"rebind-timer\": 2000,"
"\"renew-timer\": 1000,"
"\"option-data\": [ {"
" \"name\": \"foo\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"code\": 1,"
" \"data\": \"1234\","
" \"csv-format\": True"
" },"
" {"
" \"name\": \"foo2\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"code\": 2,"
" \"data\": \"192.168.2.1\","
" \"csv-format\": True"
" } ],"
"\"option-def\": [ {"
" \"name\": \"foo\","
" \"code\": 1,"
" \"type\": \"uint32\","
" \"array\": False,"
" \"record-types\": \"\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"encapsulate\": \"\""
" },"
" {"
" \"name\": \"foo2\","
" \"code\": 2,"
" \"type\": \"ipv4-address\","
" \"array\": False,"
" \"record-types\": \"\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"encapsulate\": \"\""
" } ]"
"}";
ConstElementPtr status;
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status);
checkResult(status, 0);
// Once the definitions have been added we can configure the
// standard option #17. This option comprises an enterprise
// number and sub options. By convention (introduced in
// std_option_defs.h) option named 'vendor-opts'
// encapsulates the option space named 'vendor-opts-space'.
// We add our dummy options to this option space and thus
// they should be included as sub-options in the 'vendor-opts'
// option.
config = "{ \"interface\": [ \"all\" ],"
"\"rebind-timer\": 2000,"
"\"renew-timer\": 1000,"
"\"option-data\": [ {"
" \"name\": \"vendor-encapsulated-options\","
" \"space\": \"dhcp4\","
" \"code\": 43,"
" \"data\": \"\","
" \"csv-format\": False"
" },"
" {"
" \"name\": \"foo\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"code\": 1,"
" \"data\": \"1234\","
" \"csv-format\": True"
" },"
" {"
" \"name\": \"foo2\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"code\": 2,"
" \"data\": \"192.168.2.1\","
" \"csv-format\": True"
" } ],"
"\"option-def\": [ {"
" \"name\": \"foo\","
" \"code\": 1,"
" \"type\": \"uint32\","
" \"array\": False,"
" \"record-types\": \"\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"encapsulate\": \"\""
" },"
" {"
" \"name\": \"foo2\","
" \"code\": 2,"
" \"type\": \"ipv4-address\","
" \"array\": False,"
" \"record-types\": \"\","
" \"space\": \"vendor-encapsulated-options-space\","
" \"encapsulate\": \"\""
" } ],"
"\"subnet4\": [ { "
" \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
" \"subnet\": \"192.0.2.0/24\""
" } ]"
"}";
json = Element::fromJSON(config);
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status);
checkResult(status, 0);
// Get the subnet.
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"));
ASSERT_TRUE(subnet);
// We should have one option available.
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the option.
Subnet::OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
EXPECT_TRUE(desc.option);
EXPECT_EQ(DHO_VENDOR_ENCAPSULATED_OPTIONS, desc.option->getType());
// Option with the code 1 should be added as a sub-option.
OptionPtr option_foo = desc.option->getOption(1);
ASSERT_TRUE(option_foo);
EXPECT_EQ(1, option_foo->getType());
// This option comprises a single uint32_t value thus it is
// represented by OptionInt<uint32_t> class. Let's get the
// object of this type.
boost::shared_ptr<OptionInt<uint32_t> > option_foo_uint32 =
boost::dynamic_pointer_cast<OptionInt<uint32_t> >(option_foo);
ASSERT_TRUE(option_foo_uint32);
// Validate the value according to the configuration.
EXPECT_EQ(1234, option_foo_uint32->getValue());
// Option with the code 2 should be added as a sub-option.
OptionPtr option_foo2 = desc.option->getOption(2);
ASSERT_TRUE(option_foo2);
EXPECT_EQ(2, option_foo2->getType());
// This option comprises the IPV4 address. Such option is
// represented by OptionCustom object.
OptionCustomPtr option_foo2_v4 =
boost::dynamic_pointer_cast<OptionCustom>(option_foo2);
ASSERT_TRUE(option_foo2_v4);
// Get the IP address carried by this option and validate it.
EXPECT_EQ("192.168.2.1", option_foo2_v4->readAddress().toText());
// Option with the code 3 should not be added.
EXPECT_FALSE(desc.option->getOption(3));
}
};
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