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()
|