Browse Source

[5207] Modify HostReservationParser to return parsed host.

Marcin Siodelski 8 years ago
parent
commit
dddfd55344

+ 5 - 1
src/bin/dhcp4/json_config_parser.cc

@@ -150,8 +150,12 @@ public:
         // Parse Host Reservations for this subnet if any.
         ConstElementPtr reservations = subnet->get("reservations");
         if (reservations) {
+            HostCollection hosts;
             HostReservationsListParser<HostReservationParser4> parser;
-            parser.parse(subnet_->getID(), reservations);
+            parser.parse(subnet_->getID(), reservations, hosts);
+            for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+                CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+            }
         }
 
         return (sn4ptr);

+ 5 - 1
src/bin/dhcp6/json_config_parser.cc

@@ -309,8 +309,12 @@ public:
         // Parse Host Reservations for this subnet if any.
         ConstElementPtr reservations = subnet->get("reservations");
         if (reservations) {
+            HostCollection hosts;
             HostReservationsListParser<HostReservationParser6> parser;
-            parser.parse(subnet_->getID(), reservations);
+            parser.parse(subnet_->getID(), reservations, hosts);
+            for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+                CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+            }
         }
 
         return (sn6ptr);

+ 23 - 33
src/lib/dhcpsrv/parsers/host_reservation_parser.cc

@@ -96,18 +96,19 @@ getSupportedParams6(const bool identifiers_only = false) {
 namespace isc {
 namespace dhcp {
 
-void
+HostPtr
 HostReservationParser::parse(const SubnetID& subnet_id,
                              isc::data::ConstElementPtr reservation_data) {
-    parseInternal(subnet_id, reservation_data);
+    return (parseInternal(subnet_id, reservation_data));
 }
 
-void
+HostPtr
 HostReservationParser::parseInternal(const SubnetID&,
                                      isc::data::ConstElementPtr reservation_data) {
     std::string identifier;
     std::string identifier_name;
     std::string hostname;
+    HostPtr host;
 
     try {
         // Gather those parameters that are common for both IPv4 and IPv6
@@ -153,7 +154,7 @@ HostReservationParser::parseInternal(const SubnetID&,
         }
 
         // Create a host object from the basic parameters we already parsed.
-        host_.reset(new Host(identifier, identifier_name, SubnetID(0),
+        host.reset(new Host(identifier, identifier_name, SubnetID(0),
                              SubnetID(0), IOAddress("0.0.0.0"), hostname));
 
     } catch (const std::exception& ex) {
@@ -161,18 +162,8 @@ HostReservationParser::parseInternal(const SubnetID&,
         isc_throw(DhcpConfigError, ex.what() << " ("
                   << reservation_data->getPosition() << ")");
     }
-}
-
-void
-HostReservationParser::addHost(isc::data::ConstElementPtr reservation_data) {
-    try {
-        CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host_);
 
-    } catch (const std::exception& ex) {
-        // Append line number to the exception string.
-        isc_throw(DhcpConfigError, ex.what() << " ("
-                  << reservation_data->getPosition() << ")");
-    }
+    return (host);
 }
 
 bool
@@ -185,19 +176,19 @@ HostReservationParser::isSupportedParameter(const std::string& param_name) const
     return (getSupportedParameters(false).count(param_name) > 0);
 }
 
-void
+HostPtr
 HostReservationParser4::parseInternal(const SubnetID& subnet_id,
                                       isc::data::ConstElementPtr reservation_data) {
-    HostReservationParser::parseInternal(subnet_id, reservation_data);
+    HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
 
-    host_->setIPv4SubnetID(subnet_id);
+    host->setIPv4SubnetID(subnet_id);
 
     BOOST_FOREACH(ConfigPair element, reservation_data->mapValue()) {
         // For 'option-data' element we will use another parser which
         // already returns errors with position appended, so don't
         // surround it with try-catch.
         if (element.first == "option-data") {
-            CfgOptionPtr cfg_option = host_->getCfgOption4();
+            CfgOptionPtr cfg_option = host->getCfgOption4();
 
             // This parser is converted to SimpleParser already. It
             // parses the Element structure immediately, there's no need
@@ -210,21 +201,21 @@ HostReservationParser4::parseInternal(const SubnetID& subnet_id,
         } else {
             try {
                 if (element.first == "ip-address") {
-                    host_->setIPv4Reservation(IOAddress(element.second->
+                    host->setIPv4Reservation(IOAddress(element.second->
                                                         stringValue()));
                 } else if (element.first == "next-server") {
-                    host_->setNextServer(IOAddress(element.second->stringValue()));
+                    host->setNextServer(IOAddress(element.second->stringValue()));
 
                 } else if (element.first == "server-hostname") {
-                    host_->setServerHostname(element.second->stringValue());
+                    host->setServerHostname(element.second->stringValue());
 
                 } else if (element.first == "boot-file-name") {
-                    host_->setBootFileName(element.second->stringValue());
+                    host->setBootFileName(element.second->stringValue());
 
                 } else if (element.first == "client-classes") {
                     BOOST_FOREACH(ConstElementPtr class_element,
                                   element.second->listValue()) {
-                        host_->addClientClass4(class_element->stringValue());
+                        host->addClientClass4(class_element->stringValue());
                     }
                 }
 
@@ -236,7 +227,7 @@ HostReservationParser4::parseInternal(const SubnetID& subnet_id,
         }
     }
 
-    addHost(reservation_data);
+    return (host);
 }
 
 const std::set<std::string>&
@@ -244,12 +235,12 @@ HostReservationParser4::getSupportedParameters(const bool identifiers_only) cons
     return (getSupportedParams4(identifiers_only));
 }
 
-void
+HostPtr
 HostReservationParser6::parseInternal(const SubnetID& subnet_id,
                                       isc::data::ConstElementPtr reservation_data) {
-    HostReservationParser::parseInternal(subnet_id, reservation_data);
+    HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
 
-    host_->setIPv6SubnetID(subnet_id);
+    host->setIPv6SubnetID(subnet_id);
 
     BOOST_FOREACH(ConfigPair element, reservation_data->mapValue()) {
         // Parse option values. Note that the configuration option parser
@@ -257,7 +248,7 @@ HostReservationParser6::parseInternal(const SubnetID& subnet_id,
         // need to surround it with try-clause (and rethrow with position
         // appended).
         if (element.first == "option-data") {
-            CfgOptionPtr cfg_option = host_->getCfgOption6();
+            CfgOptionPtr cfg_option = host->getCfgOption6();
 
             // This parser is converted to SimpleParser already. It
             // parses the Element structure immediately, there's no need
@@ -318,7 +309,7 @@ HostReservationParser6::parseInternal(const SubnetID& subnet_id,
                     }
 
                     // Create a reservation for an address or prefix.
-                    host_->addReservation(IPv6Resrv(resrv_type,
+                    host->addReservation(IPv6Resrv(resrv_type,
                                                     IOAddress(prefix),
                                                     prefix_len));
 
@@ -334,7 +325,7 @@ HostReservationParser6::parseInternal(const SubnetID& subnet_id,
             try {
                 BOOST_FOREACH(ConstElementPtr class_element,
                               element.second->listValue()) {
-                    host_->addClientClass6(class_element->stringValue());
+                    host->addClientClass6(class_element->stringValue());
                 }
             } catch (const std::exception& ex) {
                 // Append line number where the error occurred.
@@ -344,8 +335,7 @@ HostReservationParser6::parseInternal(const SubnetID& subnet_id,
         }
     }
 
-    // This may fail, but the addHost function will handle this on its own.
-    addHost(reservation_data);
+    return (host);
 }
 
 const std::set<std::string>&

+ 13 - 24
src/lib/dhcpsrv/parsers/host_reservation_parser.h

@@ -28,9 +28,11 @@ public:
     /// @param reservation_data Data element holding map with a host
     /// reservation configuration.
     ///
+    /// @return Pointer to the object representing parsed host.
     /// @throw DhcpConfigError If the configuration is invalid.
-    void parse(const SubnetID& subnet_id,
-               isc::data::ConstElementPtr reservation_data);
+    virtual HostPtr
+    parse(const SubnetID& subnet_id,
+          isc::data::ConstElementPtr reservation_data) final;
 
 protected:
 
@@ -44,20 +46,10 @@ protected:
     /// @param reservation_data Data element holding map with a host
     /// reservation configuration.
     ///
+    /// @return Pointer to the object representing parsed host.
     /// @throw DhcpConfigError If the configuration is invalid.
-    virtual void parseInternal(const SubnetID& subnet_id,
-                               isc::data::ConstElementPtr reservation_data);
-
-    /// @brief Inserts @c host_ object to the staging configuration.
-    ///
-    /// This method should be called by derived classes to insert the fully
-    /// parsed host reservation configuration to the @c CfgMgr.
-    ///
-    /// @param reservation_data Data element holding host reservation. It
-    /// used by this method to append the line number to the error string.
-    ///
-    /// @throw DhcpConfigError When operation to add a configured host fails.
-    void addHost(isc::data::ConstElementPtr reservation_data);
+    virtual HostPtr parseInternal(const SubnetID& subnet_id,
+                                  isc::data::ConstElementPtr reservation_data);
 
     /// @brief Checks if the specified parameter is a host identifier.
     ///
@@ -83,11 +75,6 @@ protected:
     /// @return Set of supported parameter names.
     virtual const std::set<std::string>&
     getSupportedParameters(const bool identifiers_only) const = 0;
-
-    /// @brief Holds a pointer to @c Host object representing a parsed
-    /// host reservation configuration.
-    HostPtr host_;
-
 };
 
 /// @brief Parser for a single host reservation for DHCPv4.
@@ -101,9 +88,10 @@ protected:
     /// @param reservation_data Data element holding map with a host
     /// reservation configuration.
     ///
+    /// @return Pointer to the object representing parsed host.
     /// @throw DhcpConfigError If the configuration is invalid.
-    virtual void parseInternal(const SubnetID& subnet_id,
-                               isc::data::ConstElementPtr reservation_data);
+    virtual HostPtr parseInternal(const SubnetID& subnet_id,
+                                  isc::data::ConstElementPtr reservation_data);
 
     /// @brief Returns set of the supported parameters for DHCPv4.
     ///
@@ -127,9 +115,10 @@ protected:
     /// @param reservation_data Data element holding map with a host
     /// reservation configuration.
     ///
+    /// @return Pointer to the object representing parsed host.
     /// @throw DhcpConfigError If the configuration is invalid.
-    virtual void parseInternal(const SubnetID& subnet_id,
-                               isc::data::ConstElementPtr reservation_data);
+    virtual HostPtr parseInternal(const SubnetID& subnet_id,
+                                  isc::data::ConstElementPtr reservation_data);
 
     /// @brief Returns set of the supported parameters for DHCPv6.
     ///

+ 8 - 2
src/lib/dhcpsrv/parsers/host_reservations_list_parser.h

@@ -9,6 +9,7 @@
 
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <dhcpsrv/host.h>
 #include <dhcpsrv/subnet_id.h>
 #include <boost/foreach.hpp>
 
@@ -30,14 +31,19 @@ public:
     /// belong.
     /// @param hr_list Data element holding a list of host reservations.
     /// Each host reservation is described by a map object.
+    /// @param [out] hosts_list Hosts representing parsed reservations are stored
+    /// in this list.
     ///
     /// @throw DhcpConfigError If the configuration if any of the reservations
     /// is invalid.
-    void parse(const SubnetID& subnet_id, isc::data::ConstElementPtr hr_list) {
+    void parse(const SubnetID& subnet_id, isc::data::ConstElementPtr hr_list,
+               HostCollection& hosts_list) {
+        HostCollection hosts;
         BOOST_FOREACH(data::ConstElementPtr reservation, hr_list->listValue()) {
             HostReservationParserType parser;
-            parser.parse(subnet_id, reservation);
+            hosts.push_back(parser.parse(subnet_id, reservation));
         }
+        hosts_list.swap(hosts);
     }
 };
 

+ 66 - 32
src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc

@@ -120,18 +120,15 @@ protected:
 
         ElementPtr config_element = Element::fromJSON(config);
 
+        HostPtr host;
         ParserType parser;
-        ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+        ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
 
-        // Retrieve a host.
-        HostCollection hosts;
-        CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
-        ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
-        ASSERT_EQ(1, hosts.size());
+        ASSERT_TRUE(host);
 
         // There should be no options assigned to a host.
-        EXPECT_TRUE(hosts[0]->getCfgOption4()->empty());
-        EXPECT_TRUE(hosts[0]->getCfgOption6()->empty());
+        EXPECT_TRUE(host->getCfgOption4()->empty());
+        EXPECT_TRUE(host->getCfgOption6()->empty());
     }
 
     /// @brief This test verifies that the parser can parse a DHCPv4
@@ -151,21 +148,15 @@ protected:
 
         ElementPtr config_element = Element::fromJSON(config.str());
 
+        HostPtr host;
         HostReservationParser4 parser;
-        ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+        ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+        ASSERT_TRUE(host);
 
-        CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
-        HostCollection hosts;
-        ASSERT_NO_THROW(hosts = cfg_hosts->getAll(expected_identifier_type,
-                                                  &expected_identifier[0],
-                                                  expected_identifier.size()));
-
-        ASSERT_EQ(1, hosts.size());
-
-        EXPECT_EQ(10, hosts[0]->getIPv4SubnetID());
-        EXPECT_EQ(0, hosts[0]->getIPv6SubnetID());
-        EXPECT_EQ("192.0.2.112", hosts[0]->getIPv4Reservation().toText());
-        EXPECT_TRUE(hosts[0]->getHostname().empty());
+        EXPECT_EQ(10, host->getIPv4SubnetID());
+        EXPECT_EQ(0, host->getIPv6SubnetID());
+        EXPECT_EQ("192.0.2.112", host->getIPv4Reservation().toText());
+        EXPECT_TRUE(host->getHostname().empty());
     }
 
     /// @brief This test verifies that the parser returns an error when
@@ -176,8 +167,12 @@ protected:
     template<typename ParserType>
     void testInvalidConfig(const std::string& config) const {
         ElementPtr config_element = Element::fromJSON(config);
+        HostPtr host;
         ParserType parser;
-        EXPECT_THROW(parser.parse(SubnetID(10), config_element), DhcpConfigError);
+        EXPECT_THROW({
+            host = parser.parse(SubnetID(10), config_element);
+            CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
+        }, isc::Exception);
     }
 
     /// @brief HW Address object used by tests.
@@ -361,10 +356,13 @@ TEST_F(HostReservationParserTest, dhcp4NoHostname) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser4 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
 
@@ -397,10 +395,14 @@ TEST_F(HostReservationParserTest, dhcp4ClientClasses) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser4 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
 
@@ -435,10 +437,14 @@ TEST_F(HostReservationParserTest, dhcp4MessageFields) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser4 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_HWADDR,
                                               &hwaddr_->hwaddr_[0],
@@ -540,10 +546,14 @@ TEST_F(HostReservationParserTest, noIPAddress) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser4 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
 
@@ -649,10 +659,14 @@ TEST_F(HostReservationParserTest, dhcp6HWaddr) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser6 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_, DuidPtr()));
 
@@ -714,10 +728,14 @@ TEST_F(HostReservationParserTest, dhcp6DUID) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser6 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(12), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(12), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
 
@@ -790,10 +808,14 @@ TEST_F(HostReservationParserTest, dhcp6NoHostname) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser6 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(12), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(12), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
 
@@ -843,10 +865,14 @@ TEST_F(HostReservationParserTest, dhcp6ClientClasses) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser6 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_DUID,
                                               &duid_->getDuid()[0],
@@ -968,10 +994,14 @@ TEST_F(HostReservationParserTest, options4) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser4 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
     ASSERT_EQ(1, hosts.size());
@@ -1051,11 +1081,15 @@ TEST_F(HostReservationParserTest, options6) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostPtr host;
     HostReservationParser6 parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+    ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+    ASSERT_TRUE(host);
 
     // One host should have been added to the configuration.
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    ASSERT_NO_THROW(cfg_hosts->add(host));
+
     HostCollection hosts;
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
     ASSERT_EQ(1, hosts.size());

+ 26 - 6
src/lib/dhcpsrv/tests/host_reservations_list_parser_unittest.cc

@@ -163,11 +163,15 @@ TEST_F(HostReservationsListParserTest, ipv4Reservations) {
 
     ElementPtr config_element = Element::fromJSON(config);
 
+    HostCollection hosts;
     HostReservationsListParser<HostReservationParser4> parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(1), config_element));
+    ASSERT_NO_THROW(parser.parse(SubnetID(1), config_element, hosts));
+
+    for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+        CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+    }
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
-    HostCollection hosts;
 
     // Get the first reservation for the host identified by the HW address.
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
@@ -229,8 +233,14 @@ TEST_F(HostReservationsListParserTest, duplicatedIdentifierValue4) {
 
         ElementPtr config_element = Element::fromJSON(config.str());
 
+        HostCollection hosts;
         HostReservationsListParser<HostReservationParser4> parser;
-        EXPECT_THROW(parser.parse(SubnetID(1), config_element), DhcpConfigError);
+        EXPECT_THROW({
+            parser.parse(SubnetID(1), config_element, hosts);
+            for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+                CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+            }
+        }, isc::Exception);
     }
 }
 
@@ -254,11 +264,15 @@ TEST_F(HostReservationsListParserTest, ipv6Reservations) {
     ElementPtr config_element = Element::fromJSON(config);
 
     // Parse configuration.
+    HostCollection hosts;
     HostReservationsListParser<HostReservationParser6> parser;
-    ASSERT_NO_THROW(parser.parse(SubnetID(2), config_element));
+    ASSERT_NO_THROW(parser.parse(SubnetID(2), config_element, hosts));
+
+    for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+        CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+    }
 
     CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
-    HostCollection hosts;
 
     // Get the reservation for the host identified by the HW address.
     ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
@@ -338,8 +352,14 @@ TEST_F(HostReservationsListParserTest, duplicatedIdentifierValue6) {
 
         ElementPtr config_element = Element::fromJSON(config.str());
 
+        HostCollection hosts;
         HostReservationsListParser<HostReservationParser6> parser;
-        EXPECT_THROW(parser.parse(SubnetID(1), config_element), DhcpConfigError);
+        EXPECT_THROW({
+            parser.parse(SubnetID(1), config_element, hosts);
+            for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+                CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+            }
+        }, isc::Exception);
     }
 }