dncurrency/nano/core_test/scheduler_buckets.cpp
clemahieu f400b28aa5
Renaming nano::prioritization to nano::scheduler::buckets. (#4274)
This puts the class in the correct component namespace and better describes what the class is modeling.
2023-09-01 13:25:42 +01:00

253 lines
6.1 KiB
C++

#include <nano/node/scheduler/buckets.hpp>
#include <nano/secure/common.hpp>
#include <gtest/gtest.h>
#include <unordered_set>
nano::keypair & keyzero ()
{
static nano::keypair result;
return result;
}
nano::keypair & key0 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key1 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key2 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key3 ()
{
static nano::keypair result;
return result;
}
std::shared_ptr<nano::state_block> & blockzero ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (keyzero ().pub)
.previous (0)
.representative (keyzero ().pub)
.balance (0)
.link (0)
.sign (keyzero ().prv, keyzero ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block0 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key0 ().pub)
.previous (0)
.representative (key0 ().pub)
.balance (nano::Gxrb_ratio)
.link (0)
.sign (key0 ().prv, key0 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block1 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key1 ().pub)
.previous (0)
.representative (key1 ().pub)
.balance (nano::Mxrb_ratio)
.link (0)
.sign (key1 ().prv, key1 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block2 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key2 ().pub)
.previous (0)
.representative (key2 ().pub)
.balance (nano::Gxrb_ratio)
.link (0)
.sign (key2 ().prv, key2 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block3 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key3 ().pub)
.previous (0)
.representative (key3 ().pub)
.balance (nano::Mxrb_ratio)
.link (0)
.sign (key3 ().prv, key3 ().pub)
.work (0)
.build_shared ();
return result;
}
TEST (buckets, construction)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (0, buckets.size ());
ASSERT_TRUE (buckets.empty ());
ASSERT_EQ (62, buckets.bucket_count ());
}
TEST (buckets, index_min)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (0, buckets.index (std::numeric_limits<nano::uint128_t>::min ()));
}
TEST (buckets, index_max)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (buckets.bucket_count () - 1, buckets.index (std::numeric_limits<nano::uint128_t>::max ()));
}
TEST (buckets, insert_Gxrb)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (48));
}
TEST (buckets, insert_Mxrb)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (13));
}
// Test two blocks with the same priority
TEST (buckets, insert_same_priority)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (2, buckets.size ());
ASSERT_EQ (2, buckets.bucket_size (48));
}
// Test the same block inserted multiple times
TEST (buckets, insert_duplicate)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (48));
}
TEST (buckets, insert_older)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block2 (), buckets.top ());
buckets.pop ();
}
TEST (buckets, pop)
{
nano::scheduler::buckets buckets;
ASSERT_TRUE (buckets.empty ());
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_FALSE (buckets.empty ());
buckets.pop ();
ASSERT_TRUE (buckets.empty ());
}
TEST (buckets, top_one)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
}
TEST (buckets, top_two)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block1 (), buckets.top ());
buckets.pop ();
ASSERT_TRUE (buckets.empty ());
}
TEST (buckets, top_round_robin)
{
nano::scheduler::buckets buckets;
buckets.push (1000, blockzero (), 0);
ASSERT_EQ (blockzero (), buckets.top ());
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block1 (), nano::Mxrb_ratio);
buckets.push (1100, block3 (), nano::Mxrb_ratio);
buckets.pop (); // blockzero
EXPECT_EQ (block1 (), buckets.top ());
buckets.pop ();
EXPECT_EQ (block0 (), buckets.top ());
buckets.pop ();
EXPECT_EQ (block3 (), buckets.top ());
buckets.pop ();
EXPECT_TRUE (buckets.empty ());
}
TEST (buckets, trim_normal)
{
nano::scheduler::buckets buckets{ 1 };
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
}
TEST (buckets, trim_reverse)
{
nano::scheduler::buckets buckets{ 1 };
buckets.push (1100, block2 (), nano::Gxrb_ratio);
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
}
TEST (buckets, trim_even)
{
nano::scheduler::buckets buckets{ 2 };
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
buckets.push (1000, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (2, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block1 (), buckets.top ());
}