Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.0 -> main] refactor threading of snapshot_scheduler_test #1822

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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