]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1572] backport 1542 to 1.8.2
authorRazvan Becheriu <razvan@isc.org>
Fri, 27 Nov 2020 06:42:56 +0000 (08:42 +0200)
committerRazvan Becheriu <razvan@isc.org>
Fri, 27 Nov 2020 06:42:56 +0000 (08:42 +0200)
src/hooks/dhcp/lease_cmds/lease_cmds.cc
src/hooks/dhcp/lease_cmds/tests/lease_cmds_unittest.cc

index d11788c0ed631078d6d1f75fadfecd6dcedc2ff4..ac2bb32b3065d3d8a58f969686b9378c432f4c48 100644 (file)
@@ -1819,7 +1819,7 @@ LeaseCmdsImpl::lease4UpdateHandler(CalloutHandle& handle) {
                 // Try to avoid a race.
                 ResourceHandler4 resource_handler;
                 use_cs = !resource_handler.tryLock4(lease4->addr_);
-                if (use_cs) {
+                if (!use_cs) {
                     added = addOrUpdate4(lease4, force_create);
                 }
             }
index 214eef12fd1a8d981f9f06c0189d936d68c7cfa5..1f66b12570c0380091ac0af9f6fef7a5f32fb469 100644 (file)
@@ -17,6 +17,7 @@
 #include <cc/data.h>
 #include <stats/stats_mgr.h>
 #include <testutils/user_context_utils.h>
+#include <testutils/multi_threading_utils.h>
 
 #include <gtest/gtest.h>
 
@@ -693,6 +694,11 @@ public:
         return (size);
     }
 
+    /// @brief Check lease4 statistics.
+    ///
+    /// @param id Subnet id of the stats to check.
+    /// @assigned The expected value of assigned addresses in subnet.
+    /// @declined The expected value of declined addresses in subnet.
     void checkLease4Stats(SubnetID id, int32_t assigned, int32_t declined) {
         ASSERT_EQ(StatsMgr::instance().getObservation(
                       StatsMgr::generateName("subnet", id,
@@ -703,6 +709,12 @@ public:
                           "declined-addresses"))->getInteger().first, declined);
     }
 
+    /// @brief Check lease4 statistics.
+    ///
+    /// @param id Subnet id of the stats to check.
+    /// @assigned_nas The expected value of assigned nas addresses in subnet.
+    /// @declined The expected value of declined addresses in subnet.
+    /// @assigned_pds The expected value of assigned pds addresses in subnet.
     void checkLease6Stats(SubnetID id, int32_t assigned_nas, int32_t declined,
                           int32_t assigned_pds) {
         ASSERT_EQ(StatsMgr::instance().getObservation(
@@ -717,6 +729,602 @@ public:
                       StatsMgr::generateName("subnet", id,
                           "assigned-pds"))->getInteger().first, assigned_pds);
     }
+
+    /// @brief Check that lease4-add with missing parameters will fail.
+    void testLease4AddMissingParams();
+
+    /// @brief Verify that lease4-add can be rejected if parameters are
+    /// specified, but have incorrect values.
+    void testLease4AddBadParams();
+
+    /// @brief Check that a simple, well formed lease4 can be added.
+    void testLease4Add();
+
+    /// @brief Check that a simple, well formed lease4 can be added.
+    void testLease4AddDeclinedLeases();
+
+    /// @brief Check that a lease4 is not added when it already exists.
+    void testLease4AddExisting();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own.
+    void testLease4AddSubnetIdMissing();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own.
+    void testLease4AddSubnetIdMissingDeclinedLeases();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own, but if there's no subnet for address being added,
+    /// it should fail.
+    void testLease4AddSubnetIdMissingBadAddr();
+
+    /// @brief Check that the lease with negative expiration time is rejected.
+    void testLease4AddNegativeExpireTime();
+
+    /// @brief Check that the lease with negative cltt is rejected.
+    void testLease4AddNegativeCltt();
+
+    /// @brief Check that a well formed lease4 with tons of parameters can be
+    /// added.
+    void testLease4AddFullAddr();
+
+    /// @brief Check that a well formed lease4 with a comment can be added.
+    void testLease4AddComment();
+
+    /// @brief Check that lease6-add with missing parameters will fail.
+    void testLease6AddMissingParams();
+
+    /// @brief Verify that lease6-add can be rejected if parameters are
+    /// specified, but have incorrect values.
+    void testLease6AddBadParams();
+
+    /// @brief Check that a simple, well formed lease6 can be added.
+    void testLease6Add();
+
+    /// @brief Check that a simple, well formed lease6 can be added.
+    void testLease6AddDeclinedLeases();
+
+    /// @brief Check that a lease6 is not added when it already exists.
+    void testLease6AddExisting();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own.
+    void testLease6AddSubnetIdMissing();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own.
+    void testLease6AddSubnetIdMissingDeclinedLeases();
+
+    /// @brief Check that subnet-id is optional. If not specified, Kea should
+    /// select it on its own, but if there's no subnet for address being added,
+    /// it should fail.
+    void testLease6AddSubnetIdMissingBadAddr();
+
+    /// @brief Check that the lease with negative expiration time is rejected.
+    void testLease6AddNegativeExpireTime();
+
+    /// @brief Check that the lease with negative cltt is rejected.
+    void testLease6AddNegativeCltt();
+
+    /// @brief Check that a simple, well formed prefix lease can be added.
+    void testLease6AddPrefix();
+
+    /// @brief Check that a well formed lease6 with tons of parameters can be
+    /// added.
+    void testLease6AddFullAddr();
+
+    /// @brief Check that a well formed lease6 with a comment can be added.
+    void testLease6AddComment();
+
+    /// @brief Check that lease4-get can handle a situation when the query is
+    /// broken (some required parameters are missing).
+    void testLease4GetMissingParams();
+
+    /// @brief Check that lease4-get sanitizes its input.
+    void testLease4GetByAddrBadParam();
+
+    /// @brief Check that lease4-get can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease4GetByAddrNotFound();
+
+    /// @brief Check that lease4-get can return a lease by address.
+    void testLease4GetByAddr();
+
+    /// @brief Check that lease4-get can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease4GetByHWAddrNotFound();
+
+    /// @brief Check that lease4-get can find a lease by hardware address.
+    void testLease4GetByHWAddr();
+
+    /// @brief Check that lease4-get can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease4GetByClientIdNotFound();
+
+    /// @brief Check that lease4-get can find a lease by client identifier.
+    void testLease4GetByClientId();
+
+    /// @brief Check that lease6-get can handle a situation when the query is
+    /// broken (some required parameters are missing).
+    void testLease6GetMissingParams();
+
+    /// @brief Check that lease6-get sanitizes its input.
+    void testLease6GetByAddrBadParam();
+
+    /// @brief Check that lease6-get can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease6GetByAddrNotFound();
+
+    /// @brief Check that lease6-get can return a lease by address.
+    void testLease6GetByAddr();
+
+    /// @brief Check that lease6-get can return a lease by prefix.
+    void testLease6GetByAddrPrefix();
+
+    /// @bfief Check that lease6-get rejects queries by client-id.
+    void testLease6GetByClientIdInvalidType();
+
+    /// @brief Check that lease6-get can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease6GetByDuidNotFound();
+
+    /// @bfief Check that lease6-get can find a lease by duid.
+    void testLease6GetByDuid();
+
+    /// @brief Check that lease4-get-all returns all leases.
+    void testLease4GetAll();
+
+    /// @brief Check that lease4-get-all returns empty set if no leases are
+    /// found.
+    void testLease4GetAllNoLeases();
+
+    /// @brief Check that lease4-get-all returns all leases for a subnet.
+    void testLease4GetAllBySubnetId();
+
+    /// @brief Check that lease4-get-all returns empty set when no leases are
+    /// found.
+    void testLease4GetAllBySubnetIdNoLeases();
+
+    /// @brief Check that lease4-get-all returns leases from multiple subnets.
+    void testLease4GetAllByMultipleSubnetIds();
+
+    /// @brief Check that lease4-get-all checks its input arguments.
+    void testLease4GetBySubnetIdInvalidArguments();
+
+    /// @brief Check that multiple calls to lease4-get-page return all leases.
+    void testLease4GetPaged();
+
+    /// @brief Verifies that first page of IPv4 leases can be retrieved by
+    /// specifying zero IPv4 address.
+    void testLease4GetPagedZeroAddress();
+
+    /// @brief Verifies that IPv6 address as a start address is rejected.
+    void testLease4GetPagedIPv6Address();
+
+    /// @brief Verifies that value of 'from' parameter other than 'start' or an
+    /// IPv4 address is rejected.
+    void testLease4GetPagedInvalidFrom();
+
+    /// @brief Verifies that limit is mandatory.
+    void testLease4GetPagedNoLimit();
+
+    /// @brief Verifies that the limit must be a number.
+    void testLease4GetPagedLimitNotNumber();
+
+    /// @brief Verifies that the limit of 0 is rejected.
+    void testLease4GetPagedLimitIsZero();
+
+    /// @brief Check that lease6-get-all returns all leases.
+    void testLease6GetAll();
+
+    /// @brief Check that lease6-get-all returns empty set if no leases are
+    /// found.
+    void testLease6GetAllNoLeases();
+
+    /// @brief Check that lease6-get-all returns all leases for a subnet.
+    void testLease6GetAllBySubnetId();
+
+    /// @brief Check that lease6-get-all returns empty set when no leases are
+    /// found.
+    void testLease6GetAllBySubnetIdNoLeases();
+
+    /// @brief Check that lease6-get-all returns leases from multiple subnets.
+    void testLease6GetAllByMultipleSubnetIds();
+
+    /// @brief Check that lease6-get-all checks its input arguments.
+    void testLease6GetBySubnetIdInvalidArguments();
+
+    /// @brief Check that multiple calls to lease6-get-page return all leases.
+    void testLease6GetPaged();
+
+    /// @brief Verifies that first page of IPv6 leases can be retrieved by
+    /// specifying zero IPv6 address.
+    void testLease6GetPagedZeroAddress();
+
+    /// @brief Verifies that IPv4 address as a start address is rejected.
+    void testLease6GetPagedIPv4Address();
+
+    /// @brief Verifies that value of 'from' parameter other than 'start' or an
+    /// IPv6 address is rejected.
+    void testLease6GetPagedInvalidFrom();
+
+    /// @brief Verifies that limit is mandatory.
+    void testLease6GetPagedNoLimit();
+
+    /// @brief Verifies that the limit must be a number.
+    void testLease6GetPagedLimitNotNumber();
+
+    /// @brief Verifies that the limit of 0 is rejected.
+    void testLease6GetPagedLimitIsZero();
+
+    /// @brief Check that lease4-get-by-hw-address can handle a situation when
+    /// the query is broken (required parameter is missing).
+    void testLeaseGetByHwAddressParams();
+
+    /// @brief Check that lease4-get-by-hw-address works as expected (find no
+    /// lease).
+    void testLeaseGetByHwAddressFind0();
+
+    /// @brief Check that lease4-get-by-hw-address works as expected (find two
+    /// leases).
+    void testLeaseGetByHwAddressFind2();
+
+    /// @brief Check that lease4-get-by-client-id can handle a situation when
+    /// the query is broken (required parameter is missing).
+    void testLeaseGetByClientIdParams();
+
+    /// @brief Check that lease4-get-by-client-id works as expected (find no
+    /// lease).
+    void testLeaseGetByClientIdFind0();
+
+    /// @brief Check that lease4-get-by-client-id works as expected (find two
+    /// leases).
+    void testLeaseGetByClientIdFind2();
+
+    /// @brief Check that lease6-get-by-duid can handle a situation when the
+    /// query is broken (required parameter is missing).
+    void testLeaseGetByDuidParams();
+
+    /// @brief Check that lease6-get-by-duid works as expected (find no lease).
+    void testLeaseGetByDuidFind0();
+
+    /// @brief Check that lease6-get-by-duid works as expected (find two
+    /// leases).
+    void testLeaseGetByDuidFind2();
+
+    /// @brief Check that lease4-get-by-hostname can handle a situation when
+    /// the query is broken (required parameter is missing).
+    void testLease4GetByHostnameParams();
+
+    /// @brief Check that lease4-get-by-hostname works as expected (find no
+    /// lease).
+    void testLease4GetByHostnameFind0();
+
+    /// @brief Check that lease4-get-by-hostname works as expected (find two
+    /// leases).
+    void testLease4GetByHostnameFind2();
+
+    /// @brief Check that lease6-get-by-hostname can handle a situation when
+    /// the query is broken (required parameter is missing).
+    void testLease6GetByHostnameParams();
+
+    /// @brief Check that lease6-get-by-hostname works as expected (find no
+    /// lease).
+    void testLease6GetByHostnameFind0();
+
+    /// @brief Check that lease6-get-by-hostname works as expected (find two
+    /// leases).
+    void testLease6GetByHostnameFind2();
+
+    /// @brief Test checks if lease4-update handler refuses calls with missing
+    /// parameters.
+    void testLease4UpdateMissingParams();
+
+    /// @brief Verify that lease4-update can be rejected if parameters are
+    /// specified, but have incorrect values.
+    void testLease4UpdateBadParams();
+
+    /// @brief Check that lease4-update correctly handles case when there is no
+    /// lease to be updated.
+    void testLease4UpdateNoLease();
+
+    /// @brief Check that a lease4 can be updated. We're changing hw-address and
+    /// a hostname.
+    void testLease4Update();
+
+    /// @brief Check that a lease4 can be updated. We're changing hw-address and
+    /// a hostname.
+    void testLease4UpdateDeclinedLeases();
+
+    /// @brief Check that a lease4 can be updated. We're changing hw-address and
+    /// a hostname. The subnet-id is not specified.
+    void testLease4UpdateNoSubnetId();
+
+    /// @brief Check that a lease4 can be updated. We're changing hw-address and
+    /// a hostname. The subnet-id is not specified.
+    void testLease4UpdateNoSubnetIdDeclinedLeases();
+
+    /// @brief Check that a lease4 is created if it doesn't exist during the
+    /// update. To trigger this behavior 'force-create' boolean parameter must
+    /// be included in the command.
+    void testLease4UpdateForceCreate();
+
+    /// @brief Check that a lease4 is created if it doesn't exist during the
+    /// update. To trigger this behavior 'force-create' boolean parameter must
+    /// be included in the command. The subnet-id is not specified, Kea will
+    /// figure it out.
+    void testLease4UpdateForceCreateNoSubnetId();
+
+    /// @brief Check that lease4-update correctly handles case when the
+    /// 'force-create' parameter is explicitly set to false.
+    void testLease4UpdateDoNotForceCreate();
+
+    /// @brief Check that a lease4 can be updated. We're adding a comment and an
+    /// user context.
+    void testLease4UpdateComment();
+
+    /// @brief Test checks if lease6-update handler refuses calls with missing
+    /// parameters.
+    void testLease6UpdateMissingParams();
+
+    /// @brief Verify that lease6-update can be rejected if parameters are
+    /// specified, but have incorrect values.
+    void testLease6UpdateBadParams();
+
+    /// @brief Check that lease6-update correctly handles case when there is no
+    /// lease to be updated.
+    void testLease6UpdateNoLease();
+
+    /// @brief Check that a lease6 can be updated. We're changing hw-address and
+    /// a hostname.
+    void testLease6Update();
+
+    /// @brief Check that a lease6 can be updated. We're changing hw-address and
+    /// a hostname.
+    void testLease6UpdateDeclinedLeases();
+
+    /// @brief Check that a lease6 can be updated. We're changing hw-address and
+    /// a hostname. The subnet-id is not specified.
+    void testLease6UpdateNoSubnetId();
+
+    /// @brief Check that a lease6 can be updated. We're changing hw-address and
+    /// a hostname. The subnet-id is not specified.
+    void testLease6UpdateNoSubnetIdDeclinedLeases();
+
+    /// @brief Check that a lease6 is created if it doesn't exist during the
+    /// update. To trigger this behavior 'force-create' boolean parameter must
+    /// be included in the command.
+    void testLease6UpdateForceCreate();
+
+    /// @brief Check that a lease6 is created if it doesn't exist during the
+    /// update. To trigger this behavior 'force-create' boolean parameter must
+    /// be included in the command. The subnet-id is not specified, Kea will
+    /// figure it out.
+    void testLease6UpdateForceCreateNoSubnetId();
+
+    /// @brief Check that lease6-update correctly handles case when the
+    /// 'force-create' parameter is explicitly set to false.
+    void testLease6UpdateDoNotForceCreate();
+
+    /// @brief Check that a lease6 can be updated. We're adding a comment and an
+    /// user context.
+    void testLease6UpdateComment();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// broken (some required parameters are missing).
+    void testLease4DelMissingParams();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// valid, but the lease is not there.
+    void testLease4DelByAddrNotFound();
+
+    /// @brief Check that lease4-del sanitizes its input.
+    void testLease4DelByAddrBadParam();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// correctly formed and the lease is deleted.
+    void testLease4DelByAddr();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// correctly formed and the lease is deleted.
+    void testLease4DelByAddrDeclinedLeases();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease4DelByHWAddrNotFound();
+
+    /// @brief Check that lease4-del can find and delete a lease by hardware
+    /// address.
+    void testLease4DelByHWAddr();
+
+    /// @brief Check that lease4-del can handle a situation when the query is
+    /// correctly formed, but the lease is not there.
+    void testLease4DelByClientIdNotFound();
+
+    /// @brief Check that lease4-del can find and delete a lease by client
+    /// identifier.
+    void testLease4DelByClientId();
+
+    /// @brief Check that lease6-del can handle a situation when the query is
+    /// broken (some required parameters are missing).
+    void testLease6DelMissingParams();
+
+    /// @brief Check that lease6-del(subnet-id, addr6) can handle a situation
+    /// when the query is correctly formed, but the lease is not there.
+    void testLease6DelByAddrNotFound();
+
+    /// @brief Check that lease6-del sanitizes its input.
+    void testLease6DelByAddrBadParam();
+
+    /// @brief Check that lease6-del(subnet-id, addr6) can handle a situation
+    /// when the query is correctly formed and the lease is deleted.
+    void testLease6DelByAddr();
+
+    /// @brief Check that lease6-del(subnet-id, addr6) can handle a situation
+    /// when the query is correctly formed and the lease is deleted.
+    void testLease6DelByAddrDeclinedLeases();
+
+    /// @brief Check that lease6-del(type, addr6) can handle a
+    /// situation when the query is correctly formed and the lease is deleted.
+    void testLease6DelByAddrPrefix();
+
+    /// @brief Check that lease6-del(subnet-id, addr) can handle a situation
+    /// when the query is correctly formed, but the lease is not there.
+    void testLease6DelByDuidNotFound();
+
+    /// @brief Check that lease6-del(subnet-id, iaid, identifier-type,
+    /// identifier) can find and delete a lease by duid.
+    void testLease6DelByDuid();
+
+    /// @brief Check that leaseX-del checks update-ddns input.
+    void testLeaseXDelBadUpdateDdnsParam();
+
+    /// @brief Check that lease4-wipe can remove leases.
+    void testLease4Wipe();
+
+    /// @brief Check that lease4-wipe can remove leases from all subnets at
+    /// once.
+    void testLease4WipeAll();
+
+    /// @brief Check that lease4-wipe can remove leases from all subnets at
+    /// once (when no parameters are specified).
+    void testLease4WipeAllNoArgs();
+
+    /// @brief Check that lease4-wipe properly reports when no leases were
+    /// deleted.
+    void testLease4WipeNoLeases();
+
+    /// @brief Check that lease4-wipe properly reports when no leases were
+    /// deleted.
+    void testLease4WipeNoLeasesAll();
+
+    /// @brief Check that lease6-wipe can remove leases.
+    void testLease6Wipe();
+
+    /// @brief Check that lease6-wipe can remove leases from all subnets at
+    /// once.
+    void testLease6WipeAll();
+
+    /// @brief Check that lease6-wipe can remove leases from all subnets at
+    /// once (when no parameters are specified).
+    void testLease6WipeAllNoArgs();
+
+    /// @brief Check that lease6-wipe properly reports when no leases were
+    /// deleted.
+    void testLease6WipeNoLeases();
+
+    /// @brief Check that lease6-wipe properly reports when no leases were
+    /// deleted.
+    void testLease6WipeNoLeasesAll();
+
+    /// @brief Check that an attempt to update a lease (set incorrect
+    /// subnet-id) will fail.
+    void testLease4BrokenUpdate();
+
+    /// @brief Check that an attempt to update a lease (set incorrect
+    /// subnet-id) will fail.
+    void testLease6BrokenUpdate();
+
+    /// @brief This test verifies that it is possible to add two leases and
+    /// delete two leases as a result of the single lease6-bulk-apply command.
+    void testLease6BulkApply();
+
+    /// @brief This test verifies that the lease parameters are checked when
+    /// adding new leases only with the lease6-bulk-apply.
+    void testLease6BulkApplyAddsOnlyBadParam();
+
+    /// @brief This test verifies that it is possible to send new leases only
+    /// with the lease6-bulk-apply.
+    void testLease6BulkApplyAddsOnly();
+
+    /// @brief This test verifies that the lease parameters are checked when
+    /// updating leases only with the lease6-bulk-apply.
+    void testLease6BulkApplyUpdatesOnlyBadParam();
+
+    /// @brief This test verifies that it is possible to update leases with the
+    /// lease6-bulk-apply.
+    void testLease6BulkApplyUpdatesOnly();
+
+    /// @brief This test verifies that it is possible to only delete leases with
+    /// the lease6-bulk-apply.
+    void testLease6BulkApplyDeletesOnly();
+
+    /// @brief This test verifies that deleting non existing leases returns an
+    /// 'empty' result.
+    void testLease6BulkApplyDeleteNonExiting();
+
+    /// @brief Check that changes for other leases are not applied if one of the
+    /// leases is malformed.
+    void testLease6BulkApplyRollback();
+
+    /// @brief Check that lease4-resend-ddns sanitizes its input.
+    void testLease4ResendDdnsBadParam();
+
+    /// @brief Check that lease4-resend-ddns does not generate an NCR for given
+    /// lease when DDNS updating is disabled.
+    void testLease4ResendDdnsDisabled();
+
+    /// @brief Check that lease4-resend-ddns does not generate an NCR for when
+    /// there is no matching lease.
+    void testLease4ResendDdnsNoLease();
+
+    /// @brief Check that lease4-resend-ddns does not generate an NCR for given
+    /// lease when updates are enabled but Lease::hostname_ is blank.
+    void testLease4ResendNoHostname();
+
+    /// @brief Check that lease4-resend-ddns does not generate an NCR for given
+    /// lease when updates are enabled, Lease::hostname_ is not blank, but both
+    /// Lease::fqdn_fwd_ and fdqn_rev_ are false.
+    void testLease4ResendNoDirectionsEnabled();
+
+    /// @brief Check that lease4-resend-ddns can generate an NCR for given
+    /// lease when updates are enabled, Lease::hostname_ is not blank, and at
+    /// least one of Lease::fqdn_fwd_ or fdqn_rev_ are true.
+    void testLease4ResendDdnsEnabled();
+
+    /// @brief Check that lease6-resend-ddns sanitizes its input.
+    void testLease6ResendDdnsBadParam();
+
+    /// @brief Check that lease6-resend-ddns does not generate an NCR for given
+    /// lease when DDNS updating is disabled.
+    void testLease6ResendDdnsDisabled();
+
+    /// @brief Check that lease6-resend-ddns does not generate an NCR for when
+    /// there is no matching lease.
+    void testLease6ResendDdnsNoLease();
+
+    /// @brief Check that lease6-resend-ddns does not generate an NCR for given
+    /// lease when updates are enabled but Lease::hostname_ is blank.
+    void testLease6ResendNoHostname();
+
+    /// @brief Check that lease6-resend-ddns does not generate an NCR for given
+    /// lease when updates are enabled, Lease::hostname_ is not blank, but both
+    /// Lease::fqdn_fwd_ and fdqn_rev_ are false.
+    void testLease6ResendNoDirectionsEnabled();
+
+    /// @brief Check that lease6-resend-ddns can generate an NCR for given
+    /// lease when updates are enabled, Lease::hostname_ is not blank, and at
+    /// least one of Lease::fqdn_fwd_ or fdqn_rev_ are true.
+    void testLease6ResendDdnsEnabled();
+
+    /// @brief Check that lease4-del does (or does not) generate an NCR to
+    /// remove DNS for a given lease based on lease content when DDNS updates
+    /// are enabled.
+    void testLease4DnsRemoveD2Enabled();
+
+    /// @brief Check that lease4-del does not generate an NCR to remove DNS for
+    /// a given lease based on lease content when DDNS updates are disabled.
+    void testLease4DnsRemoveD2Disabled();
+
+    /// @brief Check that lease6-del does (or does not) generate an NCR to
+    /// remove DNS for a given lease based on lease content when DDNS updates
+    /// are enabled.
+    void testLease6DnsRemoveD2Enabled();
+
+    /// @brief Check that lease6-del does not generate an NCR to remove DNS for
+    /// a given lease based on lease content when DDNS updates are disabled.
+    void testLease6DnsRemoveD2Disabled();
 };
 
 // Simple test that checks the library really registers the commands.
@@ -745,8 +1353,7 @@ TEST_F(LeaseCmdsTest, multipleLoads) {
 
 using namespace isc::dhcp;
 
-// Check that lease4-add with missing parameters will fail.
-TEST_F(LeaseCmdsTest, Lease4AddMissingParams) {
+void LeaseCmdsTest::testLease4AddMissingParams() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -798,9 +1405,16 @@ TEST_F(LeaseCmdsTest, Lease4AddMissingParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verify that lease4-add can be rejected if parameters are specified, but
-// have incorrect values.
-TEST_F(LeaseCmdsTest, Lease4AddBadParams) {
+TEST_F(LeaseCmdsTest, lease4AddMissingParams) {
+    testLease4AddMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddMissingParams();
+}
+
+void LeaseCmdsTest::testLease4AddBadParams() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -891,8 +1505,16 @@ TEST_F(LeaseCmdsTest, Lease4AddBadParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Check that a simple, well formed lease4 can be added.
-TEST_F(LeaseCmdsTest, Lease4Add) {
+TEST_F(LeaseCmdsTest, lease4AddBadParams) {
+    testLease4AddBadParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddBadParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddBadParams();
+}
+
+void LeaseCmdsTest::testLease4Add() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -938,8 +1560,16 @@ TEST_F(LeaseCmdsTest, Lease4Add) {
     EXPECT_EQ(0, l->state_);
 }
 
-// Check that a simple, well formed lease4 can be added.
-TEST_F(LeaseCmdsTest, Lease4AddDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease4Add) {
+    testLease4Add();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4Add();
+}
+
+void LeaseCmdsTest::testLease4AddDeclinedLeases() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -986,8 +1616,16 @@ TEST_F(LeaseCmdsTest, Lease4AddDeclinedLeases) {
     EXPECT_EQ(1, l->state_);
 }
 
-// Check that a lease4 is not added when it already exists.
-TEST_F(LeaseCmdsTest, Lease4AddExisting) {
+TEST_F(LeaseCmdsTest, lease4AddDeclinedLeases) {
+    testLease4AddDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease4AddExisting() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -1014,9 +1652,16 @@ TEST_F(LeaseCmdsTest, Lease4AddExisting) {
     checkLease4Stats(88, 2, 0);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own.
-TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissing) {
+TEST_F(LeaseCmdsTest, lease4AddExisting) {
+    testLease4AddExisting();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddExistingMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddExisting();
+}
+
+void LeaseCmdsTest::testLease4AddSubnetIdMissing() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1048,9 +1693,16 @@ TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissing) {
     EXPECT_EQ(44, l->subnet_id_);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own.
-TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissingDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissing) {
+    testLease4AddSubnetIdMissing();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissingMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddSubnetIdMissing();
+}
+
+void LeaseCmdsTest::testLease4AddSubnetIdMissingDeclinedLeases() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1083,10 +1735,16 @@ TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissingDeclinedLeases) {
     EXPECT_EQ(44, l->subnet_id_);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own, but if there's no subnet for address being added, it
-// should fail.
-TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissingBadAddr) {
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissingDeclinedLeases) {
+    testLease4AddSubnetIdMissingDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissingDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddSubnetIdMissingDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease4AddSubnetIdMissingBadAddr() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1118,8 +1776,16 @@ TEST_F(LeaseCmdsTest, Lease4AddSubnetIdMissingBadAddr) {
     ASSERT_FALSE(l);
 }
 
-// Check that the lease with negative expiration time is rejected.
-TEST_F(LeaseCmdsTest, Lease4AddNegativeExpireTime) {
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissingBadAddr) {
+    testLease4AddSubnetIdMissingBadAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddSubnetIdMissingBadAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddSubnetIdMissingBadAddr();
+}
+
+void LeaseCmdsTest::testLease4AddNegativeExpireTime() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1150,8 +1816,16 @@ TEST_F(LeaseCmdsTest, Lease4AddNegativeExpireTime) {
     ASSERT_FALSE(l);
 }
 
-// Check that the lease with negative cltt is rejected.
-TEST_F(LeaseCmdsTest, Lease4AddNegativeCltt) {
+TEST_F(LeaseCmdsTest, lease4AddNegativeExpireTime) {
+    testLease4AddNegativeExpireTime();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddNegativeExpireTimeMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddNegativeExpireTime();
+}
+
+void LeaseCmdsTest::testLease4AddNegativeCltt() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1184,8 +1858,16 @@ TEST_F(LeaseCmdsTest, Lease4AddNegativeCltt) {
     ASSERT_FALSE(l);
 }
 
-// Check that a well formed lease4 with tons of parameters can be added.
-TEST_F(LeaseCmdsTest, Lease4AddFull) {
+TEST_F(LeaseCmdsTest, lease4AddNegativeCltt) {
+    testLease4AddNegativeCltt();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddNegativeClttMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddNegativeCltt();
+}
+
+void LeaseCmdsTest::testLease4AddFullAddr() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1235,8 +1917,16 @@ TEST_F(LeaseCmdsTest, Lease4AddFull) {
     EXPECT_EQ("{ \"foobar\": true }", l->getContext()->str());
 }
 
-// Check that a well formed lease4 with a comment can be added.
-TEST_F(LeaseCmdsTest, Lease4AddComment) {
+TEST_F(LeaseCmdsTest, lease4AddFullAddr) {
+    testLease4AddFullAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddFullAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddFullAddr();
+}
+
+void LeaseCmdsTest::testLease4AddComment() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -1274,8 +1964,16 @@ TEST_F(LeaseCmdsTest, Lease4AddComment) {
     EXPECT_EQ("{ \"comment\": \"a comment\" }", l->getContext()->str());
 }
 
-// Check that lease6-add with missing parameters will fail.
-TEST_F(LeaseCmdsTest, Lease6AddMissingParams) {
+TEST_F(LeaseCmdsTest, lease4AddComment) {
+    testLease4AddComment();
+}
+
+TEST_F(LeaseCmdsTest, lease4AddCommentMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4AddComment();
+}
+
+void LeaseCmdsTest::testLease6AddMissingParams() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1353,9 +2051,16 @@ TEST_F(LeaseCmdsTest, Lease6AddMissingParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verify that lease6-add can be rejected if parameters specified, but
-// have incorrect values.
-TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
+TEST_F(LeaseCmdsTest, lease6AddMissingParams) {
+    testLease6AddMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddMissingParams();
+}
+
+void LeaseCmdsTest::testLease6AddBadParams() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1503,8 +2208,16 @@ TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Check that a simple, well formed lease6 can be added.
-TEST_F(LeaseCmdsTest, Lease6Add) {
+TEST_F(LeaseCmdsTest, lease6AddBadParams) {
+    testLease6AddBadParams();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddBadParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddBadParams();
+}
+
+void LeaseCmdsTest::testLease6Add() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1544,8 +2257,16 @@ TEST_F(LeaseCmdsTest, Lease6Add) {
     EXPECT_EQ(0, l->state_);
 }
 
-// Check that a simple, well formed lease6 can be added.
-TEST_F(LeaseCmdsTest, Lease6AddDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease6Add) {
+    testLease6Add();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6Add();
+}
+
+void LeaseCmdsTest::testLease6AddDeclinedLeases() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1586,8 +2307,16 @@ TEST_F(LeaseCmdsTest, Lease6AddDeclinedLeases) {
     EXPECT_EQ(1, l->state_);
 }
 
-// Check that a lease6 is not added when it already exists.
-TEST_F(LeaseCmdsTest, Lease6AddExisting) {
+TEST_F(LeaseCmdsTest, lease6AddDeclinedLeases) {
+    testLease6AddDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease6AddExisting() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -1615,9 +2344,16 @@ TEST_F(LeaseCmdsTest, Lease6AddExisting) {
     checkLease6Stats(99, 2, 0, 0);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own.
-TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissing) {
+TEST_F(LeaseCmdsTest, lease6AddExisting) {
+    testLease6AddExisting();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddExistingMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddExisting();
+}
+
+void LeaseCmdsTest::testLease6AddSubnetIdMissing() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1649,9 +2385,16 @@ TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissing) {
     EXPECT_EQ(66, l->subnet_id_);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own.
-TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissingDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissing) {
+    testLease6AddSubnetIdMissing();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissingMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddSubnetIdMissing();
+}
+
+void LeaseCmdsTest::testLease6AddSubnetIdMissingDeclinedLeases() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1684,10 +2427,16 @@ TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissingDeclinedLeases) {
     EXPECT_EQ(66, l->subnet_id_);
 }
 
-// Check that subnet-id is optional. If not specified, Kea should select
-// it on its own, but if there's no subnet for address being added, it
-// should fail.
-TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissingBadAddr) {
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissingDeclinedLeases) {
+    testLease6AddSubnetIdMissingDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissingDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddSubnetIdMissingDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease6AddSubnetIdMissingBadAddr() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1719,8 +2468,16 @@ TEST_F(LeaseCmdsTest, Lease6AddSubnetIdMissingBadAddr) {
     ASSERT_FALSE(l);
 }
 
-// Check that a simple, well formed prefix lease can be added.
-TEST_F(LeaseCmdsTest, Lease6AddPrefix) {
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissingBadAddr) {
+    testLease6AddSubnetIdMissingBadAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddSubnetIdMissingBadAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddSubnetIdMissingBadAddr();
+}
+
+void LeaseCmdsTest::testLease6AddNegativeExpireTime() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1729,37 +2486,40 @@ TEST_F(LeaseCmdsTest, Lease6AddPrefix) {
 
     checkLease6Stats(99, 0, 0, 0);
 
-    // Now send the command.
+    // Add a lease with negative expiration time.
     string txt =
         "{\n"
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8:abcd::\",\n"
-        "        \"prefix-len\": 48,\n"
-        "        \"type\": \"IA_PD\",\n"
+        "        \"ip-address\": \"2001:db8:1::3\",\n"
         "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
-        "        \"iaid\": 1234\n"
+        "        \"iaid\": 1234,\n"
+        "        \"expire\": -6218189367\n"
         "    }\n"
         "}";
-    string exp_rsp = "Lease for prefix 2001:db8:abcd::/48, subnet-id 66 added.";
-    testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
+    string exp_rsp = "expiration time must be positive for address 2001:db8:1::3";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 
-    checkLease6Stats(66, 0, 0, 1);
+    checkLease6Stats(66, 0, 0, 0);
 
     checkLease6Stats(99, 0, 0, 0);
 
-    // Now check that the lease is really there.
-    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_PD, IOAddress("2001:db8:abcd::"));
-    ASSERT_TRUE(l);
-    EXPECT_EQ(Lease::TYPE_PD, l->type_);
-    EXPECT_EQ(48, l->prefixlen_);
-    EXPECT_EQ("", l->hostname_);
-    EXPECT_FALSE(l->getContext());
+    // Now check that the lease was not added.
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
+    ASSERT_FALSE(l);
+}
+
+TEST_F(LeaseCmdsTest, lease6AddNegativeExpireTime) {
+    testLease6AddNegativeExpireTime();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddNegativeExpireTimeMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddNegativeExpireTime();
 }
 
-// Check that a well formed lease6 with tons of parameters can be added.
-TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
+void LeaseCmdsTest::testLease6AddNegativeCltt() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1768,14 +2528,105 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
 
     checkLease6Stats(99, 0, 0, 0);
 
-    // Now send the command.
+    // Add a lease with negative cltt (expiration time - valid lifetime)
     string txt =
         "{\n"
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
         "        \"ip-address\": \"2001:db8:1::3\",\n"
-        "        \"duid\": \"01:02:03:04:05:06:07:08\",\n"
+        "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"expire\": 123456,\n"
+        "        \"iaid\": 1234,\n"
+        "        \"valid-lft\": 123457"
+        "    }\n"
+        "}";
+    string exp_rsp = "expiration time must be greater than valid lifetime for "
+        "address 2001:db8:1::3";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+    checkLease6Stats(66, 0, 0, 0);
+
+    checkLease6Stats(99, 0, 0, 0);
+
+    // Now check that the lease was not added.
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
+    ASSERT_FALSE(l);
+}
+
+TEST_F(LeaseCmdsTest, lease6AddNegativeCltt) {
+    testLease6AddNegativeCltt();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddNegativeClttMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddNegativeCltt();
+}
+
+void LeaseCmdsTest::testLease6AddPrefix() {
+
+    // Initialize lease manager (true = v6, false = don't add leases)
+    initLeaseMgr(true, false);
+
+    checkLease6Stats(66, 0, 0, 0);
+
+    checkLease6Stats(99, 0, 0, 0);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease6-add\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"ip-address\": \"2001:db8:abcd::\",\n"
+        "        \"prefix-len\": 48,\n"
+        "        \"type\": \"IA_PD\",\n"
+        "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"iaid\": 1234\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "Lease for prefix 2001:db8:abcd::/48, subnet-id 66 added.";
+    testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    checkLease6Stats(66, 0, 0, 1);
+
+    checkLease6Stats(99, 0, 0, 0);
+
+    // Now check that the lease is really there.
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_PD, IOAddress("2001:db8:abcd::"));
+    ASSERT_TRUE(l);
+    EXPECT_EQ(Lease::TYPE_PD, l->type_);
+    EXPECT_EQ(48, l->prefixlen_);
+    EXPECT_EQ("", l->hostname_);
+    EXPECT_FALSE(l->getContext());
+}
+
+TEST_F(LeaseCmdsTest, lease6AddPrefix) {
+    testLease6AddPrefix();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddPrefixMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddPrefix();
+}
+
+void LeaseCmdsTest::testLease6AddFullAddr() {
+
+    // Initialize lease manager (true = v6, false = don't add leases)
+    initLeaseMgr(true, false);
+
+    checkLease6Stats(66, 0, 0, 0);
+
+    checkLease6Stats(99, 0, 0, 0);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease6-add\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"ip-address\": \"2001:db8:1::3\",\n"
+        "        \"duid\": \"01:02:03:04:05:06:07:08\",\n"
         "        \"iaid\": 1234,\n"
         "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
         "        \"preferred-lft\": 500,\n"
@@ -1812,8 +2663,16 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
     EXPECT_EQ("{ \"foobar\": true }", l->getContext()->str());
 }
 
-// Check that a well formed lease6 with a comment can be added.
-TEST_F(LeaseCmdsTest, Lease6AddComment) {
+TEST_F(LeaseCmdsTest, lease6AddFullAddr) {
+    testLease6AddFullAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddFullAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddFullAddr();
+}
+
+void LeaseCmdsTest::testLease6AddComment() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -1850,9 +2709,16 @@ TEST_F(LeaseCmdsTest, Lease6AddComment) {
     EXPECT_EQ("{ \"comment\": \"a comment\" }", l->getContext()->str());
 }
 
-// Checks that lease6-get can handle a situation when the query is
-// broken (some required parameters are missing).
-TEST_F(LeaseCmdsTest, Lease4GetMissingParams) {
+TEST_F(LeaseCmdsTest, lease6AddComment) {
+    testLease6AddComment();
+}
+
+TEST_F(LeaseCmdsTest, lease6AddCommentMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6AddComment();
+}
+
+void LeaseCmdsTest::testLease4GetMissingParams() {
 
     // No parameters whatsoever. You want just a lease, any lease?
     string cmd =
@@ -1927,8 +2793,16 @@ TEST_F(LeaseCmdsTest, Lease4GetMissingParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease4GetByAddrBadParam) {
+TEST_F(LeaseCmdsTest, lease4GetMissingParams) {
+    testLease4GetMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetMissingParams();
+}
+
+void LeaseCmdsTest::testLease4GetByAddrBadParam() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -1956,9 +2830,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByAddrBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get can handle a situation when the query is
-// valid, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4GetByAddrNotFound) {
+TEST_F(LeaseCmdsTest, lease4GetByAddrBadParam) {
+    testLease4GetByAddrBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByAddrBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByAddrBadParam();
+}
+
+void LeaseCmdsTest::testLease4GetByAddrNotFound() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -1976,8 +2857,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByAddrNotFound) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get can return a lease by address.
-TEST_F(LeaseCmdsTest, Lease4GetByAddr) {
+TEST_F(LeaseCmdsTest, lease4GetByAddrNotFound) {
+    testLease4GetByAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease4GetByAddr() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2002,9 +2891,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByAddr) {
     checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", true);
 }
 
-// Checks that lease4-get can handle a situation when the query is
-// well formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4GetByHWAddrNotFound) {
+TEST_F(LeaseCmdsTest, lease4GetByAddr) {
+    testLease4GetByAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByAddr();
+}
+
+void LeaseCmdsTest::testLease4GetByHWAddrNotFound() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -2023,8 +2919,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByHWAddrNotFound) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get can find a lease by hardware address.
-TEST_F(LeaseCmdsTest, Lease4GetByHWAddr) {
+TEST_F(LeaseCmdsTest, lease4GetByHWAddrNotFound) {
+    testLease4GetByHWAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByHWAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByHWAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease4GetByHWAddr() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2051,9 +2955,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByHWAddr) {
     checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
 }
 
-// Checks that lease6-get(addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6GetByAddr6NotFound) {
+TEST_F(LeaseCmdsTest, lease4GetByHWAddr) {
+    testLease4GetByHWAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByHWAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByHWAddr();
+}
+
+void LeaseCmdsTest::testLease6GetByAddrNotFound() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2074,9 +2985,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByAddr6NotFound) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get can handle a situation when the query is
-// well formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4GetByClientIdNotFound) {
+TEST_F(LeaseCmdsTest, lease6GetByAddrNotFound) {
+    testLease6GetByAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease4GetByClientIdNotFound() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -2095,8 +3013,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByClientIdNotFound) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Check that lease4-get can find a lease by client identifier.
-TEST_F(LeaseCmdsTest, Lease4GetByClientId) {
+TEST_F(LeaseCmdsTest, lease4GetByClientIdNotFound) {
+    testLease4GetByClientIdNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByClientIdNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByClientIdNotFound();
+}
+
+void LeaseCmdsTest::testLease4GetByClientId() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2122,8 +3048,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByClientId) {
     checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
 }
 
-// Checks that lease6-get rejects queries by client-id.
-TEST_F(LeaseCmdsTest, Lease6GetByClientIdInvalidType) {
+TEST_F(LeaseCmdsTest, lease4GetByClientId) {
+    testLease4GetByClientId();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByClientIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByClientId();
+}
+
+void LeaseCmdsTest::testLease6GetByClientIdInvalidType() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2142,9 +3076,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByClientIdInvalidType) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get(subnet-id, addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6GetByDuidNotFound) {
+TEST_F(LeaseCmdsTest, lease6GetByClientIdInvalidType) {
+    testLease6GetByClientIdInvalidType();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByClientIdInvalidTypeMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByClientIdInvalidType();
+}
+
+void LeaseCmdsTest::testLease6GetByDuidNotFound() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2166,9 +3107,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByDuidNotFound) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease6-get(subnet-id, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6GetByAddr) {
+TEST_F(LeaseCmdsTest, lease6GetByDuidNotFound) {
+    testLease6GetByDuidNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByDuidNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByDuidNotFound();
+}
+
+void LeaseCmdsTest::testLease6GetByAddr() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2194,8 +3142,100 @@ TEST_F(LeaseCmdsTest, Lease6GetByAddr) {
     checkLease6(lease, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
 }
 
-// Checks that lease6-get sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease6GetByAddrBadParam) {
+TEST_F(LeaseCmdsTest, lease6GetByAddr) {
+    testLease6GetByAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByAddr();
+}
+
+void LeaseCmdsTest::testLease6GetMissingParams() {
+
+    // No parameters whatsoever. You want just a lease, any lease?
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "    }\n"
+        "}";
+    string exp_rsp = "Mandatory 'subnet-id' parameter missing.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Just the subnet-id won't cut it, either.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123"
+        "    }\n"
+        "}";
+    exp_rsp = "No 'ip-address' provided and 'identifier-type' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // We can't identify your laptop by color. Sorry, buddy.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"color\",\n"
+        "        \"identifier\": \"blue\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "Incorrect identifier type: color, the only supported values are: "
+        "address, hw-address, duid";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Query by hw-address is not supported in v6. Sorry.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"hw-address\",\n"
+        "        \"identifier\": \"01:01:01:01:01:01\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "Query by hw-address is not allowed in v6.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Identifier value is missing.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"duid\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "No 'ip-address' provided and 'identifier' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Identifier-type is missing.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier\": \"01:02:03:04:05\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "No 'ip-address' provided and 'identifier-type' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease6GetMissingParams) {
+    testLease6GetMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetMissingParams();
+}
+
+void LeaseCmdsTest::testLease6GetByAddrBadParam() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2223,9 +3263,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByAddrBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get(subnet-id, type, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6GetByAddrPrefix) {
+TEST_F(LeaseCmdsTest, lease6GetByAddrBadParam) {
+    testLease6GetByAddrBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByAddrBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByAddrBadParam();
+}
+
+void LeaseCmdsTest::testLease6GetByAddrPrefix() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -2260,9 +3307,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByAddrPrefix) {
     checkLease6(lease, "2001:db8:1234:ab::", 56, 66, "77:77:77:77:77:77:77:77", false);
 }
 
-// Checks that lease6-get(subnet-id, iaid, identifier-type, identifier) can handle
-// a situation when the query returns a lease.
-TEST_F(LeaseCmdsTest, Lease6GetByDUID) {
+TEST_F(LeaseCmdsTest, lease6GetByAddrPrefix) {
+    testLease6GetByAddrPrefix();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByAddrPrefixMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByAddrPrefix();
+}
+
+void LeaseCmdsTest::testLease6GetByDuid() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2291,8 +3345,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByDUID) {
     checkLease6(lease, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
 }
 
-// Checks that lease4-get-all returns all leases.
-TEST_F(LeaseCmdsTest, Lease4GetAll) {
+TEST_F(LeaseCmdsTest, lease6GetByDuid) {
+    testLease6GetByDuid();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByDuidMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByDuid();
+}
+
+void LeaseCmdsTest::testLease4GetAll() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2323,8 +3385,16 @@ TEST_F(LeaseCmdsTest, Lease4GetAll) {
     checkLease4(leases, "192.0.3.2", 88, "09:09:09:09:09:09", true);
 }
 
-// Checks that lease4-get-all returns empty set if no leases are found.
-TEST_F(LeaseCmdsTest, Lease4GetAllNoLeases) {
+TEST_F(LeaseCmdsTest, lease4GetAll) {
+    testLease4GetAll();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetAll();
+}
+
+void LeaseCmdsTest::testLease4GetAllNoLeases() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -2351,8 +3421,16 @@ TEST_F(LeaseCmdsTest, Lease4GetAllNoLeases) {
     EXPECT_EQ(0, leases->size());
 }
 
-// Checks that lease4-get-all returns all leases for a subnet.
-TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetId) {
+TEST_F(LeaseCmdsTest, lease4GetAllNoLeases) {
+    testLease4GetAllNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetAllNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetAllNoLeases();
+}
+
+void LeaseCmdsTest::testLease4GetAllBySubnetId() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2385,8 +3463,16 @@ TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetId) {
     checkLease4(leases, "192.0.2.2", 44, "09:09:09:09:09:09", true);
 }
 
-// Checks that lease4-get-all returns empty set when no leases are found.
-TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetIdNoLeases) {
+TEST_F(LeaseCmdsTest, lease4GetAllBySubnetId) {
+    testLease4GetAllBySubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetAllBySubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetAllBySubnetId();
+}
+
+void LeaseCmdsTest::testLease4GetAllBySubnetIdNoLeases() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -2417,8 +3503,16 @@ TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetIdNoLeases) {
     EXPECT_EQ(0, leases->size());
 }
 
-// Checks that lease4-get-all returns leases from multiple subnets.
-TEST_F(LeaseCmdsTest, Lease4GetAllByMultipleSubnetIds) {
+TEST_F(LeaseCmdsTest, lease4GetAllBySubnetIdNoLeases) {
+    testLease4GetAllBySubnetIdNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetAllBySubnetIdNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetAllBySubnetIdNoLeases();
+}
+
+void LeaseCmdsTest::testLease4GetAllByMultipleSubnetIds() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2452,8 +3546,16 @@ TEST_F(LeaseCmdsTest, Lease4GetAllByMultipleSubnetIds) {
     checkLease4(leases, "192.0.3.2", 88, "09:09:09:09:09:09", true);
 }
 
-// Checks that lease4-get-all checks its input arguments.
-TEST_F(LeaseCmdsTest, Lease4GetBySubnetIdInvalidArguments) {
+TEST_F(LeaseCmdsTest, lease4GetAllByMultipleSubnetIds) {
+    testLease4GetAllByMultipleSubnetIds();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetAllByMultipleSubnetIdsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetAllByMultipleSubnetIds();
+}
+
+void LeaseCmdsTest::testLease4GetBySubnetIdInvalidArguments() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2492,8 +3594,16 @@ TEST_F(LeaseCmdsTest, Lease4GetBySubnetIdInvalidArguments) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that multiple calls to lease4-get-pages return all leases.
-TEST_F(LeaseCmdsTest, Lease4GetPaged) {
+TEST_F(LeaseCmdsTest, lease4GetBySubnetIdInvalidArguments) {
+    testLease4GetBySubnetIdInvalidArguments();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetBySubnetIdInvalidArgumentsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetBySubnetIdInvalidArguments();
+}
+
+void LeaseCmdsTest::testLease4GetPaged() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2584,9 +3694,16 @@ TEST_F(LeaseCmdsTest, Lease4GetPaged) {
     EXPECT_EQ(1, lease_addresses.count("192.0.3.2"));
 }
 
-// Verifies that first page of IPv4 leases can be retrieved by specifying
-// zero IPv4 address.
-TEST_F(LeaseCmdsTest, Lease4GetPagedZeroAddress) {
+TEST_F(LeaseCmdsTest, lease4GetPaged) {
+    testLease4GetPaged();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPaged();
+}
+
+void LeaseCmdsTest::testLease4GetPagedZeroAddress() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2605,8 +3722,16 @@ TEST_F(LeaseCmdsTest, Lease4GetPagedZeroAddress) {
     testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 }
 
-// Verifies that IPv6 address as a start address is rejected.
-TEST_F(LeaseCmdsTest, Lease4GetPagedIPv4Address) {
+TEST_F(LeaseCmdsTest, lease4GetPagedZeroAddress) {
+    testLease4GetPagedZeroAddress();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedZeroAddressMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedZeroAddress();
+}
+
+void LeaseCmdsTest::testLease4GetPagedIPv6Address() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -2625,8 +3750,128 @@ TEST_F(LeaseCmdsTest, Lease4GetPagedIPv4Address) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get-all returns all leases.
-TEST_F(LeaseCmdsTest, Lease6GetAll) {
+TEST_F(LeaseCmdsTest, lease4GetPagedIPv6Address) {
+    testLease4GetPagedIPv6Address();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedIPv6AddressMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedIPv6Address();
+}
+
+void LeaseCmdsTest::testLease4GetPagedInvalidFrom() {
+
+    // Initialize lease manager (false = v6, true = add leases)
+    initLeaseMgr(false, true);
+
+    // Query for a page of leases.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get-page\",\n"
+        "    \"arguments\": {"
+        "        \"from\": \"foo\","
+        "        \"limit\": 2"
+        "    }"
+        "}";
+
+    string exp_rsp = "'from' parameter value is neither 'start' keyword "
+        "nor a valid IPv4 address";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedInvalidFrom) {
+    testLease4GetPagedInvalidFrom();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedInvalidFromMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedInvalidFrom();
+}
+
+void LeaseCmdsTest::testLease4GetPagedNoLimit() {
+
+    // Initialize lease manager (false = v6, true = add leases)
+    initLeaseMgr(false, true);
+
+    // Query for a page of leases.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get-page\",\n"
+        "    \"arguments\": {"
+        "        \"from\": \"start\""
+        "    }"
+        "}";
+
+    string exp_rsp = "'limit' parameter not specified";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedNoLimit) {
+    testLease4GetPagedNoLimit();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedNoLimitMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedNoLimit();
+}
+
+void LeaseCmdsTest::testLease4GetPagedLimitNotNumber() {
+
+    // Initialize lease manager (false = v6, true = add leases)
+    initLeaseMgr(false, true);
+
+    // Query for a page of leases.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get-page\",\n"
+        "    \"arguments\": {"
+        "        \"from\": \"start\","
+        "        \"limit\": false"
+        "    }"
+        "}";
+
+    string exp_rsp = "'limit' parameter must be a number";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedLimitNotNumber) {
+    testLease4GetPagedLimitNotNumber();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedLimitNotNumberMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedLimitNotNumber();
+}
+
+void LeaseCmdsTest::testLease4GetPagedLimitIsZero() {
+
+    // Initialize lease manager (false = v6, true = add leases)
+    initLeaseMgr(false, true);
+
+    // Query for a page of leases.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get-page\",\n"
+        "    \"arguments\": {"
+        "        \"from\": \"start\","
+        "        \"limit\": 0"
+        "    }"
+        "}";
+
+    string exp_rsp = "page size of retrieved leases must not be 0";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedLimitIsZero) {
+    testLease4GetPagedLimitIsZero();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetPagedLimitIsZeroMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetPagedLimitIsZero();
+}
+
+void LeaseCmdsTest::testLease6GetAll() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2657,8 +3902,16 @@ TEST_F(LeaseCmdsTest, Lease6GetAll) {
     checkLease6(leases, "2001:db8:2::2", 0, 99, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease6-get-all returns empty set if no leases are found.
-TEST_F(LeaseCmdsTest, Lease6GetAllNoLeases) {
+TEST_F(LeaseCmdsTest, lease6GetAll) {
+    testLease6GetAll();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetAll();
+}
+
+void LeaseCmdsTest::testLease6GetAllNoLeases() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -2685,8 +3938,16 @@ TEST_F(LeaseCmdsTest, Lease6GetAllNoLeases) {
     EXPECT_EQ(0, leases->size());
 }
 
-// Checks that lease6-get-all returns all leases for a subnet.
-TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetId) {
+TEST_F(LeaseCmdsTest, lease6GetAllNoLeases) {
+    testLease6GetAllNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetAllNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetAllNoLeases();
+}
+
+void LeaseCmdsTest::testLease6GetAllBySubnetId() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2719,8 +3980,16 @@ TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetId) {
     checkLease6(leases, "2001:db8:1::2", 0, 66, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease6-get-all returns empty set when no leases are found.
-TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetIdNoLeases) {
+TEST_F(LeaseCmdsTest, lease6GetAllBySubnetId) {
+    testLease6GetAllBySubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetAllBySubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetAllBySubnetId();
+}
+
+void LeaseCmdsTest::testLease6GetAllBySubnetIdNoLeases() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -2751,8 +4020,16 @@ TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetIdNoLeases) {
     EXPECT_EQ(0, leases->size());
 }
 
-// Checks that lease6-get-all returns leases from multiple subnets.
-TEST_F(LeaseCmdsTest, Lease6GetAllByMultipleSubnetIds) {
+TEST_F(LeaseCmdsTest, lease6GetAllBySubnetIdNoLeases) {
+    testLease6GetAllBySubnetIdNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetAllBySubnetIdNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetAllBySubnetIdNoLeases();
+}
+
+void LeaseCmdsTest::testLease6GetAllByMultipleSubnetIds() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2786,8 +4063,16 @@ TEST_F(LeaseCmdsTest, Lease6GetAllByMultipleSubnetIds) {
     checkLease6(leases, "2001:db8:2::2", 0, 99, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease6-get-all checks its input arguments.
-TEST_F(LeaseCmdsTest, Lease6GetBySubnetIdInvalidArguments) {
+TEST_F(LeaseCmdsTest, lease6GetAllByMultipleSubnetIds) {
+    testLease6GetAllByMultipleSubnetIds();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetAllByMultipleSubnetIdsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetAllByMultipleSubnetIds();
+}
+
+void LeaseCmdsTest::testLease6GetBySubnetIdInvalidArguments() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2826,8 +4111,16 @@ TEST_F(LeaseCmdsTest, Lease6GetBySubnetIdInvalidArguments) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that multiple calls to lease6-get-page return all leases.
-TEST_F(LeaseCmdsTest, Lease6GetPaged) {
+TEST_F(LeaseCmdsTest, lease6GetBySubnetIdInvalidArguments) {
+    testLease6GetBySubnetIdInvalidArguments();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetBySubnetIdInvalidArgumentsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetBySubnetIdInvalidArguments();
+}
+
+void LeaseCmdsTest::testLease6GetPaged() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2919,9 +4212,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPaged) {
     EXPECT_EQ(1, lease_addresses.count("2001:db8:2::2"));
 }
 
-// Verifies that first page of IPv6 leases can be retrieved by specifying
-// zero IPv6 address.
-TEST_F(LeaseCmdsTest, Lease6GetPagedZeroAddress) {
+TEST_F(LeaseCmdsTest, lease6GetPaged) {
+    testLease6GetPaged();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPaged();
+}
+
+void LeaseCmdsTest::testLease6GetPagedZeroAddress() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2940,8 +4240,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedZeroAddress) {
     testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 }
 
-// Verifies that IPv4 address as a start address is rejected.
-TEST_F(LeaseCmdsTest, Lease6GetPagedIPv4Address) {
+TEST_F(LeaseCmdsTest, lease6GetPagedZeroAddress) {
+    testLease6GetPagedZeroAddress();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedZeroAddressMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedZeroAddress();
+}
+
+void LeaseCmdsTest::testLease6GetPagedIPv4Address() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2960,9 +4268,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedIPv4Address) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verifies that value of 'from' parameter other than 'start' or an IPv6
-// address is rejected.
-TEST_F(LeaseCmdsTest, Lease6GetPagedInvalidFrom) {
+TEST_F(LeaseCmdsTest, lease6GetPagedIPv4Address) {
+    testLease6GetPagedIPv4Address();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedIPv4AddressMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedIPv4Address();
+}
+
+void LeaseCmdsTest::testLease6GetPagedInvalidFrom() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -2982,8 +4297,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedInvalidFrom) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verifies that limit is mandatory.
-TEST_F(LeaseCmdsTest, Lease6GetPagedNoLimit) {
+TEST_F(LeaseCmdsTest, lease6GetPagedInvalidFrom) {
+    testLease6GetPagedInvalidFrom();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedInvalidFromMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedInvalidFrom();
+}
+
+void LeaseCmdsTest::testLease6GetPagedNoLimit() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -3001,8 +4324,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedNoLimit) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verifies that the limit must be a number.
-TEST_F(LeaseCmdsTest, Lease6GetPagedLimitNotNumber) {
+TEST_F(LeaseCmdsTest, lease6GetPagedNoLimit) {
+    testLease6GetPagedNoLimit();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedNoLimitMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedNoLimit();
+}
+
+void LeaseCmdsTest::testLease6GetPagedLimitNotNumber() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -3021,8 +4352,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedLimitNotNumber) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verifies that the limit of 0 is rejected.
-TEST_F(LeaseCmdsTest, Lease6GetPagedLimitIsZero) {
+TEST_F(LeaseCmdsTest, lease6GetPagedLimitNotNumber) {
+    testLease6GetPagedLimitNotNumber();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedLimitNotNumberMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedLimitNotNumber();
+}
+
+void LeaseCmdsTest::testLease6GetPagedLimitIsZero() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -3041,9 +4380,16 @@ TEST_F(LeaseCmdsTest, Lease6GetPagedLimitIsZero) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get-by-hw-address can handle a situation when
-// the query is broken (required parameter is missing).
-TEST_F(LeaseCmdsTest, LeaseGetByHwAddressParams) {
+TEST_F(LeaseCmdsTest, lease6GetPagedLimitIsZero) {
+    testLease6GetPagedLimitIsZero();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetPagedLimitIsZeroMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetPagedLimitIsZero();
+}
+
+void LeaseCmdsTest::testLeaseGetByHwAddressParams() {
 
     // No parameters whatsoever.
     string cmd =
@@ -3079,8 +4425,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByHwAddressParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get-by-hw-address works as expected (find no lease).
-TEST_F(LeaseCmdsTest, LeaseGetByHwAddressFind0) {
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressParams) {
+    testLeaseGetByHwAddressParams();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByHwAddressParams();
+}
+
+void LeaseCmdsTest::testLeaseGetByHwAddressFind0() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3097,8 +4451,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByHwAddressFind0) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get-by-hw-address works as expected (find two leases).
-TEST_F(LeaseCmdsTest, LeaseGetByHwAddressFind2) {
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressFind0) {
+    testLeaseGetByHwAddressFind0();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressFind0MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByHwAddressFind0();
+}
+
+void LeaseCmdsTest::testLeaseGetByHwAddressFind2() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3133,9 +4495,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByHwAddressFind2) {
     checkLease4(lease, "192.0.3.1", 88, "08:08:08:08:08:08", false);
 }
 
-// Checks that lease4-get-by-client-id can handle a situation when
-// the query is broken (required parameter is missing).
-TEST_F(LeaseCmdsTest, LeaseGetByClientIdParams) {
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressFind2) {
+    testLeaseGetByHwAddressFind2();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByHwAddressFind2MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByHwAddressFind2();
+}
+
+void LeaseCmdsTest::testLeaseGetByClientIdParams() {
 
     // No parameters whatsoever.
     string cmd =
@@ -3171,8 +4540,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByClientIdParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get-by-client-id works as expected (find no lease).
-TEST_F(LeaseCmdsTest, LeaseGetByClientIdFind0) {
+TEST_F(LeaseCmdsTest, leaseGetByClientIdParams) {
+    testLeaseGetByClientIdParams();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByClientIdParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByClientIdParams();
+}
+
+void LeaseCmdsTest::testLeaseGetByClientIdFind0() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3189,8 +4566,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByClientIdFind0) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get-by-client-id works as expected (find two leases).
-TEST_F(LeaseCmdsTest, LeaseGetByClientIdFind2) {
+TEST_F(LeaseCmdsTest, leaseGetByClientIdFind0) {
+    testLeaseGetByClientIdFind0();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByClientIdFind0MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByClientIdFind0();
+}
+
+void LeaseCmdsTest::testLeaseGetByClientIdFind2() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3225,9 +4610,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByClientIdFind2) {
     checkLease4(lease, "192.0.3.1", 88, "08:08:08:08:08:08", false);
 }
 
-// Checks that lease6-get-by-duid can handle a situation when
-// the query is broken (required parameter is missing).
-TEST_F(LeaseCmdsTest, LeaseGetByDuidParams) {
+TEST_F(LeaseCmdsTest, leaseGetByClientIdFind2) {
+    testLeaseGetByClientIdFind2();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByClientIdFind2MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByClientIdFind2();
+}
+
+void LeaseCmdsTest::testLeaseGetByDuidParams() {
 
     // No parameters whatsoever.
     string cmd =
@@ -3263,8 +4655,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByDuidParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get-by-duid works as expected (find no lease).
-TEST_F(LeaseCmdsTest, LeaseGetByDuidFind0) {
+TEST_F(LeaseCmdsTest, leaseGetByDuidParams) {
+    testLeaseGetByDuidParams();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByDuidParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByDuidParams();
+}
+
+void LeaseCmdsTest::testLeaseGetByDuidFind0() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -3281,8 +4681,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByDuidFind0) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease6-get-by-duid works as expected (find two leases).
-TEST_F(LeaseCmdsTest, LeaseGetByDuidFind2) {
+TEST_F(LeaseCmdsTest, leaseGetByDuidFind0) {
+    testLeaseGetByDuidFind0();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByDuidFind0MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByDuidFind0();
+}
+
+void LeaseCmdsTest::testLeaseGetByDuidFind2() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -3317,9 +4725,16 @@ TEST_F(LeaseCmdsTest, LeaseGetByDuidFind2) {
     checkLease6(lease, "2001:db8:2::1", 0, 99, "42:42:42:42:42:42:42:42", false);
 }
 
-// Checks that lease4-get-by-hostname can handle a situation when
-// the query is broken (required parameter is missing).
-TEST_F(LeaseCmdsTest, Lease4GetByHostnameParams) {
+TEST_F(LeaseCmdsTest, leaseGetByDuidFind2) {
+    testLeaseGetByDuidFind2();
+}
+
+TEST_F(LeaseCmdsTest, leaseGetByDuidFind2MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseGetByDuidFind2();
+}
+
+void LeaseCmdsTest::testLease4GetByHostnameParams() {
 
     // No parameters whatsoever.
     string cmd =
@@ -3354,8 +4769,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByHostnameParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-get-by-hostname works as expected (find no lease).
-TEST_F(LeaseCmdsTest, Lease4GetByHostnameFind0) {
+TEST_F(LeaseCmdsTest, lease4GetByHostnameParams) {
+    testLease4GetByHostnameParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByHostnameParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByHostnameParams();
+}
+
+void LeaseCmdsTest::testLease4GetByHostnameFind0() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3372,8 +4795,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByHostnameFind0) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-get-by-hostname works as expected (find two leases).
-TEST_F(LeaseCmdsTest, Lease4GetByHostnameFind2) {
+TEST_F(LeaseCmdsTest, lease4GetByHostnameFind0) {
+    testLease4GetByHostnameFind0();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByHostnameFind0MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByHostnameFind0();
+}
+
+void LeaseCmdsTest::testLease4GetByHostnameFind2() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3408,9 +4839,16 @@ TEST_F(LeaseCmdsTest, Lease4GetByHostnameFind2) {
     checkLease4(lease, "192.0.3.1", 88, "08:08:08:08:08:08", false);
 }
 
-// Checks that lease6-get-by-hostname can handle a situation when
-// the query is broken (required parameter is missing).
-TEST_F(LeaseCmdsTest, Lease6GetByHostnameParams) {
+TEST_F(LeaseCmdsTest, lease4GetByHostnameFind2) {
+    testLease4GetByHostnameFind2();
+}
+
+TEST_F(LeaseCmdsTest, lease4GetByHostnameFind2MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4GetByHostnameFind2();
+}
+
+void LeaseCmdsTest::testLease6GetByHostnameParams() {
 
     // No parameters whatsoever.
     string cmd =
@@ -3445,8 +4883,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByHostnameParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get-by-hostname works as expected (find no lease).
-TEST_F(LeaseCmdsTest, Lease6GetByHostnameFind0) {
+TEST_F(LeaseCmdsTest, lease6GetByHostnameParams) {
+    testLease6GetByHostnameParams();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByHostnameParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByHostnameParams();
+}
+
+void LeaseCmdsTest::testLease6GetByHostnameFind0() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -3463,8 +4909,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByHostnameFind0) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease6-get-by-hostname works as expected (find two leases).
-TEST_F(LeaseCmdsTest, Lease6GetByHostnameFind2) {
+TEST_F(LeaseCmdsTest, lease6GetByHostnameFind0) {
+    testLease6GetByHostnameFind0();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByHostnameFind0MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByHostnameFind0();
+}
+
+void LeaseCmdsTest::testLease6GetByHostnameFind2() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -3499,8 +4953,16 @@ TEST_F(LeaseCmdsTest, Lease6GetByHostnameFind2) {
     checkLease6(lease, "2001:db8:2::1", 0, 99, "42:42:42:42:42:42:42:42", false);
 }
 
-// Test checks if lease4-update handler refuses calls with missing parameters.
-TEST_F(LeaseCmdsTest, Lease4UpdateMissingParams) {
+TEST_F(LeaseCmdsTest, lease6GetByHostnameFind2) {
+    testLease6GetByHostnameFind2();
+}
+
+TEST_F(LeaseCmdsTest, lease6GetByHostnameFind2MultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6GetByHostnameFind2();
+}
+
+void LeaseCmdsTest::testLease4UpdateMissingParams() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3552,9 +5014,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateMissingParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Verify that lease4-update can be rejected if parameters are specified, but
-// have incorrect values.
-TEST_F(LeaseCmdsTest, Lease4UpdateBadParams) {
+TEST_F(LeaseCmdsTest, lease4UpdateMissingParams) {
+    testLease4UpdateMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateMissingParams();
+}
+
+void LeaseCmdsTest::testLease4UpdateBadParams() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3630,9 +5099,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateBadParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Check that lease4-update correctly handles case when there is
-// no lease to be updated.
-TEST_F(LeaseCmdsTest, Lease4UpdateNoLease) {
+TEST_F(LeaseCmdsTest, lease4UpdateBadParams) {
+    testLease4UpdateBadParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateBadParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateBadParams();
+}
+
+void LeaseCmdsTest::testLease4UpdateNoLease() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3654,9 +5130,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateNoLease) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Check that a lease4 can be updated. We're changing hw-address
-// and a hostname.
-TEST_F(LeaseCmdsTest, Lease4Update) {
+TEST_F(LeaseCmdsTest, lease4UpdateNoLease) {
+    testLease4UpdateNoLease();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateNoLeaseMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateNoLease();
+}
+
+void LeaseCmdsTest::testLease4Update() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3694,9 +5177,16 @@ TEST_F(LeaseCmdsTest, Lease4Update) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease4 can be updated. We're changing hw-address
-// and a hostname.
-TEST_F(LeaseCmdsTest, Lease4UpdateDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease4Update) {
+    testLease4Update();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4Update();
+}
+
+void LeaseCmdsTest::testLease4UpdateDeclinedLeases() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true, true);
@@ -3734,9 +5224,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateDeclinedLeases) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease4 can be updated. We're changing hw-address
-// and a hostname. The subnet-id is not specified.
-TEST_F(LeaseCmdsTest, Lease4UpdateNoSubnetId) {
+TEST_F(LeaseCmdsTest, lease4UpdateDeclinedLeases) {
+    testLease4UpdateDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease4UpdateNoSubnetId() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3773,9 +5270,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateNoSubnetId) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease4 can be updated. We're changing hw-address
-// and a hostname. The subnet-id is not specified.
-TEST_F(LeaseCmdsTest, Lease4UpdateNoSubnetIdDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease4UpdateNoSubnetId) {
+    testLease4UpdateNoSubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateNoSubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateNoSubnetId();
+}
+
+void LeaseCmdsTest::testLease4UpdateNoSubnetIdDeclinedLeases() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true, true);
@@ -3812,10 +5316,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateNoSubnetIdDeclinedLeases) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease4 is created if it doesn't exist during the update.
-// To trigger this behavior 'force-create' boolean parameter must be
-// included in the command.
-TEST_F(LeaseCmdsTest, Lease4UpdateForceCreate) {
+TEST_F(LeaseCmdsTest, lease4UpdateNoSubnetIdDeclinedLeases) {
+    testLease4UpdateNoSubnetIdDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateNoSubnetIdDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateNoSubnetIdDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease4UpdateForceCreate() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3854,11 +5364,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateForceCreate) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease4 is created if it doesn't exist during the update.
-// To trigger this behavior 'force-create' boolean parameter must be
-// included in the command. The subnet-id is not specified, Kea will
-// figure it out.
-TEST_F(LeaseCmdsTest, Lease4UpdateForceCreateNoSubnetId) {
+TEST_F(LeaseCmdsTest, lease4UpdateForceCreate) {
+    testLease4UpdateForceCreate();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateForceCreateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateForceCreate();
+}
+
+void LeaseCmdsTest::testLease4UpdateForceCreateNoSubnetId() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3899,9 +5414,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateForceCreateNoSubnetId) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that lease4-update correctly handles case when the 'force-create'
-// parameter is explicitly set to false.
-TEST_F(LeaseCmdsTest, Lease4UpdateDoNotForceCreate) {
+TEST_F(LeaseCmdsTest, lease4UpdateForceCreateNoSubnetId) {
+    testLease4UpdateForceCreateNoSubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateForceCreateNoSubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateForceCreateNoSubnetId();
+}
+
+void LeaseCmdsTest::testLease4UpdateDoNotForceCreate() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -3932,9 +5454,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateDoNotForceCreate) {
     checkLease4Stats(88, 0, 0);
 }
 
-// Check that a lease4 can be updated. We're adding a comment and an user
-// context.
-TEST_F(LeaseCmdsTest, Lease4UpdateComment) {
+TEST_F(LeaseCmdsTest, lease4UpdateDoNotForceCreate) {
+    testLease4UpdateDoNotForceCreate();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateDoNotForceCreateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateDoNotForceCreate();
+}
+
+void LeaseCmdsTest::testLease4UpdateComment() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -3980,8 +5509,16 @@ TEST_F(LeaseCmdsTest, Lease4UpdateComment) {
     EXPECT_EQ("true", ctx->get("foobar")->str());
 }
 
-// Test checks if lease6-update handler refuses calls with missing parameters.
-TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
+TEST_F(LeaseCmdsTest, lease4UpdateComment) {
+    testLease4UpdateComment();
+}
+
+TEST_F(LeaseCmdsTest, lease4UpdateCommentMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4UpdateComment();
+}
+
+void LeaseCmdsTest::testLease6UpdateMissingParams() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4013,7 +5550,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
         "{\n"
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
-        "            \"subnet-id\": 44,\n"
+        "            \"subnet-id\": 66,\n"
         "            \"ip-address\": \"2001:db8:1::1\"\n"
         "    }\n"
         "}";
@@ -4025,17 +5562,50 @@ TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
         "{\n"
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
-        "            \"subnet-id\": 44,\n"
+        "            \"subnet-id\": 66,\n"
         "            \"duid\": \"1a:1b:1c:1d:1e:1f\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'ip-address' (<string>:3:19)";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Just subnet-id, duid and iaid is not enough (ip missing).
+    txt =
+        "{\n"
+        "    \"command\": \"lease6-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"iaid\": 1234\n"
+        "    }\n"
+        "}";
+    exp_rsp = "missing parameter 'ip-address' (<string>:3:19)";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Close, but no cigars. Still missing iaid.
+    txt =
+        "{\n"
+        "    \"command\": \"lease6-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "missing parameter 'iaid' (<string>:3:19)";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateMissingParams) {
+    testLease6UpdateMissingParams();
 }
 
-// Verify that lease6-update can be rejected if parameters are specified, but
-// have incorrect values.
-TEST_F(LeaseCmdsTest, Lease6UpdateBadParams) {
+TEST_F(LeaseCmdsTest, lease6UpdateMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateMissingParams();
+}
+
+void LeaseCmdsTest::testLease6UpdateBadParams() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4130,9 +5700,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateBadParams) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Check that a lease6 can be updated. We're changing hw-address
-// and a hostname.
-TEST_F(LeaseCmdsTest, Lease6Update) {
+TEST_F(LeaseCmdsTest, lease6UpdateBadParams) {
+    testLease6UpdateBadParams();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateBadParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateBadParams();
+}
+
+void LeaseCmdsTest::testLease6Update() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4172,9 +5749,16 @@ TEST_F(LeaseCmdsTest, Lease6Update) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease6 can be updated. We're changing hw-address
-// and a hostname.
-TEST_F(LeaseCmdsTest, Lease6UpdateDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease6Update) {
+    testLease6Update();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6Update();
+}
+
+void LeaseCmdsTest::testLease6UpdateDeclinedLeases() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true, true);
@@ -4214,9 +5798,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateDeclinedLeases) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease6 can be updated. We're changing hw-address
-// and a hostname. The subnet-id is not specified.
-TEST_F(LeaseCmdsTest, Lease6UpdateNoSubnetId) {
+TEST_F(LeaseCmdsTest, lease6UpdateDeclinedLeases) {
+    testLease6UpdateDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease6UpdateNoSubnetId() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4258,9 +5849,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoSubnetId) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease6 can be updated. We're changing hw-address
-// and a hostname. The subnet-id is not specified.
-TEST_F(LeaseCmdsTest, Lease6UpdateNoSubnetIdDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease6UpdateNoSubnetId) {
+    testLease6UpdateNoSubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateNoSubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateNoSubnetId();
+}
+
+void LeaseCmdsTest::testLease6UpdateNoSubnetIdDeclinedLeases() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true, true);
@@ -4302,9 +5900,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoSubnetIdDeclinedLeases) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease6 can be updated. We're adding a comment and an user
-// context.
-TEST_F(LeaseCmdsTest, Lease6UpdateComment) {
+TEST_F(LeaseCmdsTest, lease6UpdateNoSubnetIdDeclinedLeases) {
+    testLease6UpdateNoSubnetIdDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateNoSubnetIdDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateNoSubnetIdDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease6UpdateComment() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4350,9 +5955,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateComment) {
     EXPECT_EQ("true", ctx->get("foobar")->str());
 }
 
-// Check that lease6-update correctly handles case when there is
-// no lease to be updated.
-TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
+TEST_F(LeaseCmdsTest, lease6UpdateComment) {
+    testLease6UpdateComment();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateCommentMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateComment();
+}
+
+void LeaseCmdsTest::testLease6UpdateNoLease() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -4383,10 +5995,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
     checkLease6Stats(99, 0, 0, 0);
 }
 
-// Check that a lease6 is created if it doesn't exist during the update.
-// To trigger this behavior 'force-create' boolean parameter must be
-// included in the command.
-TEST_F(LeaseCmdsTest, Lease6UpdateForceCreate) {
+TEST_F(LeaseCmdsTest, lease6UpdateNoLease) {
+    testLease6UpdateNoLease();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateNoLeaseMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateNoLease();
+}
+
+void LeaseCmdsTest::testLease6UpdateForceCreate() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -4427,11 +6045,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateForceCreate) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that a lease6 is created if it doesn't exist during the update.
-// To trigger this behavior 'force-create' boolean parameter must be
-// included in the command. The subnet-id is not specified, Kea will
-// figure it out.
-TEST_F(LeaseCmdsTest, Lease6UpdateForceCreateNoSubnetId) {
+TEST_F(LeaseCmdsTest, lease6UpdateForceCreate) {
+    testLease6UpdateForceCreate();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateForceCreateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateForceCreate();
+}
+
+void LeaseCmdsTest::testLease6UpdateForceCreateNoSubnetId() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -4474,9 +6097,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateForceCreateNoSubnetId) {
     EXPECT_FALSE(l->getContext());
 }
 
-// Check that lease6-update correctly handles case when the 'force-create'
-// parameter is explicitly set to false.
-TEST_F(LeaseCmdsTest, Lease6UpdateDoNotForceCreate) {
+TEST_F(LeaseCmdsTest, lease6UpdateForceCreateNoSubnetId) {
+    testLease6UpdateForceCreateNoSubnetId();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateForceCreateNoSubnetIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateForceCreateNoSubnetId();
+}
+
+void LeaseCmdsTest::testLease6UpdateDoNotForceCreate() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -4508,9 +6138,16 @@ TEST_F(LeaseCmdsTest, Lease6UpdateDoNotForceCreate) {
     checkLease6Stats(99, 0, 0, 0);
 }
 
-// Checks that lease6-del can handle a situation when the query is
-// broken (some required parameters are missing).
-TEST_F(LeaseCmdsTest, Lease4DelMissingParams) {
+TEST_F(LeaseCmdsTest, lease6UpdateDoNotForceCreate) {
+    testLease6UpdateDoNotForceCreate();
+}
+
+TEST_F(LeaseCmdsTest, lease6UpdateDoNotForceCreateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6UpdateDoNotForceCreate();
+}
+
+void LeaseCmdsTest::testLease4DelMissingParams() {
 
     // No parameters whatsoever. You want just a lease, any lease?
     string cmd =
@@ -4585,9 +6222,16 @@ TEST_F(LeaseCmdsTest, Lease4DelMissingParams) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-del can handle a situation when the query is
-// valid, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4DelByAddrNotFound) {
+TEST_F(LeaseCmdsTest, lease4DelMissingParams) {
+    testLease4DelMissingParams();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelMissingParams();
+}
+
+void LeaseCmdsTest::testLease4DelByAddrNotFound() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4613,8 +6257,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByAddrNotFound) {
     checkLease4Stats(88, 2, 0);
 }
 
-// Checks that lease4-del can return a lease by address.
-TEST_F(LeaseCmdsTest, Lease4DelByAddr) {
+TEST_F(LeaseCmdsTest, lease4DelByAddrNotFound) {
+    testLease4DelByAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease4DelByAddr() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4642,8 +6294,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByAddr) {
     EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
 }
 
-// Checks that lease4-del can return a lease by address.
-TEST_F(LeaseCmdsTest, Lease4DelByAddrDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease4DelByAddr) {
+    testLease4DelByAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByAddr();
+}
+
+void LeaseCmdsTest::testLease4DelByAddrDeclinedLeases() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true, true);
@@ -4671,8 +6331,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByAddrDeclinedLeases) {
     EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
 }
 
-// Checks that leaseX-del checks update-ddns input
-TEST_F(LeaseCmdsTest, LeaseXDelBadUpdateDdnsParam) {
+TEST_F(LeaseCmdsTest, lease4DelByAddrDeclinedLeases) {
+    testLease4DelByAddrDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByAddrDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByAddrDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLeaseXDelBadUpdateDdnsParam() {
 
     string cmd =
         "{\n"
@@ -4699,8 +6367,16 @@ TEST_F(LeaseCmdsTest, LeaseXDelBadUpdateDdnsParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-del sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease4DelByAddrBadParam) {
+TEST_F(LeaseCmdsTest, leaseXDelBadUpdateDdnsParam) {
+    testLeaseXDelBadUpdateDdnsParam();
+}
+
+TEST_F(LeaseCmdsTest, leaseXDelBadUpdateDdnsParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLeaseXDelBadUpdateDdnsParam();
+}
+
+void LeaseCmdsTest::testLease4DelByAddrBadParam() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4736,9 +6412,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByAddrBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-del can handle a situation when the query is
-// well formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4DelByHWAddrNotFound) {
+TEST_F(LeaseCmdsTest, lease4DelByAddrBadParam) {
+    testLease4DelByAddrBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByAddrBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByAddrBadParam();
+}
+
+void LeaseCmdsTest::testLease4DelByHWAddrNotFound() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4768,8 +6451,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByHWAddrNotFound) {
     EXPECT_TRUE(lmptr_->getLease4(IOAddress("192.0.2.1")));
 }
 
-// Checks that lease4-del can find a lease by hardware address.
-TEST_F(LeaseCmdsTest, Lease4DelByHWAddr) {
+TEST_F(LeaseCmdsTest, lease4DelByHWAddrNotFound) {
+    testLease4DelByHWAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByHWAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByHWAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease4DelByHWAddr() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4799,9 +6490,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByHWAddr) {
     EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
 }
 
-// Checks that lease4-del can handle a situation when the query is
-// well formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4DelByClientIdNotFound) {
+TEST_F(LeaseCmdsTest, lease4DelByHWAddr) {
+    testLease4DelByHWAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByHWAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByHWAddr();
+}
+
+void LeaseCmdsTest::testLease4DelByClientIdNotFound() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4831,8 +6529,16 @@ TEST_F(LeaseCmdsTest, Lease4DelByClientIdNotFound) {
     EXPECT_TRUE(lmptr_->getLease4(IOAddress("192.0.2.1")));
 }
 
-// Checks that lease4-del can find and delete a lease by client identifier.
-TEST_F(LeaseCmdsTest, Lease4DelByClientId) {
+TEST_F(LeaseCmdsTest, lease4DelByClientIdNotFound) {
+    testLease4DelByClientIdNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByClientIdNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByClientIdNotFound();
+}
+
+void LeaseCmdsTest::testLease4DelByClientId() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -4841,30 +6547,121 @@ TEST_F(LeaseCmdsTest, Lease4DelByClientId) {
 
     checkLease4Stats(88, 2, 0);
 
-    // Invalid
-    string cmd =
+    // Invalid
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-del\",\n"
+        "    \"arguments\": {"
+        "        \"identifier-type\": \"client-id\","
+        "        \"identifier\": \"42:42:42:42:42:42:42:42\","
+        "        \"subnet-id\": 44"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv4 lease deleted.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    checkLease4Stats(44, 1, 0);
+
+    checkLease4Stats(88, 2, 0);
+
+    // Make sure the lease is really gone.
+    EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByClientId) {
+    testLease4DelByClientId();
+}
+
+TEST_F(LeaseCmdsTest, lease4DelByClientIdMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DelByClientId();
+}
+
+void LeaseCmdsTest::testLease6DelMissingParams() {
+
+    // No parameters whatsoever. You want just a lease, any lease?
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-del\",\n"
+        "    \"arguments\": {"
+        "    }\n"
+        "}";
+    string exp_rsp = "Mandatory 'subnet-id' parameter missing.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Just the subnet-id won't cut it, either.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-del\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123"
+        "    }\n"
+        "}";
+    exp_rsp = "No 'ip-address' provided and 'identifier-type' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // We can't identify your laptop by color. Sorry, buddy.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-del\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"color\",\n"
+        "        \"identifier\": \"blue\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "Incorrect identifier type: color, the only supported values are: "
+        "address, hw-address, duid";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Query by hw-address is not supported in v6. Sorry.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-del\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"hw-address\",\n"
+        "        \"identifier\": \"01:01:01:01:01:01\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "Delete by hw-address is not allowed in v6.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // Identifier value is missing.
+    cmd =
         "{\n"
-        "    \"command\": \"lease4-del\",\n"
+        "    \"command\": \"lease6-del\",\n"
         "    \"arguments\": {"
-        "        \"identifier-type\": \"client-id\","
-        "        \"identifier\": \"42:42:42:42:42:42:42:42\","
-        "        \"subnet-id\": 44"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier-type\": \"hw-address\"\n"
         "    }\n"
         "}";
-    string exp_rsp = "IPv4 lease deleted.";
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    exp_rsp = "No 'ip-address' provided and 'identifier' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 
-    checkLease4Stats(44, 1, 0);
+    // Identifier-type is missing.
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-del\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 123,\n"
+        "        \"identifier\": \"01:02:03:04:05\"\n"
+        "    }\n"
+        "}";
+    exp_rsp = "No 'ip-address' provided and 'identifier-type' is either missing or not a string.";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
 
-    checkLease4Stats(88, 2, 0);
+TEST_F(LeaseCmdsTest, lease6DelMissingParams) {
+    testLease6DelMissingParams();
+}
 
-    // Make sure the lease is really gone.
-    EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
+TEST_F(LeaseCmdsTest, lease6DelMissingParamsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelMissingParams();
 }
 
-// Checks that lease6-del(addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6DelByAddr6NotFound) {
+void LeaseCmdsTest::testLease6DelByAddrNotFound() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4893,9 +6690,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddr6NotFound) {
     checkLease6Stats(99, 2, 0, 0);
 }
 
-// Checks that lease6-del(subnet-id, addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6DelByDuidNotFound) {
+TEST_F(LeaseCmdsTest, lease6DelByAddrNotFound) {
+    testLease6DelByAddrNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByAddrNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByAddrNotFound();
+}
+
+void LeaseCmdsTest::testLease6DelByDuidNotFound() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4928,9 +6732,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByDuidNotFound) {
     EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
-// Checks that lease6-del(subnet-id, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6DelByAddr) {
+TEST_F(LeaseCmdsTest, lease6DelByDuidNotFound) {
+    testLease6DelByDuidNotFound();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByDuidNotFoundMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByDuidNotFound();
+}
+
+void LeaseCmdsTest::testLease6DelByAddr() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -4961,9 +6772,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddr) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
-// Checks that lease6-del(subnet-id, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6DelByAddrDeclinedLeases) {
+TEST_F(LeaseCmdsTest, lease6DelByAddr) {
+    testLease6DelByAddr();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByAddrMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByAddr();
+}
+
+void LeaseCmdsTest::testLease6DelByAddrDeclinedLeases() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true, true);
@@ -4994,8 +6812,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddrDeclinedLeases) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
-// Checks that lease6-del sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease6DelByAddrBadParam) {
+TEST_F(LeaseCmdsTest, lease6DelByAddrDeclinedLeases) {
+    testLease6DelByAddrDeclinedLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByAddrDeclinedLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByAddrDeclinedLeases();
+}
+
+void LeaseCmdsTest::testLease6DelByAddrBadParam() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5023,9 +6849,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddrBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-del(subnet-id, type, addr6) can handle a situation when
-// the query is correctly formed and the lease is deleted.
-TEST_F(LeaseCmdsTest, Lease6DelByAddrPrefix) {
+TEST_F(LeaseCmdsTest, lease6DelByAddrBadParam) {
+    testLease6DelByAddrBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByAddrBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByAddrBadParam();
+}
+
+void LeaseCmdsTest::testLease6DelByAddrPrefix() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5071,9 +6904,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddrPrefix) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_PD, IOAddress("2001:db8:1234:ab::")));
 }
 
-// Checks that lease6-del(subnet-id, iaid, identifier-type, identifier) can handle
-// a situation when the query finds a lease.
-TEST_F(LeaseCmdsTest, Lease6DelByDUID) {
+TEST_F(LeaseCmdsTest, lease6DelByAddrPrefix) {
+    testLease6DelByAddrPrefix();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByAddrPrefixMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByAddrPrefix();
+}
+
+void LeaseCmdsTest::testLease6DelByDuid() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5106,8 +6946,16 @@ TEST_F(LeaseCmdsTest, Lease6DelByDUID) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
-// Checks that lease4-wipe can remove leases.
-TEST_F(LeaseCmdsTest, Lease4Wipe) {
+TEST_F(LeaseCmdsTest, lease6DelByDuid) {
+    testLease6DelByDuid();
+}
+
+TEST_F(LeaseCmdsTest, lease6DelByDuidMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DelByDuid();
+}
+
+void LeaseCmdsTest::testLease4Wipe() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5140,9 +6988,16 @@ TEST_F(LeaseCmdsTest, Lease4Wipe) {
     EXPECT_TRUE(lmptr_->getLease4(IOAddress("192.0.3.2")));
 }
 
-// Checks that lease4-wipe can remove leases from all subnets
-// at once.
-TEST_F(LeaseCmdsTest, Lease4WipeAll) {
+TEST_F(LeaseCmdsTest, lease4Wipe) {
+    testLease4Wipe();
+}
+
+TEST_F(LeaseCmdsTest, lease4WipeMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4Wipe();
+}
+
+void LeaseCmdsTest::testLease4WipeAll() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5175,9 +7030,16 @@ TEST_F(LeaseCmdsTest, Lease4WipeAll) {
     EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.3.2")));
 }
 
-// Checks that lease4-wipe can remove leases from all subnets
-// at once (when no parameters are specifed).
-TEST_F(LeaseCmdsTest, Lease4WipeAllNoArgs) {
+TEST_F(LeaseCmdsTest, lease4WipeAll) {
+    testLease4WipeAll();
+}
+
+TEST_F(LeaseCmdsTest, lease4WipeAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4WipeAll();
+}
+
+void LeaseCmdsTest::testLease4WipeAllNoArgs() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5207,8 +7069,16 @@ TEST_F(LeaseCmdsTest, Lease4WipeAllNoArgs) {
     EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.3.2")));
 }
 
-// Checks that lease4-wipe properly reports when no leases were deleted.
-TEST_F(LeaseCmdsTest, Lease4WipeNoLeases) {
+TEST_F(LeaseCmdsTest, lease4WipeAllNoArgs) {
+    testLease4WipeAllNoArgs();
+}
+
+TEST_F(LeaseCmdsTest, lease4WipeAllNoArgsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4WipeAllNoArgs();
+}
+
+void LeaseCmdsTest::testLease4WipeNoLeases() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -5233,8 +7103,16 @@ TEST_F(LeaseCmdsTest, Lease4WipeNoLeases) {
     checkLease4Stats(88, 0, 0);
 }
 
-// Checks that lease4-wipe properly reports when no leases were deleted.
-TEST_F(LeaseCmdsTest, Lease4WipeNoLeasesAll) {
+TEST_F(LeaseCmdsTest, lease4WipeNoLeases) {
+    testLease4WipeNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease4WipeNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4WipeNoLeases();
+}
+
+void LeaseCmdsTest::testLease4WipeNoLeasesAll() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -5259,8 +7137,16 @@ TEST_F(LeaseCmdsTest, Lease4WipeNoLeasesAll) {
     checkLease4Stats(88, 0, 0);
 }
 
-// Checks that lease4-wipe can remove leases.
-TEST_F(LeaseCmdsTest, Lease6Wipe) {
+TEST_F(LeaseCmdsTest, lease4WipeNoLeasesAll) {
+    testLease4WipeNoLeasesAll();
+}
+
+TEST_F(LeaseCmdsTest, lease4WipeNoLeasesAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4WipeNoLeasesAll();
+}
+
+void LeaseCmdsTest::testLease6Wipe() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5295,8 +7181,16 @@ TEST_F(LeaseCmdsTest, Lease6Wipe) {
     EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:2::2")));
 }
 
-// Checks that lease4-wipe can remove leases from all subnets
-TEST_F(LeaseCmdsTest, Lease6WipeAll) {
+TEST_F(LeaseCmdsTest, lease6Wipe) {
+    testLease6Wipe();
+}
+
+TEST_F(LeaseCmdsTest, lease6WipeMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6Wipe();
+}
+
+void LeaseCmdsTest::testLease6WipeAll() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5331,9 +7225,16 @@ TEST_F(LeaseCmdsTest, Lease6WipeAll) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:2::2")));
 }
 
-// Checks that lease4-wipe can remove leases from all subnets
-// (no arguments)
-TEST_F(LeaseCmdsTest, Lease6WipeAllNoArgs) {
+TEST_F(LeaseCmdsTest, lease6WipeAll) {
+    testLease6WipeAll();
+}
+
+TEST_F(LeaseCmdsTest, lease6WipeAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6WipeAll();
+}
+
+void LeaseCmdsTest::testLease6WipeAllNoArgs() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5365,8 +7266,16 @@ TEST_F(LeaseCmdsTest, Lease6WipeAllNoArgs) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:2::2")));
 }
 
-// Checks that lease4-wipe properly reports when no leases were deleted.
-TEST_F(LeaseCmdsTest, Lease6WipeNoLeases) {
+TEST_F(LeaseCmdsTest, lease6WipeAllNoArgs) {
+    testLease6WipeAllNoArgs();
+}
+
+TEST_F(LeaseCmdsTest, lease6WipeAllNoArgsMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6WipeAllNoArgs();
+}
+
+void LeaseCmdsTest::testLease6WipeNoLeases() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5391,8 +7300,16 @@ TEST_F(LeaseCmdsTest, Lease6WipeNoLeases) {
     checkLease6Stats(99, 0, 0, 0);
 }
 
-// Checks that lease4-wipe properly reports when no leases were deleted.
-TEST_F(LeaseCmdsTest, Lease6WipeNoLeasesAll) {
+TEST_F(LeaseCmdsTest, lease6WipeNoLeases) {
+    testLease6WipeNoLeases();
+}
+
+TEST_F(LeaseCmdsTest, lease6WipeNoLeasesMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6WipeNoLeases();
+}
+
+void LeaseCmdsTest::testLease6WipeNoLeasesAll() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5417,9 +7334,16 @@ TEST_F(LeaseCmdsTest, Lease6WipeNoLeasesAll) {
     checkLease6Stats(99, 0, 0, 0);
 }
 
-// Checks that an attempt to update a lease (set incorrect subnet-id)
-// will fail.
-TEST_F(LeaseCmdsTest, brokenUpdate) {
+TEST_F(LeaseCmdsTest, lease6WipeNoLeasesAll) {
+    testLease6WipeNoLeasesAll();
+}
+
+TEST_F(LeaseCmdsTest, lease6WipeNoLeasesAllMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6WipeNoLeasesAll();
+}
+
+void LeaseCmdsTest::testLease4BrokenUpdate() {
 
     // Initialize lease manager (false = v4, false = don't add leases)
     initLeaseMgr(false, false);
@@ -5435,8 +7359,8 @@ TEST_F(LeaseCmdsTest, brokenUpdate) {
         "    \"arguments\": {"
         "        \"subnet-id\": 444,\n"
         "        \"ip-address\": \"192.0.2.202\",\n"
-        "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\"\n"
-        "        ,\"force-create\": true\n"
+        "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"force-create\": true\n"
         "    }\n"
         "}";
     string exp_rsp = "Invalid subnet-id: No IPv4 subnet with "
@@ -5444,9 +7368,50 @@ TEST_F(LeaseCmdsTest, brokenUpdate) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// This test verifies that it is possible to add two leases and delete
-// two leases as a result of the single lease6-bulk-apply command.
-TEST_F(LeaseCmdsTest, Lease6BulkApply) {
+TEST_F(LeaseCmdsTest, lease4BrokenUpdate) {
+    testLease4BrokenUpdate();
+}
+
+TEST_F(LeaseCmdsTest, lease4BrokenUpdateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4BrokenUpdate();
+}
+
+void LeaseCmdsTest::testLease6BrokenUpdate() {
+
+    // Initialize lease manager (true = v6, false = don't add leases)
+    initLeaseMgr(true, false);
+
+    // Set the sanity checks level.
+    CfgMgr::instance().getCurrentCfg()->getConsistency()
+        ->setLeaseSanityCheck(CfgConsistency::LEASE_CHECK_FIX);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease6-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 444,\n"
+        "        \"ip-address\": \"2001:db8:1::23\",\n"
+        "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"force-create\": true\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "Invalid subnet-id: No IPv6 subnet with "
+                     "subnet-id=444 currently configured.";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+TEST_F(LeaseCmdsTest, lease6BrokenUpdate) {
+    testLease6BrokenUpdate();
+}
+
+TEST_F(LeaseCmdsTest, lease6BrokenUpdateMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BrokenUpdate();
+}
+
+void LeaseCmdsTest::testLease6BulkApply() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5504,9 +7469,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApply) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2")));
 }
 
-// This test verifies that the lease parameters are checked when adding new
-// leases only with the lease6-bulk-apply.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyAddsOnlyBadParam) {
+TEST_F(LeaseCmdsTest, lease6BulkApply) {
+    testLease6BulkApply();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApply();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyAddsOnlyBadParam() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5537,9 +7509,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyAddsOnlyBadParam) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::123")));
 }
 
-// This test verifies that it is possible to send new leases only
-// with the lease6-bulk-apply.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyAddsOnly) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyAddsOnlyBadParam) {
+    testLease6BulkApplyAddsOnlyBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyAddsOnlyBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyAddsOnlyBadParam();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyAddsOnly() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5583,9 +7562,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyAddsOnly) {
     EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:2::123")));
 }
 
-// This test verifies that the lease parameters are checked when updating leases
-// only with the lease6-bulk-apply.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyUpdatesOnlyBadParam) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyAddsOnly) {
+    testLease6BulkApplyAddsOnly();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyAddsOnlyMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyAddsOnly();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyUpdatesOnlyBadParam() {
 
     // Initialize lease manager (true = v6, false = don't add leases)
     initLeaseMgr(true, false);
@@ -5627,9 +7613,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyUpdatesOnlyBadParam) {
     EXPECT_EQ(42, lease1->iaid_);
 }
 
-// This test verifies that it is possible to update leases with
-// the lease6-bulk-apply.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyUpdatesOnly) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyUpdatesOnlyBadParam) {
+    testLease6BulkApplyUpdatesOnlyBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyUpdatesOnlyBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyUpdatesOnlyBadParam();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyUpdatesOnly() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5679,9 +7672,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyUpdatesOnly) {
     EXPECT_EQ(1234, lease2->iaid_);
 }
 
-// This test verifies that it is possible to only delete leases
-// with the lease6-bulk-apply.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyDeletesOnly) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyUpdatesOnly) {
+    testLease6BulkApplyUpdatesOnly();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyUpdatesOnlyMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyUpdatesOnly();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyDeletesOnly() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5721,9 +7721,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyDeletesOnly) {
     EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2")));
 }
 
-// This test verifies that deleting non existing leases returns an
-// 'empty' result.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyDeleteNonExiting) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyDeletesOnly) {
+    testLease6BulkApplyDeletesOnly();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyDeletesOnlyMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyDeletesOnly();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyDeleteNonExiting() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5782,9 +7789,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyDeleteNonExiting) {
     }
 }
 
-// Check that changes for other leases are not applied if one of
-// the leases is malformed.
-TEST_F(LeaseCmdsTest, Lease6BulkApplyRollback) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyDeleteNonExiting) {
+    testLease6BulkApplyDeleteNonExiting();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyDeleteNonExitingMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyDeleteNonExiting();
+}
+
+void LeaseCmdsTest::testLease6BulkApplyRollback() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -5840,8 +7854,16 @@ TEST_F(LeaseCmdsTest, Lease6BulkApplyRollback) {
     EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2")));
 }
 
-// Checks that lease4-resend-ddns sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease4ResendDdnsBadParam) {
+TEST_F(LeaseCmdsTest, lease6BulkApplyRollback) {
+    testLease6BulkApplyRollback();
+}
+
+TEST_F(LeaseCmdsTest, lease6BulkApplyRollbackMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6BulkApplyRollback();
+}
+
+void LeaseCmdsTest::testLease4ResendDdnsBadParam() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5882,9 +7904,16 @@ TEST_F(LeaseCmdsTest, Lease4ResendDdnsBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease4-resend-ddns does not generate an NCR for given lease
-// when DDNS updating is disabled.
-TEST_F(LeaseCmdsTest, lease4ResendDdnsDisabled) {
+TEST_F(LeaseCmdsTest, lease4ResendDdnsBadParam) {
+    testLease4ResendDdnsBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendDdnsBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendDdnsBadParam();
+}
+
+void LeaseCmdsTest::testLease4ResendDdnsDisabled() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5906,9 +7935,16 @@ TEST_F(LeaseCmdsTest, lease4ResendDdnsDisabled) {
     EXPECT_EQ(ncrQueueSize(), -1);
 }
 
-// Checks that lease4-resend-ddns does not generate an NCR for
-// when there is no matching lease.
-TEST_F(LeaseCmdsTest, lease4ResendDdnsNoLease) {
+TEST_F(LeaseCmdsTest, lease4ResendDdnsDisabled) {
+    testLease4ResendDdnsDisabled();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendDdnsDisabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendDdnsDisabled();
+}
+
+void LeaseCmdsTest::testLease4ResendDdnsNoLease() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5925,9 +7961,16 @@ TEST_F(LeaseCmdsTest, lease4ResendDdnsNoLease) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease4-resend-ddns does not generate an NCR for given lease
-// when updates are enabled but Lease::hostname_ is blank.
-TEST_F(LeaseCmdsTest, lease4ResendNoHostname) {
+TEST_F(LeaseCmdsTest, lease4ResendDdnsNoLease) {
+    testLease4ResendDdnsNoLease();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendDdnsNoLeaseMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendDdnsNoLease();
+}
+
+void LeaseCmdsTest::testLease4ResendNoHostname() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5957,10 +8000,16 @@ TEST_F(LeaseCmdsTest, lease4ResendNoHostname) {
     EXPECT_EQ(ncrQueueSize(), 0);
 }
 
-// Checks that lease4-resend-ddns does not generate an NCR for given lease
-// when updates are enabled, Lease::hostname_ is not blank, but both
-// Lease::fqdn_fwd_ and fdqn_rev_ are false.
-TEST_F(LeaseCmdsTest, lease4ResendNoDirectionsEnabled) {
+TEST_F(LeaseCmdsTest, lease4ResendNoHostname) {
+    testLease4ResendNoHostname();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendNoHostnameMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendNoHostname();
+}
+
+void LeaseCmdsTest::testLease4ResendNoDirectionsEnabled() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -5991,10 +8040,16 @@ TEST_F(LeaseCmdsTest, lease4ResendNoDirectionsEnabled) {
     EXPECT_EQ(ncrQueueSize(), 0);
 }
 
-// Checks that lease4-resend-ddns can generate an NCR for given lease
-// when updates are enabled, Lease::hostname_ is not blank, and at least
-// one of Lease::fqdn_fwd_ or fdqn_rev_ are true.
-TEST_F(LeaseCmdsTest, lease4ResendDdnsEnabled) {
+TEST_F(LeaseCmdsTest, lease4ResendNoDirectionsEnabled) {
+    testLease4ResendNoDirectionsEnabled();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendNoDirectionsEnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendNoDirectionsEnabled();
+}
+
+void LeaseCmdsTest::testLease4ResendDdnsEnabled() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -6046,8 +8101,16 @@ TEST_F(LeaseCmdsTest, lease4ResendDdnsEnabled) {
     }
 }
 
-// Checks that lease6-resend-ddns sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease6ResendDdnsBadParam) {
+TEST_F(LeaseCmdsTest, lease4ResendDdnsEnabled) {
+    testLease4ResendDdnsEnabled();
+}
+
+TEST_F(LeaseCmdsTest, lease4ResendDdnsEnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4ResendDdnsEnabled();
+}
+
+void LeaseCmdsTest::testLease6ResendDdnsBadParam() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6088,9 +8151,16 @@ TEST_F(LeaseCmdsTest, Lease6ResendDdnsBadParam) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-resend-ddns does not generate an NCR for given lease
-// when DDNS updating is disabled.
-TEST_F(LeaseCmdsTest, lease6ResendDdnsDisabled) {
+TEST_F(LeaseCmdsTest, lease6ResendDdnsBadParam) {
+    testLease6ResendDdnsBadParam();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendDdnsBadParamMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendDdnsBadParam();
+}
+
+void LeaseCmdsTest::testLease6ResendDdnsDisabled() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6113,9 +8183,16 @@ TEST_F(LeaseCmdsTest, lease6ResendDdnsDisabled) {
     EXPECT_EQ(ncrQueueSize(), -1);
 }
 
-// Checks that lease6-resend-ddns does not generate an NCR for
-// when there is no matching lease.
-TEST_F(LeaseCmdsTest, lease6ResendDdnsNoLease) {
+TEST_F(LeaseCmdsTest, lease6ResendDdnsDisabled) {
+    testLease6ResendDdnsDisabled();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendDdnsDisabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendDdnsDisabled();
+}
+
+void LeaseCmdsTest::testLease6ResendDdnsNoLease() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6132,9 +8209,16 @@ TEST_F(LeaseCmdsTest, lease6ResendDdnsNoLease) {
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 }
 
-// Checks that lease6-resend-ddns does not generate an NCR for given lease
-// when updates are enabled but Lease::hostname_ is blank.
-TEST_F(LeaseCmdsTest, lease6ResendNoHostname) {
+TEST_F(LeaseCmdsTest, lease6ResendDdnsNoLease) {
+    testLease6ResendDdnsNoLease();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendDdnsNoLeaseMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendDdnsNoLease();
+}
+
+void LeaseCmdsTest::testLease6ResendNoHostname() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6164,10 +8248,16 @@ TEST_F(LeaseCmdsTest, lease6ResendNoHostname) {
     EXPECT_EQ(ncrQueueSize(), 0);
 }
 
-// Checks that lease6-resend-ddns does not generate an NCR for given lease
-// when updates are enabled, Lease::hostname_ is not blank, but both
-// Lease::fqdn_fwd_ and fdqn_rev_ are false.
-TEST_F(LeaseCmdsTest, lease6ResendNoDirectionsEnabled) {
+TEST_F(LeaseCmdsTest, lease6ResendNoHostname) {
+    testLease6ResendNoHostname();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendNoHostnameMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendNoHostname();
+}
+
+void LeaseCmdsTest::testLease6ResendNoDirectionsEnabled() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6198,10 +8288,16 @@ TEST_F(LeaseCmdsTest, lease6ResendNoDirectionsEnabled) {
     EXPECT_EQ(ncrQueueSize(), 0);
 }
 
-// Checks that lease6-resend-ddns can generate an NCR for given lease
-// when updates are enabled, Lease::hostname_ is not blank, and at least
-// one of Lease::fqdn_fwd_ or fdqn_rev_ are true.
-TEST_F(LeaseCmdsTest, lease6ResendDdnsEnabled) {
+TEST_F(LeaseCmdsTest, lease6ResendNoDirectionsEnabled) {
+    testLease6ResendNoDirectionsEnabled();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendNoDirectionsEnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendNoDirectionsEnabled();
+}
+
+void LeaseCmdsTest::testLease6ResendDdnsEnabled() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6253,9 +8349,16 @@ TEST_F(LeaseCmdsTest, lease6ResendDdnsEnabled) {
     }
 }
 
-// Checks that lease4-del does (or does not) generate an NCR to remove
-// DNS for a given lease based on lease content when DDNS updates are enabled.
-TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Enabled) {
+TEST_F(LeaseCmdsTest, lease6ResendDdnsEnabled) {
+    testLease6ResendDdnsEnabled();
+}
+
+TEST_F(LeaseCmdsTest, lease6ResendDdnsEnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6ResendDdnsEnabled();
+}
+
+void LeaseCmdsTest::testLease4DnsRemoveD2Enabled() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -6373,10 +8476,16 @@ TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Enabled) {
     }
 }
 
-// Checks that lease4-del does not generate an NCR to remove
-// DNS for a given lease based on lease content when DDNS
-// updates are disabled.
-TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Disabled) {
+TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Enabled) {
+    testLease4DnsRemoveD2Enabled();
+}
+
+TEST_F(LeaseCmdsTest, lease4DnsRemoveD2EnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DnsRemoveD2Enabled();
+}
+
+void LeaseCmdsTest::testLease4DnsRemoveD2Disabled() {
 
     // Initialize lease manager (false = v4, true = add leases)
     initLeaseMgr(false, true);
@@ -6414,9 +8523,16 @@ TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Disabled) {
     ASSERT_FALSE(lease);
 }
 
-// Checks that lease6-del does (or does not) generate an NCR to remove
-// DNS for a given lease based on lease content when DDNS updates are enabled.
-TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Enabled) {
+TEST_F(LeaseCmdsTest, lease4DnsRemoveD2Disabled) {
+    testLease4DnsRemoveD2Disabled();
+}
+
+TEST_F(LeaseCmdsTest, lease4DnsRemoveD2DisabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease4DnsRemoveD2Disabled();
+}
+
+void LeaseCmdsTest::testLease6DnsRemoveD2Enabled() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6534,10 +8650,16 @@ TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Enabled) {
     }
 }
 
-// Checks that lease6-del does not generate an NCR to remove
-// DNS for a given lease based on lease content when DDNS
-// updates are disabled.
-TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Disabled) {
+TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Enabled) {
+    testLease6DnsRemoveD2Enabled();
+}
+
+TEST_F(LeaseCmdsTest, lease6DnsRemoveD2EnabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DnsRemoveD2Enabled();
+}
+
+void LeaseCmdsTest::testLease6DnsRemoveD2Disabled() {
 
     // Initialize lease manager (true = v6, true = add leases)
     initLeaseMgr(true, true);
@@ -6575,4 +8697,13 @@ TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Disabled) {
     ASSERT_FALSE(lease);
 }
 
+TEST_F(LeaseCmdsTest, lease6DnsRemoveD2Disabled) {
+    testLease6DnsRemoveD2Disabled();
+}
+
+TEST_F(LeaseCmdsTest, lease6DnsRemoveD2DisabledMultiThreading) {
+    MultiThreadingTest mt(true);
+    testLease6DnsRemoveD2Disabled();
+}
+
 } // end of anonymous namespace