Commit 9f71dcc4 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[5360] Lexer fixed, unit-tests added.

parent 67c386b5
......@@ -760,6 +760,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::CLIENT_CLASSES:
case Parser4Context::SHARED_NETWORK:
return isc::dhcp::Dhcp4Parser::make_CLIENT_CLASS(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("client-class", driver.loc_);
......
......@@ -5338,4 +5338,93 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
}
// This test checks if client-class is derived properly.
TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
// This config is structured in a way that the first shared network has
// client-class defined. This should in general be inherited by subnets, but
// it's also possible to override the values on subnet level.
string config = "{\n"
"\"renew-timer\": 1, \n" // global values here
"\"rebind-timer\": 2, \n"
"\"valid-lifetime\": 4, \n"
"\"shared-networks\": [ {\n"
" \"name\": \"foo\"\n," // shared network values here
" \"client-class\": \"alpha\",\n"
" \"subnet4\": [\n"
" { \n"
" \"subnet\": \"192.0.1.0/24\",\n"
" \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
" },\n"
" { \n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
" \"client-class\": \"beta\"\n"
" }\n"
" ]\n"
" },\n"
"{ // second shared-network starts here\n"
" \"name\": \"bar\",\n"
" \"subnet4\": [\n"
" {\n"
" \"subnet\": \"192.0.3.0/24\",\n"
" \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
" }\n"
" ]\n"
" } ]\n"
"} \n";
configure(config, CONTROL_RESULT_SUCCESS, "");
// Now verify that the shared network was indeed configured.
CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
->getCfgSharedNetworks4();
// Two shared networks are expected.
ASSERT_TRUE(cfg_net);
const SharedNetwork4Collection* nets = cfg_net->getAll();
ASSERT_TRUE(nets);
ASSERT_EQ(2, nets->size());
SharedNetwork4Ptr net = nets->at(0);
ASSERT_TRUE(net);
auto classes = net->getClientClasses();
EXPECT_TRUE(classes.contains("alpha"));
// The first shared network has two subnets.
const Subnet4Collection * subs = net->getAllSubnets();
ASSERT_TRUE(subs);
EXPECT_EQ(2, subs->size());
// For the first subnet, the client-class should be inherited from
// shared-network level.
Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 1, 2, 4);
ASSERT_TRUE(s);
classes = s->getClientClasses();
EXPECT_TRUE(classes.contains("alpha"));
// For the second subnet, the values are overridden on subnet level.
// The value should not be inherited.
s = checkSubnet(*subs, "192.0.2.0/24", 1, 2, 4);
classes = s->getClientClasses();
EXPECT_TRUE(classes.contains("beta")); // beta defined on subnet level
EXPECT_FALSE(classes.contains("alpha")); // alpha defined on shared-network level
// Ok, now check the second shared network. It doesn't have anything defined
// on shared-network or subnet level, so everything should have default
// values.
net = nets->at(1);
ASSERT_TRUE(net);
subs = net->getAllSubnets();
ASSERT_TRUE(subs);
EXPECT_EQ(1, subs->size());
s = checkSubnet(*subs, "192.0.3.0/24", 1, 2, 4);
classes = s->getClientClasses();
EXPECT_TRUE(classes.empty());
}
}
......@@ -1040,6 +1040,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::SUBNET6:
case isc::dhcp::Parser6Context::CLIENT_CLASSES:
case Parser6Context::SHARED_NETWORK:
return isc::dhcp::Dhcp6Parser::make_CLIENT_CLASS(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("client-class", driver.loc_);
......
......@@ -5778,4 +5778,88 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDeriveInterfaces) {
EXPECT_EQ("", s->getIface());
}
// This test checks if client-class is derived properly.
TEST_F(Dhcp6ParserTest, sharedNetworksDeriveClientClass) {
string config = "{\n"
"\"shared-networks\": [ {\n"
" \"name\": \"foo\"\n,"
" \"client-class\": \"alpha\",\n"
" \"subnet6\": [\n"
" { \n"
" \"subnet\": \"2001:db1::/48\",\n"
" \"pools\": [ { \"pool\": \"2001:db1::/64\" } ]\n"
" },\n"
" { \n"
" \"subnet\": \"2001:db2::/48\",\n"
" \"pools\": [ { \"pool\": \"2001:db2::/64\" } ],\n"
" \"client-class\": \"beta\"\n"
" }\n"
" ]\n"
" },\n"
"{ // second shared-network starts here\n"
" \"name\": \"bar\",\n"
" \"subnet6\": [\n"
" {\n"
" \"subnet\": \"2001:db3::/48\",\n"
" \"pools\": [ { \"pool\": \"2001:db3::/64\" } ]\n"
" }\n"
" ]\n"
"} ]\n"
"} \n";
configure(config, CONTROL_RESULT_SUCCESS, "");
// Now verify that the shared network was indeed configured.
CfgSharedNetworks6Ptr cfg_net = CfgMgr::instance().getStagingCfg()
->getCfgSharedNetworks6();
// Two shared networks are expeced.
ASSERT_TRUE(cfg_net);
const SharedNetwork6Collection* nets = cfg_net->getAll();
ASSERT_TRUE(nets);
ASSERT_EQ(2, nets->size());
// Let's check the first one.
SharedNetwork6Ptr net = nets->at(0);
ASSERT_TRUE(net);
auto classes = net->getClientClasses();
EXPECT_TRUE(classes.contains("alpha"));
const Subnet6Collection * subs = net->getAllSubnets();
ASSERT_TRUE(subs);
EXPECT_EQ(2, subs->size());
// For the first subnet, the client-class should be inherited from
// shared-network level.
Subnet6Ptr s = checkSubnet(*subs, "2001:db1::/48", 900, 1800, 3600, 7200);
ASSERT_TRUE(s);
classes = s->getClientClasses();
EXPECT_TRUE(classes.contains("alpha"));
// For the second subnet, the values are overridden on subnet level.
// The value should not be inherited.
s = checkSubnet(*subs, "2001:db2::/48", 900, 1800, 3600, 7200);
ASSERT_TRUE(s);
classes = s->getClientClasses();
EXPECT_TRUE(classes.contains("beta")); // beta defined on subnet level
EXPECT_FALSE(classes.contains("alpha")); // alpha defined on shared-network level
// Ok, now check the second shared network. It doesn't have
// anything defined on shared-network or subnet level, so
// everything should have default values.
net = nets->at(1);
ASSERT_TRUE(net);
subs = net->getAllSubnets();
ASSERT_TRUE(subs);
EXPECT_EQ(1, subs->size());
// This subnet should derive its renew-timer from global scope.
s = checkSubnet(*subs, "2001:db3::/48", 900, 1800, 3600, 7200);
classes = s->getClientClasses();
EXPECT_TRUE(classes.empty());
}
};
......@@ -91,7 +91,6 @@ const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
/// Those are: interface and reservation-mode.
const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
{ "id", Element::integer, "0" }, // 0 means autogenerate
{ "client-class", Element::string, "" },
{ "4o6-interface", Element::string, "" },
{ "4o6-interface-id", Element::string, "" },
{ "4o6-subnet", Element::string, "" },
......@@ -99,6 +98,7 @@ const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
/// @brief This table defines default values for each IPv4 shared network.
const SimpleDefaults SimpleParser4::SHARED_NETWORK4_DEFAULTS = {
{ "client-class", Element::string, "" },
{ "interface", Element::string, "" },
{ "reservation-mode", Element::string, "all" }
};
......
......@@ -75,12 +75,12 @@ const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
/// @brief This table defines default values for each IPv6 subnet.
const SimpleDefaults SimpleParser6::SHARED_SUBNET6_DEFAULTS = {
{ "id", Element::integer, "0" }, // 0 means autogenerate
{ "client-class", Element::string, "" }
{ "id", Element::integer, "0" } // 0 means autogenerate
};
/// @brief This table defines default values for each IPv6 shared network.
const SimpleDefaults SimpleParser6::SHARED_NETWORK6_DEFAULTS = {
{ "client-class", Element::string, "" },
{ "interface", Element::string, "" },
{ "interface-id", Element::string, "" },
{ "reservation-mode", Element::string, "all" },
......
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