From: Tomek Mrugalski Date: Fri, 15 Sep 2017 21:33:08 +0000 (+0200) Subject: [5360] Lexer fixed, unit-tests added. X-Git-Tag: trac5073a_base~5 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=9f71dcc4b8294242e582d8dd2fd98d16710cfbdd;p=thirdparty%2Fkea.git [5360] Lexer fixed, unit-tests added. --- diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll index 66d0cdc380..6a0687f9b4 100644 --- a/src/bin/dhcp4/dhcp4_lexer.ll +++ b/src/bin/dhcp4/dhcp4_lexer.ll @@ -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_); diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 77d9866fe3..4a9569b3e0 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -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()); +} + } diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index b7bea0d63e..6210c214a2 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -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_); diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 04a590f495..6196c197d6 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -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()); +} + }; diff --git a/src/lib/dhcpsrv/parsers/simple_parser4.cc b/src/lib/dhcpsrv/parsers/simple_parser4.cc index f30dd0cfbc..a8c47891c8 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser4.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser4.cc @@ -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" } }; diff --git a/src/lib/dhcpsrv/parsers/simple_parser6.cc b/src/lib/dhcpsrv/parsers/simple_parser6.cc index a4592cf520..f7ca2dba16 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser6.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser6.cc @@ -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" },