]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5014_phase2] Use parser in place of fromJSON
authorFrancis Dupont <fdupont@isc.org>
Tue, 29 Nov 2016 04:30:56 +0000 (05:30 +0100)
committerTomek Mrugalski <tomasz@isc.org>
Tue, 29 Nov 2016 18:58:37 +0000 (19:58 +0100)
src/bin/dhcp6/dhcp6_lexer.ll
src/bin/dhcp6/dhcp6_parser.yy
src/bin/dhcp6/parser_context.cc
src/bin/dhcp6/parser_context.h
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/sarr_unittest.cc

index d54cc0c2259b86fef91a8028e0bce7ce5a4ece77..11b32ad252d0d405bc897b2bab7ec93f47083cad 100644 (file)
@@ -107,6 +107,8 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
             return isc::dhcp::Dhcp6Parser::make_TOPLEVEL_GENERIC_JSON(driver.loc_);
         case Parser6Context::PARSER_DHCP6:
             return isc::dhcp::Dhcp6Parser::make_TOPLEVEL_DHCP6(driver.loc_);
+        case Parser6Context::SUBPARSER_DHCP6:
+            return isc::dhcp::Dhcp6Parser::make_SUB_DHCP6(driver.loc_);
         case Parser6Context::SUBPARSER_INTERFACES6:
             return isc::dhcp::Dhcp6Parser::make_SUB_INTERFACES6(driver.loc_);
         case Parser6Context::SUBPARSER_SUBNET6:
@@ -220,6 +222,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::LEASE_DATABASE:
     case isc::dhcp::Parser6Context::HOSTS_DATABASE:
+    case isc::dhcp::Parser6Context::OPTION_DEF:
     case isc::dhcp::Parser6Context::SERVER_ID:
         return isc::dhcp::Dhcp6Parser::make_TYPE(driver.loc_);
     default:
@@ -323,6 +326,15 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     }
 }
 
+\"option-def\" {
+    switch(driver.ctx_) {
+    case isc::dhcp::Parser6Context::DHCP6:
+        return isc::dhcp::Dhcp6Parser::make_OPTION_DEF(driver.loc_);
+    default:
+        return isc::dhcp::Dhcp6Parser::make_STRING("option-def", driver.loc_);
+    }
+}
+
 \"option-data\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::DHCP6:
@@ -342,6 +354,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::LEASE_DATABASE:
     case isc::dhcp::Parser6Context::HOSTS_DATABASE:
+    case isc::dhcp::Parser6Context::OPTION_DEF:
     case isc::dhcp::Parser6Context::OPTION_DATA:
     case isc::dhcp::Parser6Context::CLIENT_CLASSES:
     case isc::dhcp::Parser6Context::CLIENT_CLASS:
@@ -444,6 +457,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 
 \"code\" {
     switch(driver.ctx_) {
+    case isc::dhcp::Parser6Context::OPTION_DEF:
     case isc::dhcp::Parser6Context::OPTION_DATA:
         return isc::dhcp::Dhcp6Parser::make_CODE(driver.loc_);
     default:
@@ -621,6 +635,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 
 \"space\" {
     switch(driver.ctx_) {
+    case isc::dhcp::Parser6Context::OPTION_DEF:
     case isc::dhcp::Parser6Context::OPTION_DATA:
         return isc::dhcp::Dhcp6Parser::make_SPACE(driver.loc_);
     default:
@@ -630,6 +645,7 @@ 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:
index b6ac40fae3f17b473186d1cea78f40fea1dfe75a..8b1e3abb5d664ea9b96ee6294e4c66f5aaeddc7f 100644 (file)
@@ -67,6 +67,7 @@ using namespace std;
   RENEW_TIMER "renew-timer"
   REBIND_TIMER "rebind-timer"
   SUBNET6 "subnet6"
+  OPTION_DEF "option-def"
   OPTION_DATA "option-data"
   NAME "name"
   DATA "data"
@@ -131,11 +132,13 @@ using namespace std;
  // parse.
   TOPLEVEL_GENERIC_JSON
   TOPLEVEL_DHCP6
+  SUB_DHCP6
   SUB_INTERFACES6
   SUB_SUBNET6
   SUB_POOL6
   SUB_PD_POOL
   SUB_RESERVATION
+  SUB_OPTION_DEF
   SUB_OPTION_DATA
   SUB_HOOKS_LIBRARY
   SUB_JSON
@@ -159,11 +162,13 @@ using namespace std;
 
 start: TOPLEVEL_GENERIC_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } map2
      | TOPLEVEL_DHCP6 { ctx.ctx_ = ctx.CONFIG; } syntax_map
+     | SUB_DHCP6 { ctx.ctx_ = ctx.DHCP6; } sub_dhcp6
      | SUB_INTERFACES6 { ctx.ctx_ = ctx.INTERFACES_CONFIG; } sub_interfaces6
      | SUB_SUBNET6 { ctx.ctx_ = ctx.SUBNET6; } sub_subnet6
      | SUB_POOL6 { ctx.ctx_ = ctx.POOLS; } sub_pool6
      | SUB_PD_POOL { ctx.ctx_ = ctx.PD_POOLS; } sub_pd_pool
      | SUB_RESERVATION { ctx.ctx_ = ctx.RESERVATIONS; } sub_reservation
+     | SUB_OPTION_DEF { ctx.ctx_ = ctx.OPTION_DEF; } sub_option_def
      | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
      | SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library
      | SUB_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json
@@ -299,6 +304,16 @@ dhcp6_object: DHCP6 {
     ctx.leave();
 };
 
+// subparser: similar to the corresponding rule but without parent
+// so the stack is empty at the rule entry.
+sub_dhcp6: LCURLY_BRACKET {
+    // Parse the Dhcp6 map
+    ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+    ctx.stack_.push_back(m);
+} global_params RCURLY_BRACKET {
+    // parsing completed
+};
+
 global_params: global_param
              | global_params COMMA global_param
              ;
@@ -317,6 +332,7 @@ global_param: preferred_lifetime
             | relay_supplied_options
             | host_reservation_identifiers
             | client_classes
+            | option_def_list
             | option_data_list
             | hooks_libraries
             | expired_leases_processing
@@ -356,8 +372,6 @@ interfaces_config: INTERFACES_CONFIG {
     ctx.leave();
 };
 
-// subparser: similar to the corresponding rule but without parent
-// so the stack is empty at the rule entry.
 sub_interfaces6: LCURLY_BRACKET {
     // Parse the interfaces-config map
     ElementPtr m(new MapElement(ctx.loc2pos(@1)));
@@ -695,6 +709,95 @@ id: ID COLON INTEGER {
     ctx.stack_.back()->set("id", id);
 };
 
+// ---- option-def --------------------------
+
+// This defines the "option-def": [ ... ] entry that may appear
+// at a global option.
+option_def_list: OPTION_DEF {
+    ElementPtr l(new ListElement(ctx.loc2pos(@1)));
+    ctx.stack_.back()->set("option-def", l);
+    ctx.stack_.push_back(l);
+    ctx.enter(ctx.OPTION_DEF);
+} COLON LSQUARE_BRACKET option_def_list_content RSQUARE_BRACKET {
+    ctx.stack_.pop_back();
+    ctx.leave();
+};
+
+// This defines the content of option-def. It may be empty,
+// have one entry or multiple entries separated by comma.
+option_def_list_content: %empty
+                       | not_empty_option_def_list
+                       ;
+
+not_empty_option_def_list: option_def_entry
+                         | not_empty_option_def_list COMMA option_def_entry
+                          ;
+
+// This defines the content of a single entry { ... } within
+// option-def list.
+option_def_entry: LCURLY_BRACKET {
+    ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+    ctx.stack_.back()->add(m);
+    ctx.stack_.push_back(m);
+} option_def_params RCURLY_BRACKET {
+    ctx.stack_.pop_back();
+};
+
+sub_option_def: LCURLY_BRACKET {
+    // Parse the option-def list entry map
+    ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+    ctx.stack_.push_back(m);
+} option_def_params RCURLY_BRACKET {
+    // parsing completed
+};
+
+// This defines parameters specified inside the map that itself
+// is an entry in option-def list.
+option_def_params: %empty
+                 | not_empty_option_def_params
+                 ;
+
+not_empty_option_def_params: option_def_param
+                           | not_empty_option_def_params COMMA option_def_param
+                           ;
+
+option_def_param: option_def_name
+                | option_def_code
+                | option_def_type
+                | option_def_space
+                | option_def_csv_format
+                | unknown_map_entry
+                ;
+
+
+option_def_name: name;
+
+code: CODE COLON INTEGER {
+    ElementPtr code(new IntElement($3, ctx.loc2pos(@3)));
+    ctx.stack_.back()->set("code", code);
+};
+
+option_def_code: code;
+
+option_def_type: type;
+
+space: SPACE {
+    ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+    ElementPtr space(new StringElement($4, ctx.loc2pos(@4)));
+    ctx.stack_.back()->set("space", space);
+    ctx.leave();
+};
+
+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_csv_format: csv_format;
+
 // ---- option-data --------------------------
 
 // This defines the "option-data": [ ... ] entry that may appear
@@ -766,23 +869,11 @@ option_data_data: DATA {
     ctx.leave();
 };
 
-option_data_code: CODE COLON INTEGER {
-    ElementPtr code(new IntElement($3, ctx.loc2pos(@3)));
-    ctx.stack_.back()->set("code", code);
-};
+option_data_code: code;
 
-option_data_space: SPACE {
-    ctx.enter(ctx.NO_KEYWORD);
-} COLON STRING {
-    ElementPtr space(new StringElement($4, ctx.loc2pos(@4)));
-    ctx.stack_.back()->set("space", space);
-    ctx.leave();
-};
+option_data_space: space;
 
-option_data_csv_format: CSV_FORMAT COLON BOOLEAN {
-    ElementPtr space(new BoolElement($3, ctx.loc2pos(@3)));
-    ctx.stack_.back()->set("csv-format", space);
-};
+option_data_csv_format: csv_format;
 
 // ---- pools ------------------------------------
 
index 6b8459b847ca6f1e88af506445bd6363ef65248e..8b6153ae7642f4ad53f4020804773c604f1db026 100644 (file)
@@ -139,6 +139,8 @@ Parser6Context::context_name()
         return ("hooks-librairies");
     case SUBNET6:
         return ("subnet6");
+    case OPTION_DEF:
+        return ("option-def");
     case OPTION_DATA:
         return ("option-data");
     case CLIENT_CLASSES:
index 33b0798606ba4c72fd86965eb056eb605c64eac0..3446961bd24b2eb6f860938b4b614f01d705b7ad 100644 (file)
@@ -40,13 +40,14 @@ public:
         PARSER_GENERIC_JSON, // This will parse the content as generic JSON
         PARSER_DHCP6,        // This will parse the content as DHCP6 config
         // DHCP6 config subparsers
+        SUBPARSER_DHCP6,
         SUBPARSER_INTERFACES6,
         SUBPARSER_SUBNET6,
         SUBPARSER_POOL6,
         SUBPARSER_PD_POOL,
         SUBPARSER_HOST_RESERVATION6,
         // Common DHCP subparsers
-          // SUBPARSER_OPTION_DEF,
+        SUBPARSER_OPTION_DEF,
         SUBPARSER_OPTION_DATA,
         SUBPARSER_HOOKS_LIBRARY,
           // SUBPARSER_CONTROL_SOCKET,
@@ -131,6 +132,7 @@ public:
         HOST_RESERVATION_IDENTIFIERS,
         HOOKS_LIBRARIES,
         SUBNET6,
+        OPTION_DEF,
         OPTION_DATA,
         CLIENT_CLASSES,
         SERVER_ID,
index 82691c341662fa022beec1f908a1e120e312a5af..b8423dc7eaf80f5b711e4610b793c4f9e85484f4 100644 (file)
@@ -30,6 +30,7 @@
 #include "test_data_files_config.h"
 #include "test_libraries.h"
 #include "marker_file.h"
+#include "dhcp6_test_utils.h"
 
 #include <boost/foreach.hpp>
 #include <gtest/gtest.h>
@@ -278,25 +279,25 @@ public:
             params["space"] = DHCP6_OPTION_SPACE;
             params["code"] = "38";
             params["data"] = "ABCDEF0105";
-            params["csv-format"] = "False";
+            params["csv-format"] = "false";
         } else if (parameter == "space") {
             params["name"] = "subscriber-id";
             params["space"] = param_value;
             params["code"] = "38";
             params["data"] = "ABCDEF0105";
-            params["csv-format"] = "False";
+            params["csv-format"] = "false";
         } else if (parameter == "code") {
             params["name"] = "subscriber-id";
             params["space"] = DHCP6_OPTION_SPACE;
             params["code"] = param_value;
             params["data"] = "ABCDEF0105";
-            params["csv-format"] = "False";
+            params["csv-format"] = "false";
         } else if (parameter == "data") {
             params["name"] = "subscriber-id";
             params["space"] = DHCP6_OPTION_SPACE;
             params["code"] = "38";
             params["data"] = param_value;
-            params["csv-format"] = "False";
+            params["csv-format"] = "false";
         } else if (parameter == "csv-format") {
             params["name"] = "subscriber-id";
             params["space"] = DHCP6_OPTION_SPACE;
@@ -431,9 +432,10 @@ public:
     ///         latter case, a failure will have been added to the current test.
     bool
     executeConfiguration(const std::string& config, const char* operation) {
+        ConstElementPtr json;
         ConstElementPtr status;
         try {
-            ElementPtr json = Element::fromJSON(config);
+            json = parseJSON(config);
             status = configureDhcp6Server(srv_, json);
 
         } catch (const std::exception& ex) {
@@ -553,7 +555,7 @@ public:
                                 const std::string& parameter) {
         ConstElementPtr x;
         std::string config = createConfigWithOption(param_value, parameter);
-        ElementPtr json = Element::fromJSON(config);
+        ConstElementPtr json = parseJSON(config);
         EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
         checkResult(x, 1);
         EXPECT_TRUE(errorContainsPosition(x, "<string>"));
@@ -571,7 +573,7 @@ public:
     testInvalidOptionParam(const std::map<std::string, std::string>& params) {
         ConstElementPtr x;
         std::string config = createConfigWithOption(params);
-        ElementPtr json = Element::fromJSON(config);
+        ConstElementPtr json = parseJSON(config);
         EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
         checkResult(x, 1);
         EXPECT_TRUE(errorContainsPosition(x, "<string>"));
@@ -672,7 +674,7 @@ public:
         CfgMgr::instance().clear();
 
         // Configure the server.
-        ElementPtr json = Element::fromJSON(config);
+        ConstElementPtr json = parseJSON(config);
 
         // Make sure that the configuration was successful.
         ConstElementPtr status;
@@ -738,7 +740,7 @@ TEST_F(Dhcp6ParserTest, version) {
     ConstElementPtr x;
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_,
-                    Element::fromJSON("{\"version\": 0}")));
+                    parseJSON("{\"version\": 0}")));
 
     // returned value must be 0 (configuration accepted)
     checkResult(x, 0);
@@ -751,7 +753,7 @@ TEST_F(Dhcp6ParserTest, bogusCommand) {
     ConstElementPtr x;
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_,
-                    Element::fromJSON("{\"bogus\": 5}")));
+                    parseJSON("{\"bogus\": 5}")));
 
     // returned value must be 1 (configuration parse error)
     checkResult(x, 1);
@@ -761,16 +763,17 @@ TEST_F(Dhcp6ParserTest, bogusCommand) {
 /// subnets defined can be accepted.
 TEST_F(Dhcp6ParserTest, emptySubnet) {
 
-    ConstElementPtr status;
-
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-                    Element::fromJSON("{ " + genIfaceConfig() + ","
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6("{ " + genIfaceConfig() + ","
                                       "\"preferred-lifetime\": 3000,"
                                       "\"rebind-timer\": 2000, "
                                       "\"renew-timer\": 1000, "
                                       "\"subnet6\": [  ], "
-                                      "\"valid-lifetime\": 4000 }")));
+                                      "\"valid-lifetime\": 4000 }"));
 
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
+                    
     // returned value should be 0 (success)
     checkResult(status, 0);
 }
@@ -779,8 +782,6 @@ TEST_F(Dhcp6ParserTest, emptySubnet) {
 /// parameter timer definitions.
 TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
 
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
@@ -790,8 +791,10 @@ TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // check if returned status is OK
@@ -841,7 +844,8 @@ TEST_F(Dhcp6ParserTest, multipleSubnets) {
 
     int cnt = 0; // Number of reconfigurations
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     do {
         EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
@@ -899,7 +903,8 @@ TEST_F(Dhcp6ParserTest, multipleSubnetsExplicitIDs) {
 
     int cnt = 0; // Number of reconfigurations
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     do {
         EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
@@ -953,7 +958,8 @@ TEST_F(Dhcp6ParserTest, multipleSubnetsOverlapingIDs) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 1);
@@ -1040,7 +1046,8 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     // CASE 1: Configure 4 subnets, then reconfigure and remove the
     // last one.
 
-    ElementPtr json = Element::fromJSON(config4);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config4));
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
 
@@ -1052,7 +1059,7 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
 
     // Do the reconfiguration (the last subnet is removed)
-    json = Element::fromJSON(config_first3);
+    ASSERT_NO_THROW(json = parseDHCP6(config_first3));
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
 
@@ -1069,14 +1076,14 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     /// CASE 2: Configure 4 subnets, then reconfigure and remove one
     /// from in between (not first, not last)
 
-    json = Element::fromJSON(config4);
+    ASSERT_NO_THROW(json = parseDHCP6(config4));
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
 
     CfgMgr::instance().commit();
 
     // Do reconfiguration
-    json = Element::fromJSON(config_second_removed);
+    ASSERT_NO_THROW(json = parseDHCP6(config_second_removed));
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
 
@@ -1098,8 +1105,6 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
 // on a per subnet basis.
 TEST_F(Dhcp6ParserTest, subnetLocal) {
 
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
@@ -1113,8 +1118,10 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (configuration success)
@@ -1133,8 +1140,6 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
 // interface defined.
 TEST_F(Dhcp6ParserTest, subnetInterface) {
 
-    ConstElementPtr status;
-
     // There should be at least one interface
 
     string config = "{ " + genIfaceConfig() + ","
@@ -1148,8 +1153,10 @@ TEST_F(Dhcp6ParserTest, subnetInterface) {
         "\"valid-lifetime\": 4000 }";
     cout << config << endl;
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (configuration success)
@@ -1165,8 +1172,6 @@ TEST_F(Dhcp6ParserTest, subnetInterface) {
 // Subnet6 definition.
 TEST_F(Dhcp6ParserTest, subnetInterfaceBogus) {
 
-    ConstElementPtr status;
-
     // There should be at least one interface
 
     string config = "{ " + genIfaceConfig() + ","
@@ -1180,8 +1185,10 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceBogus) {
         "\"valid-lifetime\": 4000 }";
     cout << config << endl;
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 1 (configuration error)
@@ -1198,8 +1205,6 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceBogus) {
 // parameter.
 TEST_F(Dhcp6ParserTest, interfaceGlobal) {
 
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
@@ -1211,8 +1216,10 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) {
         "\"valid-lifetime\": 4000 }";
     cout << config << endl;
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 1 (parse error)
@@ -1240,7 +1247,8 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1281,7 +1289,8 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1305,7 +1314,8 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceAndInterfaceId) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1341,7 +1351,7 @@ TEST_F(Dhcp6ParserTest, subnetRapidCommit) {
                         "\"subnet6\": [ { "
                         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - "
                         "2001:db8:1::ffff\" } ],"
-                        "    \"rapid-commit\": True,"
+                        "    \"rapid-commit\": true,"
                         "    \"subnet\": \"2001:db8:1::/64\" } ],"
                         "\"valid-lifetime\": 4000 }",
                         true);
@@ -1356,7 +1366,7 @@ TEST_F(Dhcp6ParserTest, subnetRapidCommit) {
                         "\"subnet6\": [ { "
                         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - "
                         "2001:db8:1::ffff\" } ],"
-                        "    \"rapid-commit\": False,"
+                        "    \"rapid-commit\": false,"
                         "    \"subnet\": \"2001:db8:1::/64\" } ],"
                         "\"valid-lifetime\": 4000 }",
                         false);
@@ -1386,8 +1396,8 @@ TEST_F(Dhcp6ParserTest, multiplePools) {
         "    \"subnet\": \"2001:db8:2::/64\""
         " } ],"
         "\"valid-lifetime\": 4000 }";
-    ElementPtr json;
-    ASSERT_NO_THROW(json = Element::fromJSON(config));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     ConstElementPtr status;
     ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1426,8 +1436,6 @@ TEST_F(Dhcp6ParserTest, multiplePools) {
 // pool are rejected.
 TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
 
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
@@ -1438,8 +1446,10 @@ TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
         "\"valid-lifetime\": 4000 }";
 
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value must be 1 (values error)
@@ -1466,7 +1476,8 @@ TEST_F(Dhcp6ParserTest, poolPrefixLen) {
         "    \"subnet\": \"2001:db8:1::/64\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
 
@@ -1505,8 +1516,8 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) {
         "] }";
 
     // Convert the JSON string into Elements.
-    ElementPtr json;
-    ASSERT_NO_THROW(json = Element::fromJSON(config));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Verify that DHCP6 configuration processing succeeds.
     // Returned value must be non-empty ConstElementPtr to config result.
@@ -1643,8 +1654,8 @@ TEST_F(Dhcp6ParserTest, pdPoolList) {
         "] }";
 
     // Convert the JSON string into Elements.
-    ElementPtr json = Element::fromJSON(config);
-    ASSERT_NO_THROW(json = Element::fromJSON(config));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Verify that DHCP6 configuration processing succeeds.
     // Returned value must be non-empty ConstElementPtr to config result.
@@ -1699,8 +1710,8 @@ TEST_F(Dhcp6ParserTest, subnetAndPrefixDelegated) {
         "] }";
 
     // Convert the JSON string into Elements.
-    ElementPtr json;
-    ASSERT_NO_THROW(json = Element::fromJSON(config));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Verify that DHCP6 configuration processing succeeds.
     // Returned value must be non-empty ConstElementPtr to config result.
@@ -1798,11 +1809,11 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
         "] }"
         };
 
-    ElementPtr json;
+    ConstElementPtr json;
     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 = Element::fromJSON(config[i]));
+        ASSERT_NO_THROW(json = parseJSON(config[i]));
 
         // Configuration processing should fail without a throw.
         ASSERT_NO_THROW(x = configureDhcp6Server(srv_, json));
@@ -1827,7 +1838,8 @@ TEST_F(Dhcp6ParserTest, optionDefIpv6Address) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Make sure that the particular option definition does not exist.
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -1868,7 +1880,7 @@ TEST_F(Dhcp6ParserTest, optionDefIpv6Address) {
     // configuration and should result in removal of the option 100 from the
     // libdhcp++.
     config = "{ }";
-    json = Element::fromJSON(config);
+    json = parseOPTION_DEF(config);
     ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
     checkResult(status, 0);
 
@@ -1890,7 +1902,8 @@ TEST_F(Dhcp6ParserTest, optionDefRecord) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Make sure that the particular option definition does not exist.
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -1942,7 +1955,8 @@ TEST_F(Dhcp6ParserTest, optionDefMultiple) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Make sure that the option definitions do not exist yet.
     ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->
@@ -2008,7 +2022,8 @@ TEST_F(Dhcp6ParserTest, optionDefDuplicate) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Make sure that the option definition does not exist yet.
     ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->
@@ -2042,11 +2057,12 @@ TEST_F(Dhcp6ParserTest, optionDefArray) {
         "      \"name\": \"foo\","
         "      \"code\": 100,"
         "      \"type\": \"uint32\","
-        "      \"array\": True,"
+        "      \"array\": true,"
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Make sure that the particular option definition does not exist.
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -2085,7 +2101,8 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulate) {
         "      \"encapsulate\": \"sub-opts-space\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Make sure that the particular option definition does not exist.
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -2123,7 +2140,8 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidName) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2147,7 +2165,8 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidType) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2172,7 +2191,8 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidRecordType) {
         "      \"space\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2197,7 +2217,8 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidEncapsulatedSpace) {
         "      \"encapsulate\": \"invalid%space%name\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2220,12 +2241,13 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulatedSpaceAndArray) {
         "      \"name\": \"foo\","
         "      \"code\": 100,"
         "      \"type\": \"uint32\","
-        "      \"array\": True,"
+        "      \"array\": true,"
         "      \"space\": \"isc\","
         "      \"encapsulate\": \"valid-space-name\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2250,7 +2272,8 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulateOwnSpace) {
         "      \"encapsulate\": \"isc\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     // Use the configuration string to create new option definition.
     ConstElementPtr status;
@@ -2279,7 +2302,8 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "      \"space\": \"dhcp6\""
         "  } ]"
         "}";
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseOPTION_DEF(config));
 
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
         getCfgOptionDef()->get(DHCP6_OPTION_SPACE, 100);
@@ -2313,7 +2337,7 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "      \"space\": \"dhcp6\""
         "  } ]"
         "}";
-    json = Element::fromJSON(config);
+    json = parseOPTION_DEF(config);
 
     // Use the configuration string to create new option definition.
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -2335,7 +2359,7 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "      \"space\": \"dhcp6\""
         "  } ]"
         "}";
-    json = Element::fromJSON(config);
+    json = parseOPTION_DEF(config);
 
     // Use the configuration string to create new option definition.
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -2364,7 +2388,7 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsGlobal) {
         "\"option-data\": [ {"
         "    \"name\": \"subscriber-id\","
         "    \"data\": \"ABCDEF0105\","
-        "    \"csv-format\": False"
+        "    \"csv-format\": false"
         " },"
         " {"
         "    \"name\": \"preference\","
@@ -2376,7 +2400,8 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsGlobal) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -2438,7 +2463,7 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsSubnet) {
         "    \"option-data\": [ {"
         "        \"name\": \"subscriber-id\","
         "        \"data\": \"ABCDEF0105\","
-        "        \"csv-format\": False"
+        "        \"csv-format\": false"
         "     },"
         "     {"
         "        \"name\": \"preference\","
@@ -2447,7 +2472,8 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsSubnet) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -2517,7 +2543,7 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
         "\"option-data\": [ {"
         "    \"name\": \"subscriber-id\","
         "    \"data\": \"ABCDEF0105\","
-        "    \"csv-format\": False"
+        "    \"csv-format\": false"
         " },"
         " {"
         "    \"name\": \"foo\","
@@ -2536,10 +2562,10 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
         " } ]"
         "}";
 
-    ConstElementPtr status;
-
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -2612,10 +2638,10 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
         " } ]"
         "}";
 
-    ConstElementPtr status;
-
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -2671,7 +2697,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
         "}";
 
 
-    json = Element::fromJSON(config);
+    json = parseJSON(config);
 
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
@@ -2715,7 +2741,7 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
         "    \"option-data\": [ {"
         "          \"name\": \"subscriber-id\","
         "          \"data\": \"0102030405060708090A\","
-        "          \"csv-format\": False"
+        "          \"csv-format\": false"
         "        } ]"
         " },"
         " {"
@@ -2724,12 +2750,13 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
         "    \"option-data\": [ {"
         "          \"name\": \"user-class\","
         "          \"data\": \"FFFEFDFCFB\","
-        "          \"csv-format\": False"
+        "          \"csv-format\": false"
         "        } ]"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -2793,7 +2820,7 @@ TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
         "        \"option-data\": [ {"
         "            \"name\": \"subscriber-id\","
         "            \"data\": \"0102030405060708090A\","
-        "            \"csv-format\": False"
+        "            \"csv-format\": false"
         "        } ]"
         "    },"
         "    {"
@@ -2801,7 +2828,7 @@ TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
         "        \"option-data\": [ {"
         "            \"name\": \"user-class\","
         "            \"data\": \"FFFEFDFCFB\","
-        "            \"csv-format\": False"
+        "            \"csv-format\": false"
         "        } ]"
         "    } ],"
         "    \"pd-pools\": [ { "
@@ -2811,7 +2838,7 @@ TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
         "        \"option-data\": [ {"
         "            \"name\": \"subscriber-id\","
         "            \"data\": \"112233445566\","
-        "            \"csv-format\": False"
+        "            \"csv-format\": false"
         "        } ]"
         "    },"
         "    {"
@@ -2821,14 +2848,15 @@ TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
         "        \"option-data\": [ {"
         "            \"name\": \"user-class\","
         "            \"data\": \"aabbccddee\","
-        "            \"csv-format\": False"
+        "            \"csv-format\": false"
         "        } ]"
         "    } ],"
         "    \"subnet\": \"2001:db8:1::/64\""
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -3072,7 +3100,7 @@ TEST_F(Dhcp6ParserTest, optionDataUnexpectedPrefix) {
 TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
     ConstElementPtr x;
     std::string config = createConfigWithOption("0a0b0C0D", "data");
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json = parseDHCP6(config);
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -3112,10 +3140,10 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
     // Option code 3 means OPTION_IA_NA.
     params["code"] = "3";
     params["data"] = "12345, 6789, 1516";
-    params["csv-format"] = "True";
+    params["csv-format"] = "true";
 
     std::string config = createConfigWithOption(params);
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json = parseDHCP6(config);
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -3174,14 +3202,14 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
         "    \"space\": \"vendor-4491\","
         "    \"code\": 100,"
         "    \"data\": \"ABCDEF0105\","
-        "    \"csv-format\": False"
+        "    \"csv-format\": false"
         " },"
         " {"
         "    \"name\": \"option-two\","
         "    \"space\": \"vendor-1234\","
         "    \"code\": 100,"
         "    \"data\": \"1234\","
-        "    \"csv-format\": False"
+        "    \"csv-format\": false"
         " } ],"
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
@@ -3189,10 +3217,10 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
         " } ]"
         "}";
 
-    ConstElementPtr status;
-
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -3248,7 +3276,8 @@ TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
 
     ConstElementPtr status;
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
@@ -3312,10 +3341,10 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
         " } ]"
         "}";
 
-    ConstElementPtr status;
-
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -3365,9 +3394,7 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
         " } ]"
         "}";
 
-
-    json = Element::fromJSON(config);
-
+    ASSERT_NO_THROW(json = parseDHCP6(config));
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -3432,7 +3459,7 @@ buildHooksLibrariesConfig(const std::vector<std::string>& libraries) {
 
     // Create the first part of the configuration string.
     string config =
-        "{ \"interfaces-config\": { },"
+        "{ \"interfaces-config\": { \"interfaces\": [] },"
            "\"hooks-libraries\": [";
 
     // Append the libraries (separated by commas if needed)
@@ -3512,8 +3539,10 @@ TEST_F(Dhcp6ParserTest, InvalidLibrary) {
     // Parse a configuration containing a failing library.
     string config = buildHooksLibrariesConfig(NOT_PRESENT_LIBRARY);
 
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+
     ConstElementPtr status;
-    ElementPtr json = Element::fromJSON(config);
     ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // The status object must not be NULL
@@ -3568,8 +3597,6 @@ TEST_F(Dhcp6ParserTest, selectedInterfaces) {
     ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET6));
     ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET6));
 
-    ConstElementPtr status;
-
     string config = "{ \"interfaces-config\": {"
         "  \"interfaces\": [ \"eth0\" ]"
         "},"
@@ -3579,8 +3606,10 @@ TEST_F(Dhcp6ParserTest, selectedInterfaces) {
         "\"valid-lifetime\": 4000 }";
 
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value must be 1 (values error)
@@ -3602,8 +3631,6 @@ TEST_F(Dhcp6ParserTest, allInterfaces) {
     ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET6));
     ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET6));
 
-    ConstElementPtr status;
-
     // This configuration specifies two interfaces on which server should listen
     // but also includes '*'. This keyword switches server into the
     // mode when it listens on all interfaces regardless of what interface names
@@ -3617,8 +3644,10 @@ TEST_F(Dhcp6ParserTest, allInterfaces) {
         "\"valid-lifetime\": 4000 }";
 
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     checkResult(status, 0);
 
@@ -3633,8 +3662,6 @@ TEST_F(Dhcp6ParserTest, allInterfaces) {
 // This test checks if it is possible to specify relay information
 TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
 
-    ConstElementPtr status;
-
     // A config with relay information.
     string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
@@ -3648,8 +3675,10 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
         "\"preferred-lifetime\": 3000, "
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (configuration success)
@@ -3690,7 +3719,8 @@ TEST_F(Dhcp6ParserTest, classifySubnets) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -3751,8 +3781,6 @@ TEST_F(Dhcp6ParserTest, classifySubnets) {
 // This test checks the ability of the server to parse a configuration
 // containing a full, valid dhcp-ddns (D2ClientConfig) entry.
 TEST_F(Dhcp6ParserTest, d2ClientConfig) {
-    ConstElementPtr status;
-
     // Verify that the D2 configuraiton can be fetched and is set to disabled.
     D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
     EXPECT_FALSE(d2_client_config->getEnableUpdates());
@@ -3787,10 +3815,11 @@ TEST_F(Dhcp6ParserTest, d2ClientConfig) {
         "\"valid-lifetime\": 4000 }";
 
     // Convert the JSON string to configuration elements.
-    ElementPtr config;
-    ASSERT_NO_THROW(config = Element::fromJSON(config_str));
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseJSON(config_str));
 
     // Pass the configuration in for parsing.
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
 
     // check if returned status is OK
@@ -3823,8 +3852,6 @@ TEST_F(Dhcp6ParserTest, d2ClientConfig) {
 // This test checks the ability of the server to handle a configuration
 // containing an invalid dhcp-ddns (D2ClientConfig) entry.
 TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) {
-    ConstElementPtr status;
-
     // Configuration string with an invalid D2 client config,
     // "server-ip" is invalid.
     string config_str = "{ " + genIfaceConfig() + ","
@@ -3849,10 +3876,11 @@ TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) {
         "\"valid-lifetime\": 4000 }";
 
     // Convert the JSON string to configuration elements.
-    ElementPtr config;
-    ASSERT_NO_THROW(config = Element::fromJSON(config_str));
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseJSON(config_str));
 
     // Configuration should not throw, but should fail.
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
 
     // check if returned status is failed.
@@ -3965,7 +3993,8 @@ TEST_F(Dhcp6ParserTest, reservations) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -4120,7 +4149,8 @@ TEST_F(Dhcp6ParserTest, reservationWithOptionDefinition) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 0);
@@ -4173,7 +4203,8 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
     checkResult(x, 1);
@@ -4200,7 +4231,7 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    json = Element::fromJSON(config);
+    json = parseDHCP6(config);
 
     // Remove existing configuration, if any.
     CfgMgr::instance().clear();
@@ -4227,7 +4258,7 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    json = Element::fromJSON(config);
+    json = parseDHCP6(config);
 
     // Remove existing configuration, if any.
     CfgMgr::instance().clear();
@@ -4260,7 +4291,7 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    json = Element::fromJSON(config);
+    json = parseDHCP6(config);
 
     // Remove existing configuration, if any.
     CfgMgr::instance().clear();
@@ -4275,17 +4306,19 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
 /// rfc4580 = subscriber-id).
 TEST_F(Dhcp6ParserTest, macSources) {
 
-    ConstElementPtr status;
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json =
+        parseDHCP6("{ " + genIfaceConfig() + ","
+                   "\"mac-sources\": [ \"rfc6939\", \"rfc4649\", \"rfc4580\","
+                   "\"client-link-addr-option\", \"remote-id\", \"subscriber-id\"],"
+                   "\"preferred-lifetime\": 3000,"
+                   "\"rebind-timer\": 2000, "
+                   "\"renew-timer\": 1000, "
+                   "\"subnet6\": [  ], "
+                   "\"valid-lifetime\": 4000 }"));
 
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-        Element::fromJSON("{ " + genIfaceConfig() + ","
-                          "\"mac-sources\": [ \"rfc6939\", \"rfc4649\", \"rfc4580\","
-                          "\"client-link-addr-option\", \"remote-id\", \"subscriber-id\"],"
-                          "\"preferred-lifetime\": 3000,"
-                          "\"rebind-timer\": 2000, "
-                          "\"renew-timer\": 1000, "
-                          "\"subnet6\": [  ], "
-                          "\"valid-lifetime\": 4000 }")));
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (success)
     checkResult(status, 0);
@@ -4310,13 +4343,13 @@ TEST_F(Dhcp6ParserTest, macSourcesEmpty) {
     ConstElementPtr status;
 
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-                    Element::fromJSON("{ " + genIfaceConfig() + ","
-                                      "\"mac-sources\": [ ],"
-                                      "\"preferred-lifetime\": 3000,"
-                                      "\"rebind-timer\": 2000, "
-                                      "\"renew-timer\": 1000, "
-                                      "\"subnet6\": [  ], "
-                                      "\"valid-lifetime\": 4000 }")));
+                    parseJSON("{ " + genIfaceConfig() + ","
+                              "\"mac-sources\": [ ],"
+                              "\"preferred-lifetime\": 3000,"
+                              "\"rebind-timer\": 2000, "
+                              "\"renew-timer\": 1000, "
+                              "\"subnet6\": [  ], "
+                              "\"valid-lifetime\": 4000 }")));
 
     // returned value should be 0 (success)
     checkResult(status, 0);
@@ -4329,17 +4362,17 @@ TEST_F(Dhcp6ParserTest, macSourcesEmpty) {
 /// only use valid parameters.
 TEST_F(Dhcp6ParserTest, macSourcesBogus) {
 
-    ConstElementPtr status;
-
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-                    Element::fromJSON("{ " + genIfaceConfig() + ","
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6("{ " + genIfaceConfig() + ","
                                       "\"mac-sources\": [ \"from-wire\" ],"
                                       "\"preferred-lifetime\": 3000,"
                                       "\"rebind-timer\": 2000, "
                                       "\"renew-timer\": 1000, "
                                       "\"subnet6\": [  ], "
-                                      "\"valid-lifetime\": 4000 }")));
+                                      "\"valid-lifetime\": 4000 }"));
 
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     // returned value should be 1 (failure)
     checkResult(status, 1);
 }
@@ -4384,7 +4417,7 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
     ConstElementPtr status;
 
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-                    Element::fromJSON(HR_CONFIG)));
+                    parseJSON(HR_CONFIG)));
 
     // returned value should be 0 (success)
     checkResult(status, 0);
@@ -4424,16 +4457,18 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
 /// Relay Supplied options (specified as numbers).
 TEST_F(Dhcp6ParserTest, rsooNumbers) {
 
-    ConstElementPtr status;
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json =
+       parseDHCP6("{ " + genIfaceConfig() + ","
+                   "\"relay-supplied-options\": [ \"10\", \"20\", \"30\" ],"
+                   "\"preferred-lifetime\": 3000,"
+                   "\"rebind-timer\": 2000, "
+                   "\"renew-timer\": 1000, "
+                   "\"subnet6\": [  ], "
+                   "\"valid-lifetime\": 4000 }"));
 
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-        Element::fromJSON("{ " + genIfaceConfig() + ","
-                          "\"relay-supplied-options\": [ \"10\", \"20\", \"30\" ],"
-                          "\"preferred-lifetime\": 3000,"
-                          "\"rebind-timer\": 2000, "
-                          "\"renew-timer\": 1000, "
-                          "\"subnet6\": [  ], "
-                          "\"valid-lifetime\": 4000 }")));
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (success)
     checkResult(status, 0);
@@ -4457,16 +4492,18 @@ TEST_F(Dhcp6ParserTest, rsooNumbers) {
 /// Relay Supplied options (specified as names).
 TEST_F(Dhcp6ParserTest, rsooNames) {
 
-    ConstElementPtr status;
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json =
+       parseDHCP6("{ " + genIfaceConfig() + ","
+                   "\"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],"
+                   "\"preferred-lifetime\": 3000,"
+                   "\"rebind-timer\": 2000, "
+                   "\"renew-timer\": 1000, "
+                   "\"subnet6\": [  ], "
+                   "\"valid-lifetime\": 4000 }"));
 
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-        Element::fromJSON("{ " + genIfaceConfig() + ","
-                          "\"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],"
-                          "\"preferred-lifetime\": 3000,"
-                          "\"rebind-timer\": 2000, "
-                          "\"renew-timer\": 1000, "
-                          "\"subnet6\": [  ], "
-                          "\"valid-lifetime\": 4000 }")));
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (success)
     checkResult(status, 0);
@@ -4505,32 +4542,36 @@ TEST_F(Dhcp6ParserTest, rsooNames) {
 }
 
 TEST_F(Dhcp6ParserTest, rsooNegativeNumber) {
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-        Element::fromJSON("{ " + genIfaceConfig() + ","
-                          "\"relay-supplied-options\": [ \"80\", \"-2\" ],"
-                          "\"preferred-lifetime\": 3000,"
-                          "\"rebind-timer\": 2000, "
-                          "\"renew-timer\": 1000, "
-                          "\"subnet6\": [  ], "
-                          "\"valid-lifetime\": 4000 }")));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json =
+       parseDHCP6("{ " + genIfaceConfig() + ","
+                   "\"relay-supplied-options\": [ \"80\", \"-2\" ],"
+                   "\"preferred-lifetime\": 3000,"
+                   "\"rebind-timer\": 2000, "
+                   "\"renew-timer\": 1000, "
+                   "\"subnet6\": [  ], "
+                   "\"valid-lifetime\": 4000 }"));
 
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     // returned value should be 0 (success)
     checkResult(status, 1);
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 
 TEST_F(Dhcp6ParserTest, rsooBogusName) {
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
-        Element::fromJSON("{ " + genIfaceConfig() + ","
-                          "\"relay-supplied-options\": [ \"bogus\", \"dns-servers\" ],"
-                          "\"preferred-lifetime\": 3000,"
-                          "\"rebind-timer\": 2000, "
-                          "\"renew-timer\": 1000, "
-                          "\"subnet6\": [  ], "
-                          "\"valid-lifetime\": 4000 }")));
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json =
+       parseDHCP6("{ " + genIfaceConfig() + ","
+                   "\"relay-supplied-options\": [ \"bogus\", \"dns-servers\" ],"
+                   "\"preferred-lifetime\": 3000,"
+                   "\"rebind-timer\": 2000, "
+                   "\"renew-timer\": 1000, "
+                   "\"subnet6\": [  ], "
+                   "\"valid-lifetime\": 4000 }"));
 
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     // returned value should be 0 (success)
     checkResult(status, 1);
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
@@ -4539,13 +4580,13 @@ TEST_F(Dhcp6ParserTest, rsooBogusName) {
 /// Check that the decline-probation-period value can be set properly.
 TEST_F(Dhcp6ParserTest, declineTimerDefault) {
 
-    ConstElementPtr status;
-
     string config_txt = "{ " + genIfaceConfig() + ","
         "\"subnet6\": [  ] "
         "}";
-    ElementPtr config = Element::fromJSON(config_txt);
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseJSON(config_txt));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
 
     // returned value should be 0 (success)
@@ -4559,15 +4600,15 @@ TEST_F(Dhcp6ParserTest, declineTimerDefault) {
 
 /// Check that the decline-probation-period value can be set properly.
 TEST_F(Dhcp6ParserTest, declineTimer) {
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + "," +
         "\"decline-probation-period\": 12345,"
         "\"subnet6\": [ ]"
         "}";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 0 (success)
@@ -4581,15 +4622,15 @@ TEST_F(Dhcp6ParserTest, declineTimer) {
 
 /// Check that an incorrect decline-probation-period value will be caught.
 TEST_F(Dhcp6ParserTest, declineTimerError) {
-    ConstElementPtr status;
-
     string config = "{ " + genIfaceConfig() + "," +
         "\"decline-probation-period\": \"soon\","
         "\"subnet6\": [ ]"
         "}";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
 
     // returned value should be 1 (error)
@@ -4616,7 +4657,8 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) {
         "\"subnet6\": [ ]"
         "}";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4656,7 +4698,8 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessingError) {
         "\"subnet6\": [ ]"
         "}";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4692,9 +4735,10 @@ TEST_F(Dhcp6ParserTest, validClientClassDictionary) {
         "    \"subnet\": \"2001:db8:1::/64\" } ], \n"
         "\"valid-lifetime\": 4000 } \n";
 
-    ConstElementPtr status;
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -4733,9 +4777,10 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
         " } ] \n"
         "} \n";
 
-    ConstElementPtr status;
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 1);
index 9b6ba605be41257f97abced1ab2e23b4266ba231..ce007ba37d661805bff415e5aedb29e9d3983dbc 100644 (file)
@@ -145,7 +145,8 @@ public:
 
         ASSERT_NO_THROW(server_.reset(new NakedControlledDhcpv6Srv()));
 
-        ConstElementPtr config = Element::fromJSON(config_txt);
+        ConstElementPtr config;
+        ASSERT_NO_THROW(config = parseJSON(config_txt));
         ConstElementPtr answer = server_->processConfig(config);
         ASSERT_TRUE(answer);
 
@@ -321,7 +322,8 @@ TEST_F(CtrlDhcpv6SrvTest, configReload) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr config = Element::fromJSON(config_txt);
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseDHCP6(config_txt));
 
     // Make sure there are no subnets configured.
     CfgMgr::instance().clear();
index b1a08cb7e892aa6fbc074024e8554183802db77b..48bc40b3a446fb00c143088d73f9b9c3bf41712d 100644 (file)
@@ -75,7 +75,7 @@ const char* CONFIGS[] = {
     "        {"
     "          \"name\": \"subscriber-id\","
     "          \"data\": \"1234\","
-    "          \"csv-format\": False"
+    "          \"csv-format\": false"
     "        } ]"
     " } ],"
     "\"valid-lifetime\": 4000 }",
@@ -1682,7 +1682,7 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) {
         "          \"code\": ";
     string config_postfix = ","
         "          \"data\": \"normal_erouter_v6.cm\","
-        "          \"csv-format\": True"
+        "          \"csv-format\": true"
         "        }],"
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
@@ -1704,8 +1704,10 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) {
     // definition, the config should fail.
     string config_bogus = config_prefix + "99" + config_postfix;
 
-    ElementPtr json_bogus = Element::fromJSON(config_bogus);
-    ElementPtr json_valid = Element::fromJSON(config_valid);
+    ConstElementPtr json_bogus;
+    ASSERT_NO_THROW(json_bogus = parseJSON(config_bogus));
+    ConstElementPtr json_valid;
+    ASSERT_NO_THROW(json_valid = parseJSON(config_valid));
 
     NakedDhcpv6Srv srv(0);
 
index e7f06b7969e46eafd044b663cdbb7440ee449996..7ab67b7cdd37bd74ff4ab4ecbdf63d47ecaa205a 100644 (file)
@@ -693,7 +693,8 @@ Dhcpv6SrvTest::configure(const std::string& config) {
 
 void
 Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
-    ElementPtr json = data::Element::fromJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
     ConstElementPtr status;
 
     // Configure the server and make sure the config is accepted
index ca7fb3d6edd897e1c3764acfe9ed693147e067e0..d15de0879f9499a1ba649b6b094a6990f1682a67 100644 (file)
@@ -26,6 +26,7 @@
 #include <dhcpsrv/lease_mgr.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <dhcp6/dhcp6_srv.h>
+#include <dhcp6/parser_context.h>
 #include <hooks/hooks_manager.h>
 
 #include <list>
@@ -638,6 +639,42 @@ public:
     NakedDhcpv6Srv srv_;
 };
 
+// For parser testing (JSON map, no exception expected)
+inline isc::data::ConstElementPtr
+parseJSON(const std::string& in)
+{
+    isc::dhcp::Parser6Context ctx;
+    return (ctx.parseString(in, isc::dhcp::Parser6Context::PARSER_GENERIC_JSON));
+}
+
+// For parser testing (DHCP6)
+inline isc::data::ConstElementPtr
+parseDHCP6(const std::string& in)
+{
+    try {
+        isc::dhcp::Parser6Context ctx;
+        return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6));
+    }
+    catch (const std::exception& ex) {
+        std::cout << "EXCEPTION: " << ex.what() << std::endl;
+        throw;
+    }
+}
+
+// For parser testing (OPTION_DEF)
+inline isc::data::ConstElementPtr
+parseOPTION_DEF(const std::string& in)
+{
+    try {
+        isc::dhcp::Parser6Context ctx;
+        return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_OPTION_DEF));
+    }
+    catch (const std::exception& ex) {
+        std::cout << "EXCEPTION: " << ex.what() << std::endl;
+        throw;
+    }
+}
+
 }; // end of isc::dhcp::test namespace
 }; // end of isc::dhcp namespace
 }; // end of isc namespace
index 65539128608d160aa8acf2d4c4d5b9327b9f5b5f..d94a19dffa6ed63eb0c4824ddf1519ee64dade5f 100644 (file)
@@ -1197,7 +1197,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6Select) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    EXPECT_NO_THROW(json = parseDHCP6(config));
     ConstElementPtr status;
 
     // Configure the server and make sure the config is accepted
@@ -1273,7 +1274,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SselectChange) {
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
-    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr json;
+    EXPECT_NO_THROW(json = parseDHCP6(config));
     ConstElementPtr status;
 
     // Configure the server and make sure the config is accepted
index d053bd3b2a9f018483bd1f187c707c79c6bcdc05..0aea09fd55b38c138b0d777762b2fd897ee3a4c6 100644 (file)
@@ -85,17 +85,17 @@ const char* CONFIGS[] = {
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::10\" } ],"
         "    \"subnet\": \"2001:db8:1::/48\", "
         "    \"interface\": \"eth0\","
-        "    \"rapid-commit\": True"
+        "    \"rapid-commit\": true"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"2001:db8:2::1 - 2001:db8:2::10\" } ],"
         "    \"subnet\": \"2001:db8:2::/48\", "
         "    \"interface\": \"eth1\","
-        "    \"rapid-commit\": False"
+        "    \"rapid-commit\": false"
         " } ],"
         "\"valid-lifetime\": 4000,"
         " \"dhcp-ddns\" : {"
-        "     \"enable-updates\" : True, "
+        "     \"enable-updates\" : true, "
         "     \"qualifying-suffix\" : \"example.com\" }"
     "}",