diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/dhcp6/dhcp6_lexer.ll | 126 | ||||
-rw-r--r-- | src/bin/dhcp6/dhcp6_parser.yy | 240 | ||||
-rw-r--r-- | src/bin/dhcp6/parser_context.cc | 6 | ||||
-rw-r--r-- | src/bin/dhcp6/parser_context.h | 3 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/config_parser_unittest.cc | 112 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc | 2 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 4 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_test_utils.h | 4 |
8 files changed, 368 insertions, 129 deletions
diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 11b32ad252..efc4b62c74 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -284,6 +284,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"preferred-lifetime\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: return isc::dhcp::Dhcp6Parser::make_PREFERRED_LIFETIME(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("preferred-lifetime", driver.loc_); @@ -293,6 +294,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"valid-lifetime\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: return isc::dhcp::Dhcp6Parser::make_VALID_LIFETIME(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("valid-lifetime", driver.loc_); @@ -302,6 +304,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"renew-timer\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: return isc::dhcp::Dhcp6Parser::make_RENEW_TIMER(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("renew-timer", driver.loc_); @@ -311,12 +314,22 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"rebind-timer\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: return isc::dhcp::Dhcp6Parser::make_REBIND_TIMER(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("rebind-timer", driver.loc_); } } +\"decline-probation-period\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP6: + return isc::dhcp::Dhcp6Parser::make_DECLINE_PROBATION_PERIOD(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("decline-probation-period", driver.loc_); + } +} + \"subnet6\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: @@ -446,6 +459,15 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } } +\"interface-id\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::SUBNET6: + return isc::dhcp::Dhcp6Parser::make_INTERFACE_ID(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("interface-id", driver.loc_); + } +} + \"id\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::SUBNET6: @@ -455,6 +477,24 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } } +\"rapid-commit\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::SUBNET6: + return isc::dhcp::Dhcp6Parser::make_RAPID_COMMIT(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("rapid-commit", driver.loc_); + } +} + +\"reservation-mode\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::SUBNET6: + return isc::dhcp::Dhcp6Parser::make_RESERVATION_MODE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("reservation-mode", driver.loc_); + } +} + \"code\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::OPTION_DEF: @@ -645,7 +685,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"csv-format\" { switch(driver.ctx_) { - case isc::dhcp::Parser6Context::OPTION_DEF: case isc::dhcp::Parser6Context::OPTION_DATA: return isc::dhcp::Dhcp6Parser::make_CSV_FORMAT(driver.loc_); default: @@ -653,6 +692,51 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } } +\"record-types\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::OPTION_DEF: + return isc::dhcp::Dhcp6Parser::make_RECORD_TYPES(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("record-types", driver.loc_); + } +} + +\"encapsulate\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::OPTION_DEF: + return isc::dhcp::Dhcp6Parser::make_ENCAPSULATE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("encapsulate", driver.loc_); + } +} + +\"array\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::OPTION_DEF: + return isc::dhcp::Dhcp6Parser::make_ARRAY(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("array", driver.loc_); + } +} + +\"relay\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::SUBNET6: + return isc::dhcp::Dhcp6Parser::make_RELAY(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("relay", driver.loc_); + } +} + +\"ip-address\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::RELAY: + return isc::dhcp::Dhcp6Parser::make_IP_ADDRESS(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("ip-address", driver.loc_); + } +} + \"hooks-libraries\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: @@ -734,30 +818,48 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } } -\"dhcp-ddns\" { +\"version\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: - return isc::dhcp::Dhcp6Parser::make_DHCP_DDNS(driver.loc_); + return isc::dhcp::Dhcp6Parser::make_VERSION(driver.loc_); default: - return isc::dhcp::Dhcp6Parser::make_STRING("dhcp-ddns", driver.loc_); + return isc::dhcp::Dhcp6Parser::make_STRING("version", driver.loc_); + } +} + +\"control-socket\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP6: + return isc::dhcp::Dhcp6Parser::make_CONTROL_SOCKET(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("control-socket", driver.loc_); } } -\"enable-updates\" { +\"socket-type\" { switch(driver.ctx_) { - case isc::dhcp::Parser6Context::DHCP_DDNS: - return isc::dhcp::Dhcp6Parser::make_ENABLE_UPDATES(driver.loc_); + case isc::dhcp::Parser6Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp6Parser::make_SOCKET_TYPE(driver.loc_); default: - return isc::dhcp::Dhcp6Parser::make_STRING("enable-updates", driver.loc_); + return isc::dhcp::Dhcp6Parser::make_STRING("socket-type", driver.loc_); } } -\"qualifying-suffix\" { +\"socket-name\" { switch(driver.ctx_) { - case isc::dhcp::Parser6Context::DHCP_DDNS: - return isc::dhcp::Dhcp6Parser::make_QUALIFYING_SUFFIX(driver.loc_); + case isc::dhcp::Parser6Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp6Parser::make_SOCKET_NAME(driver.loc_); default: - return isc::dhcp::Dhcp6Parser::make_STRING("qualifying-suffix", driver.loc_); + return isc::dhcp::Dhcp6Parser::make_STRING("socket-name", driver.loc_); + } +} + +\"dhcp-ddns\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP6: + return isc::dhcp::Dhcp6Parser::make_DHCP_DDNS(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("dhcp-ddns", driver.loc_); } } diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index 8b1e3abb5d..33c365cf9b 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -66,6 +66,7 @@ using namespace std; VALID_LIFETIME "valid-lifetime" RENEW_TIMER "renew-timer" REBIND_TIMER "rebind-timer" + DECLINE_PROBATION_PERIOD "decline-probation-period" SUBNET6 "subnet6" OPTION_DEF "option-def" OPTION_DATA "option-data" @@ -74,6 +75,9 @@ using namespace std; CODE "code" SPACE "space" CSV_FORMAT "csv-format" + RECORD_TYPES "record-types" + ENCAPSULATE "encapsulate" + ARRAY "array" POOLS "pools" POOL "pool" @@ -84,7 +88,10 @@ using namespace std; SUBNET "subnet" INTERFACE "interface" + INTERFACE_ID "interface-id" ID "id" + RAPID_COMMIT "rapid-commit" + RESERVATION_MODE "reservation-mode" MAC_SOURCES "mac-sources" RELAY_SUPPLIED_OPTIONS "relay-supplied-options" @@ -101,6 +108,9 @@ using namespace std; HW_ADDRESS "hw-address" HOSTNAME "hostname" + RELAY "relay" + IP_ADDRESS "ip-address" + HOOKS_LIBRARIES "hooks-libraries" LIBRARY "library" @@ -113,6 +123,13 @@ using namespace std; ENTERPRISE_ID "enterprise-id" DHCP4O6_PORT "dhcp4o6-port" + VERSION "version" + + CONTROL_SOCKET "control-socket" + SOCKET_TYPE "socket-type" + SOCKET_NAME "socket-name" + + DHCP_DDNS "dhcp-ddns" LOGGING "Logging" LOGGERS "loggers" @@ -121,10 +138,6 @@ using namespace std; DEBUGLEVEL "debuglevel" SEVERITY "severity" - DHCP_DDNS "dhcp-ddns" - ENABLE_UPDATES "enable-updates" - QUALIFYING_SUFFIX "qualifying-suffix" - DHCP4 "Dhcp4" DHCPDDNS "DhcpDdns" @@ -150,6 +163,7 @@ using namespace std; %token <bool> BOOLEAN "boolean" %type <ElementPtr> value +%type <ElementPtr> version_value %printer { yyoutput << $$; } <*>; @@ -324,6 +338,7 @@ global_param: preferred_lifetime | valid_lifetime | renew_timer | rebind_timer + | decline_probation_period | subnet6_list | interfaces_config | lease_database @@ -338,6 +353,8 @@ global_param: preferred_lifetime | expired_leases_processing | server_id | dhcp4o6_port + | version + | control_socket | dhcp_ddns | unknown_map_entry ; @@ -362,6 +379,11 @@ rebind_timer: REBIND_TIMER COLON INTEGER { ctx.stack_.back()->set("rebind-timer", prf); }; +decline_probation_period: DECLINE_PROBATION_PERIOD COLON INTEGER { + ElementPtr dpp(new IntElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("decline-probation-period", dpp); +}; + interfaces_config: INTERFACES_CONFIG { ElementPtr i(new MapElement(ctx.loc2pos(@1))); ctx.stack_.back()->set("interfaces-config", i); @@ -669,14 +691,22 @@ subnet6_params: subnet6_param ; // This defines a list of allowed parameters for each subnet. -subnet6_param: option_data_list +subnet6_param: preferred_lifetime + | valid_lifetime + | renew_timer + | rebind_timer + | option_data_list | pools_list | pd_pools_list | subnet | interface + | interface_id | id + | rapid_commit | client_class | reservations + | reservation_mode + | relay | unknown_map_entry ; @@ -696,6 +726,14 @@ interface: INTERFACE { ctx.leave(); }; +interface_id: INTERFACE_ID { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr iface(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("interface-id", iface); + ctx.leave(); +}; + client_class: CLIENT_CLASS { ctx.enter(ctx.CLIENT_CLASS); } COLON STRING { @@ -704,11 +742,24 @@ client_class: CLIENT_CLASS { ctx.leave(); }; +reservation_mode: RESERVATION_MODE { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr rm(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("reservation-mode", rm); + ctx.leave(); +}; + id: ID COLON INTEGER { ElementPtr id(new IntElement($3, ctx.loc2pos(@3))); ctx.stack_.back()->set("id", id); }; +rapid_commit: RAPID_COMMIT COLON BOOLEAN { + ElementPtr rc(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("rapid-commit", rc); +}; + // ---- option-def -------------------------- // This defines the "option-def": [ ... ] entry that may appear @@ -764,12 +815,13 @@ not_empty_option_def_params: option_def_param option_def_param: option_def_name | option_def_code | option_def_type + | option_def_record_types | option_def_space - | option_def_csv_format + | option_def_encapsulate + | option_def_array | unknown_map_entry ; - option_def_name: name; code: CODE COLON INTEGER { @@ -781,6 +833,14 @@ option_def_code: code; option_def_type: type; +option_def_record_types: RECORD_TYPES { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr rtypes(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("record-types", rtypes); + ctx.leave(); +}; + space: SPACE { ctx.enter(ctx.NO_KEYWORD); } COLON STRING { @@ -791,12 +851,18 @@ space: SPACE { option_def_space: space; -csv_format: CSV_FORMAT COLON BOOLEAN { - ElementPtr space(new BoolElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("csv-format", space); +option_def_encapsulate: ENCAPSULATE { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr encap(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("encapsulate", encap); + ctx.leave(); }; -option_def_csv_format: csv_format; +option_def_array: ARRAY COLON BOOLEAN { + ElementPtr array(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("array", array); +}; // ---- option-data -------------------------- @@ -858,7 +924,6 @@ option_data_param: option_data_name | unknown_map_entry ; - option_data_name: name; option_data_data: DATA { @@ -873,7 +938,10 @@ option_data_code: code; option_data_space: space; -option_data_csv_format: csv_format; +option_data_csv_format: CSV_FORMAT COLON BOOLEAN { + ElementPtr space(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("csv-format", space); +}; // ---- pools ------------------------------------ @@ -1111,6 +1179,27 @@ reservation_client_classes: CLIENT_CLASSES { // --- end of reservations definitions ----------------------- +// --- relay ------------------------------------------------- +relay: RELAY { + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("relay", m); + ctx.stack_.push_back(m); + ctx.enter(ctx.RELAY); +} COLON LCURLY_BRACKET relay_map RCURLY_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + +relay_map: IP_ADDRESS { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr ip(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("ip-address", ip); + ctx.leave(); +}; + +// --- end of relay definitions ------------------------------ + // --- client classes ---------------------------------------- client_classes: CLIENT_CLASSES { ElementPtr l(new ListElement(ctx.loc2pos(@1))); @@ -1158,7 +1247,6 @@ client_class_test: TEST { ctx.leave(); } - // --- end of client classes --------------------------------- // --- server-id --------------------------------------------- @@ -1215,6 +1303,84 @@ dhcp4o6_port: DHCP4O6_PORT COLON INTEGER { ctx.stack_.back()->set("dhcp4o6-port", time); }; +// code says it is a string, unit test a number +version: VERSION { + ctx.enter(ctx.NO_KEYWORD); +} COLON version_value { + ctx.stack_.back()->set("version", $4); + ctx.leave(); +}; + +version_value: + INTEGER { $$ = ElementPtr(new IntElement($1, ctx.loc2pos(@1))); } + | FLOAT { $$ = ElementPtr(new DoubleElement($1, ctx.loc2pos(@1))); } + | STRING { $$ = ElementPtr(new StringElement($1, ctx.loc2pos(@1))); } + ; + +// --- control socket ---------------------------------------- + +control_socket: CONTROL_SOCKET { + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("control-socket", m); + ctx.stack_.push_back(m); + ctx.enter(ctx.CONTROL_SOCKET); +} COLON LCURLY_BRACKET control_socket_params RCURLY_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + +control_socket_params: control_socket_param + | control_socket_params COMMA control_socket_param + ; + +control_socket_param: socket_type + | socket_name + ; + +socket_type: SOCKET_TYPE { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr stype(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("socket-type", stype); + ctx.leave(); +}; + +socket_name: SOCKET_NAME { + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr name(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("socket-name", name); + ctx.leave(); +}; + +// --- dhcp ddns --------------------------------------------- + +dhcp_ddns: DHCP_DDNS { + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("dhcp-ddns", m); + ctx.stack_.push_back(m); + ctx.enter(ctx.NO_KEYWORD); +} COLON LCURLY_BRACKET not_empty_map RCURLY_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + +// JSON entries for Dhcp4 and DhcpDdns + +dhcp4_json_object: DHCP4 { + ctx.enter(ctx.NO_KEYWORD); +} COLON value { + ctx.stack_.back()->set("Dhcp4", $4); + ctx.leave(); +}; + +dhcpddns_json_object: DHCPDDNS { + ctx.enter(ctx.NO_KEYWORD); +} COLON value { + ctx.stack_.back()->set("DhcpDdns", $4); + ctx.leave(); +}; + // --- logging entry ----------------------------------------- // This defines the top level "Logging" object. It parses @@ -1324,52 +1490,6 @@ output_param: OUTPUT { ctx.leave(); }; -dhcp_ddns: DHCP_DDNS { - ElementPtr m(new MapElement(ctx.loc2pos(@1))); - ctx.stack_.back()->set("dhcp-ddns", m); - ctx.stack_.push_back(m); - ctx.enter(ctx.DHCP_DDNS); -} COLON LCURLY_BRACKET dhcp_ddns_params RCURLY_BRACKET { - ctx.stack_.pop_back(); - ctx.leave(); -}; - -dhcp_ddns_params: dhcp_ddns_param - | dhcp_ddns_params COMMA dhcp_ddns_param - ; - -dhcp_ddns_param: enable_updates - | qualifying_suffix - | unknown_map_entry - ; - -enable_updates: ENABLE_UPDATES COLON BOOLEAN { - ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("enable-updates", b); -}; - -qualifying_suffix: QUALIFYING_SUFFIX { - ctx.enter(ctx.NO_KEYWORD); -} COLON STRING { - ElementPtr qs(new StringElement($4, ctx.loc2pos(@4))); - ctx.stack_.back()->set("qualifying-suffix", qs); - ctx.leave(); -}; - -dhcp4_json_object: DHCP4 { - ctx.enter(ctx.NO_KEYWORD); -} COLON value { - ctx.stack_.back()->set("Dhcp4", $4); - ctx.leave(); -}; - -dhcpddns_json_object: DHCPDDNS { - ctx.enter(ctx.NO_KEYWORD); -} COLON value { - ctx.stack_.back()->set("DhcpDdns", $4); - ctx.leave(); -}; - %% void diff --git a/src/bin/dhcp6/parser_context.cc b/src/bin/dhcp6/parser_context.cc index 8b6153ae76..3b9c25f86e 100644 --- a/src/bin/dhcp6/parser_context.cc +++ b/src/bin/dhcp6/parser_context.cc @@ -147,14 +147,16 @@ Parser6Context::context_name() return ("client-classes"); case SERVER_ID: return ("server-id"); - case DHCP_DDNS: - return ("dhcp-ddns"); + case CONTROL_SOCKET: + return ("control-socket"); case POOLS: return ("pools"); case PD_POOLS: return ("pd-pools"); case RESERVATIONS: return ("reservations"); + case RELAY: + return ("relay"); case CLIENT_CLASS: return ("client-class"); case LOGGERS: diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index 3446961bd2..2ba32a572a 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -136,11 +136,12 @@ public: OPTION_DATA, CLIENT_CLASSES, SERVER_ID, - DHCP_DDNS, + CONTROL_SOCKET, /// subnet6 POOLS, PD_POOLS, RESERVATIONS, + RELAY, /// client-classes CLIENT_CLASS, /// Logging diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index b8423dc7ea..460fc625b4 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -555,7 +555,7 @@ public: const std::string& parameter) { ConstElementPtr x; std::string config = createConfigWithOption(param_value, parameter); - ConstElementPtr json = parseJSON(config); + ConstElementPtr json = parseDHCP6(config); EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json)); checkResult(x, 1); EXPECT_TRUE(errorContainsPosition(x, "<string>")); @@ -573,7 +573,7 @@ public: testInvalidOptionParam(const std::map<std::string, std::string>& params) { ConstElementPtr x; std::string config = createConfigWithOption(params); - ConstElementPtr json = parseJSON(config); + ConstElementPtr json = parseDHCP6(config); EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json)); checkResult(x, 1); EXPECT_TRUE(errorContainsPosition(x, "<string>")); @@ -674,7 +674,7 @@ public: CfgMgr::instance().clear(); // Configure the server. - ConstElementPtr json = parseJSON(config); + ConstElementPtr json = parseDHCP6(config); // Make sure that the configuration was successful. ConstElementPtr status; @@ -737,11 +737,11 @@ public: // config update. TEST_F(Dhcp6ParserTest, version) { - ConstElementPtr x; - - EXPECT_NO_THROW(x = configureDhcp6Server(srv_, - parseJSON("{\"version\": 0}"))); + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP6("{\"version\": 0}")); + ConstElementPtr x; + EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json)); // returned value must be 0 (configuration accepted) checkResult(x, 0); } @@ -757,6 +757,9 @@ TEST_F(Dhcp6ParserTest, bogusCommand) { // returned value must be 1 (configuration parse error) checkResult(x, 1); + + // it should be refused by syntax too + EXPECT_THROW(parseDHCP6("{\"bogus\": 5}"), Dhcp6ParseError); } /// The goal of this test is to verify if configuration without any @@ -1119,7 +1122,7 @@ TEST_F(Dhcp6ParserTest, subnetLocal) { "\"valid-lifetime\": 4000 }"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -1216,8 +1219,7 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) { "\"valid-lifetime\": 4000 }"; cout << config << endl; - ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ConstElementPtr json = parseJSON(config); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -1225,6 +1227,8 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) { // returned value should be 1 (parse error) checkResult(status, 1); EXPECT_TRUE(errorContainsPosition(status, "<string>")); + + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); } @@ -1248,7 +1252,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) { "\"valid-lifetime\": 4000 }"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -1289,8 +1293,7 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) { " \"subnet\": \"2001:db8:1::/64\" } ]," "\"valid-lifetime\": 4000 }"; - ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ConstElementPtr json = parseJSON(config); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -1298,6 +1301,8 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) { // Returned value should be 1 (parse error) checkResult(status, 1); EXPECT_TRUE(errorContainsPosition(status, "<string>")); + + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); } // This test checks if it is not possible to define a subnet with an @@ -1315,7 +1320,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceAndInterfaceId) { "\"valid-lifetime\": 4000 }"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -1517,7 +1522,7 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) { // Convert the JSON string into Elements. ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); // Verify that DHCP6 configuration processing succeeds. // Returned value must be non-empty ConstElementPtr to config result. @@ -1655,7 +1660,7 @@ TEST_F(Dhcp6ParserTest, pdPoolList) { // Convert the JSON string into Elements. ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); // Verify that DHCP6 configuration processing succeeds. // Returned value must be non-empty ConstElementPtr to config result. @@ -1711,7 +1716,7 @@ TEST_F(Dhcp6ParserTest, subnetAndPrefixDelegated) { // Convert the JSON string into Elements. ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); // Verify that DHCP6 configuration processing succeeds. // Returned value must be non-empty ConstElementPtr to config result. @@ -1754,7 +1759,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { const char *config[] = { // No prefix. - "{ \"interfaces-config\": { }," + "{ \"interfaces-config\": { \"interfaces\": [ ] }," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " @@ -1768,7 +1773,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { "\"valid-lifetime\": 4000 }" "] }", // No prefix-len. - "{ \"interfaces-config\": { }," + "{ \"interfaces-config\": { \"interfaces\": [ ] }," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " @@ -1781,7 +1786,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { "\"valid-lifetime\": 4000 }" "] }", // No delegated-len. - "{ \"interfaces-config\": { }," + "{ \"interfaces-config\": { \"interfaces\": [ ] }," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " @@ -1794,7 +1799,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { "\"valid-lifetime\": 4000 }" "] }", // Delegated length is too short. - "{ \"interfaces-config\": { }," + "{ \"interfaces-config\": { \"interfaces\": [ ] }," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " @@ -1813,7 +1818,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { int num_msgs = sizeof(config)/sizeof(char*); for (unsigned int i = 0; i < num_msgs; i++) { // Convert JSON string to Elements. - ASSERT_NO_THROW(json = parseJSON(config[i])); + ASSERT_NO_THROW(json = parseDHCP6(config[i])); // Configuration processing should fail without a throw. ASSERT_NO_THROW(x = configureDhcp6Server(srv_, json)); @@ -1903,7 +1908,7 @@ TEST_F(Dhcp6ParserTest, optionDefRecord) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Make sure that the particular option definition does not exist. OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()-> @@ -2062,7 +2067,7 @@ TEST_F(Dhcp6ParserTest, optionDefArray) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Make sure that the particular option definition does not exist. OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()-> @@ -2102,7 +2107,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulate) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Make sure that the particular option definition does not exist. OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()-> @@ -2192,7 +2197,7 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidRecordType) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Use the configuration string to create new option definition. ConstElementPtr status; @@ -2247,7 +2252,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulatedSpaceAndArray) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Use the configuration string to create new option definition. ConstElementPtr status; @@ -2273,7 +2278,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulateOwnSpace) { " } ]" "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseOPTION_DEF(config)); // Use the configuration string to create new option definition. ConstElementPtr status; @@ -2696,8 +2701,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) { " } ]" "}"; - - json = parseJSON(config); + ASSERT_NO_THROW(json = parseDHCP6(config)); EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); ASSERT_TRUE(status); @@ -3013,7 +3017,7 @@ TEST_F(Dhcp6ParserTest, optionDataBoolean) { sizeof(expected_option_data)); // Bogus values should not be accepted. - params["data"] = "bugus"; + params["data"] = "bogus"; testInvalidOptionParam(params); params["data"] = "2"; @@ -3676,7 +3680,7 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) { "\"valid-lifetime\": 4000 }"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -3816,7 +3820,7 @@ TEST_F(Dhcp6ParserTest, d2ClientConfig) { // Convert the JSON string to configuration elements. ConstElementPtr config; - ASSERT_NO_THROW(config = parseJSON(config_str)); + ASSERT_NO_THROW(config = parseDHCP6(config_str)); // Pass the configuration in for parsing. ConstElementPtr status; @@ -3877,7 +3881,7 @@ TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) { // Convert the JSON string to configuration elements. ConstElementPtr config; - ASSERT_NO_THROW(config = parseJSON(config_str)); + ASSERT_NO_THROW(config = parseDHCP6(config_str)); // Configuration should not throw, but should fail. ConstElementPtr status; @@ -4203,12 +4207,13 @@ TEST_F(Dhcp6ParserTest, reservationBogus) { "\"preferred-lifetime\": 3000," "\"valid-lifetime\": 4000 }"; - ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ConstElementPtr json = parseJSON(config); EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json)); checkResult(x, 1); + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); + // Case 2: DUID and HW Address both specified. config = "{ " + genIfaceConfig() + "," "\"rebind-timer\": 2000, " @@ -4338,6 +4343,7 @@ TEST_F(Dhcp6ParserTest, macSources) { /// The goal of this test is to verify that MAC sources configuration can be /// empty. +/// Note the Dhcp6 parser requires the list to NOT be empty?! TEST_F(Dhcp6ParserTest, macSourcesEmpty) { ConstElementPtr status; @@ -4414,10 +4420,11 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) { " } ]," "\"valid-lifetime\": 4000 }"; - ConstElementPtr status; + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP6(HR_CONFIG)); - EXPECT_NO_THROW(status = configureDhcp6Server(srv_, - parseJSON(HR_CONFIG))); + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); // returned value should be 0 (success) checkResult(status, 0); @@ -4459,7 +4466,7 @@ TEST_F(Dhcp6ParserTest, rsooNumbers) { ConstElementPtr json; ASSERT_NO_THROW(json = - parseDHCP6("{ " + genIfaceConfig() + "," + parseDHCP6("{ " + genIfaceConfig() + "," "\"relay-supplied-options\": [ \"10\", \"20\", \"30\" ]," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " @@ -4494,7 +4501,7 @@ TEST_F(Dhcp6ParserTest, rsooNames) { ConstElementPtr json; ASSERT_NO_THROW(json = - parseDHCP6("{ " + genIfaceConfig() + "," + parseDHCP6("{ " + genIfaceConfig() + "," "\"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ]," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " @@ -4544,7 +4551,7 @@ TEST_F(Dhcp6ParserTest, rsooNames) { TEST_F(Dhcp6ParserTest, rsooNegativeNumber) { ConstElementPtr json; ASSERT_NO_THROW(json = - parseDHCP6("{ " + genIfaceConfig() + "," + parseDHCP6("{ " + genIfaceConfig() + "," "\"relay-supplied-options\": [ \"80\", \"-2\" ]," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " @@ -4562,7 +4569,7 @@ TEST_F(Dhcp6ParserTest, rsooNegativeNumber) { TEST_F(Dhcp6ParserTest, rsooBogusName) { ConstElementPtr json; ASSERT_NO_THROW(json = - parseDHCP6("{ " + genIfaceConfig() + "," + parseDHCP6("{ " + genIfaceConfig() + "," "\"relay-supplied-options\": [ \"bogus\", \"dns-servers\" ]," "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " @@ -4584,7 +4591,7 @@ TEST_F(Dhcp6ParserTest, declineTimerDefault) { "\"subnet6\": [ ] " "}"; ConstElementPtr config; - ASSERT_NO_THROW(config = parseJSON(config_txt)); + ASSERT_NO_THROW(config = parseDHCP6(config_txt)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config)); @@ -4606,7 +4613,7 @@ TEST_F(Dhcp6ParserTest, declineTimer) { "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -4627,8 +4634,7 @@ TEST_F(Dhcp6ParserTest, declineTimerError) { "\"subnet6\": [ ]" "}"; - ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ConstElementPtr json = parseJSON(config); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -4638,6 +4644,9 @@ TEST_F(Dhcp6ParserTest, declineTimerError) { // Check that the error contains error position. EXPECT_TRUE(errorContainsPosition(status, "<string>")); + + // Check that the Dhcp6 parser catches the type error + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); } // Check that configuration for the expired leases processing may be @@ -4658,7 +4667,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) { "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -4699,7 +4708,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessingError) { "}"; ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ASSERT_NO_THROW(json = parseDHCP6(config)); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); @@ -4777,13 +4786,14 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) { " } ] \n" "} \n"; - ConstElementPtr json; - ASSERT_NO_THROW(json = parseJSON(config)); + ConstElementPtr json = parseJSON(config); ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); ASSERT_TRUE(status); checkResult(status, 1); + + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); } // Test verifies that regular configuration does not provide any user context diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc index ce007ba37d..1b4ade9daf 100644 --- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc @@ -146,7 +146,7 @@ public: ASSERT_NO_THROW(server_.reset(new NakedControlledDhcpv6Srv())); ConstElementPtr config; - ASSERT_NO_THROW(config = parseJSON(config_txt)); + ASSERT_NO_THROW(config = parseDHCP6(config_txt)); ConstElementPtr answer = server_->processConfig(config); ASSERT_TRUE(answer); diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 48bc40b3a4..9e72527ce5 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -1705,9 +1705,9 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) { string config_bogus = config_prefix + "99" + config_postfix; ConstElementPtr json_bogus; - ASSERT_NO_THROW(json_bogus = parseJSON(config_bogus)); + ASSERT_NO_THROW(json_bogus = parseDHCP6(config_bogus)); ConstElementPtr json_valid; - ASSERT_NO_THROW(json_valid = parseJSON(config_valid)); + ASSERT_NO_THROW(json_valid = parseDHCP6(config_valid)); NakedDhcpv6Srv srv(0); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index d15de0879f..47b4a92500 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -656,7 +656,9 @@ parseDHCP6(const std::string& in) return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6)); } catch (const std::exception& ex) { +#ifdef ENABLE_DEBUG std::cout << "EXCEPTION: " << ex.what() << std::endl; +#endif // ENABLE_DEBUG throw; } } @@ -670,7 +672,9 @@ parseOPTION_DEF(const std::string& in) return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_OPTION_DEF)); } catch (const std::exception& ex) { +#ifdef ENABLE_DEBUG std::cout << "EXCEPTION: " << ex.what() << std::endl; +#endif // ENABLE_DEBUG throw; } } |