Skip to content

Commit

Permalink
Fix unit test election_scheduler.no_vacancy
Browse files Browse the repository at this point in the history
  • Loading branch information
theohax committed Feb 13, 2022
1 parent d67f7be commit 22332c0
Showing 1 changed file with 45 additions and 26 deletions.
71 changes: 45 additions & 26 deletions nano/core_test/election_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,32 @@ TEST (election_scheduler, activate_one_flush)
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)
{
nano::system system;
nano::system system{};

nano::node_config config{ nano::get_available_port (), system.logging };
config.active_elections_size = 1;
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;

auto & node = *system.add_node (config);
nano::state_block_builder builder;
nano::keypair key;
nano::state_block_builder builder{};
nano::keypair key{};

// Activating accounts depends on confirmed dependencies. First, prepare 2 accounts
auto send = builder.make_block ()
Expand All @@ -69,6 +87,9 @@ TEST (election_scheduler, no_vacancy)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (nano::dev::genesis->hash ()))
.build_shared ();
ASSERT_EQ (nano::process_result::progress, node.process (*send).code);
node.process_confirmed (nano::election_status{ send });

auto receive = builder.make_block ()
.account (key.pub)
.previous (0)
Expand All @@ -78,15 +99,11 @@ TEST (election_scheduler, no_vacancy)
.sign (key.prv, key.pub)
.work (*system.work.generate (key.pub))
.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);
nano::blocks_confirm (node, { receive }, true);
ASSERT_TIMELY (1s, node.active.empty ());
node.process_confirmed (nano::election_status{ receive });

// Second, process two eligble transactions
auto block0 = builder.make_block ()
// Second, process two eligible transactions
auto block1 = builder.make_block ()
.account (nano::dev::genesis_key.pub)
.previous (send->hash ())
.representative (nano::dev::genesis_key.pub)
Expand All @@ -95,7 +112,14 @@ TEST (election_scheduler, no_vacancy)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (send->hash ()))
.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)
.previous (receive->hash ())
.representative (key.pub)
Expand All @@ -104,22 +128,17 @@ TEST (election_scheduler, no_vacancy)
.sign (key.prv, key.pub)
.work (*system.work.generate (receive->hash ()))
.build_shared ();
ASSERT_EQ (nano::process_result::progress, node.process (*block0).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 ());
ASSERT_EQ (nano::process_result::progress, node.process (*block2).code);

// There is no vacancy so it should stay queued
ASSERT_TIMELY (1s, node.scheduler.size () == 1);
auto election3 = node.active.election (block0->qualified_root ());
ASSERT_NE (nullptr, election3);
election3->force_confirm ();
// Election completed, next in queue should begin
ASSERT_TIMELY (1s, node.scheduler.size () == 0);
ASSERT_TIMELY (1s, node.active.size () == 1);
auto election4 = node.active.election (block1->qualified_root ());
ASSERT_NE (nullptr, election4);
node.scheduler.activate (key.pub, node.store.tx_begin_read ());
ASSERT_TIMELY (5s, node.scheduler.size () == 1);
ASSERT_TRUE (node.active.election (block2->qualified_root ()) == nullptr);

// Election confirmed, next in queue should begin
election->force_confirm ();
ASSERT_TIMELY (5s, node.active.election (block2->qualified_root ()) != nullptr);
ASSERT_TRUE (node.scheduler.empty ());
}

// Ensure that election_scheduler::flush terminates even if no elections can currently be queued e.g. shutdown or no active_transactions vacancy
Expand Down

0 comments on commit 22332c0

Please sign in to comment.