Browse Source

[5014_phase2] Use Dhcp6 (vs JSON) parser as much as possible in unit tests

Francis Dupont 8 years ago
parent
commit
4204443ad1

+ 114 - 12
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_);
     }
 }
 

+ 180 - 60
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

+ 4 - 2
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:

+ 2 - 1
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

+ 61 - 51
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

+ 1 - 1
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);
 

+ 2 - 2
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);
 

+ 4 - 0
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;
     }
 }