Changeset View
Changeset View
Standalone View
Standalone View
src/test/validationinterface_tests.cpp
// Copyright (c) 2020 The Bitcoin Core developers | // Copyright (c) 2020 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <primitives/block.h> | #include <primitives/block.h> | ||||
#include <scheduler.h> | #include <scheduler.h> | ||||
#include <test/util/setup_common.h> | #include <test/util/setup_common.h> | ||||
#include <util/check.h> | #include <util/check.h> | ||||
#include <validationinterface.h> | #include <validationinterface.h> | ||||
BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup) | BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup) | ||||
struct TestSubscriberNoop final : public CValidationInterface { | |||||
void BlockChecked(const CBlock &, const BlockValidationState &) override {} | |||||
}; | |||||
BOOST_AUTO_TEST_CASE(unregister_validation_interface_race) { | |||||
std::atomic<bool> generate{true}; | |||||
// Start thread to generate notifications | |||||
std::thread gen{[&] { | |||||
const CBlock block_dummy; | |||||
const BlockValidationState state_dummy; | |||||
while (generate) { | |||||
GetMainSignals().BlockChecked(block_dummy, state_dummy); | |||||
} | |||||
}}; | |||||
// Start thread to consume notifications | |||||
std::thread sub{[&] { | |||||
// keep going for about 1 sec, which is 250k iterations | |||||
for (int i = 0; i < 250000; i++) { | |||||
auto subscriber = std::make_shared<TestSubscriberNoop>(); | |||||
RegisterSharedValidationInterface(subscriber); | |||||
UnregisterSharedValidationInterface(subscriber); | |||||
} | |||||
// tell the other thread we are done | |||||
generate = false; | |||||
}}; | |||||
gen.join(); | |||||
sub.join(); | |||||
BOOST_CHECK(!generate); | |||||
} | |||||
class TestInterface : public CValidationInterface { | class TestInterface : public CValidationInterface { | ||||
public: | public: | ||||
TestInterface(std::function<void()> on_call = nullptr, | TestInterface(std::function<void()> on_call = nullptr, | ||||
std::function<void()> on_destroy = nullptr) | std::function<void()> on_destroy = nullptr) | ||||
: m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)) {} | : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)) {} | ||||
virtual ~TestInterface() { | virtual ~TestInterface() { | ||||
if (m_on_destroy) { | if (m_on_destroy) { | ||||
m_on_destroy(); | m_on_destroy(); | ||||
Show All 37 Lines |