| File: | usr/include/boost/smart_ptr/detail/shared_count.hpp |
| Warning: | line 559, column 22 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") | |||
| 2 | // | |||
| 3 | // This Source Code Form is subject to the terms of the Mozilla Public | |||
| 4 | // License, v. 2.0. If a copy of the MPL was not distributed with this | |||
| 5 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
| 6 | ||||
| 7 | #include <config.h> | |||
| 8 | #include <asiolink/io_address.h> | |||
| 9 | #include <dhcp/hwaddr.h> | |||
| 10 | #include <dhcpsrv/flq_allocator.h> | |||
| 11 | #include <dhcpsrv/testutils/alloc_engine_utils.h> | |||
| 12 | #include <boost/make_shared.hpp> | |||
| 13 | #include <gtest/gtest.h> | |||
| 14 | ||||
| 15 | using namespace isc::asiolink; | |||
| 16 | using namespace std; | |||
| 17 | ||||
| 18 | namespace isc { | |||
| 19 | namespace dhcp { | |||
| 20 | namespace test { | |||
| 21 | ||||
| 22 | /// @brief Test fixture class for the DHCPv4 Free Lease Queue allocator. | |||
| 23 | class FreeLeaseQueueAllocatorTest4 : public AllocEngine4Test { | |||
| 24 | public: | |||
| 25 | ||||
| 26 | /// @brief Creates a DHCPv4 lease for an address and MAC address. | |||
| 27 | /// | |||
| 28 | /// @param address Lease address. | |||
| 29 | /// @param hw_address_seed a seed from which the hardware address is generated. | |||
| 30 | /// @return Created lease pointer. | |||
| 31 | Lease4Ptr | |||
| 32 | createLease4(const IOAddress& address, uint64_t hw_address_seed) const { | |||
| 33 | vector<uint8_t> hw_address_vec(sizeof(hw_address_seed)); | |||
| 34 | for (unsigned i = 0; i < sizeof(hw_address_seed); ++i) { | |||
| 35 | hw_address_vec[i] = (hw_address_seed >> i) & 0xFF; | |||
| 36 | } | |||
| 37 | auto hw_address = boost::make_shared<HWAddr>(hw_address_vec, HTYPE_ETHER); | |||
| 38 | auto lease = boost::make_shared<Lease4>(address, hw_address, ClientIdPtr(), | |||
| 39 | 3600, time(0), subnet_->getID()); | |||
| 40 | return (lease); | |||
| 41 | } | |||
| 42 | }; | |||
| 43 | ||||
| 44 | // Test that the allocator returns the correct type. | |||
| 45 | TEST_F(FreeLeaseQueueAllocatorTest4, getType)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("getType") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_getType_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_getType_Test() = default ; ~FreeLeaseQueueAllocatorTest4_getType_Test() override = default ; FreeLeaseQueueAllocatorTest4_getType_Test (const FreeLeaseQueueAllocatorTest4_getType_Test &) = delete; FreeLeaseQueueAllocatorTest4_getType_Test & operator=( const FreeLeaseQueueAllocatorTest4_getType_Test & ) = delete; FreeLeaseQueueAllocatorTest4_getType_Test (FreeLeaseQueueAllocatorTest4_getType_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_getType_Test & operator=( FreeLeaseQueueAllocatorTest4_getType_Test && ) noexcept = delete; private: void TestBody() override; [[maybe_unused ]] static ::testing::TestInfo* const test_info_; }; ::testing ::TestInfo* const FreeLeaseQueueAllocatorTest4_getType_Test:: test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "getType", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 45 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 45), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 45), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_getType_Test >); void FreeLeaseQueueAllocatorTest4_getType_Test::TestBody () { | |||
| 46 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 47 | EXPECT_EQ("flq", alloc.getType())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("\"flq\"" , "alloc.getType()", "flq", alloc.getType()))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 47, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 48 | } | |||
| 49 | ||||
| 50 | // Test populating free DHCPv4 leases to the queue. | |||
| 51 | TEST_F(FreeLeaseQueueAllocatorTest4, populateFreeAddressLeases)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("populateFreeAddressLeases") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test () = default; ~FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test () override = default; FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test (const FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test &) = delete; FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test & operator=( const FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test &) = delete; FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test (FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test & operator=( FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "populateFreeAddressLeases", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 51), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 51), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 51), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test >); void FreeLeaseQueueAllocatorTest4_populateFreeAddressLeases_Test ::TestBody() { | |||
| 52 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 53 | ||||
| 54 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 55 | ||||
| 56 | EXPECT_TRUE(lease_mgr.addLease((createLease4(IOAddress("192.0.2.100"), 0))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease4 (IOAddress("192.0.2.100"), 0))))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 56, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease4(IOAddress(\"192.0.2.100\"), 0)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 57 | EXPECT_TRUE(lease_mgr.addLease((createLease4(IOAddress("192.0.2.102"), 1))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease4 (IOAddress("192.0.2.102"), 1))))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 57, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease4(IOAddress(\"192.0.2.102\"), 1)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 58 | EXPECT_TRUE(lease_mgr.addLease((createLease4(IOAddress("192.0.2.104"), 2))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease4 (IOAddress("192.0.2.104"), 2))))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 58, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease4(IOAddress(\"192.0.2.104\"), 2)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 59 | EXPECT_TRUE(lease_mgr.addLease((createLease4(IOAddress("192.0.2.106"), 3))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease4 (IOAddress("192.0.2.106"), 3))))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 59, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease4(IOAddress(\"192.0.2.106\"), 3)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 60 | EXPECT_TRUE(lease_mgr.addLease((createLease4(IOAddress("192.0.2.108"), 4))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease4 (IOAddress("192.0.2.108"), 4))))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 60, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease4(IOAddress(\"192.0.2.108\"), 4)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 61 | ||||
| 62 | EXPECT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_62 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_62 ; } } else gtest_label_testnothrow_62 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 62, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 63 | ||||
| 64 | auto pool_state = boost::dynamic_pointer_cast<PoolFreeLeaseQueueAllocationState>(pool_->getAllocationState()); | |||
| 65 | ASSERT_TRUE(pool_state)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool_state)) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult:: kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 65, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state", "false", "true") .c_str()) = ::testing::Message (); | |||
| 66 | EXPECT_FALSE(pool_state->exhausted())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(pool_state->exhausted ()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 66, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state->exhausted()", "true", "false") .c_str()) = :: testing::Message(); | |||
| 67 | ||||
| 68 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.101"), cc_); | |||
| 69 | EXPECT_EQ(.6, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".6", "r" , .6, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 69, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 70 | r = alloc.getOccupancyRate(IOAddress("192.0.2.1"), cc_); | |||
| 71 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 71, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 72 | ||||
| 73 | std::set<IOAddress> addresses; | |||
| 74 | for (auto i = 0; i < 5; ++i) { | |||
| 75 | auto lease = pool_state->offerFreeLease(); | |||
| 76 | ASSERT_FALSE(lease.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(lease.isV4Zero()))) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult ::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 76, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease.isV4Zero()", "true", "false") .c_str()) = ::testing:: Message(); | |||
| 77 | addresses.insert(lease); | |||
| 78 | } | |||
| 79 | ASSERT_EQ(5, addresses.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("5", "addresses.size()" , 5, addresses.size()))) ; else return ::testing::internal::AssertHelper (::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 79, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 80 | EXPECT_EQ(1, addresses.count(IOAddress("192.0.2.101")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"192.0.2.101\"))" , 1, addresses.count(IOAddress("192.0.2.101"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 80, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 81 | EXPECT_EQ(1, addresses.count(IOAddress("192.0.2.103")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"192.0.2.103\"))" , 1, addresses.count(IOAddress("192.0.2.103"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 81, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 82 | EXPECT_EQ(1, addresses.count(IOAddress("192.0.2.105")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"192.0.2.105\"))" , 1, addresses.count(IOAddress("192.0.2.105"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 82, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 83 | EXPECT_EQ(1, addresses.count(IOAddress("192.0.2.107")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"192.0.2.107\"))" , 1, addresses.count(IOAddress("192.0.2.107"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 83, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 84 | EXPECT_EQ(1, addresses.count(IOAddress("192.0.2.109")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"192.0.2.109\"))" , 1, addresses.count(IOAddress("192.0.2.109"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 84, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 85 | } | |||
| 86 | ||||
| 87 | // Test allocating IPv4 addresses when a subnet has a single pool. | |||
| 88 | TEST_F(FreeLeaseQueueAllocatorTest4, singlePool)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePool") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_singlePool_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_singlePool_Test () = default; ~FreeLeaseQueueAllocatorTest4_singlePool_Test() override = default; FreeLeaseQueueAllocatorTest4_singlePool_Test (const FreeLeaseQueueAllocatorTest4_singlePool_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePool_Test & operator =( const FreeLeaseQueueAllocatorTest4_singlePool_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePool_Test (FreeLeaseQueueAllocatorTest4_singlePool_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_singlePool_Test & operator=( FreeLeaseQueueAllocatorTest4_singlePool_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_singlePool_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "singlePool", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 88 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 88), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 88), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_singlePool_Test >); void FreeLeaseQueueAllocatorTest4_singlePool_Test::TestBody () { | |||
| 89 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 90 | ||||
| 91 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_91 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_91 ; } } else gtest_label_testnothrow_91 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 91, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 92 | ||||
| 93 | // Remember returned addresses, so we can verify that unique addresses | |||
| 94 | // are returned. | |||
| 95 | std::set<IOAddress> addresses; | |||
| 96 | for (auto i = 0; i < 1000; ++i) { | |||
| 97 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 98 | addresses.insert(candidate); | |||
| 99 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 99, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 100 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 100, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 101 | } | |||
| 102 | // The pool comprises 10 addresses. All should be returned. | |||
| 103 | EXPECT_EQ(10, addresses.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("10", "addresses.size()" , 10, addresses.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 103, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 104 | } | |||
| 105 | ||||
| 106 | // Test allocating IPv4 addresses and re-allocating these that are | |||
| 107 | // deleted (released). | |||
| 108 | TEST_F(FreeLeaseQueueAllocatorTest4, singlePoolWithAllocations)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePoolWithAllocations") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test () = default; ~FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test () override = default; FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test (const FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test & operator=( const FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test (FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test & operator=( FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "singlePoolWithAllocations", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 108), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 108), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 108), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test >); void FreeLeaseQueueAllocatorTest4_singlePoolWithAllocations_Test ::TestBody() { | |||
| 109 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 110 | ||||
| 111 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_111 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_111 ; } } else gtest_label_testnothrow_111 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 111, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 112 | ||||
| 113 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 114 | ||||
| 115 | // Remember returned addresses, so we can verify that unique addresses | |||
| 116 | // are returned. | |||
| 117 | std::map<IOAddress, Lease4Ptr> leases; | |||
| 118 | for (auto i = 0; i < 10; ++i) { | |||
| 119 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 120 | auto lease = createLease4(candidate, i); | |||
| 121 | leases[candidate] = lease; | |||
| 122 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 122, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 123 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 123, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 124 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 124, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 125 | } | |||
| 126 | // The pool comprises 10 addresses. All should be returned. | |||
| 127 | EXPECT_EQ(10, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("10", "leases.size()" , 10, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 127, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 128 | ||||
| 129 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 130 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 130, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 131 | ||||
| 132 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 133 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 133, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 134 | ||||
| 135 | auto i = 0; | |||
| 136 | for (auto const& address_lease : leases) { | |||
| 137 | if (i % 2) { | |||
| 138 | EXPECT_TRUE(lease_mgr.deleteLease(address_lease.second))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.deleteLease (address_lease.second))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 138, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.deleteLease(address_lease.second)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 139 | } | |||
| 140 | ++i; | |||
| 141 | } | |||
| 142 | ||||
| 143 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 144 | EXPECT_EQ(.5, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".5", "r" , .5, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 144, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 145 | ||||
| 146 | for (auto j = 0; j < 5; ++j) { | |||
| 147 | candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 148 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 148, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 149 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 149, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 150 | auto lease = createLease4(candidate, j); | |||
| 151 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 151, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 152 | } | |||
| 153 | ||||
| 154 | candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 155 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 155, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 156 | ||||
| 157 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 158 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 158, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 159 | } | |||
| 160 | ||||
| 161 | // Test allocating IPv4 addresses and re-allocating these that are | |||
| 162 | // reclaimed. | |||
| 163 | TEST_F(FreeLeaseQueueAllocatorTest4, singlePoolWithReclamations)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePoolWithReclamations") > 1, "test_name must not be empty"); class FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test () = default; ~FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test () override = default; FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test (const FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test & operator=( const FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test (FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test & operator=( FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "singlePoolWithReclamations", nullptr, nullptr, ::testing:: internal::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 163), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 163), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 163), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test >); void FreeLeaseQueueAllocatorTest4_singlePoolWithReclamations_Test ::TestBody() { | |||
| 164 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 165 | ||||
| 166 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_166 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_166 ; } } else gtest_label_testnothrow_166 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 166, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 167 | ||||
| 168 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 169 | ||||
| 170 | // Remember returned addresses, so we can verify that unique addresses | |||
| 171 | // are returned. | |||
| 172 | std::map<IOAddress, Lease4Ptr> leases; | |||
| 173 | for (auto i = 0; i < 10; ++i) { | |||
| 174 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 175 | auto lease = createLease4(candidate, i); | |||
| 176 | leases[candidate] = lease; | |||
| 177 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 177, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 178 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 178, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 179 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 179, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 180 | } | |||
| 181 | // The pool comprises 10 addresses. All should be returned. | |||
| 182 | EXPECT_EQ(10, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("10", "leases.size()" , 10, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 182, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 183 | ||||
| 184 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 185 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 185, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 186 | ||||
| 187 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 188 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 188, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 189 | ||||
| 190 | auto i = 0; | |||
| 191 | for (auto const& address_lease : leases) { | |||
| 192 | if (i % 2) { | |||
| 193 | auto lease = address_lease.second; | |||
| 194 | lease->state_ = Lease::STATE_EXPIRED_RECLAIMED; | |||
| 195 | EXPECT_NO_THROW(lease_mgr.updateLease4(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease4(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_195 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_195 ; } } else gtest_label_testnothrow_195 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 195, ("Expected: " "lease_mgr.updateLease4(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 196 | } | |||
| 197 | ++i; | |||
| 198 | } | |||
| 199 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 200 | EXPECT_EQ(.5, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".5", "r" , .5, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 200, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 201 | ||||
| 202 | for (auto j = 0; j < 5; ++j) { | |||
| 203 | candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 204 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 204, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 205 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 205, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 206 | auto lease = lease_mgr.getLease4(candidate); | |||
| 207 | lease->state_ = Lease::STATE_DEFAULT; | |||
| 208 | EXPECT_NO_THROW(lease_mgr.updateLease4(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease4(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_208 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_208 ; } } else gtest_label_testnothrow_208 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 208, ("Expected: " "lease_mgr.updateLease4(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 209 | } | |||
| 210 | candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 211 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 211, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 212 | ||||
| 213 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 214 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 214, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 215 | } | |||
| 216 | ||||
| 217 | // Test allocating DHCPv4 leases for many pools in a subnet. | |||
| 218 | TEST_F(FreeLeaseQueueAllocatorTest4, manyPools)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPools") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_manyPools_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_manyPools_Test () = default; ~FreeLeaseQueueAllocatorTest4_manyPools_Test() override = default; FreeLeaseQueueAllocatorTest4_manyPools_Test (const FreeLeaseQueueAllocatorTest4_manyPools_Test &) = delete; FreeLeaseQueueAllocatorTest4_manyPools_Test & operator=( const FreeLeaseQueueAllocatorTest4_manyPools_Test &) = delete ; FreeLeaseQueueAllocatorTest4_manyPools_Test (FreeLeaseQueueAllocatorTest4_manyPools_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_manyPools_Test & operator=( FreeLeaseQueueAllocatorTest4_manyPools_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_manyPools_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "manyPools", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 218 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 218), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 218), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_manyPools_Test >); void FreeLeaseQueueAllocatorTest4_manyPools_Test::TestBody () { | |||
| 219 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 220 | ||||
| 221 | // Add several more pools. | |||
| 222 | for (int i = 1; i < 10; ++i) { | |||
| 223 | stringstream min, max; | |||
| 224 | min << "192.0.2." << i * 10; | |||
| 225 | max << "192.0.2." << i * 10 + 9; | |||
| 226 | auto pool = boost::make_shared<Pool4>(IOAddress(min.str()), | |||
| 227 | IOAddress(max.str())); | |||
| 228 | subnet_->addPool(pool); | |||
| 229 | } | |||
| 230 | ||||
| 231 | // There are ten pools with 10 addresses each. | |||
| 232 | int total = 100; | |||
| 233 | ||||
| 234 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_234 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_234 ; } } else gtest_label_testnothrow_234 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 234, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 235 | ||||
| 236 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 237 | ||||
| 238 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 239 | // 1/100 | |||
| 240 | EXPECT_EQ(.01, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".01", "r" , .01, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 240, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 241 | ||||
| 242 | std::set<IOAddress> addresses_set; | |||
| 243 | std::vector<IOAddress> addresses_vector; | |||
| 244 | std::vector<PoolPtr> pools_vector; | |||
| 245 | ||||
| 246 | // Pick random addresses the number of times equal to the | |||
| 247 | // subnet capacity to ensure that all addresses are returned. | |||
| 248 | for (auto i = 0; i < total; ++i) { | |||
| 249 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 250 | addresses_set.insert(candidate); | |||
| 251 | addresses_vector.push_back(candidate); | |||
| 252 | auto lease = createLease4(candidate, i); | |||
| 253 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 253, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 254 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 254, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 255 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_V4, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 255, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_V4, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 256 | pools_vector.push_back(subnet_->getPool(Lease::TYPE_V4, candidate)); | |||
| 257 | } | |||
| 258 | // Make sure that unique addresses have been returned. | |||
| 259 | EXPECT_EQ(total, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "addresses_set.size()" , total, addresses_set.size()))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 259, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 260 | ||||
| 261 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 262 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 262, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 263 | ||||
| 264 | // Verify that the addresses are returned in the random order. | |||
| 265 | // Count how many times we found consecutive addresses. It should | |||
| 266 | // be 0 or close to 0. | |||
| 267 | size_t consecutive_addresses = 0; | |||
| 268 | for (unsigned k = 0; k < addresses_vector.size()-1; ++k) { | |||
| 269 | if (addresses_vector[k].toUint32() == addresses_vector[k+1].toUint32()-1) { | |||
| 270 | ++consecutive_addresses; | |||
| 271 | } | |||
| 272 | } | |||
| 273 | // Ideally, the number of consecutive occurrences should be 0 but we | |||
| 274 | // allow some to make sure the test doesn't fall over sporadically. | |||
| 275 | EXPECT_LT(consecutive_addresses, addresses_vector.size()/4)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::CmpHelperLT("consecutive_addresses" , "addresses_vector.size()/4", consecutive_addresses, addresses_vector .size()/4))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 275, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 276 | ||||
| 277 | // Repeat similar check for pools. The pools should be picked in the | |||
| 278 | // random order too. | |||
| 279 | size_t consecutive_pools = 0; | |||
| 280 | for (unsigned k = 0; k < pools_vector.size()-1; ++k) { | |||
| 281 | // Check if the pools are adjacent (i.e., last address of the | |||
| 282 | // previous pool is a neighbor of the first address of the next | |||
| 283 | // pool). | |||
| 284 | if (pools_vector[k]->getLastAddress().toUint32()+1 == | |||
| 285 | pools_vector[k+1]->getFirstAddress().toUint32()) { | |||
| 286 | ++consecutive_pools; | |||
| 287 | } | |||
| 288 | } | |||
| 289 | EXPECT_LT(consecutive_pools, pools_vector.size()/2)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::CmpHelperLT("consecutive_pools" , "pools_vector.size()/2", consecutive_pools, pools_vector.size ()/2))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 289, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 290 | } | |||
| 291 | ||||
| 292 | // Test that the allocator returns a zero address when there are no pools | |||
| 293 | // in a subnet. | |||
| 294 | TEST_F(FreeLeaseQueueAllocatorTest4, noPools)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("noPools") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_noPools_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_noPools_Test() = default ; ~FreeLeaseQueueAllocatorTest4_noPools_Test() override = default ; FreeLeaseQueueAllocatorTest4_noPools_Test (const FreeLeaseQueueAllocatorTest4_noPools_Test &) = delete; FreeLeaseQueueAllocatorTest4_noPools_Test & operator=( const FreeLeaseQueueAllocatorTest4_noPools_Test & ) = delete; FreeLeaseQueueAllocatorTest4_noPools_Test (FreeLeaseQueueAllocatorTest4_noPools_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_noPools_Test & operator=( FreeLeaseQueueAllocatorTest4_noPools_Test && ) noexcept = delete; private: void TestBody() override; [[maybe_unused ]] static ::testing::TestInfo* const test_info_; }; ::testing ::TestInfo* const FreeLeaseQueueAllocatorTest4_noPools_Test:: test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "noPools", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 294 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 294), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 294), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_noPools_Test >); void FreeLeaseQueueAllocatorTest4_noPools_Test::TestBody () { | |||
| 295 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 296 | ||||
| 297 | subnet_->delPools(Lease::TYPE_V4); | |||
| 298 | ||||
| 299 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 300 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 300, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 301 | ||||
| 302 | // rate is 0. because of the address can't be found, not from 0./0.... | |||
| 303 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 304 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 304, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 305 | } | |||
| 306 | ||||
| 307 | // Test that the allocator respects client class guards. | |||
| 308 | TEST_F(FreeLeaseQueueAllocatorTest4, clientClasses)static_assert(sizeof("FreeLeaseQueueAllocatorTest4") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("clientClasses") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest4_clientClasses_Test : public FreeLeaseQueueAllocatorTest4 { public: FreeLeaseQueueAllocatorTest4_clientClasses_Test () = default; ~FreeLeaseQueueAllocatorTest4_clientClasses_Test () override = default; FreeLeaseQueueAllocatorTest4_clientClasses_Test (const FreeLeaseQueueAllocatorTest4_clientClasses_Test & ) = delete; FreeLeaseQueueAllocatorTest4_clientClasses_Test & operator=( const FreeLeaseQueueAllocatorTest4_clientClasses_Test &) = delete; FreeLeaseQueueAllocatorTest4_clientClasses_Test (FreeLeaseQueueAllocatorTest4_clientClasses_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest4_clientClasses_Test & operator=( FreeLeaseQueueAllocatorTest4_clientClasses_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest4_clientClasses_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest4" , "clientClasses", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 308 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest4 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 308), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest4 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 308), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest4_clientClasses_Test >); void FreeLeaseQueueAllocatorTest4_clientClasses_Test:: TestBody() { | |||
| 309 | FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_); | |||
| 310 | ||||
| 311 | // First pool only allows the client class foo. | |||
| 312 | pool_->allowClientClass("foo"); | |||
| 313 | ||||
| 314 | // Second pool. It only allows client class bar. | |||
| 315 | auto pool1 = boost::make_shared<Pool4>(IOAddress("192.0.2.120"), | |||
| 316 | IOAddress("192.0.2.129")); | |||
| 317 | pool1->allowClientClass("bar"); | |||
| 318 | subnet_->addPool(pool1); | |||
| 319 | ||||
| 320 | // Third pool. It only allows client class foo. | |||
| 321 | auto pool2 = boost::make_shared<Pool4>(IOAddress("192.0.2.140"), | |||
| 322 | IOAddress("192.0.2.149")); | |||
| 323 | pool2->allowClientClass("foo"); | |||
| 324 | subnet_->addPool(pool2); | |||
| 325 | ||||
| 326 | // Forth pool. It only allows client class bar. | |||
| 327 | auto pool3 = boost::make_shared<Pool4>(IOAddress("192.0.2.160"), | |||
| 328 | IOAddress("192.0.2.169")); | |||
| 329 | pool3->allowClientClass("bar"); | |||
| 330 | subnet_->addPool(pool3); | |||
| 331 | ||||
| 332 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_332 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_332 ; } } else gtest_label_testnothrow_332 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 332, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 333 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 334 | ||||
| 335 | // Remember offered addresses. | |||
| 336 | std::set<IOAddress> addresses_set; | |||
| 337 | ||||
| 338 | // Simulate client's request belonging to the class bar. | |||
| 339 | cc_.insert("bar"); | |||
| 340 | double r = alloc.getOccupancyRate(IOAddress("192.0.2.120"), cc_); | |||
| 341 | // 1/20 | |||
| 342 | EXPECT_EQ(.05, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".05", "r" , .05, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 342, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 343 | for (auto i = 0; i < 20; ++i) { | |||
| 344 | // Allocate random addresses and make sure they belong to the | |||
| 345 | // pools associated with the class bar. | |||
| 346 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 347 | EXPECT_FALSE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV4Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 347, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 348 | EXPECT_TRUE(lease_mgr.addLease(createLease4(candidate, i+50)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease4 (candidate, i+50)))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 348, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease4(candidate, i+50))", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 349 | addresses_set.insert(candidate); | |||
| 350 | EXPECT_TRUE(pool1->inRange(candidate) || pool3->inRange(candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool1->inRange(candidate ) || pool3->inRange(candidate))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 350, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool1->inRange(candidate) || pool3->inRange(candidate)" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 351 | } | |||
| 352 | EXPECT_EQ(20, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("20", "addresses_set.size()" , 20, addresses_set.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 352, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 353 | ||||
| 354 | r = alloc.getOccupancyRate(IOAddress("192.0.2.120"), cc_); | |||
| 355 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 355, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 356 | ||||
| 357 | addresses_set.clear(); | |||
| 358 | ||||
| 359 | // Simulate the case that the client also belongs to the class foo. | |||
| 360 | // All pools should now be available. | |||
| 361 | cc_.insert("foo"); | |||
| 362 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 363 | // 21/40 | |||
| 364 | EXPECT_EQ(.525, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".525", "r" , .525, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 364, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 365 | for (auto i = 0; i < 20; ++i) { | |||
| 366 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 367 | addresses_set.insert(candidate); | |||
| 368 | EXPECT_TRUE(lease_mgr.addLease(createLease4(candidate, i+100)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease4 (candidate, i+100)))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 368, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease4(candidate, i+100))", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 369 | EXPECT_TRUE(subnet_->inRange(candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inRange(candidate ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 369, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inRange(candidate)", "false", "true") .c_str() ) = ::testing::Message(); | |||
| 370 | } | |||
| 371 | EXPECT_EQ(20, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("20", "addresses_set.size()" , 20, addresses_set.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 371, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 372 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 373 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 373, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 374 | ||||
| 375 | // When the client does not belong to any client class the allocator | |||
| 376 | // can't offer any address to the client. | |||
| 377 | cc_.clear(); | |||
| 378 | IOAddress candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")); | |||
| 379 | EXPECT_TRUE(candidate.isV4Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV4Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 379, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV4Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 380 | r = alloc.getOccupancyRate(IOAddress("192.0.2.100"), cc_); | |||
| 381 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 381, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 382 | } | |||
| 383 | ||||
| 384 | /// @brief Test fixture class for the DHCPv6 Free Lease Queue allocator. | |||
| 385 | class FreeLeaseQueueAllocatorTest6 : public AllocEngine6Test { | |||
| 386 | public: | |||
| 387 | ||||
| 388 | /// @brief Creates a DHCPv6 lease for an address and DUID. | |||
| 389 | /// | |||
| 390 | /// @param type lease type. | |||
| 391 | /// @param address Lease address. | |||
| 392 | /// @param duid_seed a seed from which the DUID is generated. | |||
| 393 | /// @return Created lease pointer. | |||
| 394 | Lease6Ptr | |||
| 395 | createLease6(Lease::Type type, const IOAddress& address, uint64_t duid_seed) const { | |||
| 396 | vector<uint8_t> duid_vec(sizeof(duid_seed)); | |||
| 397 | for (unsigned i = 0; i < sizeof(duid_seed); ++i) { | |||
| 398 | duid_vec[i] = (duid_seed >> i) & 0xFF; | |||
| 399 | } | |||
| 400 | auto duid = boost::make_shared<DUID>(duid_vec); | |||
| 401 | auto lease = boost::make_shared<Lease6>(type, address, duid, 1, 1800, | |||
| 402 | 3600, subnet_->getID()); | |||
| 403 | return (lease); | |||
| 404 | } | |||
| 405 | ||||
| 406 | }; | |||
| 407 | ||||
| 408 | // Test that the allocator returns the correct type. | |||
| 409 | TEST_F(FreeLeaseQueueAllocatorTest6, getType)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("getType") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_getType_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_getType_Test() = default ; ~FreeLeaseQueueAllocatorTest6_getType_Test() override = default ; FreeLeaseQueueAllocatorTest6_getType_Test (const FreeLeaseQueueAllocatorTest6_getType_Test &) = delete; FreeLeaseQueueAllocatorTest6_getType_Test & operator=( const FreeLeaseQueueAllocatorTest6_getType_Test & ) = delete; FreeLeaseQueueAllocatorTest6_getType_Test (FreeLeaseQueueAllocatorTest6_getType_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_getType_Test & operator=( FreeLeaseQueueAllocatorTest6_getType_Test && ) noexcept = delete; private: void TestBody() override; [[maybe_unused ]] static ::testing::TestInfo* const test_info_; }; ::testing ::TestInfo* const FreeLeaseQueueAllocatorTest6_getType_Test:: test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "getType", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 409 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 409), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 409), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_getType_Test >); void FreeLeaseQueueAllocatorTest6_getType_Test::TestBody () { | |||
| 410 | FreeLeaseQueueAllocator allocNA(Lease::TYPE_NA, subnet_); | |||
| ||||
| 411 | EXPECT_EQ("flq", allocNA.getType())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("\"flq\"" , "allocNA.getType()", "flq", allocNA.getType()))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 411, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 412 | ||||
| 413 | FreeLeaseQueueAllocator allocPD(Lease::TYPE_PD, subnet_); | |||
| 414 | EXPECT_EQ("flq", allocPD.getType())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("\"flq\"" , "allocPD.getType()", "flq", allocPD.getType()))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 414, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 415 | } | |||
| 416 | ||||
| 417 | // Test populating free DHCPv6 address leases to the queue. | |||
| 418 | TEST_F(FreeLeaseQueueAllocatorTest6, populateFreeAddressLeases)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("populateFreeAddressLeases") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test () = default; ~FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test () override = default; FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test (const FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test &) = delete; FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test & operator=( const FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test &) = delete; FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test (FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test & operator=( FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "populateFreeAddressLeases", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 418), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 418), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 418), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test >); void FreeLeaseQueueAllocatorTest6_populateFreeAddressLeases_Test ::TestBody() { | |||
| 419 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 420 | ||||
| 421 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 422 | ||||
| 423 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::10"), 0))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_NA, IOAddress("2001:db8:1::10"), 0))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 423, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress(\"2001:db8:1::10\"), 0)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 424 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::12"), 1))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_NA, IOAddress("2001:db8:1::12"), 1))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 424, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress(\"2001:db8:1::12\"), 1)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 425 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::14"), 2))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_NA, IOAddress("2001:db8:1::14"), 2))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 425, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress(\"2001:db8:1::14\"), 2)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 426 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::16"), 3))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_NA, IOAddress("2001:db8:1::16"), 3))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 426, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress(\"2001:db8:1::16\"), 3)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 427 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::18"), 4))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_NA, IOAddress("2001:db8:1::18"), 4))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 427, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_NA, IOAddress(\"2001:db8:1::18\"), 4)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 428 | ||||
| 429 | EXPECT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_429 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_429 ; } } else gtest_label_testnothrow_429 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 429, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 430 | ||||
| 431 | // Address getOccupancyRate is for IPv4 only. | |||
| 432 | double r = alloc.getOccupancyRate(IOAddress("2001:db8:1::10"), cc_); | |||
| 433 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 433, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 434 | ||||
| 435 | auto pool_state = boost::dynamic_pointer_cast<PoolFreeLeaseQueueAllocationState>(pool_->getAllocationState()); | |||
| 436 | ASSERT_TRUE(pool_state)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool_state)) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult:: kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 436, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state", "false", "true") .c_str()) = ::testing::Message (); | |||
| 437 | EXPECT_FALSE(pool_state->exhausted())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(pool_state->exhausted ()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 437, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state->exhausted()", "true", "false") .c_str()) = :: testing::Message(); | |||
| 438 | ||||
| 439 | std::set<IOAddress> addresses; | |||
| 440 | for (auto i = 0; i < 12; ++i) { | |||
| 441 | auto lease = pool_state->offerFreeLease(); | |||
| 442 | ASSERT_FALSE(lease.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(lease.isV6Zero()))) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult ::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 442, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease.isV6Zero()", "true", "false") .c_str()) = ::testing:: Message(); | |||
| 443 | addresses.insert(lease); | |||
| 444 | } | |||
| 445 | ASSERT_EQ(12, addresses.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("12", "addresses.size()" , 12, addresses.size()))) ; else return ::testing::internal:: AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 445, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 446 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::11")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::11\"))" , 1, addresses.count(IOAddress("2001:db8:1::11"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 446, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 447 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::13")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::13\"))" , 1, addresses.count(IOAddress("2001:db8:1::13"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 447, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 448 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::15")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::15\"))" , 1, addresses.count(IOAddress("2001:db8:1::15"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 448, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 449 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::17")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::17\"))" , 1, addresses.count(IOAddress("2001:db8:1::17"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 449, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 450 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::19")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::19\"))" , 1, addresses.count(IOAddress("2001:db8:1::19"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 450, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 451 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1a")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1a\"))" , 1, addresses.count(IOAddress("2001:db8:1::1a"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 451, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 452 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1b")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1b\"))" , 1, addresses.count(IOAddress("2001:db8:1::1b"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 452, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 453 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1c")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1c\"))" , 1, addresses.count(IOAddress("2001:db8:1::1c"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 453, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 454 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1d")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1d\"))" , 1, addresses.count(IOAddress("2001:db8:1::1d"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 454, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 455 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1e")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1e\"))" , 1, addresses.count(IOAddress("2001:db8:1::1e"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 455, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 456 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::1f")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::1f\"))" , 1, addresses.count(IOAddress("2001:db8:1::1f"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 456, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 457 | EXPECT_EQ(1, addresses.count(IOAddress("2001:db8:1::20")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1", "addresses.count(IOAddress(\"2001:db8:1::20\"))" , 1, addresses.count(IOAddress("2001:db8:1::20"))))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 457, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 458 | } | |||
| 459 | ||||
| 460 | // Test allocating IPv6 addresses when a subnet has a single pool. | |||
| 461 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePool)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePool") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_singlePool_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePool_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePool_Test() override = default; FreeLeaseQueueAllocatorTest6_singlePool_Test (const FreeLeaseQueueAllocatorTest6_singlePool_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePool_Test & operator =( const FreeLeaseQueueAllocatorTest6_singlePool_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePool_Test (FreeLeaseQueueAllocatorTest6_singlePool_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePool_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePool_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePool_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePool", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 461 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 461), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 461), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePool_Test >); void FreeLeaseQueueAllocatorTest6_singlePool_Test::TestBody () { | |||
| 462 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 463 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_463 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_463 ; } } else gtest_label_testnothrow_463 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 463, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 464 | ||||
| 465 | // Remember returned addresses, so we can verify that unique addresses | |||
| 466 | // are returned. | |||
| 467 | std::set<IOAddress> addresses; | |||
| 468 | for (auto i = 0; i < 1000; ++i) { | |||
| 469 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 470 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 470, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 471 | addresses.insert(candidate); | |||
| 472 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 472, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 473 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 473, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 474 | } | |||
| 475 | // The pool comprises 17 addresses. All should be returned. | |||
| 476 | EXPECT_EQ(17, addresses.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("17", "addresses.size()" , 17, addresses.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 476, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 477 | } | |||
| 478 | ||||
| 479 | // Test allocating IPv6 addresses and re-allocating these that are | |||
| 480 | // deleted (released). | |||
| 481 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePoolWithAllocations)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePoolWithAllocations") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test () override = default; FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test (const FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test & operator=( const FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test (FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePoolWithAllocations", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 481), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 481), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 481), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test >); void FreeLeaseQueueAllocatorTest6_singlePoolWithAllocations_Test ::TestBody() { | |||
| 482 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 483 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_483 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_483 ; } } else gtest_label_testnothrow_483 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 483, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 484 | ||||
| 485 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 486 | ||||
| 487 | // Remember returned addresses, so we can verify that unique addresses | |||
| 488 | // are returned. | |||
| 489 | std::map<IOAddress, Lease6Ptr> leases; | |||
| 490 | for (auto i = 0; i < 17; ++i) { | |||
| 491 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 492 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 492, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 493 | auto lease = createLease6(Lease::TYPE_NA, candidate, i); | |||
| 494 | leases[candidate] = lease; | |||
| 495 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 495, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 496 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 496, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 497 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 497, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 498 | } | |||
| 499 | // The pool comprises 17 addresses. All should be returned. | |||
| 500 | EXPECT_EQ(17, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("17", "leases.size()" , 17, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 500, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 501 | ||||
| 502 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 503 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 503, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 504 | ||||
| 505 | auto i = 0; | |||
| 506 | for (auto const& address_lease : leases) { | |||
| 507 | if (i % 2) { | |||
| 508 | EXPECT_TRUE(lease_mgr.deleteLease(address_lease.second))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.deleteLease (address_lease.second))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 508, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.deleteLease(address_lease.second)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 509 | } | |||
| 510 | ++i; | |||
| 511 | } | |||
| 512 | ||||
| 513 | for (auto j = 0; j < 8; ++j) { | |||
| 514 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 515 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 515, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 516 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 516, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 517 | auto lease = createLease6(Lease::TYPE_NA, candidate, i); | |||
| 518 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 518, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 519 | } | |||
| 520 | ||||
| 521 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 522 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 522, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 523 | } | |||
| 524 | ||||
| 525 | // Test allocating IPv6 addresses and re-allocating these that are | |||
| 526 | // reclaimed. | |||
| 527 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePoolWithReclamations)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePoolWithReclamations") > 1, "test_name must not be empty"); class FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test () override = default; FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test (const FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test & operator=( const FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test (FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePoolWithReclamations", nullptr, nullptr, ::testing:: internal::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 527), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 527), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 527), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test >); void FreeLeaseQueueAllocatorTest6_singlePoolWithReclamations_Test ::TestBody() { | |||
| 528 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 529 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_529 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_529 ; } } else gtest_label_testnothrow_529 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 529, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 530 | ||||
| 531 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 532 | ||||
| 533 | // Remember returned addresses, so we can verify that unique addresses | |||
| 534 | // are returned. | |||
| 535 | std::map<IOAddress, Lease6Ptr> leases; | |||
| 536 | for (auto i = 0; i < 17; ++i) { | |||
| 537 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 538 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 538, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 539 | auto lease = createLease6(Lease::TYPE_NA, candidate, i); | |||
| 540 | leases[candidate] = lease; | |||
| 541 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 541, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 542 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 542, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 543 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 543, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 544 | } | |||
| 545 | // The pool comprises 17 addresses. All should be returned. | |||
| 546 | EXPECT_EQ(17, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("17", "leases.size()" , 17, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 546, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 547 | ||||
| 548 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 549 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 549, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 550 | ||||
| 551 | auto i = 0; | |||
| 552 | for (auto const& address_lease : leases) { | |||
| 553 | if (i % 2) { | |||
| 554 | auto lease = address_lease.second; | |||
| 555 | lease->state_ = Lease::STATE_EXPIRED_RECLAIMED; | |||
| 556 | EXPECT_NO_THROW(lease_mgr.updateLease6(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease6(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_556 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_556 ; } } else gtest_label_testnothrow_556 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 556, ("Expected: " "lease_mgr.updateLease6(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 557 | } | |||
| 558 | ++i; | |||
| 559 | } | |||
| 560 | ||||
| 561 | for (auto j = 0; j < 8; ++j) { | |||
| 562 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 563 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 563, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 564 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 564, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 565 | auto lease = lease_mgr.getLease6(Lease::TYPE_NA, candidate); | |||
| 566 | lease->state_ = Lease::STATE_DEFAULT; | |||
| 567 | EXPECT_NO_THROW(lease_mgr.updateLease6(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease6(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_567 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_567 ; } } else gtest_label_testnothrow_567 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 567, ("Expected: " "lease_mgr.updateLease6(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 568 | } | |||
| 569 | ||||
| 570 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 571 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 571, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 572 | } | |||
| 573 | ||||
| 574 | // Test allocating DHCPv6 leases for many pools in a subnet. | |||
| 575 | TEST_F(FreeLeaseQueueAllocatorTest6, manyPools)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPools") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_manyPools_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_manyPools_Test () = default; ~FreeLeaseQueueAllocatorTest6_manyPools_Test() override = default; FreeLeaseQueueAllocatorTest6_manyPools_Test (const FreeLeaseQueueAllocatorTest6_manyPools_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPools_Test & operator=( const FreeLeaseQueueAllocatorTest6_manyPools_Test &) = delete ; FreeLeaseQueueAllocatorTest6_manyPools_Test (FreeLeaseQueueAllocatorTest6_manyPools_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_manyPools_Test & operator=( FreeLeaseQueueAllocatorTest6_manyPools_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_manyPools_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "manyPools", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 575 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 575), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 575), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_manyPools_Test >); void FreeLeaseQueueAllocatorTest6_manyPools_Test::TestBody () { | |||
| 576 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 577 | ||||
| 578 | // Add several more pools. | |||
| 579 | for (int i = 2; i < 10; ++i) { | |||
| 580 | stringstream min, max; | |||
| 581 | min << "2001:db8:1::" << hex << i * 16 + 1; | |||
| 582 | max << "2001:db8:1::" << hex << i * 16 + 16; | |||
| 583 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, | |||
| 584 | IOAddress(min.str()), | |||
| 585 | IOAddress(max.str())); | |||
| 586 | subnet_->addPool(pool); | |||
| 587 | } | |||
| 588 | ||||
| 589 | // First pool (::10 - ::20) has 17 addresses. | |||
| 590 | // There are 8 extra pools with 16 addresses in each. | |||
| 591 | int total = 17 + 8 * 16; | |||
| 592 | ||||
| 593 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_593 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_593 ; } } else gtest_label_testnothrow_593 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 593, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 594 | ||||
| 595 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 596 | ||||
| 597 | std::set<IOAddress> addresses_set; | |||
| 598 | std::vector<IOAddress> addresses_vector; | |||
| 599 | std::vector<PoolPtr> pools_vector; | |||
| 600 | ||||
| 601 | // Pick random addresses the number of times equal to the | |||
| 602 | // subnet capacity to ensure that all addresses are returned. | |||
| 603 | for (auto i = 0; i < total; ++i) { | |||
| 604 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 605 | addresses_set.insert(candidate); | |||
| 606 | addresses_vector.push_back(candidate); | |||
| 607 | auto lease = createLease6(Lease::TYPE_NA, candidate, i); | |||
| 608 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 608, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 609 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 609, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 610 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_NA, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 610, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_NA, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 611 | pools_vector.push_back(subnet_->getPool(Lease::TYPE_NA, candidate)); | |||
| 612 | } | |||
| 613 | // Make sure that unique addresses have been returned. | |||
| 614 | EXPECT_EQ(total, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "addresses_set.size()" , total, addresses_set.size()))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 614, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 615 | ||||
| 616 | // Verify that the addresses are returned in the random order. | |||
| 617 | // Count how many times we found consecutive addresses. It should | |||
| 618 | // be 0 or close to 0. | |||
| 619 | size_t consecutive_addresses = 0; | |||
| 620 | for (unsigned k = 0; k < addresses_vector.size()-1; ++k) { | |||
| 621 | if (IOAddress::increase(addresses_vector[k]) == addresses_vector[k+1]) { | |||
| 622 | ++consecutive_addresses; | |||
| 623 | } | |||
| 624 | } | |||
| 625 | // Ideally, the number of consecutive occurrences should be 0 but we | |||
| 626 | // allow some to make sure the test doesn't fall over sporadically. | |||
| 627 | EXPECT_LT(consecutive_addresses, addresses_vector.size()/4)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::CmpHelperLT("consecutive_addresses" , "addresses_vector.size()/4", consecutive_addresses, addresses_vector .size()/4))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 627, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 628 | ||||
| 629 | // Repeat similar check for pools. The pools should be picked in the | |||
| 630 | // random order too. | |||
| 631 | size_t consecutive_pools = 0; | |||
| 632 | for (unsigned k = 0; k < pools_vector.size()-1; ++k) { | |||
| 633 | if (IOAddress::increase(pools_vector[k]->getLastAddress()) == | |||
| 634 | pools_vector[k]->getFirstAddress()) { | |||
| 635 | ++consecutive_pools; | |||
| 636 | } | |||
| 637 | } | |||
| 638 | EXPECT_LT(consecutive_pools, pools_vector.size()/2)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::CmpHelperLT("consecutive_pools" , "pools_vector.size()/2", consecutive_pools, pools_vector.size ()/2))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 638, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 639 | } | |||
| 640 | ||||
| 641 | // Test that the allocator returns a zero address when there are no pools | |||
| 642 | // in a subnet. | |||
| 643 | TEST_F(FreeLeaseQueueAllocatorTest6, noPools)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("noPools") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_noPools_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_noPools_Test() = default ; ~FreeLeaseQueueAllocatorTest6_noPools_Test() override = default ; FreeLeaseQueueAllocatorTest6_noPools_Test (const FreeLeaseQueueAllocatorTest6_noPools_Test &) = delete; FreeLeaseQueueAllocatorTest6_noPools_Test & operator=( const FreeLeaseQueueAllocatorTest6_noPools_Test & ) = delete; FreeLeaseQueueAllocatorTest6_noPools_Test (FreeLeaseQueueAllocatorTest6_noPools_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_noPools_Test & operator=( FreeLeaseQueueAllocatorTest6_noPools_Test && ) noexcept = delete; private: void TestBody() override; [[maybe_unused ]] static ::testing::TestInfo* const test_info_; }; ::testing ::TestInfo* const FreeLeaseQueueAllocatorTest6_noPools_Test:: test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "noPools", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 643 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 643), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 643), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_noPools_Test >); void FreeLeaseQueueAllocatorTest6_noPools_Test::TestBody () { | |||
| 644 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 645 | ||||
| 646 | subnet_->delPools(Lease::TYPE_NA); | |||
| 647 | ||||
| 648 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 649 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 649, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 650 | } | |||
| 651 | ||||
| 652 | // Test that the allocator respects client class guards. | |||
| 653 | TEST_F(FreeLeaseQueueAllocatorTest6, clientClasses)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("clientClasses") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_clientClasses_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_clientClasses_Test () = default; ~FreeLeaseQueueAllocatorTest6_clientClasses_Test () override = default; FreeLeaseQueueAllocatorTest6_clientClasses_Test (const FreeLeaseQueueAllocatorTest6_clientClasses_Test & ) = delete; FreeLeaseQueueAllocatorTest6_clientClasses_Test & operator=( const FreeLeaseQueueAllocatorTest6_clientClasses_Test &) = delete; FreeLeaseQueueAllocatorTest6_clientClasses_Test (FreeLeaseQueueAllocatorTest6_clientClasses_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_clientClasses_Test & operator=( FreeLeaseQueueAllocatorTest6_clientClasses_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_clientClasses_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "clientClasses", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 653 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 653), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 653), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_clientClasses_Test >); void FreeLeaseQueueAllocatorTest6_clientClasses_Test:: TestBody() { | |||
| 654 | FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_); | |||
| 655 | ||||
| 656 | // First pool only allows the client class foo. | |||
| 657 | pool_->allowClientClass("foo"); | |||
| 658 | ||||
| 659 | // Second pool. It only allows client class bar. | |||
| 660 | auto pool1 = boost::make_shared<Pool6>(Lease::TYPE_NA, | |||
| 661 | IOAddress("2001:db8:1::120"), | |||
| 662 | IOAddress("2001:db8:1::129")); | |||
| 663 | pool1->allowClientClass("bar"); | |||
| 664 | subnet_->addPool(pool1); | |||
| 665 | ||||
| 666 | // Third pool. It only allows client class foo. | |||
| 667 | auto pool2 = boost::make_shared<Pool6>(Lease::TYPE_NA, | |||
| 668 | IOAddress("2001:db8:1::140"), | |||
| 669 | IOAddress("2001:db8:1::149")); | |||
| 670 | pool2->allowClientClass("foo"); | |||
| 671 | subnet_->addPool(pool2); | |||
| 672 | ||||
| 673 | // Forth pool. It only allows client class bar. | |||
| 674 | auto pool3 = boost::make_shared<Pool6>(Lease::TYPE_NA, | |||
| 675 | IOAddress("2001:db8:1::160"), | |||
| 676 | IOAddress("2001:db8:1::169")); | |||
| 677 | pool3->allowClientClass("bar"); | |||
| 678 | subnet_->addPool(pool3); | |||
| 679 | ||||
| 680 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_680 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_680 ; } } else gtest_label_testnothrow_680 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 680, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 681 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 682 | ||||
| 683 | // When the client does not belong to any client class the allocator | |||
| 684 | // can't offer any address to the client. | |||
| 685 | IOAddress candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 686 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 686, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 687 | ||||
| 688 | // Remember offered addresses. | |||
| 689 | std::set<IOAddress> addresses_set; | |||
| 690 | ||||
| 691 | // Simulate client's request belonging to the class bar. | |||
| 692 | cc_.insert("bar"); | |||
| 693 | for (auto i = 0; i < 20; ++i) { | |||
| 694 | // Allocate random addresses and make sure they belong to the | |||
| 695 | // pools associated with the class bar. | |||
| 696 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 697 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 697, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 698 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_NA, candidate, i+50)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_NA, candidate, i+50)))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 698, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_NA, candidate, i+50))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 699 | addresses_set.insert(candidate); | |||
| 700 | EXPECT_TRUE(pool1->inRange(candidate) || pool3->inRange(candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool1->inRange(candidate ) || pool3->inRange(candidate))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 700, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool1->inRange(candidate) || pool3->inRange(candidate)" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 701 | } | |||
| 702 | EXPECT_EQ(20, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("20", "addresses_set.size()" , 20, addresses_set.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 702, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 703 | ||||
| 704 | // Simulate the case that the client also belongs to the class foo. | |||
| 705 | // All pools should now be available. | |||
| 706 | cc_.insert("foo"); | |||
| 707 | for (auto i = 0; i < 27; ++i) { | |||
| 708 | candidate = alloc.pickAddress(cc_, duid_, IOAddress("::")); | |||
| 709 | addresses_set.insert(candidate); | |||
| 710 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_NA, candidate, i+100)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_NA, candidate, i+100)))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 710, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_NA, candidate, i+100))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 711 | EXPECT_TRUE(subnet_->inRange(candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inRange(candidate ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 711, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inRange(candidate)", "false", "true") .c_str() ) = ::testing::Message(); | |||
| 712 | } | |||
| 713 | EXPECT_EQ(47, addresses_set.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("47", "addresses_set.size()" , 47, addresses_set.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 713, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 714 | } | |||
| 715 | ||||
| 716 | // Test populating free DHCPv6 prefix leases to the queue. | |||
| 717 | TEST_F(FreeLeaseQueueAllocatorTest6, populateFreePrefixDelegationLeases)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("populateFreePrefixDelegationLeases") > 1, "test_name must not be empty"); class FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test () = default; ~FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test () override = default; FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test (const FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test &) = delete; FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test & operator=( const FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test &) = delete; FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test (FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test & operator=( FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "populateFreePrefixDelegationLeases", nullptr, nullptr, ::testing ::internal::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 717), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 717), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 717), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test >); void FreeLeaseQueueAllocatorTest6_populateFreePrefixDelegationLeases_Test ::TestBody() { | |||
| 718 | subnet_->delPools(Lease::TYPE_PD); | |||
| 719 | ||||
| 720 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 721 | ||||
| 722 | auto pool = Pool6::create(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 112, 120); | |||
| 723 | subnet_->addPool(pool); | |||
| 724 | ||||
| 725 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 726 | ||||
| 727 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 0))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_PD, IOAddress("2001:db8:2::"), 0))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 727, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress(\"2001:db8:2::\"), 0)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 728 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress("2001:db8:2::1000"), 1))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_PD, IOAddress("2001:db8:2::1000"), 1))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 728, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress(\"2001:db8:2::1000\"), 1)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 729 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress("2001:db8:2::2000"), 2))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_PD, IOAddress("2001:db8:2::2000"), 2))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 729, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress(\"2001:db8:2::2000\"), 2)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 730 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress("2001:db8:2::3000"), 3))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_PD, IOAddress("2001:db8:2::3000"), 3))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 730, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress(\"2001:db8:2::3000\"), 3)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 731 | EXPECT_TRUE(lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress("2001:db8:2::4000"), 4))))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease((createLease6 (Lease::TYPE_PD, IOAddress("2001:db8:2::4000"), 4))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 731, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease((createLease6(Lease::TYPE_PD, IOAddress(\"2001:db8:2::4000\"), 4)))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 732 | ||||
| 733 | EXPECT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_733 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_733 ; } } else gtest_label_testnothrow_733 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 733, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 734 | ||||
| 735 | auto pool_state = boost::dynamic_pointer_cast<PoolFreeLeaseQueueAllocationState>(pool->getAllocationState()); | |||
| 736 | ASSERT_TRUE(pool_state)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool_state)) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult:: kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 736, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state", "false", "true") .c_str()) = ::testing::Message (); | |||
| 737 | EXPECT_FALSE(pool_state->exhausted())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(pool_state->exhausted ()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 737, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool_state->exhausted()", "true", "false") .c_str()) = :: testing::Message(); | |||
| 738 | ||||
| 739 | double r = alloc.getOccupancyRate(IOAddress("2001:db8:2::"), 128, cc_); | |||
| 740 | EXPECT_EQ(5. / 256., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("5. / 256." , "r", 5. / 256., r))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 740, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 741 | ||||
| 742 | std::set<IOAddress> addresses; | |||
| 743 | for (auto i = 0; i < 256; ++i) { | |||
| 744 | auto lease = pool_state->offerFreeLease(); | |||
| 745 | ASSERT_FALSE(lease.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(lease.isV6Zero()))) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult ::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 745, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease.isV6Zero()", "true", "false") .c_str()) = ::testing:: Message(); | |||
| 746 | addresses.insert(lease); | |||
| 747 | } | |||
| 748 | ASSERT_EQ(251, addresses.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("251", "addresses.size()" , 251, addresses.size()))) ; else return ::testing::internal:: AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 748, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 749 | EXPECT_EQ(0, addresses.count(IOAddress("2001:db8:2::")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0", "addresses.count(IOAddress(\"2001:db8:2::\"))" , 0, addresses.count(IOAddress("2001:db8:2::"))))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 749, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 750 | EXPECT_EQ(0, addresses.count(IOAddress("2001:db8:2::1000")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0", "addresses.count(IOAddress(\"2001:db8:2::1000\"))" , 0, addresses.count(IOAddress("2001:db8:2::1000"))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 750, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 751 | EXPECT_EQ(0, addresses.count(IOAddress("2001:db8:2::2000")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0", "addresses.count(IOAddress(\"2001:db8:2::2000\"))" , 0, addresses.count(IOAddress("2001:db8:2::2000"))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 751, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 752 | EXPECT_EQ(0, addresses.count(IOAddress("2001:db8:2::3000")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0", "addresses.count(IOAddress(\"2001:db8:2::3000\"))" , 0, addresses.count(IOAddress("2001:db8:2::3000"))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 752, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 753 | EXPECT_EQ(0, addresses.count(IOAddress("2001:db8:2::4000")))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0", "addresses.count(IOAddress(\"2001:db8:2::4000\"))" , 0, addresses.count(IOAddress("2001:db8:2::4000"))))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 753, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 754 | } | |||
| 755 | ||||
| 756 | // Test allocating delegated prefixes when a subnet has a single pool. | |||
| 757 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePdPool)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePdPool") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_singlePdPool_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePdPool_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePdPool_Test () override = default; FreeLeaseQueueAllocatorTest6_singlePdPool_Test (const FreeLeaseQueueAllocatorTest6_singlePdPool_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPool_Test & operator=( const FreeLeaseQueueAllocatorTest6_singlePdPool_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPool_Test (FreeLeaseQueueAllocatorTest6_singlePdPool_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePdPool_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePdPool_Test && ) noexcept = delete; private: void TestBody() override; [[maybe_unused ]] static ::testing::TestInfo* const test_info_; }; ::testing ::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePdPool_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePdPool", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 757 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 757), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 757), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePdPool_Test >); void FreeLeaseQueueAllocatorTest6_singlePdPool_Test::TestBody () { | |||
| 758 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 759 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_759 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_759 ; } } else gtest_label_testnothrow_759 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 759, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 760 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 761 | ||||
| 762 | Pool6Ptr pool; | |||
| 763 | ||||
| 764 | // Remember returned prefixes, so we can verify that unique addresses | |||
| 765 | // are returned. | |||
| 766 | std::set<IOAddress> prefixes; | |||
| 767 | for (auto i = 0; i < 65536; ++i) { | |||
| 768 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 769 | EXPECT_EQ(pd_pool_, pool)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("pd_pool_" , "pool", pd_pool_, pool))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 769, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 770 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 770, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 771 | prefixes.insert(candidate); | |||
| 772 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 772, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 773 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 773, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 774 | } | |||
| 775 | // The pool comprises 65536 prefixes. All should be returned. | |||
| 776 | EXPECT_EQ(65536, prefixes.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("65536", "prefixes.size()" , 65536, prefixes.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 776, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 777 | ||||
| 778 | double r = alloc.getOccupancyRate(IOAddress("2001:db8:1:2::"), 128, cc_); | |||
| 779 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 779, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 780 | } | |||
| 781 | ||||
| 782 | // Test allocating delegated prefixes and re-allocating these that are | |||
| 783 | // deleted (released). | |||
| 784 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePdPoolWithAllocations)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePdPoolWithAllocations") > 1 , "test_name must not be empty"); class FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test () override = default; FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test (const FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test & operator=( const FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test (FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePdPoolWithAllocations", nullptr, nullptr, ::testing:: internal::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 784), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 784), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 784), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test >); void FreeLeaseQueueAllocatorTest6_singlePdPoolWithAllocations_Test ::TestBody() { | |||
| 785 | // Remove the default pool because it is too large for this test case. | |||
| 786 | subnet_->delPools(Lease::TYPE_PD); | |||
| 787 | // Add a smaller pool. | |||
| 788 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 789 | IOAddress("3000::"), | |||
| 790 | 120, | |||
| 791 | 128); | |||
| 792 | subnet_->addPool(pool); | |||
| 793 | ||||
| 794 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 795 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_795 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_795 ; } } else gtest_label_testnothrow_795 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 795, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 796 | ||||
| 797 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 798 | ||||
| 799 | // Remember returned addresses, so we can verify that unique addresses | |||
| 800 | // are returned. | |||
| 801 | std::map<IOAddress, Lease6Ptr> leases; | |||
| 802 | for (auto i = 0; i < 256; ++i) { | |||
| 803 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 804 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 804, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 805 | auto lease = createLease6(Lease::TYPE_PD, candidate, i); | |||
| 806 | leases[candidate] = lease; | |||
| 807 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 807, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 808 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 808, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 809 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 809, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 810 | } | |||
| 811 | // The pool comprises 256 delegated prefixes. All should be returned. | |||
| 812 | EXPECT_EQ(256, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("256", "leases.size()" , 256, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 812, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 813 | ||||
| 814 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 815 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 815, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 816 | double r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 817 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 817, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 818 | ||||
| 819 | auto i = 0; | |||
| 820 | for (auto const& address_lease : leases) { | |||
| 821 | if (i % 2) { | |||
| 822 | EXPECT_TRUE(lease_mgr.deleteLease(address_lease.second))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.deleteLease (address_lease.second))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 822, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.deleteLease(address_lease.second)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 823 | } | |||
| 824 | ++i; | |||
| 825 | } | |||
| 826 | r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 827 | EXPECT_EQ(.5, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".5", "r" , .5, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 827, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 828 | ||||
| 829 | for (auto j = 0; j < 128; ++j) { | |||
| 830 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 831 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 831, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 832 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 832, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 833 | auto lease = createLease6(Lease::TYPE_PD, candidate, j); | |||
| 834 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 834, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 835 | } | |||
| 836 | ||||
| 837 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 838 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 838, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 839 | ||||
| 840 | r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 841 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 841, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 842 | } | |||
| 843 | ||||
| 844 | // Test allocating delegated prefixes and re-allocating these that are | |||
| 845 | // reclaimed. | |||
| 846 | TEST_F(FreeLeaseQueueAllocatorTest6, singlePdPoolWithReclamations)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("singlePdPoolWithReclamations") > 1 , "test_name must not be empty"); class FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test () = default; ~FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test () override = default; FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test (const FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test & operator=( const FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test &) = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test (FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test & operator=( FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "singlePdPoolWithReclamations", nullptr, nullptr, ::testing ::internal::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 846), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 846), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 846), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test >); void FreeLeaseQueueAllocatorTest6_singlePdPoolWithReclamations_Test ::TestBody() { | |||
| 847 | // Remove the default pool because it is too large for this test case. | |||
| 848 | subnet_->delPools(Lease::TYPE_PD); | |||
| 849 | // Add a smaller pool. | |||
| 850 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 851 | IOAddress("3000::"), | |||
| 852 | 120, | |||
| 853 | 128); | |||
| 854 | subnet_->addPool(pool); | |||
| 855 | ||||
| 856 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 857 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_857 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_857 ; } } else gtest_label_testnothrow_857 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 857, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 858 | ||||
| 859 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 860 | ||||
| 861 | // Remember returned addresses, so we can verify that unique addresses | |||
| 862 | // are returned. | |||
| 863 | std::map<IOAddress, Lease6Ptr> leases; | |||
| 864 | for (auto i = 0; i < 256; ++i) { | |||
| 865 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 866 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 866, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 867 | auto lease = createLease6(Lease::TYPE_PD, candidate, i); | |||
| 868 | leases[candidate] = lease; | |||
| 869 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 869, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 870 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 870, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 871 | EXPECT_TRUE(lease_mgr.addLease(lease))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(lease ))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 871, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(lease)", "false", "true") .c_str()) = :: testing::Message(); | |||
| 872 | } | |||
| 873 | // The pool comprises 256 delegated prefixes. All should be returned. | |||
| 874 | EXPECT_EQ(256, leases.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("256", "leases.size()" , 256, leases.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 874, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 875 | ||||
| 876 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 877 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 877, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 878 | double r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 879 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 879, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 880 | ||||
| 881 | auto i = 0; | |||
| 882 | for (auto const& address_lease : leases) { | |||
| 883 | if (i % 2) { | |||
| 884 | auto lease = address_lease.second; | |||
| 885 | lease->state_ = Lease::STATE_EXPIRED_RECLAIMED; | |||
| 886 | EXPECT_NO_THROW(lease_mgr.updateLease6(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease6(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_886 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_886 ; } } else gtest_label_testnothrow_886 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 886, ("Expected: " "lease_mgr.updateLease6(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 887 | } | |||
| 888 | ++i; | |||
| 889 | } | |||
| 890 | r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 891 | EXPECT_EQ(.5, r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare(".5", "r" , .5, r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 891, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 892 | ||||
| 893 | for (auto j = 0; j < 128; ++j) { | |||
| 894 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 895 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 895, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 896 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 896, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 897 | auto lease = lease_mgr.getLease6(Lease::TYPE_PD, candidate); | |||
| 898 | lease->state_ = Lease::STATE_DEFAULT; | |||
| 899 | EXPECT_NO_THROW(lease_mgr.updateLease6(lease))switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { lease_mgr.updateLease6(lease); } else static_assert(true, "" ); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_899 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_899 ; } } else gtest_label_testnothrow_899 : ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 899, ("Expected: " "lease_mgr.updateLease6(lease)" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 900 | } | |||
| 901 | ||||
| 902 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 903 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 903, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 904 | ||||
| 905 | r = alloc.getOccupancyRate(IOAddress("3000::"), 128, cc_); | |||
| 906 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 906, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 907 | } | |||
| 908 | ||||
| 909 | // Test allocating delegated prefixes from multiple pools. | |||
| 910 | TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPools)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPdPools") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_manyPdPools_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_manyPdPools_Test () = default; ~FreeLeaseQueueAllocatorTest6_manyPdPools_Test( ) override = default; FreeLeaseQueueAllocatorTest6_manyPdPools_Test (const FreeLeaseQueueAllocatorTest6_manyPdPools_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPools_Test & operator =( const FreeLeaseQueueAllocatorTest6_manyPdPools_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPools_Test (FreeLeaseQueueAllocatorTest6_manyPdPools_Test &&) noexcept = delete; FreeLeaseQueueAllocatorTest6_manyPdPools_Test & operator=( FreeLeaseQueueAllocatorTest6_manyPdPools_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_manyPdPools_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "manyPdPools", nullptr, nullptr, ::testing::internal::CodeLocation ("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 910 ), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 910), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 910), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_manyPdPools_Test >); void FreeLeaseQueueAllocatorTest6_manyPdPools_Test::TestBody () { | |||
| 911 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 912 | ||||
| 913 | for (auto i = 0; i < 10; ++i) { | |||
| 914 | ostringstream s; | |||
| 915 | s << "300" << hex << i + 1 << "::"; | |||
| 916 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 917 | IOAddress(s.str()), | |||
| 918 | 120, | |||
| 919 | 128); | |||
| 920 | subnet_->addPool(pool); | |||
| 921 | } | |||
| 922 | size_t total = 65536 + 10 * 256; | |||
| 923 | ||||
| 924 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_924 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_924 ; } } else gtest_label_testnothrow_924 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 924, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 925 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 926 | ||||
| 927 | Pool6Ptr pool; | |||
| 928 | ||||
| 929 | std::set<IOAddress> prefixes; | |||
| 930 | for (size_t i = 0; i < total; ++i) { | |||
| 931 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 0); | |||
| 932 | EXPECT_TRUE(pool)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(pool)) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 932, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "pool", "false", "true") .c_str()) = ::testing::Message(); | |||
| 933 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 933, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 934 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 934, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 935 | prefixes.insert(candidate); | |||
| 936 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 936, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 937 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 937, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 938 | } | |||
| 939 | // Make sure that unique prefixes have been returned. | |||
| 940 | EXPECT_EQ(total, prefixes.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "prefixes.size()" , total, prefixes.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 940, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 941 | ||||
| 942 | double r = alloc.getOccupancyRate(IOAddress("3001::"), 128, cc_); | |||
| 943 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 943, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 944 | } | |||
| 945 | ||||
| 946 | // Test allocating delegated prefixes from multiple pools. | |||
| 947 | TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferLower)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPdPoolsPreferLower") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test () = default; ~FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test () override = default; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test (const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test & operator=( const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test (FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test && ) noexcept = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test & operator=( FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "manyPdPoolsPreferLower", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 947), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 947), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 947), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test >); void FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferLower_Test ::TestBody() { | |||
| 948 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 949 | ||||
| 950 | for (auto i = 0; i < 10; ++i) { | |||
| 951 | ostringstream s; | |||
| 952 | s << "300" << hex << i + 1 << "::"; | |||
| 953 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 954 | IOAddress(s.str()), | |||
| 955 | 120, | |||
| 956 | 128); | |||
| 957 | subnet_->addPool(pool); | |||
| 958 | } | |||
| 959 | ||||
| 960 | size_t total = 65536; | |||
| 961 | ||||
| 962 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_962 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_962 ; } } else gtest_label_testnothrow_962 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 962, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 963 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 964 | ||||
| 965 | Pool6Ptr pool; | |||
| 966 | ||||
| 967 | std::set<IOAddress> prefixes; | |||
| 968 | for (size_t i = 0; i < total; ++i) { | |||
| 969 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_LOWER, IOAddress("::"), 120); | |||
| 970 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 970, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 971 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 971, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 972 | prefixes.insert(candidate); | |||
| 973 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 973, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 974 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 974, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 975 | } | |||
| 976 | // Make sure that unique prefixes have been returned. | |||
| 977 | EXPECT_EQ(total, prefixes.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "prefixes.size()" , total, prefixes.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 977, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 978 | ||||
| 979 | double r = alloc.getOccupancyRate(IOAddress("2001:db8:1:2::"), 120, cc_); | |||
| 980 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 980, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 981 | r = alloc.getOccupancyRate(IOAddress("2001:db8:1:2::"), 128, cc_); | |||
| 982 | EXPECT_EQ(65536. / 68096., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("65536. / 68096." , "r", 65536. / 68096., r))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 982, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 983 | r = alloc.getOccupancyRate(IOAddress("2001:db8:1:2::"), 64, cc_); | |||
| 984 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 984, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 985 | } | |||
| 986 | ||||
| 987 | // Test allocating delegated prefixes from multiple pools. | |||
| 988 | TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferEqual)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPdPoolsPreferEqual") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test () = default; ~FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test () override = default; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test (const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test & operator=( const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test (FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test && ) noexcept = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test & operator=( FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "manyPdPoolsPreferEqual", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 988), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 988), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 988), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test >); void FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferEqual_Test ::TestBody() { | |||
| 989 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 990 | ||||
| 991 | for (auto i = 0; i < 10; ++i) { | |||
| 992 | ostringstream s; | |||
| 993 | s << "300" << hex << i + 1 << "::"; | |||
| 994 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 995 | IOAddress(s.str()), | |||
| 996 | 120, | |||
| 997 | 128); | |||
| 998 | subnet_->addPool(pool); | |||
| 999 | } | |||
| 1000 | ||||
| 1001 | size_t total = 10 * 256; | |||
| 1002 | ||||
| 1003 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1003 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1003 ; } } else gtest_label_testnothrow_1003 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1003, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 1004 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 1005 | ||||
| 1006 | Pool6Ptr pool; | |||
| 1007 | ||||
| 1008 | std::set<IOAddress> prefixes; | |||
| 1009 | for (size_t i = 0; i < total; ++i) { | |||
| 1010 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_EQUAL, IOAddress("::"), 128); | |||
| 1011 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1011, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 1012 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1012, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 1013 | prefixes.insert(candidate); | |||
| 1014 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1014, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 1015 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1015, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 1016 | } | |||
| 1017 | // Make sure that unique prefixes have been returned. | |||
| 1018 | EXPECT_EQ(total, prefixes.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "prefixes.size()" , total, prefixes.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1018, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1019 | double r = alloc.getOccupancyRate(IOAddress("3001::"), 128, cc_); | |||
| 1020 | EXPECT_EQ(2560. / 68096., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("2560. / 68096." , "r", 2560. / 68096., r))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1020, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1021 | } | |||
| 1022 | ||||
| 1023 | // Test allocating delegated prefixes from multiple pools. | |||
| 1024 | TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferHigher)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("manyPdPoolsPreferHigher") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test () = default; ~FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test () override = default; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test (const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test & operator=( const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test &) = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test (FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test && ) noexcept = delete; FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test & operator=( FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "manyPdPoolsPreferHigher", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1024), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1024), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1024), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test >); void FreeLeaseQueueAllocatorTest6_manyPdPoolsPreferHigher_Test ::TestBody() { | |||
| 1025 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 1026 | ||||
| 1027 | for (auto i = 0; i < 10; ++i) { | |||
| 1028 | ostringstream s; | |||
| 1029 | s << "300" << hex << i + 1 << "::"; | |||
| 1030 | auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 1031 | IOAddress(s.str()), | |||
| 1032 | 120, | |||
| 1033 | 128); | |||
| 1034 | subnet_->addPool(pool); | |||
| 1035 | } | |||
| 1036 | ||||
| 1037 | size_t total = 10 * 256; | |||
| 1038 | ||||
| 1039 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1039 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1039 ; } } else gtest_label_testnothrow_1039 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1039, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 1040 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 1041 | ||||
| 1042 | Pool6Ptr pool; | |||
| 1043 | ||||
| 1044 | std::set<IOAddress> prefixes; | |||
| 1045 | bool assigned = false; | |||
| 1046 | for (size_t i = 0; i < total; ++i) { | |||
| 1047 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 64); | |||
| 1048 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1048, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 1049 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1049, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 1050 | prefixes.insert(candidate); | |||
| 1051 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1051, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 1052 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1052, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 1053 | if (candidate == IOAddress("3001::")) { | |||
| 1054 | assigned = true; | |||
| 1055 | } | |||
| 1056 | } | |||
| 1057 | // Make sure that unique prefixes have been returned. | |||
| 1058 | EXPECT_EQ(total, prefixes.size())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("total", "prefixes.size()" , total, prefixes.size()))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1058, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1059 | double r = alloc.getOccupancyRate(IOAddress("3001::"), 128, cc_); | |||
| 1060 | // getOccupancyRate argument is always considered as not free. | |||
| 1061 | EXPECT_EQ((assigned ? 2560. : 2561.) / 68096., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("(assigned ? 2560. : 2561.) / 68096." , "r", (assigned ? 2560. : 2561.) / 68096., r))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc", 1061, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1062 | } | |||
| 1063 | ||||
| 1064 | // Test that the allocator respects client class guards. | |||
| 1065 | TEST_F(FreeLeaseQueueAllocatorTest6, pdPoolsClientClasses)static_assert(sizeof("FreeLeaseQueueAllocatorTest6") > 1, "test_suite_name must not be empty" ); static_assert(sizeof("pdPoolsClientClasses") > 1, "test_name must not be empty" ); class FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test : public FreeLeaseQueueAllocatorTest6 { public: FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test () = default; ~FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test () override = default; FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test (const FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test &) = delete; FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test & operator=( const FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test &) = delete; FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test (FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test && ) noexcept = delete; FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test & operator=( FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test &&) noexcept = delete; private: void TestBody() override ; [[maybe_unused]] static ::testing::TestInfo* const test_info_ ; }; ::testing::TestInfo* const FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "FreeLeaseQueueAllocatorTest6" , "pdPoolsClientClasses", nullptr, nullptr, ::testing::internal ::CodeLocation("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1065), (::testing::internal::GetTypeId<FreeLeaseQueueAllocatorTest6 >()), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetSetUpCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1065), ::testing::internal::SuiteApiResolver< FreeLeaseQueueAllocatorTest6 >::GetTearDownCaseOrSuite("../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1065), new ::testing::internal::TestFactoryImpl<FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test >); void FreeLeaseQueueAllocatorTest6_pdPoolsClientClasses_Test ::TestBody() { | |||
| 1066 | FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_); | |||
| 1067 | ||||
| 1068 | // First pool only allows the client class foo. | |||
| 1069 | pd_pool_->allowClientClass("foo"); | |||
| 1070 | ||||
| 1071 | auto pool2 = boost::make_shared<Pool6>(Lease::TYPE_PD, | |||
| 1072 | IOAddress("3000:1::"), | |||
| 1073 | 120, | |||
| 1074 | 128); | |||
| 1075 | // Second pool only allows the client class bar. | |||
| 1076 | pool2->allowClientClass("bar"); | |||
| 1077 | subnet_->addPool(pool2); | |||
| 1078 | ||||
| 1079 | ASSERT_NO_THROW(alloc.initAfterConfigure())switch (0) case 0: default: if (::testing::internal::TrueWithString gtest_msg{}) { try { if (::testing::internal::AlwaysTrue()) { alloc.initAfterConfigure(); } else static_assert(true, ""); } catch (std::exception const& e) { gtest_msg.value = "it throws " ; gtest_msg.value += ::testing::internal::GetTypeName(typeid( e)); gtest_msg.value += " with description \""; gtest_msg.value += e.what(); gtest_msg.value += "\"."; goto gtest_label_testnothrow_1079 ; } catch (...) { gtest_msg.value = "it throws."; goto gtest_label_testnothrow_1079 ; } } else gtest_label_testnothrow_1079 : return ::testing::internal ::AssertHelper(::testing::TestPartResult::kFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1079, ("Expected: " "alloc.initAfterConfigure()" " doesn't throw an exception.\n" " Actual: " + gtest_msg.value) .c_str()) = ::testing::Message (); | |||
| 1080 | auto& lease_mgr = LeaseMgrFactory::instance(); | |||
| 1081 | ||||
| 1082 | Pool6Ptr pool; | |||
| 1083 | ||||
| 1084 | IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 64); | |||
| 1085 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1085, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 1086 | ||||
| 1087 | cc_.insert("bar"); | |||
| 1088 | for (auto i = 0; i < 256; ++i) { | |||
| 1089 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 64); | |||
| 1090 | EXPECT_FALSE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(candidate.isV6Zero( )))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1090, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "true", "false") .c_str()) = ::testing ::Message(); | |||
| 1091 | EXPECT_TRUE(lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i)))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(lease_mgr.addLease(createLease6 (Lease::TYPE_PD, candidate, i)))) ; else ::testing::internal:: AssertHelper(::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1091, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "lease_mgr.addLease(createLease6(Lease::TYPE_PD, candidate, i))" , "false", "true") .c_str()) = ::testing::Message(); | |||
| 1092 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1092, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate)", "false", "true" ) .c_str()) = ::testing::Message(); | |||
| 1093 | EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(subnet_->inPool(Lease ::TYPE_PD, candidate, cc_))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1093, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "subnet_->inPool(Lease::TYPE_PD, candidate, cc_)", "false" , "true") .c_str()) = ::testing::Message(); | |||
| 1094 | } | |||
| 1095 | ||||
| 1096 | candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 64); | |||
| 1097 | EXPECT_TRUE(candidate.isV6Zero())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(candidate.isV6Zero()) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1097, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "candidate.isV6Zero()", "false", "true") .c_str()) = ::testing ::Message(); | |||
| 1098 | ||||
| 1099 | double r = alloc.getOccupancyRate(IOAddress("3000:1::"), 128, cc_); | |||
| 1100 | EXPECT_EQ(1., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("1.", "r" , 1., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1100, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1101 | cc_.insert("foo"); | |||
| 1102 | r = alloc.getOccupancyRate(IOAddress("3000:1::"), 128, cc_); | |||
| 1103 | EXPECT_EQ(256. / 65792., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("256. / 65792." , "r", 256. / 65792., r))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1103, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1104 | cc_.clear(); | |||
| 1105 | r = alloc.getOccupancyRate(IOAddress("3000:1::"), 128, cc_); | |||
| 1106 | EXPECT_EQ(0., r)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("0.", "r" , 0., r))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "../../../src/lib/dhcpsrv/tests/flq_allocator_unittest.cc" , 1106, gtest_ar.failure_message()) = ::testing::Message(); | |||
| 1107 | } | |||
| 1108 | ||||
| 1109 | } // end of isc::dhcp::test namespace | |||
| 1110 | } // end of isc::dhcp namespace | |||
| 1111 | } // end of isc namespace |
| 1 | #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED |
| 2 | #define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED |
| 3 | |
| 4 | // |
| 5 | // weak_ptr.hpp |
| 6 | // |
| 7 | // Copyright (c) 2001, 2002, 2003 Peter Dimov |
| 8 | // |
| 9 | // Distributed under the Boost Software License, Version 1.0. (See |
| 10 | // accompanying file LICENSE_1_0.txt or copy at |
| 11 | // http://www.boost.org/LICENSE_1_0.txt) |
| 12 | // |
| 13 | // See http://www.boost.org/libs/smart_ptr/ for documentation. |
| 14 | // |
| 15 | |
| 16 | #include <boost/smart_ptr/detail/requires_cxx11.hpp> |
| 17 | #include <boost/smart_ptr/detail/shared_count.hpp> |
| 18 | #include <boost/smart_ptr/shared_ptr.hpp> |
| 19 | #include <boost/smart_ptr/detail/sp_noexcept.hpp> |
| 20 | #include <memory> |
| 21 | #include <cstddef> |
| 22 | |
| 23 | namespace boost |
| 24 | { |
| 25 | |
| 26 | template<class T> class weak_ptr |
| 27 | { |
| 28 | private: |
| 29 | |
| 30 | // Borland 5.5.1 specific workarounds |
| 31 | typedef weak_ptr<T> this_type; |
| 32 | |
| 33 | public: |
| 34 | |
| 35 | typedef typename boost::detail::sp_element< T >::type element_type; |
| 36 | |
| 37 | BOOST_CONSTEXPRconstexpr weak_ptr() BOOST_SP_NOEXCEPTnoexcept : px(0), pn() |
| 38 | { |
| 39 | } |
| 40 | |
| 41 | // generated copy constructor, assignment, destructor are fine... |
| 42 | |
| 43 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
| 44 | |
| 45 | // ... except in C++0x, move disables the implicit copy |
| 46 | |
| 47 | weak_ptr( weak_ptr const & r ) BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn( r.pn ) |
| 48 | { |
| 49 | } |
| 50 | |
| 51 | weak_ptr & operator=( weak_ptr const & r ) BOOST_SP_NOEXCEPTnoexcept |
| 52 | { |
| 53 | px = r.px; |
| 54 | pn = r.pn; |
| 55 | return *this; |
| 56 | } |
| 57 | |
| 58 | #endif |
| 59 | |
| 60 | // |
| 61 | // The "obvious" converting constructor implementation: |
| 62 | // |
| 63 | // template<class Y> |
| 64 | // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) |
| 65 | // { |
| 66 | // } |
| 67 | // |
| 68 | // has a serious problem. |
| 69 | // |
| 70 | // r.px may already have been invalidated. The px(r.px) |
| 71 | // conversion may require access to *r.px (virtual inheritance). |
| 72 | // |
| 73 | // It is not possible to avoid spurious access violations since |
| 74 | // in multithreaded programs r.px may be invalidated at any point. |
| 75 | // |
| 76 | |
| 77 | template<class Y> |
| 78 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
| 79 | |
| 80 | weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) |
| 81 | |
| 82 | #else |
| 83 | |
| 84 | weak_ptr( weak_ptr<Y> const & r ) |
| 85 | |
| 86 | #endif |
| 87 | BOOST_SP_NOEXCEPTnoexcept : px(r.lock().get()), pn(r.pn) |
| 88 | { |
| 89 | boost::detail::sp_assert_convertible< Y, T >(); |
| 90 | } |
| 91 | |
| 92 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
| 93 | |
| 94 | template<class Y> |
| 95 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
| 96 | |
| 97 | weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) |
| 98 | |
| 99 | #else |
| 100 | |
| 101 | weak_ptr( weak_ptr<Y> && r ) |
| 102 | |
| 103 | #endif |
| 104 | BOOST_SP_NOEXCEPTnoexcept : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) |
| 105 | { |
| 106 | boost::detail::sp_assert_convertible< Y, T >(); |
| 107 | r.px = 0; |
| 108 | } |
| 109 | |
| 110 | // for better efficiency in the T == Y case |
| 111 | weak_ptr( weak_ptr && r ) |
| 112 | BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) |
| 113 | { |
| 114 | r.px = 0; |
| 115 | } |
| 116 | |
| 117 | // for better efficiency in the T == Y case |
| 118 | weak_ptr & operator=( weak_ptr && r ) BOOST_SP_NOEXCEPTnoexcept |
| 119 | { |
| 120 | this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); |
| 121 | return *this; |
| 122 | } |
| 123 | |
| 124 | |
| 125 | #endif |
| 126 | |
| 127 | template<class Y> |
| 128 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
| 129 | |
| 130 | weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) |
| 131 | |
| 132 | #else |
| 133 | |
| 134 | weak_ptr( shared_ptr<Y> const & r ) |
| 135 | |
| 136 | #endif |
| 137 | BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn( r.pn ) |
| 138 | { |
| 139 | boost::detail::sp_assert_convertible< Y, T >(); |
| 140 | } |
| 141 | |
| 142 | // aliasing |
| 143 | template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPTnoexcept: px( p ), pn( r.pn ) |
| 144 | { |
| 145 | } |
| 146 | |
| 147 | template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPTnoexcept: px( p ), pn( r.pn ) |
| 148 | { |
| 149 | } |
| 150 | |
| 151 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
| 152 | |
| 153 | template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) BOOST_SP_NOEXCEPTnoexcept: px( p ), pn( std::move( r.pn ) ) |
| 154 | { |
| 155 | } |
| 156 | |
| 157 | #endif |
| 158 | |
| 159 | #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) |
| 160 | |
| 161 | template<class Y> |
| 162 | weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_SP_NOEXCEPTnoexcept |
| 163 | { |
| 164 | boost::detail::sp_assert_convertible< Y, T >(); |
| 165 | |
| 166 | px = r.lock().get(); |
| 167 | pn = r.pn; |
| 168 | |
| 169 | return *this; |
| 170 | } |
| 171 | |
| 172 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
| 173 | |
| 174 | template<class Y> |
| 175 | weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_SP_NOEXCEPTnoexcept |
| 176 | { |
| 177 | this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this ); |
| 178 | return *this; |
| 179 | } |
| 180 | |
| 181 | #endif |
| 182 | |
| 183 | template<class Y> |
| 184 | weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPTnoexcept |
| 185 | { |
| 186 | boost::detail::sp_assert_convertible< Y, T >(); |
| 187 | |
| 188 | px = r.px; |
| 189 | pn = r.pn; |
| 190 | |
| 191 | return *this; |
| 192 | } |
| 193 | |
| 194 | #endif |
| 195 | |
| 196 | shared_ptr<T> lock() const BOOST_SP_NOEXCEPTnoexcept |
| 197 | { |
| 198 | return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() ); |
| 199 | } |
| 200 | |
| 201 | long use_count() const BOOST_SP_NOEXCEPTnoexcept |
| 202 | { |
| 203 | return pn.use_count(); |
| 204 | } |
| 205 | |
| 206 | bool expired() const BOOST_SP_NOEXCEPTnoexcept |
| 207 | { |
| 208 | return pn.use_count() == 0; |
| 209 | } |
| 210 | |
| 211 | bool _empty() const BOOST_SP_NOEXCEPTnoexcept // extension, not in std::weak_ptr |
| 212 | { |
| 213 | return pn.empty(); |
| 214 | } |
| 215 | |
| 216 | bool empty() const BOOST_SP_NOEXCEPTnoexcept // extension, not in std::weak_ptr |
| 217 | { |
| 218 | return pn.empty(); |
| 219 | } |
| 220 | |
| 221 | void reset() BOOST_SP_NOEXCEPTnoexcept |
| 222 | { |
| 223 | this_type().swap(*this); |
| 224 | } |
| 225 | |
| 226 | void swap(this_type & other) BOOST_SP_NOEXCEPTnoexcept |
| 227 | { |
| 228 | std::swap(px, other.px); |
| 229 | pn.swap(other.pn); |
| 230 | } |
| 231 | |
| 232 | template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
| 233 | { |
| 234 | return pn < rhs.pn; |
| 235 | } |
| 236 | |
| 237 | template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
| 238 | { |
| 239 | return pn < rhs.pn; |
| 240 | } |
| 241 | |
| 242 | template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
| 243 | { |
| 244 | return pn == rhs.pn; |
| 245 | } |
| 246 | |
| 247 | template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
| 248 | { |
| 249 | return pn == rhs.pn; |
| 250 | } |
| 251 | |
| 252 | std::size_t owner_hash_value() const BOOST_SP_NOEXCEPTnoexcept |
| 253 | { |
| 254 | return pn.hash_value(); |
| 255 | } |
| 256 | |
| 257 | // Tasteless as this may seem, making all members public allows member templates |
| 258 | // to work in the absence of member template friends. (Matthew Langston) |
| 259 | |
| 260 | #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
| 261 | |
| 262 | private: |
| 263 | |
| 264 | template<class Y> friend class weak_ptr; |
| 265 | template<class Y> friend class shared_ptr; |
| 266 | |
| 267 | #endif |
| 268 | |
| 269 | element_type * px; // contained pointer |
| 270 | boost::detail::weak_count pn; // reference counter |
| 271 | |
| 272 | }; // weak_ptr |
| 273 | |
| 274 | template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_SP_NOEXCEPTnoexcept |
| 275 | { |
| 276 | return a.owner_before( b ); |
| 277 | } |
| 278 | |
| 279 | template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_SP_NOEXCEPTnoexcept |
| 280 | { |
| 281 | a.swap(b); |
| 282 | } |
| 283 | |
| 284 | #if defined(__cpp_deduction_guides201703L) |
| 285 | |
| 286 | template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>; |
| 287 | |
| 288 | #endif |
| 289 | |
| 290 | // hash_value |
| 291 | |
| 292 | template< class T > std::size_t hash_value( boost::weak_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
| 293 | { |
| 294 | return p.owner_hash_value(); |
| 295 | } |
| 296 | |
| 297 | } // namespace boost |
| 298 | |
| 299 | // std::hash, std::equal_to |
| 300 | |
| 301 | namespace std |
| 302 | { |
| 303 | |
| 304 | #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
| 305 | |
| 306 | template<class T> struct hash< ::boost::weak_ptr<T> > |
| 307 | { |
| 308 | std::size_t operator()( ::boost::weak_ptr<T> const & p ) const BOOST_SP_NOEXCEPTnoexcept |
| 309 | { |
| 310 | return p.owner_hash_value(); |
| 311 | } |
| 312 | }; |
| 313 | |
| 314 | #endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
| 315 | |
| 316 | template<class T> struct equal_to< ::boost::weak_ptr<T> > |
| 317 | { |
| 318 | bool operator()( ::boost::weak_ptr<T> const & a, ::boost::weak_ptr<T> const & b ) const BOOST_SP_NOEXCEPTnoexcept |
| 319 | { |
| 320 | return a.owner_equals( b ); |
| 321 | } |
| 322 | }; |
| 323 | |
| 324 | } // namespace std |
| 325 | |
| 326 | #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED |
| 1 | #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED | ||||||||
| 2 | #define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED | ||||||||
| 3 | |||||||||
| 4 | // MS compatible compilers support #pragma once | ||||||||
| 5 | |||||||||
| 6 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||||||
| 7 | # pragma once | ||||||||
| 8 | #endif | ||||||||
| 9 | |||||||||
| 10 | // | ||||||||
| 11 | // detail/shared_count.hpp | ||||||||
| 12 | // | ||||||||
| 13 | // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||||||
| 14 | // Copyright 2004-2005 Peter Dimov | ||||||||
| 15 | // | ||||||||
| 16 | // Distributed under the Boost Software License, Version 1.0. (See | ||||||||
| 17 | // accompanying file LICENSE_1_0.txt or copy at | ||||||||
| 18 | // http://www.boost.org/LICENSE_1_0.txt) | ||||||||
| 19 | // | ||||||||
| 20 | |||||||||
| 21 | #if defined(__BORLANDC__) && !defined(__clang__1) | ||||||||
| 22 | # pragma warn -8027 // Functions containing try are not expanded inline | ||||||||
| 23 | #endif | ||||||||
| 24 | |||||||||
| 25 | #include <boost/smart_ptr/bad_weak_ptr.hpp> | ||||||||
| 26 | #include <boost/smart_ptr/detail/sp_counted_base.hpp> | ||||||||
| 27 | #include <boost/smart_ptr/detail/sp_counted_impl.hpp> | ||||||||
| 28 | #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> | ||||||||
| 29 | #include <boost/smart_ptr/detail/sp_noexcept.hpp> | ||||||||
| 30 | #include <boost/core/checked_delete.hpp> | ||||||||
| 31 | #include <boost/throw_exception.hpp> | ||||||||
| 32 | #include <boost/core/addressof.hpp> | ||||||||
| 33 | #include <boost/config.hpp> | ||||||||
| 34 | #include <boost/config/workaround.hpp> | ||||||||
| 35 | #include <boost/cstdint.hpp> | ||||||||
| 36 | #include <memory> // std::auto_ptr | ||||||||
| 37 | #include <functional> // std::less | ||||||||
| 38 | #include <cstddef> // std::size_t | ||||||||
| 39 | |||||||||
| 40 | #ifdef BOOST_NO_EXCEPTIONS | ||||||||
| 41 | # include <new> // std::bad_alloc | ||||||||
| 42 | #endif | ||||||||
| 43 | |||||||||
| 44 | #if defined( BOOST_SP_DISABLE_DEPRECATED ) | ||||||||
| 45 | #pragma GCC diagnostic push | ||||||||
| 46 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||||||||
| 47 | #endif | ||||||||
| 48 | |||||||||
| 49 | namespace boost | ||||||||
| 50 | { | ||||||||
| 51 | |||||||||
| 52 | namespace movelib | ||||||||
| 53 | { | ||||||||
| 54 | |||||||||
| 55 | template< class T, class D > class unique_ptr; | ||||||||
| 56 | |||||||||
| 57 | } // namespace movelib | ||||||||
| 58 | |||||||||
| 59 | namespace detail | ||||||||
| 60 | { | ||||||||
| 61 | |||||||||
| 62 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 63 | |||||||||
| 64 | int const shared_count_id = 0x2C35F101; | ||||||||
| 65 | int const weak_count_id = 0x298C38A4; | ||||||||
| 66 | |||||||||
| 67 | #endif | ||||||||
| 68 | |||||||||
| 69 | struct sp_nothrow_tag {}; | ||||||||
| 70 | |||||||||
| 71 | template< class D > struct sp_inplace_tag | ||||||||
| 72 | { | ||||||||
| 73 | }; | ||||||||
| 74 | |||||||||
| 75 | template< class T > class sp_reference_wrapper | ||||||||
| 76 | { | ||||||||
| 77 | public: | ||||||||
| 78 | |||||||||
| 79 | explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) ) | ||||||||
| 80 | { | ||||||||
| 81 | } | ||||||||
| 82 | |||||||||
| 83 | template< class Y > void operator()( Y * p ) const | ||||||||
| 84 | { | ||||||||
| 85 | (*t_)( p ); | ||||||||
| 86 | } | ||||||||
| 87 | |||||||||
| 88 | private: | ||||||||
| 89 | |||||||||
| 90 | T * t_; | ||||||||
| 91 | }; | ||||||||
| 92 | |||||||||
| 93 | template< class D > struct sp_convert_reference | ||||||||
| 94 | { | ||||||||
| 95 | typedef D type; | ||||||||
| 96 | }; | ||||||||
| 97 | |||||||||
| 98 | template< class D > struct sp_convert_reference< D& > | ||||||||
| 99 | { | ||||||||
| 100 | typedef sp_reference_wrapper< D > type; | ||||||||
| 101 | }; | ||||||||
| 102 | |||||||||
| 103 | template<class T> std::size_t sp_hash_pointer( T* p ) BOOST_NOEXCEPTnoexcept | ||||||||
| 104 | { | ||||||||
| 105 | boost::uintptr_t v = reinterpret_cast<boost::uintptr_t>( p ); | ||||||||
| 106 | |||||||||
| 107 | // match boost::hash<T*> | ||||||||
| 108 | return static_cast<std::size_t>( v + ( v >> 3 ) ); | ||||||||
| 109 | } | ||||||||
| 110 | |||||||||
| 111 | class weak_count; | ||||||||
| 112 | |||||||||
| 113 | class shared_count | ||||||||
| 114 | { | ||||||||
| 115 | private: | ||||||||
| 116 | |||||||||
| 117 | sp_counted_base * pi_; | ||||||||
| 118 | |||||||||
| 119 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 120 | int id_; | ||||||||
| 121 | #endif | ||||||||
| 122 | |||||||||
| 123 | friend class weak_count; | ||||||||
| 124 | |||||||||
| 125 | public: | ||||||||
| 126 | |||||||||
| 127 | BOOST_CONSTEXPRconstexpr shared_count() BOOST_SP_NOEXCEPTnoexcept: pi_(0) | ||||||||
| 128 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 129 | , id_(shared_count_id) | ||||||||
| 130 | #endif | ||||||||
| 131 | { | ||||||||
| 132 | } | ||||||||
| 133 | |||||||||
| 134 | BOOST_CONSTEXPRconstexpr explicit shared_count( sp_counted_base * pi ) BOOST_SP_NOEXCEPTnoexcept: pi_( pi ) | ||||||||
| 135 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 136 | , id_(shared_count_id) | ||||||||
| 137 | #endif | ||||||||
| 138 | { | ||||||||
| 139 | } | ||||||||
| 140 | |||||||||
| 141 | template<class Y> explicit shared_count( Y * p ): pi_( 0 ) | ||||||||
| 142 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 143 | , id_(shared_count_id) | ||||||||
| 144 | #endif | ||||||||
| 145 | { | ||||||||
| 146 | #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 147 | |||||||||
| 148 | try | ||||||||
| 149 | { | ||||||||
| 150 | pi_ = new sp_counted_impl_p<Y>( p ); | ||||||||
| 151 | } | ||||||||
| 152 | catch(...) | ||||||||
| 153 | { | ||||||||
| 154 | boost::checked_delete( p ); | ||||||||
| 155 | throw; | ||||||||
| 156 | } | ||||||||
| 157 | |||||||||
| 158 | #else | ||||||||
| 159 | |||||||||
| 160 | pi_ = new sp_counted_impl_p<Y>( p ); | ||||||||
| 161 | |||||||||
| 162 | if( pi_ == 0 ) | ||||||||
| 163 | { | ||||||||
| 164 | boost::checked_delete( p ); | ||||||||
| 165 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 166 | } | ||||||||
| 167 | |||||||||
| 168 | #endif | ||||||||
| 169 | } | ||||||||
| 170 | |||||||||
| 171 | #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )((1 + 0 == 0) && (BOOST_MSVC != 0) && (1 % (( (BOOST_MSVC <= 1200) ) + 1))) | ||||||||
| 172 | template<class Y, class D> shared_count( Y * p, D d ): pi_(0) | ||||||||
| 173 | #else | ||||||||
| 174 | template<class P, class D> shared_count( P p, D d ): pi_(0) | ||||||||
| 175 | #endif | ||||||||
| 176 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 177 | , id_(shared_count_id) | ||||||||
| 178 | #endif | ||||||||
| 179 | { | ||||||||
| 180 | #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )((1 + 0 == 0) && (BOOST_MSVC != 0) && (1 % (( (BOOST_MSVC <= 1200) ) + 1))) | ||||||||
| 181 | typedef Y* P; | ||||||||
| 182 | #endif | ||||||||
| 183 | #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 184 | |||||||||
| 185 | try | ||||||||
| 186 | { | ||||||||
| 187 | pi_ = new sp_counted_impl_pd<P, D>(p, d); | ||||||||
| 188 | } | ||||||||
| 189 | catch(...) | ||||||||
| 190 | { | ||||||||
| 191 | d(p); // delete p | ||||||||
| 192 | throw; | ||||||||
| 193 | } | ||||||||
| 194 | |||||||||
| 195 | #else | ||||||||
| 196 | |||||||||
| 197 | pi_ = new sp_counted_impl_pd<P, D>(p, d); | ||||||||
| 198 | |||||||||
| 199 | if(pi_ == 0) | ||||||||
| 200 | { | ||||||||
| 201 | d(p); // delete p | ||||||||
| 202 | boost::throw_exception(std::bad_alloc()); | ||||||||
| 203 | } | ||||||||
| 204 | |||||||||
| 205 | #endif | ||||||||
| 206 | } | ||||||||
| 207 | |||||||||
| 208 | #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) | ||||||||
| 209 | |||||||||
| 210 | template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 ) | ||||||||
| 211 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 212 | , id_(shared_count_id) | ||||||||
| 213 | #endif | ||||||||
| 214 | { | ||||||||
| 215 | #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 216 | |||||||||
| 217 | try | ||||||||
| 218 | { | ||||||||
| 219 | pi_ = new sp_counted_impl_pd< P, D >( p ); | ||||||||
| 220 | } | ||||||||
| 221 | catch( ... ) | ||||||||
| 222 | { | ||||||||
| 223 | D::operator_fn( p ); // delete p | ||||||||
| 224 | throw; | ||||||||
| 225 | } | ||||||||
| 226 | |||||||||
| 227 | #else | ||||||||
| 228 | |||||||||
| 229 | pi_ = new sp_counted_impl_pd< P, D >( p ); | ||||||||
| 230 | |||||||||
| 231 | if( pi_ == 0 ) | ||||||||
| 232 | { | ||||||||
| 233 | D::operator_fn( p ); // delete p | ||||||||
| 234 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 235 | } | ||||||||
| 236 | |||||||||
| 237 | #endif // #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 238 | } | ||||||||
| 239 | |||||||||
| 240 | #endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) | ||||||||
| 241 | |||||||||
| 242 | template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 ) | ||||||||
| 243 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 244 | , id_(shared_count_id) | ||||||||
| 245 | #endif | ||||||||
| 246 | { | ||||||||
| 247 | typedef sp_counted_impl_pda<P, D, A> impl_type; | ||||||||
| 248 | |||||||||
| 249 | #if !defined( BOOST_NO_CXX11_ALLOCATOR ) | ||||||||
| 250 | |||||||||
| 251 | typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2; | ||||||||
| 252 | |||||||||
| 253 | #else | ||||||||
| 254 | |||||||||
| 255 | typedef typename A::template rebind< impl_type >::other A2; | ||||||||
| 256 | |||||||||
| 257 | #endif | ||||||||
| 258 | |||||||||
| 259 | A2 a2( a ); | ||||||||
| 260 | |||||||||
| 261 | #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 262 | |||||||||
| 263 | try | ||||||||
| 264 | { | ||||||||
| 265 | pi_ = a2.allocate( 1 ); | ||||||||
| 266 | ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); | ||||||||
| 267 | } | ||||||||
| 268 | catch(...) | ||||||||
| 269 | { | ||||||||
| 270 | d( p ); | ||||||||
| 271 | |||||||||
| 272 | if( pi_ != 0 ) | ||||||||
| 273 | { | ||||||||
| 274 | a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); | ||||||||
| 275 | } | ||||||||
| 276 | |||||||||
| 277 | throw; | ||||||||
| 278 | } | ||||||||
| 279 | |||||||||
| 280 | #else | ||||||||
| 281 | |||||||||
| 282 | pi_ = a2.allocate( 1 ); | ||||||||
| 283 | |||||||||
| 284 | if( pi_ != 0 ) | ||||||||
| 285 | { | ||||||||
| 286 | ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); | ||||||||
| 287 | } | ||||||||
| 288 | else | ||||||||
| 289 | { | ||||||||
| 290 | d( p ); | ||||||||
| 291 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 292 | } | ||||||||
| 293 | |||||||||
| 294 | #endif | ||||||||
| 295 | } | ||||||||
| 296 | |||||||||
| 297 | #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) | ||||||||
| 298 | |||||||||
| 299 | template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 ) | ||||||||
| 300 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 301 | , id_(shared_count_id) | ||||||||
| 302 | #endif | ||||||||
| 303 | { | ||||||||
| 304 | typedef sp_counted_impl_pda< P, D, A > impl_type; | ||||||||
| 305 | |||||||||
| 306 | #if !defined( BOOST_NO_CXX11_ALLOCATOR ) | ||||||||
| 307 | |||||||||
| 308 | typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2; | ||||||||
| 309 | |||||||||
| 310 | #else | ||||||||
| 311 | |||||||||
| 312 | typedef typename A::template rebind< impl_type >::other A2; | ||||||||
| 313 | |||||||||
| 314 | #endif | ||||||||
| 315 | |||||||||
| 316 | A2 a2( a ); | ||||||||
| 317 | |||||||||
| 318 | #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 319 | |||||||||
| 320 | try | ||||||||
| 321 | { | ||||||||
| 322 | pi_ = a2.allocate( 1 ); | ||||||||
| 323 | ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); | ||||||||
| 324 | } | ||||||||
| 325 | catch(...) | ||||||||
| 326 | { | ||||||||
| 327 | D::operator_fn( p ); | ||||||||
| 328 | |||||||||
| 329 | if( pi_ != 0 ) | ||||||||
| 330 | { | ||||||||
| 331 | a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); | ||||||||
| 332 | } | ||||||||
| 333 | |||||||||
| 334 | throw; | ||||||||
| 335 | } | ||||||||
| 336 | |||||||||
| 337 | #else | ||||||||
| 338 | |||||||||
| 339 | pi_ = a2.allocate( 1 ); | ||||||||
| 340 | |||||||||
| 341 | if( pi_ != 0 ) | ||||||||
| 342 | { | ||||||||
| 343 | ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); | ||||||||
| 344 | } | ||||||||
| 345 | else | ||||||||
| 346 | { | ||||||||
| 347 | D::operator_fn( p ); | ||||||||
| 348 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 349 | } | ||||||||
| 350 | |||||||||
| 351 | #endif // #ifndef BOOST_NO_EXCEPTIONS | ||||||||
| 352 | } | ||||||||
| 353 | |||||||||
| 354 | #endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) | ||||||||
| 355 | |||||||||
| 356 | #ifndef BOOST_NO_AUTO_PTR | ||||||||
| 357 | |||||||||
| 358 | // auto_ptr<Y> is special cased to provide the strong guarantee | ||||||||
| 359 | |||||||||
| 360 | template<class Y> | ||||||||
| 361 | explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) ) | ||||||||
| 362 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 363 | , id_(shared_count_id) | ||||||||
| 364 | #endif | ||||||||
| 365 | { | ||||||||
| 366 | #ifdef BOOST_NO_EXCEPTIONS | ||||||||
| 367 | |||||||||
| 368 | if( pi_ == 0 ) | ||||||||
| 369 | { | ||||||||
| 370 | boost::throw_exception(std::bad_alloc()); | ||||||||
| 371 | } | ||||||||
| 372 | |||||||||
| 373 | #endif | ||||||||
| 374 | |||||||||
| 375 | r.release(); | ||||||||
| 376 | } | ||||||||
| 377 | |||||||||
| 378 | #endif | ||||||||
| 379 | |||||||||
| 380 | #if !defined( BOOST_NO_CXX11_SMART_PTR ) | ||||||||
| 381 | |||||||||
| 382 | template<class Y, class D> | ||||||||
| 383 | explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 ) | ||||||||
| 384 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 385 | , id_(shared_count_id) | ||||||||
| 386 | #endif | ||||||||
| 387 | { | ||||||||
| 388 | typedef typename sp_convert_reference<D>::type D2; | ||||||||
| 389 | |||||||||
| 390 | D2 d2( static_cast<D&&>( r.get_deleter() ) ); | ||||||||
| 391 | pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 ); | ||||||||
| 392 | |||||||||
| 393 | #ifdef BOOST_NO_EXCEPTIONS | ||||||||
| 394 | |||||||||
| 395 | if( pi_ == 0 ) | ||||||||
| 396 | { | ||||||||
| 397 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 398 | } | ||||||||
| 399 | |||||||||
| 400 | #endif | ||||||||
| 401 | |||||||||
| 402 | r.release(); | ||||||||
| 403 | } | ||||||||
| 404 | |||||||||
| 405 | #endif | ||||||||
| 406 | |||||||||
| 407 | template<class Y, class D> | ||||||||
| 408 | explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 ) | ||||||||
| 409 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 410 | , id_(shared_count_id) | ||||||||
| 411 | #endif | ||||||||
| 412 | { | ||||||||
| 413 | typedef typename sp_convert_reference<D>::type D2; | ||||||||
| 414 | |||||||||
| 415 | D2 d2( r.get_deleter() ); | ||||||||
| 416 | pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 ); | ||||||||
| 417 | |||||||||
| 418 | #ifdef BOOST_NO_EXCEPTIONS | ||||||||
| 419 | |||||||||
| 420 | if( pi_ == 0 ) | ||||||||
| 421 | { | ||||||||
| 422 | boost::throw_exception( std::bad_alloc() ); | ||||||||
| 423 | } | ||||||||
| 424 | |||||||||
| 425 | #endif | ||||||||
| 426 | |||||||||
| 427 | r.release(); | ||||||||
| 428 | } | ||||||||
| 429 | |||||||||
| 430 | ~shared_count() /*BOOST_SP_NOEXCEPT*/ | ||||||||
| 431 | { | ||||||||
| 432 | if( pi_ != 0 ) pi_->release(); | ||||||||
| 433 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 434 | id_ = 0; | ||||||||
| 435 | #endif | ||||||||
| 436 | } | ||||||||
| 437 | |||||||||
| 438 | shared_count(shared_count const & r) BOOST_SP_NOEXCEPTnoexcept: pi_(r.pi_) | ||||||||
| 439 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 440 | , id_(shared_count_id) | ||||||||
| 441 | #endif | ||||||||
| 442 | { | ||||||||
| 443 | if( pi_ != 0 ) pi_->add_ref_copy(); | ||||||||
| 444 | } | ||||||||
| 445 | |||||||||
| 446 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||||||
| 447 | |||||||||
| 448 | shared_count(shared_count && r) BOOST_SP_NOEXCEPTnoexcept: pi_(r.pi_) | ||||||||
| 449 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 450 | , id_(shared_count_id) | ||||||||
| 451 | #endif | ||||||||
| 452 | { | ||||||||
| 453 | r.pi_ = 0; | ||||||||
| 454 | } | ||||||||
| 455 | |||||||||
| 456 | #endif | ||||||||
| 457 | |||||||||
| 458 | explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 | ||||||||
| 459 | shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPTnoexcept; // constructs an empty *this when r.use_count() == 0 | ||||||||
| 460 | |||||||||
| 461 | shared_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 462 | { | ||||||||
| 463 | sp_counted_base * tmp = r.pi_; | ||||||||
| 464 | |||||||||
| 465 | if( tmp != pi_ ) | ||||||||
| 466 | { | ||||||||
| 467 | if( tmp != 0 ) tmp->add_ref_copy(); | ||||||||
| 468 | if( pi_ != 0 ) pi_->release(); | ||||||||
| 469 | pi_ = tmp; | ||||||||
| 470 | } | ||||||||
| 471 | |||||||||
| 472 | return *this; | ||||||||
| 473 | } | ||||||||
| 474 | |||||||||
| 475 | void swap(shared_count & r) BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 476 | { | ||||||||
| 477 | sp_counted_base * tmp = r.pi_; | ||||||||
| 478 | r.pi_ = pi_; | ||||||||
| 479 | pi_ = tmp; | ||||||||
| 480 | } | ||||||||
| 481 | |||||||||
| 482 | long use_count() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 483 | { | ||||||||
| 484 | return pi_ != 0? pi_->use_count(): 0; | ||||||||
| 485 | } | ||||||||
| 486 | |||||||||
| 487 | bool unique() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 488 | { | ||||||||
| 489 | return use_count() == 1; | ||||||||
| 490 | } | ||||||||
| 491 | |||||||||
| 492 | bool empty() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 493 | { | ||||||||
| 494 | return pi_ == 0; | ||||||||
| 495 | } | ||||||||
| 496 | |||||||||
| 497 | bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 498 | { | ||||||||
| 499 | return pi_ == r.pi_; | ||||||||
| 500 | } | ||||||||
| 501 | |||||||||
| 502 | bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept; | ||||||||
| 503 | |||||||||
| 504 | bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 505 | { | ||||||||
| 506 | return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||||||
| 507 | } | ||||||||
| 508 | |||||||||
| 509 | bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept; | ||||||||
| 510 | |||||||||
| 511 | void * get_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 512 | { | ||||||||
| 513 | return pi_? pi_->get_deleter( ti ): 0; | ||||||||
| 514 | } | ||||||||
| 515 | |||||||||
| 516 | void * get_local_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 517 | { | ||||||||
| 518 | return pi_? pi_->get_local_deleter( ti ): 0; | ||||||||
| 519 | } | ||||||||
| 520 | |||||||||
| 521 | void * get_untyped_deleter() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 522 | { | ||||||||
| 523 | return pi_? pi_->get_untyped_deleter(): 0; | ||||||||
| 524 | } | ||||||||
| 525 | |||||||||
| 526 | std::size_t hash_value() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 527 | { | ||||||||
| 528 | return sp_hash_pointer( pi_ ); | ||||||||
| 529 | } | ||||||||
| 530 | }; | ||||||||
| 531 | |||||||||
| 532 | |||||||||
| 533 | class weak_count | ||||||||
| 534 | { | ||||||||
| 535 | private: | ||||||||
| 536 | |||||||||
| 537 | sp_counted_base * pi_; | ||||||||
| 538 | |||||||||
| 539 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 540 | int id_; | ||||||||
| 541 | #endif | ||||||||
| 542 | |||||||||
| 543 | friend class shared_count; | ||||||||
| 544 | |||||||||
| 545 | public: | ||||||||
| 546 | |||||||||
| 547 | BOOST_CONSTEXPRconstexpr weak_count() BOOST_SP_NOEXCEPTnoexcept: pi_(0) | ||||||||
| 548 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 549 | , id_(weak_count_id) | ||||||||
| 550 | #endif | ||||||||
| 551 | { | ||||||||
| 552 | } | ||||||||
| 553 | |||||||||
| 554 | weak_count(shared_count const & r) BOOST_SP_NOEXCEPTnoexcept: pi_(r.pi_) | ||||||||
| 555 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 556 | , id_(weak_count_id) | ||||||||
| 557 | #endif | ||||||||
| 558 | { | ||||||||
| 559 | if(pi_
| ||||||||
| |||||||||
| 560 | } | ||||||||
| 561 | |||||||||
| 562 | weak_count(weak_count const & r) BOOST_SP_NOEXCEPTnoexcept: pi_(r.pi_) | ||||||||
| 563 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 564 | , id_(weak_count_id) | ||||||||
| 565 | #endif | ||||||||
| 566 | { | ||||||||
| 567 | if(pi_ != 0) pi_->weak_add_ref(); | ||||||||
| 568 | } | ||||||||
| 569 | |||||||||
| 570 | // Move support | ||||||||
| 571 | |||||||||
| 572 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||||||
| 573 | |||||||||
| 574 | weak_count(weak_count && r) BOOST_SP_NOEXCEPTnoexcept: pi_(r.pi_) | ||||||||
| 575 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 576 | , id_(weak_count_id) | ||||||||
| 577 | #endif | ||||||||
| 578 | { | ||||||||
| 579 | r.pi_ = 0; | ||||||||
| 580 | } | ||||||||
| 581 | |||||||||
| 582 | #endif | ||||||||
| 583 | |||||||||
| 584 | ~weak_count() /*BOOST_SP_NOEXCEPT*/ | ||||||||
| 585 | { | ||||||||
| 586 | if(pi_
| ||||||||
| 587 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 588 | id_ = 0; | ||||||||
| 589 | #endif | ||||||||
| 590 | } | ||||||||
| 591 | |||||||||
| 592 | weak_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 593 | { | ||||||||
| 594 | sp_counted_base * tmp = r.pi_; | ||||||||
| 595 | |||||||||
| 596 | if( tmp != pi_ ) | ||||||||
| 597 | { | ||||||||
| 598 | if(tmp != 0) tmp->weak_add_ref(); | ||||||||
| 599 | if(pi_ != 0) pi_->weak_release(); | ||||||||
| 600 | pi_ = tmp; | ||||||||
| 601 | } | ||||||||
| 602 | |||||||||
| 603 | return *this; | ||||||||
| 604 | } | ||||||||
| 605 | |||||||||
| 606 | weak_count & operator= (weak_count const & r) BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 607 | { | ||||||||
| 608 | sp_counted_base * tmp = r.pi_; | ||||||||
| 609 | |||||||||
| 610 | if( tmp != pi_ ) | ||||||||
| 611 | { | ||||||||
| 612 | if(tmp != 0) tmp->weak_add_ref(); | ||||||||
| 613 | if(pi_ != 0) pi_->weak_release(); | ||||||||
| 614 | pi_ = tmp; | ||||||||
| 615 | } | ||||||||
| 616 | |||||||||
| 617 | return *this; | ||||||||
| 618 | } | ||||||||
| 619 | |||||||||
| 620 | void swap(weak_count & r) BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 621 | { | ||||||||
| 622 | sp_counted_base * tmp = r.pi_; | ||||||||
| 623 | r.pi_ = pi_; | ||||||||
| 624 | pi_ = tmp; | ||||||||
| 625 | } | ||||||||
| 626 | |||||||||
| 627 | long use_count() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 628 | { | ||||||||
| 629 | return pi_ != 0? pi_->use_count(): 0; | ||||||||
| 630 | } | ||||||||
| 631 | |||||||||
| 632 | bool empty() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 633 | { | ||||||||
| 634 | return pi_ == 0; | ||||||||
| 635 | } | ||||||||
| 636 | |||||||||
| 637 | bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 638 | { | ||||||||
| 639 | return pi_ == r.pi_; | ||||||||
| 640 | } | ||||||||
| 641 | |||||||||
| 642 | bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 643 | { | ||||||||
| 644 | return pi_ == r.pi_; | ||||||||
| 645 | } | ||||||||
| 646 | |||||||||
| 647 | bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 648 | { | ||||||||
| 649 | return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||||||
| 650 | } | ||||||||
| 651 | |||||||||
| 652 | bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 653 | { | ||||||||
| 654 | return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||||||
| 655 | } | ||||||||
| 656 | |||||||||
| 657 | std::size_t hash_value() const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 658 | { | ||||||||
| 659 | return sp_hash_pointer( pi_ ); | ||||||||
| 660 | } | ||||||||
| 661 | }; | ||||||||
| 662 | |||||||||
| 663 | inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) | ||||||||
| 664 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 665 | , id_(shared_count_id) | ||||||||
| 666 | #endif | ||||||||
| 667 | { | ||||||||
| 668 | if( pi_ == 0 || !pi_->add_ref_lock() ) | ||||||||
| 669 | { | ||||||||
| 670 | boost::throw_exception( boost::bad_weak_ptr() ); | ||||||||
| 671 | } | ||||||||
| 672 | } | ||||||||
| 673 | |||||||||
| 674 | inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPTnoexcept: pi_( r.pi_ ) | ||||||||
| 675 | #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||||||
| 676 | , id_(shared_count_id) | ||||||||
| 677 | #endif | ||||||||
| 678 | { | ||||||||
| 679 | if( pi_ != 0 && !pi_->add_ref_lock() ) | ||||||||
| 680 | { | ||||||||
| 681 | pi_ = 0; | ||||||||
| 682 | } | ||||||||
| 683 | } | ||||||||
| 684 | |||||||||
| 685 | inline bool shared_count::operator==( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 686 | { | ||||||||
| 687 | return pi_ == r.pi_; | ||||||||
| 688 | } | ||||||||
| 689 | |||||||||
| 690 | inline bool shared_count::operator<( weak_count const & r ) const BOOST_SP_NOEXCEPTnoexcept | ||||||||
| 691 | { | ||||||||
| 692 | return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||||||
| 693 | } | ||||||||
| 694 | |||||||||
| 695 | } // namespace detail | ||||||||
| 696 | |||||||||
| 697 | } // namespace boost | ||||||||
| 698 | |||||||||
| 699 | #if defined( BOOST_SP_DISABLE_DEPRECATED ) | ||||||||
| 700 | #pragma GCC diagnostic pop | ||||||||
| 701 | #endif | ||||||||
| 702 | |||||||||
| 703 | #if defined(__BORLANDC__) && !defined(__clang__1) | ||||||||
| 704 | # pragma warn .8027 // Functions containing try are not expanded inline | ||||||||
| 705 | #endif | ||||||||
| 706 | |||||||||
| 707 | #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED |
| 1 | #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED |
| 2 | #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED |
| 3 | |
| 4 | // MS compatible compilers support #pragma once |
| 5 | |
| 6 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| 7 | # pragma once |
| 8 | #endif |
| 9 | |
| 10 | // detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics |
| 11 | // |
| 12 | // Copyright 2007, 2020 Peter Dimov |
| 13 | // Distributed under the Boost Software License, Version 1.0. |
| 14 | // https://www.boost.org/LICENSE_1_0.txt |
| 15 | |
| 16 | #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> |
| 17 | #include <boost/config.hpp> |
| 18 | #include <boost/cstdint.hpp> |
| 19 | |
| 20 | #if defined(BOOST_SP_REPORT_IMPLEMENTATION) |
| 21 | |
| 22 | #include <boost/config/pragma_message.hpp> |
| 23 | BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base")message("Using __atomic sp_counted_base") |
| 24 | |
| 25 | #endif |
| 26 | |
| 27 | namespace boost |
| 28 | { |
| 29 | |
| 30 | namespace detail |
| 31 | { |
| 32 | |
| 33 | inline void atomic_increment( boost::uint_least32_t * pw ) |
| 34 | { |
| 35 | __atomic_fetch_add( pw, 1, __ATOMIC_RELAXED0 ); |
| 36 | } |
| 37 | |
| 38 | inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw ) |
| 39 | { |
| 40 | return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL4 ); |
| 41 | } |
| 42 | |
| 43 | inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw ) |
| 44 | { |
| 45 | // long r = *pw; |
| 46 | // if( r != 0 ) ++*pw; |
| 47 | // return r; |
| 48 | |
| 49 | boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED0 ); |
| 50 | |
| 51 | for( ;; ) |
| 52 | { |
| 53 | if( r == 0 ) |
| 54 | { |
| 55 | return r; |
| 56 | } |
| 57 | |
| 58 | if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED0, __ATOMIC_RELAXED0 ) ) |
| 59 | { |
| 60 | return r; |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw ) |
| 66 | { |
| 67 | return __atomic_load_n( pw, __ATOMIC_ACQUIRE2 ); |
| 68 | } |
| 69 | |
| 70 | class BOOST_SYMBOL_VISIBLE__attribute__((__visibility__("default"))) sp_counted_base |
| 71 | { |
| 72 | private: |
| 73 | |
| 74 | sp_counted_base( sp_counted_base const & ); |
| 75 | sp_counted_base & operator= ( sp_counted_base const & ); |
| 76 | |
| 77 | boost::uint_least32_t use_count_; // #shared |
| 78 | boost::uint_least32_t weak_count_; // #weak + (#shared != 0) |
| 79 | |
| 80 | public: |
| 81 | |
| 82 | sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) |
| 83 | { |
| 84 | } |
| 85 | |
| 86 | virtual ~sp_counted_base() // nothrow |
| 87 | { |
| 88 | } |
| 89 | |
| 90 | // dispose() is called when use_count_ drops to zero, to release |
| 91 | // the resources managed by *this. |
| 92 | |
| 93 | virtual void dispose() = 0; // nothrow |
| 94 | |
| 95 | // destroy() is called when weak_count_ drops to zero. |
| 96 | |
| 97 | virtual void destroy() // nothrow |
| 98 | { |
| 99 | delete this; |
| 100 | } |
| 101 | |
| 102 | virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; |
| 103 | virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; |
| 104 | virtual void * get_untyped_deleter() = 0; |
| 105 | |
| 106 | void add_ref_copy() |
| 107 | { |
| 108 | atomic_increment( &use_count_ ); |
| 109 | } |
| 110 | |
| 111 | bool add_ref_lock() // true on success |
| 112 | { |
| 113 | return atomic_conditional_increment( &use_count_ ) != 0; |
| 114 | } |
| 115 | |
| 116 | void release() // nothrow |
| 117 | { |
| 118 | if( atomic_decrement( &use_count_ ) == 1 ) |
| 119 | { |
| 120 | dispose(); |
| 121 | weak_release(); |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | void weak_add_ref() // nothrow |
| 126 | { |
| 127 | atomic_increment( &weak_count_ ); |
| 128 | } |
| 129 | |
| 130 | void weak_release() // nothrow |
| 131 | { |
| 132 | if( atomic_decrement( &weak_count_ ) == 1 ) |
| 133 | { |
| 134 | destroy(); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | long use_count() const // nothrow |
| 139 | { |
| 140 | return static_cast<long>( atomic_load( &use_count_ ) ); |
| 141 | } |
| 142 | }; |
| 143 | |
| 144 | } // namespace detail |
| 145 | |
| 146 | } // namespace boost |
| 147 | |
| 148 | #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED |