Browse Source

[3360] Memfile now opens v4 or v6 lease file, not both.

Marcin Siodelski 11 years ago
parent
commit
5785c87a15

+ 1 - 1
src/bin/dhcp4/config_parser.cc

@@ -407,7 +407,7 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
         parser  = new StringParser(config_id,
                                     globalContext()->string_values_);
     } else if (config_id.compare("lease-database") == 0) {
-        parser = new DbAccessParser(config_id);
+        parser = new DbAccessParser(config_id, *globalContext());
     } else if (config_id.compare("hooks-libraries") == 0) {
         parser = new HooksLibrariesParser(config_id);
     } else if (config_id.compare("echo-client-id") == 0) {

+ 12 - 0
src/bin/dhcp4/dhcp4.spec

@@ -191,6 +191,18 @@
                 "item_type": "string",
                 "item_optional": true,
                 "item_default": ""
+            },
+            {
+                "item_name": "persist",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": true
+            },
+            {
+                "item_name": "leasefile",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": ""
             }
         ]
       },

+ 2 - 2
src/bin/dhcp6/config_parser.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -637,7 +637,7 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
         parser  = new StringParser(config_id,
                                    globalContext()->string_values_);
     } else if (config_id.compare("lease-database") == 0) {
-        parser = new DbAccessParser(config_id);
+        parser = new DbAccessParser(config_id, *globalContext());
     } else if (config_id.compare("hooks-libraries") == 0) {
         parser = new HooksLibrariesParser(config_id);
     } else if (config_id.compare("dhcp-ddns") == 0) {

+ 12 - 0
src/bin/dhcp6/dhcp6.spec

@@ -185,6 +185,18 @@
                 "item_type": "string",
                 "item_optional": true,
                 "item_default": ""
+            },
+            {
+                "item_name": "persist",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": true
+            },
+            {
+                "item_name": "leasefile",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": ""
             }
         ]
       },

+ 17 - 11
src/lib/dhcpsrv/dbaccess_parser.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -12,6 +12,7 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <dhcp/option.h>
 #include <dhcpsrv/dbaccess_parser.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/lease_mgr_factory.h>
@@ -30,11 +31,10 @@ namespace dhcp {
 
 
 // Factory function to build the parser
-DbAccessParser::DbAccessParser(const std::string& param_name) : values_()
+DbAccessParser::DbAccessParser(const std::string&, const ParserContext& ctx)
+    : values_(), ctx_(ctx)
 {
-    if (param_name != "lease-database") {
-        LOG_WARN(dhcpsrv_logger, DHCPSRV_UNEXPECTED_NAME).arg(param_name);
-    }
+    ctx_ = ctx;
 }
 
 // Parse the configuration and check that the various keywords are consistent.
@@ -43,19 +43,25 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
 
     // To cope with incremental updates, the strategy is:
     // 1. Take a copy of the stored keyword/value pairs.
-    // 2. Update the copy with the passed keywords.
-    // 3. Perform validation checks on the updated keyword/value pairs.
-    // 4. If all is OK, update the stored keyword/value pairs.
+    // 2. Inject the universe parameter.
+    // 3. Update the copy with the passed keywords.
+    // 4. Perform validation checks on the updated keyword/value pairs.
+    // 5. If all is OK, update the stored keyword/value pairs.
 
     // 1. Take a copy of the stored keyword/value pairs.
     std::map<string, string> values_copy = values_;
 
-    // 2. Update the copy with the passed keywords.
+    // 2. Inject the parameter which defines whether we are configuring
+    // DHCPv4 or DHCPv6. Some database backends (e.g. Memfile make
+    // use of it).
+    values_copy["universe"] = ctx_.universe_ == Option::V4 ? "4" : "6";
+
+    // 3. Update the copy with the passed keywords.
     BOOST_FOREACH(ConfigPair param, config_value->mapValue()) {
         values_copy[param.first] = param.second->stringValue();
     }
 
-    // 3. Perform validation checks on the updated set of keyword/values.
+    // 4. Perform validation checks on the updated set of keyword/values.
     //
     // a. Check if the "type" keyword exists and thrown an exception if not.
     StringPairMap::const_iterator type_ptr = values_copy.find("type");
@@ -71,7 +77,7 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
         isc_throw(BadValue, "unknown backend database type: " << dbtype);
     }
 
-    // 4. If all is OK, update the stored keyword/value pairs.  We do this by
+    // 5. If all is OK, update the stored keyword/value pairs.  We do this by
     // swapping contents - values_copy is destroyed immediately after the
     // operation (when the method exits), so we are not interested in its new
     // value.

+ 11 - 4
src/lib/dhcpsrv/dbaccess_parser.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,7 @@
 
 #include <cc/data.h>
 #include <dhcpsrv/dhcp_config_parser.h>
+#include <dhcpsrv/dhcp_parsers.h>
 #include <exceptions/exceptions.h>
 
 #include <string>
@@ -54,7 +55,8 @@ public:
     ///
     /// @param param_name Name of the parameter under which the database
     ///        access details are held.
-    DbAccessParser(const std::string& param_name);
+    /// @param ctx Parser context.
+    DbAccessParser(const std::string& param_name, const ParserContext& ctx);
 
     /// The destructor.
     virtual ~DbAccessParser()
@@ -96,11 +98,13 @@ public:
     ///
     /// @param param_name Name of the parameter used to access the
     /// 	configuration.
+    /// @param ctx Parser context.
     ///
     /// @return Pointer to a DbAccessParser.  The caller is responsible for
     ///         destroying the parser after use.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new DbAccessParser(param_name));
+    static DhcpConfigParser* factory(const std::string& param_name,
+                                     const ParserContext& ctx) {
+        return (new DbAccessParser(param_name, ctx));
     }
 
 protected:
@@ -124,7 +128,10 @@ protected:
     std::string getDbAccessString() const;
 
 private:
+
     std::map<std::string, std::string> values_; ///< Stored parameter values
+
+    ParserContext ctx_; ///< Parser context
 };
 
 };  // namespace dhcp

+ 24 - 22
src/lib/dhcpsrv/memfile_lease_mgr.cc

@@ -23,18 +23,22 @@ using namespace isc::dhcp;
 
 Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
     : LeaseMgr(parameters) {
-    // Get the lease files locations and open for IO.
-    std::string file4 = initLeaseFilePath(V4);
-    if (!file4.empty()) {
-        lease_file4_.reset(new CSVLeaseFile4(file4));
-        lease_file4_->open();
-        load4();
-    }
-    std::string file6 = initLeaseFilePath(V6);
-    if (!file6.empty()) {
-        lease_file6_.reset(new CSVLeaseFile6(file6));
-        lease_file6_->open();
-        load6();
+    // Check the universe and use v4 file or v6 file.
+    std::string universe = getParameter("universe");
+    if (universe == "4") {
+        std::string file4 = initLeaseFilePath(V4);
+        if (!file4.empty()) {
+            lease_file4_.reset(new CSVLeaseFile4(file4));
+            lease_file4_->open();
+            load4();
+        }
+    } else {
+        std::string file6 = initLeaseFilePath(V6);
+        if (!file6.empty()) {
+            lease_file6_.reset(new CSVLeaseFile6(file6));
+            lease_file6_->open();
+            load6();
+        }
     }
 
     // If lease persistence have been disabled for both v4 and v6,
@@ -424,28 +428,26 @@ Memfile_LeaseMgr::persistLeases(Universe u) const {
 std::string
 Memfile_LeaseMgr::initLeaseFilePath(Universe u) {
     std::string persist_val;
-    std::string persist_str = (u == V4 ? "persist4" : "persist6");
     try {
-        persist_val = getParameter(persist_str);
+        persist_val = getParameter("persist");
     } catch (const Exception& ex) {
         // If parameter persist hasn't been specified, we use a default value
         // 'yes'.
-        persist_val = "yes";
+        persist_val = "true";
     }
-    // If persist_val is 'no' we will not store leases to disk, so let's
+    // If persist_val is 'false' we will not store leases to disk, so let's
     // return empty file name.
-    if (persist_val == "no") {
+    if (persist_val == "false") {
         return ("");
 
-    } else if (persist_val != "yes") {
-        isc_throw(isc::BadValue, "invalid value '" << persist_str
-                  << "=" << persist_val << "'");
+    } else if (persist_val != "true") {
+        isc_throw(isc::BadValue, "invalid value 'persist="
+                  << persist_val << "'");
     }
 
-    std::string param_name = (u == V4 ? "leasefile4" : "leasefile6");
     std::string lease_file;
     try {
-        lease_file = getParameter(param_name);
+        lease_file = getParameter("leasefile");
     } catch (const Exception& ex) {
         lease_file = getDefaultLeaseFilePath(u);
     }

+ 2 - 2
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc

@@ -101,7 +101,7 @@ public:
 
         initFqdn("", false, false);
 
-        factory_.create("type=memfile persist4=no persist6=no");
+        factory_.create("type=memfile universe=6 persist=false");
     }
 
     /// @brief Configures a subnet and adds one pool to it.
@@ -424,7 +424,7 @@ public:
         subnet_->addPool(pool_);
         cfg_mgr.addSubnet4(subnet_);
 
-        factory_.create("type=memfile persist4=no persist6=no");
+        factory_.create("type=memfile universe=4 persist=false");
     }
 
     /// @brief checks if Lease4 matches expected configuration

+ 60 - 18
src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc

@@ -15,6 +15,7 @@
 #include <config.h>
 
 #include <dhcpsrv/dbaccess_parser.h>
+#include <dhcpsrv/dhcp_parsers.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <config/ccsession.h>
 #include <gtest/gtest.h>
@@ -114,14 +115,18 @@ public:
     /// @param dbaccess set of database access parameters to check
     /// @param keyval Array of "const char*" strings in the order keyword,
     ///        value, keyword, value ...  A NULL entry terminates the list.
+    /// @param u Universe (V4 or V6).
     void checkAccessString(const char* trace_string,
                            const DbAccessParser::StringPairMap& parameters,
-                           const char* keyval[]) {
+                           const char* keyval[],
+                           Option::Universe u = Option::V4) {
         SCOPED_TRACE(trace_string);
 
         // Construct a map of keyword value pairs.
         std::map<string, string> expected;
-        size_t expected_count = 0;
+        expected["universe"] = (u == Option::V4 ? "4" : "6");
+        // The universe is always injected by the parser itself.
+        size_t expected_count = 1;
         for (size_t i = 0; keyval[i] != NULL; i += 2) {
             // Get the value.  This should not be NULL
             ASSERT_NE(static_cast<const char*>(NULL), keyval[i + 1]) <<
@@ -134,7 +139,7 @@ public:
         }
 
         // Check no duplicates in the test set of reference keywords.
-        ASSERT_EQ(expected_count, expected.size()) << 
+        ASSERT_EQ(expected_count, expected.size()) <<
             "Supplied reference keyword/value list contains duplicate keywords";
 
         // The passed parameter map should have the same number of entries as
@@ -169,8 +174,8 @@ public:
     /// @brief Constructor
     ///
     /// @brief Keyword/value collection of ddatabase access parameters
-    TestDbAccessParser(const std::string& param_name)
-        : DbAccessParser(param_name)
+    TestDbAccessParser(const std::string& param_name, const ParserContext& ctx)
+        : DbAccessParser(param_name, ctx)
     {}
 
     /// @brief Destructor
@@ -211,7 +216,7 @@ TEST_F(DbAccessParserTest, validTypeMemfile) {
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_NO_THROW(parser.build(json_elements));
     checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
 }
@@ -227,11 +232,49 @@ TEST_F(DbAccessParserTest, emptyKeyword) {
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_NO_THROW(parser.build(json_elements));
     checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
 }
 
+// Check that the parser works with more complex configuration when
+// lease file path is specified for DHCPv4.
+TEST_F(DbAccessParserTest, persistV4Memfile) {
+    const char* config[] = {"type", "memfile",
+                            "persist", "true",
+                            "leasefile", "/opt/bind10/var/kea-leases4.csv",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
+    EXPECT_NO_THROW(parser.build(json_elements));
+
+    checkAccessString("Valid memfile", parser.getDbAccessParameters(),
+                      config);
+}
+
+// Check that the parser works with more complex configuration when
+// lease file path is specified for DHCPv6.
+TEST_F(DbAccessParserTest, persistV6Memfile) {
+    const char* config[] = {"type", "memfile",
+                            "persist", "true",
+                            "leasefile", "/opt/bind10/var/kea-leases6.csv",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+    EXPECT_NO_THROW(parser.build(json_elements));
+
+    checkAccessString("Valid memfile", parser.getDbAccessParameters(),
+                      config, Option::V6);
+}
+
 // Check that the parser works with a valid MySQL configuration
 TEST_F(DbAccessParserTest, validTypeMysql) {
     const char* config[] = {"type",     "mysql",
@@ -245,7 +288,7 @@ TEST_F(DbAccessParserTest, validTypeMysql) {
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_NO_THROW(parser.build(json_elements));
     checkAccessString("Valid mysql", parser.getDbAccessParameters(), config);
 }
@@ -262,7 +305,7 @@ TEST_F(DbAccessParserTest, missingTypeKeyword) {
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_THROW(parser.build(json_elements), TypeKeywordMissing);
 }
 
@@ -271,7 +314,8 @@ TEST_F(DbAccessParserTest, factory) {
 
     // Check that the parser is built through the factory.
     boost::scoped_ptr<DhcpConfigParser> parser(
-        DbAccessParser::factory("lease-database"));
+        DbAccessParser::factory("lease-database", ParserContext(Option::V4))
+    );
     EXPECT_TRUE(parser);
     DbAccessParser* dbap = dynamic_cast<DbAccessParser*>(parser.get());
     EXPECT_NE(static_cast<DbAccessParser*>(NULL), dbap);
@@ -321,7 +365,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
                              "name",     "keatest",
                              NULL};
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
 
     // First configuration string should cause a representation of that string
     // to be held.
@@ -385,7 +429,7 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_NO_THROW(parser.build(json_elements));
 
     // Get the database access string
@@ -394,8 +438,7 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
     // String should be either "type=mysql name=keatest" or
     // "name=keatest type=mysql". The "host" entry is null, so should not be
     // output.
-    EXPECT_TRUE((dbaccess == "type=mysql name=keatest") ||
-                (dbaccess == "name=keatest type=mysql"));
+    EXPECT_EQ(dbaccess, "name=keatest type=mysql universe=4");
 }
 
 // Check that the "commit" function actually opens the database.  We will
@@ -410,18 +453,17 @@ TEST_F(DbAccessParserTest, commit) {
             }, isc::dhcp::NoLeaseManager);
 
     // Set up the parser to open the memfile database.
-    const char* config[] = {"type", "memfile", "persist4", "no",
-                            "persist6", "no", NULL};
+    const char* config[] = {"type", "memfile", "persist", "false", NULL};
     string json_config = toJson(config);
 
     ConstElementPtr json_elements = Element::fromJSON(json_config);
     EXPECT_TRUE(json_elements);
 
-    TestDbAccessParser parser("lease-database");
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
     EXPECT_NO_THROW(parser.build(json_elements));
 
     // Ensure that the access string is as expected.
-    EXPECT_EQ(std::string("persist4=no persist6=no type=memfile"),
+    EXPECT_EQ("persist=false type=memfile universe=4",
               parser.getDbAccessString());
 
     // Committal of the parser changes should open the database.

+ 3 - 3
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc

@@ -766,7 +766,7 @@ GenericLeaseMgrTest::testBasicLease6() {
     lmptr_->commit();
 
     // Reopen the database to ensure that they actually got stored.
-    reopen();
+    reopen(V6);
 
     Lease6Ptr l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
@@ -795,7 +795,7 @@ GenericLeaseMgrTest::testBasicLease6() {
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[2], l_returned);
 
-    reopen();
+    reopen(V6);
 
     // The deleted lease should be still gone after we re-read leases from
     // persistent storage.
@@ -814,7 +814,7 @@ GenericLeaseMgrTest::testBasicLease6() {
 
     ASSERT_NO_THROW(lmptr_->updateLease6(leases[2]));
 
-    reopen();
+    reopen(V6);
 
     // The lease should be now updated in the storage.
     l_returned = lmptr_->getLease6(leasetype6_[2], ioaddress6_[2]);

+ 9 - 1
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h

@@ -30,6 +30,12 @@ namespace test {
 class GenericLeaseMgrTest : public ::testing::Test {
 public:
 
+    /// @brief Universe (V4 or V6).
+    enum Universe {
+        V4,
+        V6
+    };
+
     /// @brief Default constructor.
     GenericLeaseMgrTest();
 
@@ -40,7 +46,9 @@ public:
     ///
     /// Closes the database and re-opens it. It must be implemented
     /// in derived classes.
-    virtual void reopen() = 0;
+    ///
+    /// @param u Universe (V4 or V6), required by some backends.
+    virtual void reopen(Universe u = V4) = 0;
 
     /// @brief Initialize Lease4 Fields
     ///

+ 1 - 1
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc

@@ -253,7 +253,7 @@ public:
     ///
     /// No-op implementation. We need to provide concrete implementation,
     /// as this is a pure virtual method in GenericLeaseMgrTest.
-    virtual void reopen() {
+    virtual void reopen(Universe) {
     }
 
 };

+ 71 - 43
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

@@ -50,21 +50,18 @@ public:
         // Make sure there are no dangling files after previous tests.
         io4_.removeFile();
         io6_.removeFile();
-
-        try {
-            LeaseMgrFactory::create(getConfigString());
-        } catch (...) {
-            std::cerr << "*** ERROR: unable to create instance of the Memfile\n"
-                " lease database backend.\n";
-            throw;
-        }
-        lmptr_ = &(LeaseMgrFactory::instance());
     }
 
-    virtual void reopen() {
+    /// @brief Reopens the connection to the backend.
+    ///
+    /// This function is called by unit tests to force reconnection of the
+    /// backend to check that the leases are stored and can be retrieved
+    /// from the storage.
+    ///
+    /// @param u Universe (V4 or V6)
+    virtual void reopen(Universe u) {
         LeaseMgrFactory::destroy();
-        LeaseMgrFactory::create(getConfigString());
-        lmptr_ = &(LeaseMgrFactory::instance());
+        startBackend(u);
     }
 
     /// @brief destructor
@@ -92,14 +89,32 @@ public:
     /// backend and use leasefile4_0.csv and leasefile6_0.csv files as
     /// storage for leases.
     ///
+    /// @param no_universe Indicates whether universe parameter should be
+    /// included (false), or not (true).
+    ///
     /// @return Configuration string for @c LeaseMgrFactory.
-    static std::string getConfigString() {
+    static std::string getConfigString(Universe u) {
         std::ostringstream s;
-        s << "type=memfile leasefile4=" << getLeaseFilePath("leasefile4_0.csv")
-          << " leasefile6=" << getLeaseFilePath("leasefile6_0.csv");
+        s << "type=memfile " << (u == V4 ? "universe=4 " : "universe=6 ")
+          << "leasefile="
+          << getLeaseFilePath(u == V4 ? "leasefile4_0.csv" : "leasefile6_0.csv");
         return (s.str());
     }
 
+    /// @brief Creates instance of the backend.
+    ///
+    /// @param u Universe (v4 or V6).
+    void startBackend(Universe u) {
+        try {
+            LeaseMgrFactory::create(getConfigString(u));
+        } catch (...) {
+            std::cerr << "*** ERROR: unable to create instance of the Memfile\n"
+                " lease database backend.\n";
+            throw;
+        }
+        lmptr_ = &(LeaseMgrFactory::instance());
+    }
+
     /// @brief Object providing access to v4 lease IO.
     LeaseFileIO io4_;
 
@@ -111,37 +126,27 @@ public:
 // This test checks if the LeaseMgr can be instantiated and that it
 // parses parameters string properly.
 TEST_F(MemfileLeaseMgrTest, constructor) {
-
     LeaseMgr::ParameterMap pmap;
-    pmap["persist4"] = "no";
-    pmap["persist6"] = "no";
+    pmap["universe"] = "4";
+    pmap["persist"] = "false";
     boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr;
 
     EXPECT_NO_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)));
 
-    pmap["persist4"] = "yes";
-    pmap["persist6"] = "yes";
-    pmap["leasefile4"] = getLeaseFilePath("leasefile4_1.csv");
-    pmap["leasefile6"] = getLeaseFilePath("leasefile6_1.csv");
+    pmap["persist"] = "true";
+    pmap["leasefile"] = getLeaseFilePath("leasefile4_1.csv");
     EXPECT_NO_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)));
 
     // Expecting that persist parameter is yes or no. Everything other than
     // that is wrong.
-    pmap["persist4"] = "bogus";
-    pmap["persist6"] = "yes";
-    pmap["leasefile4"] = getLeaseFilePath("leasefile4_1.csv");
-    pmap["leasefile6"] = getLeaseFilePath("leasefile6_1.csv");
-    EXPECT_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)), isc::BadValue);
-
-    pmap["persist4"] = "yes";
-    pmap["persist6"] = "bogus";
-    pmap["leasefile4"] = getLeaseFilePath("leasefile4_1.csv");
-    pmap["leasefile6"] = getLeaseFilePath("leasefile6_1.csv");
+    pmap["persist"] = "bogus";
+    pmap["leasefile"] = getLeaseFilePath("leasefile4_1.csv");
     EXPECT_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)), isc::BadValue);
 }
 
 // Checks if the getType() and getName() methods both return "memfile".
 TEST_F(MemfileLeaseMgrTest, getTypeAndName) {
+    startBackend(V4);
     EXPECT_EQ(std::string("memfile"), lmptr_->getType());
     EXPECT_EQ(std::string("memory"),  lmptr_->getName());
 }
@@ -154,24 +159,21 @@ TEST_F(MemfileLeaseMgrTest, getLeaseFilePath) {
     LeaseFileIO io6(getLeaseFilePath("leasefile6_1.csv"));
 
     LeaseMgr::ParameterMap pmap;
-    pmap["leasefile4"] = getLeaseFilePath("leasefile4_1.csv");
-    pmap["leasefile6"] = getLeaseFilePath("leasefile6_1.csv");
+    pmap["universe"] = "4";
+    pmap["leasefile"] = getLeaseFilePath("leasefile4_1.csv");
     boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
 
-    EXPECT_EQ(pmap["leasefile4"],
+    EXPECT_EQ(pmap["leasefile"],
               lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V4));
-    EXPECT_EQ(pmap["leasefile6"],
-              lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V6));
 
-    pmap["persist4"] = "no";
-    pmap["persist6"] = "no";
+    pmap["persist"] = "false";
     lease_mgr.reset(new Memfile_LeaseMgr(pmap));
     EXPECT_TRUE(lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V4).empty());
     EXPECT_TRUE(lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V6).empty());
 }
 
 // Check if the persitLeases correctly checks that leases should not be written
-// to disk when lease file is set to empty value.
+// to disk when disabled through configuration.
 TEST_F(MemfileLeaseMgrTest, persistLeases) {
     // Initialize IO objects, so as the test csv files get removed after the
     // test (when destructors are called).
@@ -179,17 +181,23 @@ TEST_F(MemfileLeaseMgrTest, persistLeases) {
     LeaseFileIO io6(getLeaseFilePath("leasefile6_1.csv"));
 
     LeaseMgr::ParameterMap pmap;
+    pmap["universe"] = "4";
     // Specify the names of the lease files. Leases will be written.
-    pmap["leasefile4"] = getLeaseFilePath("leasefile4_1.csv");
-    pmap["leasefile6"] = getLeaseFilePath("leasefile6_1.csv");
+    pmap["leasefile"] = getLeaseFilePath("leasefile4_1.csv");
     boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
 
     lease_mgr.reset(new Memfile_LeaseMgr(pmap));
     EXPECT_TRUE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
+    EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
+
+    pmap["universe"] = "6";
+    pmap["leasefile"] = getLeaseFilePath("leasefile6_1.csv");
+    lease_mgr.reset(new Memfile_LeaseMgr(pmap));
+    EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
     EXPECT_TRUE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
 
     // This should disable writes of leases to disk.
-    pmap["persist"] = "no";
+    pmap["persist"] = "false";
     lease_mgr.reset(new Memfile_LeaseMgr(pmap));
     EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
     EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
@@ -198,6 +206,7 @@ TEST_F(MemfileLeaseMgrTest, persistLeases) {
 
 // Checks that adding/getting/deleting a Lease6 object works.
 TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
+    startBackend(V6);
     testAddGetDelete6(true); // true - check T1,T2 values
     // memfile is able to preserve those values, but some other
     // backends can't do that.
@@ -208,6 +217,7 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
 /// Checks that the addLease, getLease4 (by address) and deleteLease (with an
 /// IPv4 address) works.
 TEST_F(MemfileLeaseMgrTest, basicLease4) {
+    startBackend(V4);
     testBasicLease4();
 }
 
@@ -215,16 +225,19 @@ TEST_F(MemfileLeaseMgrTest, basicLease4) {
 
 // Simple test about lease4 retrieval through client id method
 TEST_F(MemfileLeaseMgrTest, getLease4ClientId) {
+    startBackend(V4);
     testGetLease4ClientId();
 }
 
 // Checks that lease4 retrieval client id is null is working
 TEST_F(MemfileLeaseMgrTest, getLease4NullClientId) {
+    startBackend(V4);
     testGetLease4NullClientId();
 }
 
 // Checks lease4 retrieval through HWAddr
 TEST_F(MemfileLeaseMgrTest, getLease4HWAddr1) {
+    startBackend(V4);
     testGetLease4HWAddr1();
 }
 
@@ -233,11 +246,13 @@ TEST_F(MemfileLeaseMgrTest, getLease4HWAddr1) {
 /// Adds leases to the database and checks that they can be accessed via
 /// a combination of DUID and IAID.
 TEST_F(MemfileLeaseMgrTest, getLease4HWAddr2) {
+    startBackend(V4);
     testGetLease4HWAddr2();
 }
 
 // Checks lease4 retrieval with clientId, HWAddr and subnet_id
 TEST_F(MemfileLeaseMgrTest, getLease4ClientIdHWAddrSubnetId) {
+    startBackend(V4);
     testGetLease4ClientIdHWAddrSubnetId();
 }
 
@@ -247,6 +262,7 @@ TEST_F(MemfileLeaseMgrTest, getLease4ClientIdHWAddrSubnetId) {
 /// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id.
 /// (client-id is optional and may not be present)
 TEST_F(MemfileLeaseMgrTest, lease4NullClientId) {
+    startBackend(V4);
     testLease4NullClientId();
 }
 
@@ -257,6 +273,7 @@ TEST_F(MemfileLeaseMgrTest, lease4NullClientId) {
 TEST_F(MemfileLeaseMgrTest, DISABLED_getLease4HwaddrSubnetId) {
 
     /// @todo: fails on memfile. It's probably a memfile bug.
+    startBackend(V4);
     testGetLease4HWAddrSubnetId();
 }
 
@@ -265,6 +282,7 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_getLease4HwaddrSubnetId) {
 /// Adds leases to the database and checks that they can be accessed via
 /// the Client ID.
 TEST_F(MemfileLeaseMgrTest, getLease4ClientId2) {
+    startBackend(V4);
     testGetLease4ClientId2();
 }
 
@@ -272,6 +290,7 @@ TEST_F(MemfileLeaseMgrTest, getLease4ClientId2) {
 //
 // Check that the system can cope with a client ID of any size.
 TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSize) {
+    startBackend(V4);
     testGetLease4ClientIdSize();
 }
 
@@ -280,6 +299,7 @@ TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSize) {
 /// Adds leases to the database and checks that they can be accessed via
 /// a combination of client and subnet IDs.
 TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSubnetId) {
+    startBackend(V4);
     testGetLease4ClientIdSubnetId();
 }
 
@@ -288,6 +308,7 @@ TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSubnetId) {
 /// Checks that the addLease, getLease6 (by address) and deleteLease (with an
 /// IPv6 address) works.
 TEST_F(MemfileLeaseMgrTest, basicLease6) {
+    startBackend(V6);
     testBasicLease6();
 }
 
@@ -299,6 +320,7 @@ TEST_F(MemfileLeaseMgrTest, basicLease6) {
 /// @todo: test disabled, because Memfile_LeaseMgr::getLeases6(Lease::Type,
 /// const DUID& duid, uint32_t iaid) const is not implemented yet.
 TEST_F(MemfileLeaseMgrTest, DISABLED_getLeases6DuidIaid) {
+    startBackend(V6);
     testGetLeases6DuidIaid();
 }
 
@@ -307,6 +329,7 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_getLeases6DuidIaid) {
 /// @todo: test disabled, because Memfile_LeaseMgr::getLeases6(Lease::Type,
 /// const DUID& duid, uint32_t iaid) const is not implemented yet.
 TEST_F(MemfileLeaseMgrTest, DISABLED_getLeases6DuidSize) {
+    startBackend(V6);
     testGetLeases6DuidSize();
 }
 
@@ -319,6 +342,7 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_getLeases6DuidSize) {
 /// @todo: Disabled, because type parameter in Memfile_LeaseMgr::getLease6
 /// (Lease::Type, const isc::asiolink::IOAddress& addr) const is not used.
 TEST_F(MemfileLeaseMgrTest, DISABLED_lease6LeaseTypeCheck) {
+    startBackend(V6);
     testLease6LeaseTypeCheck();
 }
 
@@ -327,12 +351,14 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_lease6LeaseTypeCheck) {
 /// Adds leases to the database and checks that they can be accessed via
 /// a combination of DIUID and IAID.
 TEST_F(MemfileLeaseMgrTest, getLease6DuidIaidSubnetId) {
+    startBackend(V6);
     testGetLease6DuidIaidSubnetId();
 }
 
 /// Checks that getLease6(type, duid, iaid, subnet-id) works with different
 /// DUID sizes
 TEST_F(MemfileLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
+    startBackend(V6);
     testGetLease6DuidIaidSubnetIdSize();
 }
 
@@ -343,6 +369,7 @@ TEST_F(MemfileLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
 /// We should reconsider if lease{4,6} structures should have a limit
 /// implemented in them.
 TEST_F(MemfileLeaseMgrTest, DISABLED_updateLease4) {
+    startBackend(V4);
     testUpdateLease4();
 }
 
@@ -353,6 +380,7 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_updateLease4) {
 /// We should reconsider if lease{4,6} structures should have a limit
 /// implemented in them.
 TEST_F(MemfileLeaseMgrTest, DISABLED_updateLease6) {
+    startBackend(V6);
     testUpdateLease6();
 }
 

+ 4 - 1
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -183,7 +183,10 @@ public:
     ///
     /// Closes the database and re-open it.  Anything committed should be
     /// visible.
-    void reopen() {
+    ///
+    /// Parameter is ignored for MySQL backend as the v4 and v6 leases share
+    /// the same database.
+    void reopen(Universe) {
         LeaseMgrFactory::destroy();
         LeaseMgrFactory::create(validConnectionString());
         lmptr_ = &(LeaseMgrFactory::instance());