Fix unit test election_scheduler.no_vacancy (#3732)
This commit is contained in:
parent
ca3ec20ee8
commit
eb8ad785f5
1 changed files with 45 additions and 26 deletions
|
|
@ -50,14 +50,32 @@ TEST (election_scheduler, activate_one_flush)
|
||||||
ASSERT_NE (nullptr, system.nodes[0]->active.election (send1->qualified_root ()));
|
ASSERT_NE (nullptr, system.nodes[0]->active.election (send1->qualified_root ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that the election scheduler and the active transactions container (AEC)
|
||||||
|
* work in sync with regards to the node configuration value "active_elections_size".
|
||||||
|
*
|
||||||
|
* The test sets up two forcefully cemented blocks -- a send on the genesis account and a receive on a second account.
|
||||||
|
* It then creates two other blocks, each a successor to one of the previous two,
|
||||||
|
* and processes them locally (without the node starting elections for them, but just saving them to disk).
|
||||||
|
*
|
||||||
|
* Elections for these latter two (B1 and B2) are started by the test code manually via `election_scheduler::activate`.
|
||||||
|
* The test expects E1 to start right off and take its seat into the AEC.
|
||||||
|
* E2 is expected not to start though (because the AEC is full), so B2 should be awaiting in the scheduler's queue.
|
||||||
|
*
|
||||||
|
* As soon as the test code manually confirms E1 (and thus evicts it out of the AEC),
|
||||||
|
* it is expected that E2 begins and the scheduler's queue becomes empty again.
|
||||||
|
*/
|
||||||
TEST (election_scheduler, no_vacancy)
|
TEST (election_scheduler, no_vacancy)
|
||||||
{
|
{
|
||||||
nano::system system;
|
nano::system system{};
|
||||||
|
|
||||||
nano::node_config config{ nano::get_available_port (), system.logging };
|
nano::node_config config{ nano::get_available_port (), system.logging };
|
||||||
config.active_elections_size = 1;
|
config.active_elections_size = 1;
|
||||||
|
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||||
|
|
||||||
auto & node = *system.add_node (config);
|
auto & node = *system.add_node (config);
|
||||||
nano::state_block_builder builder;
|
nano::state_block_builder builder{};
|
||||||
nano::keypair key;
|
nano::keypair key{};
|
||||||
|
|
||||||
// Activating accounts depends on confirmed dependencies. First, prepare 2 accounts
|
// Activating accounts depends on confirmed dependencies. First, prepare 2 accounts
|
||||||
auto send = builder.make_block ()
|
auto send = builder.make_block ()
|
||||||
|
|
@ -69,6 +87,9 @@ TEST (election_scheduler, no_vacancy)
|
||||||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||||
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
||||||
.build_shared ();
|
.build_shared ();
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node.process (*send).code);
|
||||||
|
node.process_confirmed (nano::election_status{ send });
|
||||||
|
|
||||||
auto receive = builder.make_block ()
|
auto receive = builder.make_block ()
|
||||||
.account (key.pub)
|
.account (key.pub)
|
||||||
.previous (0)
|
.previous (0)
|
||||||
|
|
@ -78,15 +99,11 @@ TEST (election_scheduler, no_vacancy)
|
||||||
.sign (key.prv, key.pub)
|
.sign (key.prv, key.pub)
|
||||||
.work (*system.work.generate (key.pub))
|
.work (*system.work.generate (key.pub))
|
||||||
.build_shared ();
|
.build_shared ();
|
||||||
ASSERT_EQ (nano::process_result::progress, node.process (*send).code);
|
|
||||||
nano::blocks_confirm (node, { send }, true);
|
|
||||||
ASSERT_TIMELY (1s, node.active.empty ());
|
|
||||||
ASSERT_EQ (nano::process_result::progress, node.process (*receive).code);
|
ASSERT_EQ (nano::process_result::progress, node.process (*receive).code);
|
||||||
nano::blocks_confirm (node, { receive }, true);
|
node.process_confirmed (nano::election_status{ receive });
|
||||||
ASSERT_TIMELY (1s, node.active.empty ());
|
|
||||||
|
|
||||||
// Second, process two eligble transactions
|
// Second, process two eligible transactions
|
||||||
auto block0 = builder.make_block ()
|
auto block1 = builder.make_block ()
|
||||||
.account (nano::dev::genesis_key.pub)
|
.account (nano::dev::genesis_key.pub)
|
||||||
.previous (send->hash ())
|
.previous (send->hash ())
|
||||||
.representative (nano::dev::genesis_key.pub)
|
.representative (nano::dev::genesis_key.pub)
|
||||||
|
|
@ -95,7 +112,14 @@ TEST (election_scheduler, no_vacancy)
|
||||||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||||
.work (*system.work.generate (send->hash ()))
|
.work (*system.work.generate (send->hash ()))
|
||||||
.build_shared ();
|
.build_shared ();
|
||||||
auto block1 = builder.make_block ()
|
ASSERT_EQ (nano::process_result::progress, node.process (*block1).code);
|
||||||
|
|
||||||
|
// There is vacancy so it should be inserted
|
||||||
|
node.scheduler.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
|
||||||
|
std::shared_ptr<nano::election> election{};
|
||||||
|
ASSERT_TIMELY (5s, (election = node.active.election (block1->qualified_root ())) != nullptr);
|
||||||
|
|
||||||
|
auto block2 = builder.make_block ()
|
||||||
.account (key.pub)
|
.account (key.pub)
|
||||||
.previous (receive->hash ())
|
.previous (receive->hash ())
|
||||||
.representative (key.pub)
|
.representative (key.pub)
|
||||||
|
|
@ -104,22 +128,17 @@ TEST (election_scheduler, no_vacancy)
|
||||||
.sign (key.prv, key.pub)
|
.sign (key.prv, key.pub)
|
||||||
.work (*system.work.generate (receive->hash ()))
|
.work (*system.work.generate (receive->hash ()))
|
||||||
.build_shared ();
|
.build_shared ();
|
||||||
ASSERT_EQ (nano::process_result::progress, node.process (*block0).code);
|
ASSERT_EQ (nano::process_result::progress, node.process (*block2).code);
|
||||||
ASSERT_EQ (nano::process_result::progress, node.process (*block1).code);
|
|
||||||
node.scheduler.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
|
|
||||||
// There is vacancy so it should be inserted
|
|
||||||
ASSERT_TIMELY (1s, node.active.size () == 1);
|
|
||||||
node.scheduler.activate (key.pub, node.store.tx_begin_read ());
|
|
||||||
// There is no vacancy so it should stay queued
|
// There is no vacancy so it should stay queued
|
||||||
ASSERT_TIMELY (1s, node.scheduler.size () == 1);
|
node.scheduler.activate (key.pub, node.store.tx_begin_read ());
|
||||||
auto election3 = node.active.election (block0->qualified_root ());
|
ASSERT_TIMELY (5s, node.scheduler.size () == 1);
|
||||||
ASSERT_NE (nullptr, election3);
|
ASSERT_TRUE (node.active.election (block2->qualified_root ()) == nullptr);
|
||||||
election3->force_confirm ();
|
|
||||||
// Election completed, next in queue should begin
|
// Election confirmed, next in queue should begin
|
||||||
ASSERT_TIMELY (1s, node.scheduler.size () == 0);
|
election->force_confirm ();
|
||||||
ASSERT_TIMELY (1s, node.active.size () == 1);
|
ASSERT_TIMELY (5s, node.active.election (block2->qualified_root ()) != nullptr);
|
||||||
auto election4 = node.active.election (block1->qualified_root ());
|
ASSERT_TRUE (node.scheduler.empty ());
|
||||||
ASSERT_NE (nullptr, election4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that election_scheduler::flush terminates even if no elections can currently be queued e.g. shutdown or no active_transactions vacancy
|
// Ensure that election_scheduler::flush terminates even if no elections can currently be queued e.g. shutdown or no active_transactions vacancy
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue