LCOV - code coverage report
Current view: top level - dpdklibs/unittest - DpdkOwnership_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 100.0 % 29 29
Test Date: 2026-10-11 15:05:20 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /**
       2              :  * @file DpdkOwnership_test.cxx
       3              :  *
       4              :  * Ownership tests for the DPDK mempool handles: the unique_mempool transfer
       5              :  * contract and the BorrowedPoolMap release-without-delete guarantee.  All
       6              :  * tests run without EAL.
       7              :  *
       8              :  * No deleter may run on a fake pool address.  A missing release would invoke a
       9              :  * deleter on static storage and terminate the process.  Completion of the test
      10              :  * is therefore the assertion.
      11              :  *
      12              :  * This is part of the DUNE DAQ Application Framework, copyright 2020.
      13              :  * Licensing/copyright details are in the COPYING file that you should have
      14              :  * received with this code.
      15              :  */
      16              : 
      17              : #include "dpdklibs/DpdkMempool.hpp"
      18              : 
      19              : #define BOOST_TEST_MODULE DpdkOwnership_test // NOLINT
      20              : 
      21              : #include "boost/test/unit_test.hpp"
      22              : 
      23              : #include <array>
      24              : #include <memory>
      25              : #include <utility>
      26              : 
      27              : using namespace dunedaq::dpdklibs;
      28              : 
      29              : namespace {
      30              : 
      31              : // Static storage used as stand-in rte_mempool addresses.
      32              : alignas(8) std::array<char, 8> g_fake_pool_a;
      33              : alignas(8) std::array<char, 8> g_fake_pool_b;
      34              : 
      35              : rte_mempool*
      36            2 : fake_pool_a()
      37              : {
      38            2 :   return reinterpret_cast<rte_mempool*>(g_fake_pool_a.data()); // NOLINT
      39              : }
      40              : 
      41              : rte_mempool*
      42            1 : fake_pool_b()
      43              : {
      44            1 :   return reinterpret_cast<rte_mempool*>(g_fake_pool_b.data()); // NOLINT
      45              : }
      46              : 
      47              : } // namespace ""
      48              : 
      49              : BOOST_AUTO_TEST_SUITE(DpdkOwnership_test)
      50              : 
      51            2 : BOOST_AUTO_TEST_CASE(MempoolDeleterIgnoresNullptr)
      52              : {
      53            1 :   MempoolDeleter deleter;
      54            1 :   deleter(nullptr); // must be a no-op, not a call to rte_mempool_free
      55              : 
      56            1 :   unique_mempool empty;
      57            1 :   BOOST_CHECK(empty.get() == nullptr);
      58              :   // empty is destroyed here; the deleter must not call DPDK for a null handle
      59            1 : }
      60              : 
      61            2 : BOOST_AUTO_TEST_CASE(TakeMempoolOwnershipTransfersWithoutDeleting)
      62              : {
      63            1 :   std::unique_ptr<rte_mempool> legacy(fake_pool_a());
      64            1 :   auto owned = take_mempool_ownership(std::move(legacy));
      65              : 
      66              :   // Ownership moved.  The legacy handle is empty, so its default deleter
      67              :   // (operator delete, incorrect for rte_mempool) cannot run.
      68            1 :   BOOST_CHECK(legacy.get() == nullptr);
      69            1 :   BOOST_CHECK_EQUAL(static_cast<void*>(owned.get()), static_cast<void*>(fake_pool_a()));
      70              : 
      71              :   // Detach before scope exit so MempoolDeleter is not given the fake address.
      72            1 :   owned.release(); // NOLINT(bugprone-unused-return-value)
      73            1 : }
      74              : 
      75            2 : BOOST_AUTO_TEST_CASE(BorrowedPoolMapFeedsLegacyMapAndReleasesOnDestruction)
      76              : {
      77            1 :   {
      78            1 :     BorrowedPoolMap borrowed;
      79            1 :     borrowed.borrow(0, fake_pool_a());
      80            1 :     borrowed.borrow(3, fake_pool_b());
      81              : 
      82            1 :     auto& legacy_map = borrowed.get();
      83            1 :     BOOST_REQUIRE_EQUAL(legacy_map.size(), 2);
      84            1 :     BOOST_CHECK_EQUAL(static_cast<void*>(legacy_map.at(0).get()), static_cast<void*>(fake_pool_a()));
      85            1 :     BOOST_CHECK_EQUAL(static_cast<void*>(legacy_map.at(3).get()), static_cast<void*>(fake_pool_b()));
      86            1 :   }
      87              :   // The map was destroyed with both entries populated.  Reaching this line
      88              :   // means every entry was released rather than deleted.
      89            1 :   BOOST_CHECK(true);
      90            1 : }
      91              : 
      92              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1