Skip to content

Commit

Permalink
Merge pull request #1476 from AntelopeIO/GH-1111-tests
Browse files Browse the repository at this point in the history
Tests: Add back old commented out unittests
  • Loading branch information
heifner authored Aug 3, 2023
2 parents 78136f2 + ac8c349 commit 5b6226b
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 263 deletions.
92 changes: 33 additions & 59 deletions unittests/api_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2915,69 +2915,43 @@ BOOST_FIXTURE_TEST_CASE(resource_limits_tests, validating_tester) {
BOOST_CHECK_THROW(pushit(), wasm_exception);
}

#if 0
/*************************************************************************************
* privileged_tests test case
*************************************************************************************/
BOOST_FIXTURE_TEST_CASE(privileged_tests, tester) { try {
produce_blocks(2);
create_account( "testapi"_n );
create_account( "acc1"_n );
produce_blocks(100);
set_code( "testapi"_n, contracts::test_api_wasm() );
produce_blocks(1);

{
signed_transaction trx;

auto pl = vector<permission_level>{{config::system_account_name, config::active_name}};
action act(pl, test_chain_action<"setprods"_n>());
vector<producer_key> prod_keys = {
{ "inita"_n, get_public_key( "inita"_n, "active" ) },
{ "initb"_n, get_public_key( "initb"_n, "active" ) },
{ "initc"_n, get_public_key( "initc"_n, "active" ) },
{ "initd"_n, get_public_key( "initd"_n, "active" ) },
{ "inite"_n, get_public_key( "inite"_n, "active" ) },
{ "initf"_n, get_public_key( "initf"_n, "active" ) },
{ "initg"_n, get_public_key( "initg"_n, "active" ) },
{ "inith"_n, get_public_key( "inith"_n, "active" ) },
{ "initi"_n, get_public_key( "initi"_n, "active" ) },
{ "initj"_n, get_public_key( "initj"_n, "active" ) },
{ "initk"_n, get_public_key( "initk"_n, "active" ) },
{ "initl"_n, get_public_key( "initl"_n, "active" ) },
{ "initm"_n, get_public_key( "initm"_n, "active" ) },
{ "initn"_n, get_public_key( "initn"_n, "active" ) },
{ "inito"_n, get_public_key( "inito"_n, "active" ) },
{ "initp"_n, get_public_key( "initp"_n, "active" ) },
{ "initq"_n, get_public_key( "initq"_n, "active" ) },
{ "initr"_n, get_public_key( "initr"_n, "active" ) },
{ "inits"_n, get_public_key( "inits"_n, "active" ) },
{ "initt"_n, get_public_key( "initt"_n, "active" ) },
{ "initu"_n, get_public_key( "initu"_n, "active" ) }
};
vector<char> data = fc::raw::pack(uint32_t(0));
vector<char> keys = fc::raw::pack(prod_keys);
data.insert( data.end(), keys.begin(), keys.end() );
act.data = data;
trx.actions.push_back(act);

set_tapos(trx);
BOOST_AUTO_TEST_CASE( set_producers_legacy ) { try {
fc::temp_directory tempdir;
validating_tester t( tempdir, true );
t.execute_setup_policy( setup_policy::preactivate_feature_and_new_bios );

vector<account_name> prods = {
"inita"_n,
"initb"_n,
"initc"_n,
"initd"_n,
"inite"_n,
"initf"_n,
"initg"_n,
"inith"_n,
"initi"_n,
"initj"_n,
"initk"_n,
"initl"_n,
"initm"_n,
"initn"_n,
"inito"_n,
"initp"_n,
"initq"_n,
"initr"_n,
"inits"_n,
"initt"_n,
"initu"_n
};

auto sigs = trx.sign(get_private_key(config::system_account_name, "active"), control->get_chain_id());
trx.get_signature_keys(control->get_chain_id() );
auto res = push_transaction(trx);
BOOST_CHECK_EQUAL(res.status, transaction_receipt::executed);
}
t.create_accounts( prods );
t.produce_block();

CALL_TEST_FUNCTION( *this, "test_privileged", "test_is_privileged", {} );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( *this, "test_privileged", "test_is_privileged", {} ), transaction_exception,
[](const fc::exception& e) {
return expect_assert_message(e, "context.privileged: testapi does not have permission to call this API");
}
);
auto trace = t.set_producers_legacy(prods);
BOOST_REQUIRE(trace && trace->receipt);
BOOST_CHECK_EQUAL(trace->receipt->status, transaction_receipt::executed);

} FC_LOG_AND_RETHROW() }
#endif

/*************************************************************************************
* real_tests test cases
Expand Down
274 changes: 100 additions & 174 deletions unittests/producer_schedule_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,187 +11,113 @@ using mvo = fc::mutable_variant_object;

BOOST_AUTO_TEST_SUITE(producer_schedule_tests)

// Calculate expected producer given the schedule and slot number
account_name get_expected_producer(const vector<producer_authority>& schedule, const uint64_t slot) {
const auto& index = (slot % (schedule.size() * config::producer_repetitions)) / config::producer_repetitions;
return schedule.at(index).producer_name;
};
namespace {

// Calculate expected producer given the schedule and slot number
account_name get_expected_producer(const vector<producer_authority>& schedule, block_timestamp_type t) {
const auto& index = (t.slot % (schedule.size() * config::producer_repetitions)) / config::producer_repetitions;
return schedule.at(index).producer_name;
};

} // anonymous namespace

BOOST_FIXTURE_TEST_CASE( verify_producer_schedule, validating_tester ) try {

// Utility function to ensure that producer schedule work as expected
const auto& confirm_schedule_correctness = [&](const vector<producer_authority>& new_prod_schd, uint32_t expected_schd_ver) {
const uint32_t check_duration = 1000; // number of blocks
bool scheduled_changed_to_new = false;
for (uint32_t i = 0; i < check_duration; ++i) {
const auto current_schedule = control->head_block_state()->active_schedule.producers;
if (new_prod_schd == current_schedule) {
scheduled_changed_to_new = true;
}

// Produce block
produce_block();

// Check if two schedule is equal
bool is_schedule_equal(const vector<producer_authority>& first, const vector<producer_authority>& second) {
bool is_equal = first.size() == second.size();
for (uint32_t i = 0; i < first.size(); i++) {
is_equal = is_equal && first.at(i) == second.at(i);
// Check if the producer is the same as what we expect
const auto block_time = control->head_block_time();
const auto& expected_producer = get_expected_producer(current_schedule, block_time);
BOOST_TEST(control->head_block_producer() == expected_producer);

if (scheduled_changed_to_new)
break;
}
return is_equal;

BOOST_TEST(scheduled_changed_to_new);

const auto current_schd_ver = control->head_block_header().schedule_version;
BOOST_TEST(current_schd_ver == expected_schd_ver);
};

// Calculate the block num of the next round first block
// The new producer schedule will become effective when it's in the block of the next round first block
// However, it won't be applied until the effective block num is deemed irreversible
uint64_t calc_block_num_of_next_round_first_block(const controller& control){
auto res = control.head_block_num() + 1;
const auto blocks_per_round = control.head_block_state()->active_schedule.producers.size() * config::producer_repetitions;
while((res % blocks_per_round) != 0) {
res++;
}
return res;
// Create producer accounts
vector<account_name> producers = {
"inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n,
"inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n,
"inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n
};
#if 0
BOOST_FIXTURE_TEST_CASE( verify_producer_schedule, validating_tester ) try {

// Utility function to ensure that producer schedule work as expected
const auto& confirm_schedule_correctness = [&](const vector<producer_key>& new_prod_schd, const uint64_t eff_new_prod_schd_block_num) {
const uint32_t check_duration = 1000; // number of blocks
for (uint32_t i = 0; i < check_duration; ++i) {
const auto current_schedule = control->head_block_state()->active_schedule.producers;
const auto& current_absolute_slot = control->get_global_properties().proposed_schedule_block_num;
// Determine expected producer
const auto& expected_producer = get_expected_producer(current_schedule, *current_absolute_slot + 1);

// The new schedule will only be applied once the effective block num is deemed irreversible
const bool is_new_schedule_applied = control->last_irreversible_block_num() > eff_new_prod_schd_block_num;

// Ensure that we have the correct schedule at the right time
if (is_new_schedule_applied) {
BOOST_TEST(is_schedule_equal(new_prod_schd, current_schedule));
} else {
BOOST_TEST(!is_schedule_equal(new_prod_schd, current_schedule));
}

// Produce block
produce_block();

// Check if the producer is the same as what we expect
BOOST_TEST(control->head_block_producer() == expected_producer);
}
};

// Create producer accounts
vector<account_name> producers = {
"inita", "initb", "initc", "initd", "inite", "initf", "initg",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"
};
create_accounts(producers);

// ---- Test first set of producers ----
// Send set prods action and confirm schedule correctness
set_producers(producers);
const auto first_prod_schd = get_producer_keys(producers);
const auto eff_first_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
confirm_schedule_correctness(first_prod_schd, eff_first_prod_schd_block_num);

// ---- Test second set of producers ----
vector<account_name> second_set_of_producer = {
producers[3], producers[6], producers[9], producers[12], producers[15], producers[18], producers[20]
};
// Send set prods action and confirm schedule correctness
set_producers(second_set_of_producer);
const auto second_prod_schd = get_producer_keys(second_set_of_producer);
const auto& eff_second_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
confirm_schedule_correctness(second_prod_schd, eff_second_prod_schd_block_num);

// ---- Test deliberately miss some blocks ----
const int64_t num_of_missed_blocks = 5000;
produce_block(fc::microseconds(500 * 1000 * num_of_missed_blocks));
// Ensure schedule is still correct
confirm_schedule_correctness(second_prod_schd, eff_second_prod_schd_block_num);
produce_block();
create_accounts(producers);

// ---- Test third set of producers ----
vector<account_name> third_set_of_producer = {
producers[2], producers[5], producers[8], producers[11], producers[14], producers[17], producers[20],
producers[0], producers[3], producers[6], producers[9], producers[12], producers[15], producers[18],
producers[1], producers[4], producers[7], producers[10], producers[13], producers[16], producers[19]
};
// Send set prods action and confirm schedule correctness
set_producers(third_set_of_producer);
const auto third_prod_schd = get_producer_keys(third_set_of_producer);
const auto& eff_third_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
confirm_schedule_correctness(third_prod_schd, eff_third_prod_schd_block_num);

} FC_LOG_AND_RETHROW()


BOOST_FIXTURE_TEST_CASE( verify_producers, validating_tester ) try {

vector<account_name> valid_producers = {
"inita", "initb", "initc", "initd", "inite", "initf", "initg",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"
};
create_accounts(valid_producers);
set_producers(valid_producers);

// account initz does not exist
vector<account_name> nonexisting_producer = { "initz" };
BOOST_CHECK_THROW(set_producers(nonexisting_producer), wasm_execution_error);

// replace initg with inita, inita is now duplicate
vector<account_name> invalid_producers = {
"inita", "initb", "initc", "initd", "inite", "initf", "inita",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"
};

BOOST_CHECK_THROW(set_producers(invalid_producers), wasm_execution_error);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( verify_header_schedule_version, validating_tester ) try {

// Utility function to ensure that producer schedule version in the header is correct
const auto& confirm_header_schd_ver_correctness = [&](const uint64_t expected_version, const uint64_t eff_new_prod_schd_block_num) {
const uint32_t check_duration = 1000; // number of blocks
for (uint32_t i = 0; i < check_duration; ++i) {
// The new schedule will only be applied once the effective block num is deemed irreversible
const bool is_new_schedule_applied = control->last_irreversible_block_num() > eff_new_prod_schd_block_num;

// Produce block
produce_block();

// Ensure that the head block header is updated at the right time
const auto current_schd_ver = control->head_block_header().schedule_version;
if (is_new_schedule_applied) {
BOOST_TEST(current_schd_ver == expected_version);
} else {
BOOST_TEST(current_schd_ver != expected_version);
}
}
};

// Create producer accounts
vector<account_name> producers = {
"inita", "initb", "initc", "initd", "inite", "initf", "initg",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"
};
create_accounts(producers);

// Send set prods action and confirm schedule correctness
set_producers(producers, 1);
const auto& eff_first_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
// Confirm the version is correct
confirm_header_schd_ver_correctness(1, eff_first_prod_schd_block_num);

// Shuffle the producers and set the new one with smaller version
boost::range::random_shuffle(producers);
set_producers(producers, 0);
const auto& eff_second_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
// Even though we set it with smaller version number, the version should be incremented instead
confirm_header_schd_ver_correctness(2, eff_second_prod_schd_block_num);

// Shuffle the producers and set the new one with much larger version number
boost::range::random_shuffle(producers);
set_producers(producers, 1000);
const auto& eff_third_prod_schd_block_num = calc_block_num_of_next_round_first_block(*control);
// Even though we set it with much large version number, the version should be incremented instead
confirm_header_schd_ver_correctness(3, eff_third_prod_schd_block_num);

} FC_LOG_AND_RETHROW()
#endif
// ---- Test first set of producers ----
// Send set prods action and confirm schedule correctness
set_producers(producers);
const auto first_prod_schd = get_producer_authorities(producers);
confirm_schedule_correctness(first_prod_schd, 1);

// ---- Test second set of producers ----
vector<account_name> second_set_of_producer = {
producers[3], producers[6], producers[9], producers[12], producers[15], producers[18], producers[20]
};
// Send set prods action and confirm schedule correctness
set_producers(second_set_of_producer);
const auto second_prod_schd = get_producer_authorities(second_set_of_producer);
confirm_schedule_correctness(second_prod_schd, 2);

// ---- Test deliberately miss some blocks ----
const int64_t num_of_missed_blocks = 5000;
produce_block(fc::microseconds(500 * 1000 * num_of_missed_blocks));
// Ensure schedule is still correct
confirm_schedule_correctness(second_prod_schd, 2);
produce_block();

// ---- Test third set of producers ----
vector<account_name> third_set_of_producer = {
producers[2], producers[5], producers[8], producers[11], producers[14], producers[17], producers[20],
producers[0], producers[3], producers[6], producers[9], producers[12], producers[15], producers[18],
producers[1], producers[4], producers[7], producers[10], producers[13], producers[16], producers[19]
};
// Send set prods action and confirm schedule correctness
set_producers(third_set_of_producer);
const auto third_prod_schd = get_producer_authorities(third_set_of_producer);
confirm_schedule_correctness(third_prod_schd, 3);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( verify_producers, validating_tester ) try {

vector<account_name> valid_producers = {
"inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n,
"inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n,
"inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n
};
create_accounts(valid_producers);
set_producers(valid_producers);

// account initz does not exist
vector<account_name> nonexisting_producer = { "initz"_n };
BOOST_CHECK_THROW(set_producers(nonexisting_producer), wasm_execution_error);

// replace initg with inita, inita is now duplicate
vector<account_name> invalid_producers = {
"inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "inita"_n,
"inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n,
"inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n
};

BOOST_CHECK_THROW(set_producers(invalid_producers), wasm_execution_error);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( producer_schedule_promotion_test, validating_tester ) try {
create_accounts( {"alice"_n,"bob"_n,"carol"_n} );
Expand Down
Loading

0 comments on commit 5b6226b

Please sign in to comment.