LCOV - code coverage report
Current view: top level - src/test - validationinterface_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 48 48 100.0 %
Date: 2022-04-21 14:51:19 Functions: 11 11 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 6 8 75.0 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2020 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : #include <boost/test/unit_test.hpp>
#       6                 :            : #include <consensus/validation.h>
#       7                 :            : #include <primitives/block.h>
#       8                 :            : #include <scheduler.h>
#       9                 :            : #include <test/util/setup_common.h>
#      10                 :            : #include <util/check.h>
#      11                 :            : #include <validationinterface.h>
#      12                 :            : 
#      13                 :            : BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup)
#      14                 :            : 
#      15                 :            : struct TestSubscriberNoop final : public CValidationInterface {
#      16                 :        528 :     void BlockChecked(const CBlock&, const BlockValidationState&) override {}
#      17                 :            : };
#      18                 :            : 
#      19                 :            : BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
#      20                 :          1 : {
#      21                 :          1 :     std::atomic<bool> generate{true};
#      22                 :            : 
#      23                 :            :     // Start thread to generate notifications
#      24                 :          1 :     std::thread gen{[&] {
#      25                 :          1 :         const CBlock block_dummy;
#      26                 :          1 :         BlockValidationState state_dummy;
#      27         [ +  + ]:       2512 :         while (generate) {
#      28                 :       2511 :             GetMainSignals().BlockChecked(block_dummy, state_dummy);
#      29                 :       2511 :         }
#      30                 :          1 :     }};
#      31                 :            : 
#      32                 :            :     // Start thread to consume notifications
#      33                 :          1 :     std::thread sub{[&] {
#      34                 :            :         // keep going for about 1 sec, which is 250k iterations
#      35         [ +  + ]:     250001 :         for (int i = 0; i < 250000; i++) {
#      36                 :     250000 :             auto sub = std::make_shared<TestSubscriberNoop>();
#      37                 :     250000 :             RegisterSharedValidationInterface(sub);
#      38                 :     250000 :             UnregisterSharedValidationInterface(sub);
#      39                 :     250000 :         }
#      40                 :            :         // tell the other thread we are done
#      41                 :          1 :         generate = false;
#      42                 :          1 :     }};
#      43                 :            : 
#      44                 :          1 :     gen.join();
#      45                 :          1 :     sub.join();
#      46                 :          1 :     BOOST_CHECK(!generate);
#      47                 :          1 : }
#      48                 :            : 
#      49                 :            : class TestInterface : public CValidationInterface
#      50                 :            : {
#      51                 :            : public:
#      52                 :            :     TestInterface(std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
#      53                 :            :         : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy))
#      54                 :          1 :     {
#      55                 :          1 :     }
#      56                 :            :     virtual ~TestInterface()
#      57                 :          1 :     {
#      58         [ +  - ]:          1 :         if (m_on_destroy) m_on_destroy();
#      59                 :          1 :     }
#      60                 :            :     void BlockChecked(const CBlock& block, const BlockValidationState& state) override
#      61                 :          1 :     {
#      62         [ +  - ]:          1 :         if (m_on_call) m_on_call();
#      63                 :          1 :     }
#      64                 :            :     static void Call()
#      65                 :          1 :     {
#      66                 :          1 :         CBlock block;
#      67                 :          1 :         BlockValidationState state;
#      68                 :          1 :         GetMainSignals().BlockChecked(block, state);
#      69                 :          1 :     }
#      70                 :            :     std::function<void()> m_on_call;
#      71                 :            :     std::function<void()> m_on_destroy;
#      72                 :            : };
#      73                 :            : 
#      74                 :            : // Regression test to ensure UnregisterAllValidationInterfaces calls don't
#      75                 :            : // destroy a validation interface while it is being called. Bug:
#      76                 :            : // https://github.com/bitcoin/bitcoin/pull/18551
#      77                 :            : BOOST_AUTO_TEST_CASE(unregister_all_during_call)
#      78                 :          1 : {
#      79                 :          1 :     bool destroyed = false;
#      80                 :          1 :     RegisterSharedValidationInterface(std::make_shared<TestInterface>(
#      81                 :          1 :         [&] {
#      82                 :            :             // First call should decrements reference count 2 -> 1
#      83                 :          1 :             UnregisterAllValidationInterfaces();
#      84                 :          1 :             BOOST_CHECK(!destroyed);
#      85                 :            :             // Second call should not decrement reference count 1 -> 0
#      86                 :          1 :             UnregisterAllValidationInterfaces();
#      87                 :          1 :             BOOST_CHECK(!destroyed);
#      88                 :          1 :         },
#      89                 :          1 :         [&] { destroyed = true; }));
#      90                 :          1 :     TestInterface::Call();
#      91                 :          1 :     BOOST_CHECK(destroyed);
#      92                 :          1 : }
#      93                 :            : 
#      94                 :            : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a