Skip to content

Commit

Permalink
Merge pull request #1822 from AntelopeIO/snapschedthreads
Browse files Browse the repository at this point in the history
[5.0 -> main] refactor threading of snapshot_scheduler_test
  • Loading branch information
spoonincode authored Oct 25, 2023
2 parents a9fa4dc + 8c4babc commit 5fe528f
Showing 1 changed file with 68 additions and 60 deletions.
128 changes: 68 additions & 60 deletions tests/test_snapshot_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ BOOST_AUTO_TEST_CASE(snapshot_scheduler_test) {
std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();

std::promise<void> at_block_20_promise;
std::future<void> at_block_20_fut = at_block_20_promise.get_future();

std::thread app_thread([&]() {
try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
Expand All @@ -68,54 +71,55 @@ BOOST_AUTO_TEST_CASE(snapshot_scheduler_test) {
"-p", "eosio", "-e"};
app->initialize<chain_plugin, producer_plugin>(argv.size(), (char**) &argv[0]);
app->startup();
plugin_promise.set_value(
{app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()});

producer_plugin* prod_plug = app->find_plugin<producer_plugin>();
chain_plugin* chain_plug = app->find_plugin<chain_plugin>();
plugin_promise.set_value({prod_plug, chain_plug});

auto bs = chain_plug->chain().block_start.connect([&prod_plug, &at_block_20_promise](uint32_t bn) {
if(bn == 20u)
at_block_20_promise.set_value();
// catching pending snapshot
if (!prod_plug->get_snapshot_requests().snapshot_requests.empty()) {
const auto& snapshot_requests = prod_plug->get_snapshot_requests().snapshot_requests;

auto validate_snapshot_request = [&](uint32_t sid, uint32_t block_num, uint32_t spacing = 0, bool fuzzy_start = false) {
auto it = find_if(snapshot_requests.begin(), snapshot_requests.end(), [sid](const snapshot_scheduler::snapshot_schedule_information& obj) {return obj.snapshot_request_id == sid;});
if (it != snapshot_requests.end()) {
auto& pending = it->pending_snapshots;
if (pending.size()==1u) {
// pending snapshot block number
auto pbn = pending.begin()->head_block_num;

// first pending snapshot
auto ps_start = (spacing != 0) ? (spacing + (pbn%spacing)) : pbn;

if (!fuzzy_start) {
BOOST_CHECK_EQUAL(block_num, ps_start);
}
else {
int diff = block_num - ps_start;
BOOST_CHECK(std::abs(diff) <= 5); // accept +/- 5 blocks if start block not specified
}
}
return true;
}
return false;
};

BOOST_REQUIRE(validate_snapshot_request(0, 9, 8)); // snapshot #0 should have pending snapshot at block #9 (8 + 1) and it never expires
BOOST_REQUIRE(validate_snapshot_request(4, 12, 10, true)); // snapshot #4 should have pending snapshot at block # at the moment of scheduling (2) plus 10 = 12
BOOST_REQUIRE(validate_snapshot_request(5, 10, 10)); // snapshot #5 should have pending snapshot at block #10, #20 etc
}
});

app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
});

auto [prod_plug, chain_plug] = plugin_fut.get();
std::deque<block_state_ptr> all_blocks;
std::promise<void> empty_blocks_promise;
std::future<void> empty_blocks_fut = empty_blocks_promise.get_future();
auto pp = app->find_plugin<producer_plugin>();

auto bs = chain_plug->chain().block_start.connect([&pp](uint32_t bn) {
// catching pending snapshot
if (!pp->get_snapshot_requests().snapshot_requests.empty()) {
const auto& snapshot_requests = pp->get_snapshot_requests().snapshot_requests;

auto validate_snapshot_request = [&](uint32_t sid, uint32_t block_num, uint32_t spacing = 0, bool fuzzy_start = false) {
auto it = find_if(snapshot_requests.begin(), snapshot_requests.end(), [sid](const snapshot_scheduler::snapshot_schedule_information& obj) {return obj.snapshot_request_id == sid;});
if (it != snapshot_requests.end()) {
auto& pending = it->pending_snapshots;
if (pending.size()==1u) {
// pending snapshot block number
auto pbn = pending.begin()->head_block_num;

// first pending snapshot
auto ps_start = (spacing != 0) ? (spacing + (pbn%spacing)) : pbn;

if (!fuzzy_start) {
BOOST_CHECK_EQUAL(block_num, ps_start);
}
else {
int diff = block_num - ps_start;
BOOST_CHECK(std::abs(diff) <= 5); // accept +/- 5 blocks if start block not specified
}
}
return true;
}
return false;
};

BOOST_REQUIRE(validate_snapshot_request(0, 9, 8)); // snapshot #0 should have pending snapshot at block #9 (8 + 1) and it never expires
BOOST_REQUIRE(validate_snapshot_request(4, 12, 10, true)); // snapshot #4 should have pending snapshot at block # at the moment of scheduling (2) plus 10 = 12
BOOST_REQUIRE(validate_snapshot_request(5, 10, 10)); // snapshot #5 should have pending snapshot at block #10, #20 etc
}
});

snapshot_request_params sri1 = {.block_spacing = 8, .start_block_num = 1, .end_block_num = 300000, .snapshot_description = "Example of recurring snapshot 1"};
snapshot_request_params sri2 = {.block_spacing = 5000, .start_block_num = 100000, .end_block_num = 300000, .snapshot_description = "Example of recurring snapshot 2 that wont happen in test"};
Expand All @@ -124,31 +128,35 @@ BOOST_AUTO_TEST_CASE(snapshot_scheduler_test) {
snapshot_request_params sri5 = {.block_spacing = 10, .snapshot_description = "Recurring every 10 blocks snapshot starting now"};
snapshot_request_params sri6 = {.block_spacing = 10, .start_block_num = 0, .snapshot_description = "Recurring every 10 blocks snapshot starting from 0"};

pp->schedule_snapshot(sri1);
pp->schedule_snapshot(sri2);
pp->schedule_snapshot(sri3);
pp->schedule_snapshot(sri4);
pp->schedule_snapshot(sri5);
pp->schedule_snapshot(sri6);
app->post(appbase::priority::medium_low, [&]() {
prod_plug->schedule_snapshot(sri1);
prod_plug->schedule_snapshot(sri2);
prod_plug->schedule_snapshot(sri3);
prod_plug->schedule_snapshot(sri4);
prod_plug->schedule_snapshot(sri5);
prod_plug->schedule_snapshot(sri6);

// all six snapshot requests should be present now
BOOST_CHECK_EQUAL(6u, pp->get_snapshot_requests().snapshot_requests.size());
// all six snapshot requests should be present now
BOOST_CHECK_EQUAL(6u, prod_plug->get_snapshot_requests().snapshot_requests.size());
});

empty_blocks_fut.wait_for(std::chrono::seconds(10));
at_block_20_fut.get();

// two of the snapshots are done here and requests, corresponding to them should be deleted
BOOST_CHECK_EQUAL(4u, pp->get_snapshot_requests().snapshot_requests.size());
app->post(appbase::priority::medium_low, [&]() {
// two of the snapshots are done here and requests, corresponding to them should be deleted
BOOST_CHECK_EQUAL(4u, prod_plug->get_snapshot_requests().snapshot_requests.size());

// check whether no pending snapshots present for a snapshot with id 0
const auto& snapshot_requests = pp->get_snapshot_requests().snapshot_requests;
auto it = find_if(snapshot_requests.begin(), snapshot_requests.end(),[](const snapshot_scheduler::snapshot_schedule_information& obj) {return obj.snapshot_request_id == 0;});
// check whether no pending snapshots present for a snapshot with id 0
const auto& snapshot_requests = prod_plug->get_snapshot_requests().snapshot_requests;
auto it = find_if(snapshot_requests.begin(), snapshot_requests.end(),[](const snapshot_scheduler::snapshot_schedule_information& obj) {return obj.snapshot_request_id == 0;});

// snapshot request with id = 0 should be found and should not have any pending snapshots
BOOST_REQUIRE(it != snapshot_requests.end());
BOOST_CHECK(!it->pending_snapshots.size());
// snapshot request with id = 0 should be found and should not have any pending snapshots
BOOST_REQUIRE(it != snapshot_requests.end());
BOOST_CHECK(!it->pending_snapshots.size());

// quit app
app->quit();
// quit app
app->quit();
});
app_thread.join();

// lets check whether schedule can be read back after restart
Expand Down

0 comments on commit 5fe528f

Please sign in to comment.