Skip to content

Commit

Permalink
Merge pull request #145 from AntelopeIO/unittest_svnn_and_legacy
Browse files Browse the repository at this point in the history
Add support to run unit tests in both Legacy and Savanna (Part 1)
  • Loading branch information
linh2931 authored May 16, 2024
2 parents 22d970f + 3846aa0 commit 1874c5f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 67 deletions.
22 changes: 22 additions & 0 deletions libraries/testing/include/eosio/testing/tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,14 @@ namespace eosio::testing {

};

class savanna_tester : public tester {
public:
savanna_tester();
};

using legacy_tester = tester;
using testers = boost::mpl::list<legacy_tester, savanna_tester>;

class tester_no_disable_deferred_trx : public tester {
public:
tester_no_disable_deferred_trx(): tester(setup_policy::full_except_do_not_disable_deferred_trx) {
Expand Down Expand Up @@ -757,6 +765,14 @@ namespace eosio::testing {
}
};

class savanna_validating_tester : public validating_tester {
public:
savanna_validating_tester();
};

using legacy_validating_tester = validating_tester;
using validating_testers = boost::mpl::list<legacy_validating_tester, savanna_validating_tester>;

// -------------------------------------------------------------------------------------
// creates and manages a set of `bls_public_key` used for finalizers voting and policies
// Supports initial transition to Savanna.
Expand Down Expand Up @@ -865,6 +881,12 @@ namespace eosio::testing {
return finalizer_policy{}.apply_diff(*fin_policy_diff);
}

void activate_savanna(size_t first_key_idx) {
set_node_finalizers(first_key_idx, pubkeys.size());
set_finalizer_policy(first_key_idx);
transition_to_savanna();
}

Tester& t;
vector<account_name> key_names;
vector<bls_public_key> pubkeys;
Expand Down
12 changes: 12 additions & 0 deletions libraries/testing/tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,12 @@ namespace eosio::testing {
execute_setup_policy(policy);
}

savanna_tester::savanna_tester() {
// Activate Savanna consensus
finalizer_keys fin_keys(*this, 4u /* num_keys */, 4u /* finset_size */);
fin_keys.activate_savanna(0u /* first_key_idx */);
}

unique_ptr<controller> validating_tester::create_validating_node(controller::config vcfg, const genesis_state& genesis, bool use_genesis, deep_mind_handler* dmlog) {
unique_ptr<controller> validating_node = std::make_unique<controller>(vcfg, make_protocol_feature_set(), genesis.compute_chain_id());
validating_node->add_indices();
Expand All @@ -1413,6 +1419,12 @@ namespace eosio::testing {
return validating_node;
}

savanna_validating_tester::savanna_validating_tester() {
// Activate Savanna consensus
finalizer_keys fin_keys(*this, 4u /* num_keys */, 4u /* finset_size */);
fin_keys.activate_savanna(0u /* first_key_idx */);
}

bool fc_exception_message_is::operator()( const fc::exception& ex ) {
auto message = ex.get_log().at( 0 ).get_message();
bool match = (message == expected);
Expand Down
142 changes: 75 additions & 67 deletions unittests/auth_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,81 +17,89 @@ using namespace eosio::testing;

BOOST_AUTO_TEST_SUITE(auth_tests)

BOOST_FIXTURE_TEST_CASE( missing_sigs, validating_tester ) { try {
create_accounts( {"alice"_n} );
produce_block();
BOOST_AUTO_TEST_CASE_TEMPLATE( missing_sigs, TESTER, validating_testers ) { try {
TESTER chain;

BOOST_REQUIRE_THROW( push_reqauth( "alice"_n, {permission_level{"alice"_n, config::active_name}}, {} ), unsatisfied_authorization );
auto trace = push_reqauth("alice"_n, "owner");
chain.create_accounts( {"alice"_n} );
chain.produce_block();

BOOST_REQUIRE_THROW( chain.push_reqauth( "alice"_n, {permission_level{"alice"_n, config::active_name}}, {} ), unsatisfied_authorization );
auto trace = chain.push_reqauth("alice"_n, "owner");

produce_block();
BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id));
chain.produce_block();
BOOST_REQUIRE_EQUAL(true, chain.chain_has_transaction(trace->id));

} FC_LOG_AND_RETHROW() } /// missing_sigs

BOOST_FIXTURE_TEST_CASE( missing_multi_sigs, validating_tester ) { try {
produce_block();
create_account("alice"_n, config::system_account_name, true);
produce_block();
BOOST_AUTO_TEST_CASE_TEMPLATE( missing_multi_sigs, TESTER, validating_testers ) { try {
TESTER chain;

chain.produce_block();
chain.create_account("alice"_n, config::system_account_name, true);
chain.produce_block();

BOOST_REQUIRE_THROW(push_reqauth("alice"_n, "owner"), unsatisfied_authorization); // without multisig
auto trace = push_reqauth("alice"_n, "owner", true); // with multisig
BOOST_REQUIRE_THROW(chain.push_reqauth("alice"_n, "owner"), unsatisfied_authorization); // without multisig
auto trace = chain.push_reqauth("alice"_n, "owner", true); // with multisig

produce_block();
BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id));
chain.produce_block();
BOOST_REQUIRE_EQUAL(true, chain.chain_has_transaction(trace->id));

} FC_LOG_AND_RETHROW() } /// missing_multi_sigs

BOOST_FIXTURE_TEST_CASE( missing_auths, validating_tester ) { try {
create_accounts( {"alice"_n, "bob"_n} );
produce_block();
BOOST_AUTO_TEST_CASE_TEMPLATE( missing_auths, TESTER, validating_testers ) { try {
TESTER chain;

chain.create_accounts( {"alice"_n, "bob"_n} );
chain.produce_block();

/// action not provided from authority
BOOST_REQUIRE_THROW( push_reqauth( "alice"_n, {permission_level{"bob"_n, config::active_name}}, { get_private_key("bob"_n, "active") } ), missing_auth_exception);
BOOST_REQUIRE_THROW( chain.push_reqauth( "alice"_n, {permission_level{"bob"_n, config::active_name}}, { chain.get_private_key("bob"_n, "active") } ), missing_auth_exception);

} FC_LOG_AND_RETHROW() } /// transfer_test

/**
* This test case will attempt to allow one account to transfer on behalf
* of another account by updating the active authority.
*/
BOOST_FIXTURE_TEST_CASE( delegate_auth, validating_tester ) { try {
create_accounts( {"alice"_n,"bob"_n});
produce_block();
BOOST_AUTO_TEST_CASE_TEMPLATE( delegate_auth, TESTER, validating_testers ) { try {
TESTER chain;

chain.create_accounts( {"alice"_n,"bob"_n});
chain.produce_block();

auto delegated_auth = authority( 1, {},
{
{ .permission = {"bob"_n,config::active_name}, .weight = 1}
});

auto original_auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
auto original_auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
wdump((original_auth));

set_authority( "alice"_n, config::active_name, delegated_auth );
chain.set_authority( "alice"_n, config::active_name, delegated_auth );

auto new_auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
auto new_auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
wdump((new_auth));
BOOST_CHECK_EQUAL((new_auth == delegated_auth), true);

produce_block();
produce_block();
chain.produce_block();
chain.produce_block();

auto auth = control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
auto auth = chain.control->get_authorization_manager().get_permission({"alice"_n, config::active_name}).auth.to_authority();
wdump((auth));
BOOST_CHECK_EQUAL((new_auth == auth), true);

/// execute nonce from alice signed by bob
auto trace = push_reqauth("alice"_n, {permission_level{"alice"_n, config::active_name}}, { get_private_key("bob"_n, "active") } );
auto trace = chain.push_reqauth("alice"_n, {permission_level{"alice"_n, config::active_name}}, { chain.get_private_key("bob"_n, "active") } );

produce_block();
chain.produce_block();
//todoBOOST_REQUIRE_EQUAL(true, chain_has_transaction(trace->id));

} FC_LOG_AND_RETHROW() }


BOOST_AUTO_TEST_CASE(update_auths) {
try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( update_auths, TESTER, validating_testers ) { try {
TESTER chain;

chain.create_account(name("alice"));
chain.create_account(name("bob"));

Expand All @@ -108,7 +116,7 @@ try {
// Ensure the permission is updated
permission_object::id_type owner_id;
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("owner")));
auto obj = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("owner")));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == name("alice"));
BOOST_TEST(obj->name == name("owner"));
Expand All @@ -131,7 +139,7 @@ try {
chain.produce_blocks();

{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("active")));
auto obj = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("active")));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == name("alice"));
BOOST_TEST(obj->name == name("active"));
Expand Down Expand Up @@ -160,12 +168,12 @@ try {
{ permission_level{name("alice"), name("active")} }, { new_active_priv_key });
chain.produce_blocks();
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
auto obj = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == name("alice"));
BOOST_TEST(obj->name == name("spending"));
BOOST_TEST(chain.get<permission_object>(obj->parent).owner == name("alice"));
BOOST_TEST(chain.get<permission_object>(obj->parent).name == name("active"));
BOOST_TEST(chain.template get<permission_object>(obj->parent).owner == name("alice"));
BOOST_TEST(chain.template get<permission_object>(obj->parent).name == name("active"));
}

// Update spending auth parent to be its own, should fail
Expand All @@ -178,7 +186,7 @@ try {
// Remove spending auth
chain.delete_authority(name("alice"), name("spending"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key });
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
auto obj = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
BOOST_TEST(obj == nullptr);
}
chain.produce_blocks();
Expand All @@ -193,17 +201,17 @@ try {

// Verify correctness of trading and spending
{
const auto* trading = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("trading")));
const auto* spending = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
const auto* trading = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("trading")));
const auto* spending = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")));
BOOST_TEST(trading != nullptr);
BOOST_TEST(spending != nullptr);
BOOST_TEST(trading->owner == name("alice"));
BOOST_TEST(spending->owner == name("alice"));
BOOST_TEST(trading->name == name("trading"));
BOOST_TEST(spending->name == name("spending"));
BOOST_TEST(spending->parent == trading->id);
BOOST_TEST(chain.get(trading->parent).owner == name("alice"));
BOOST_TEST(chain.get(trading->parent).name == name("active"));
BOOST_TEST(chain.template get(trading->parent).owner == name("alice"));
BOOST_TEST(chain.template get(trading->parent).name == name("active"));

}

Expand All @@ -216,16 +224,15 @@ try {

// Delete spending auth
chain.delete_authority(name("alice"), name("spending"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key });
BOOST_TEST((chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")))) == nullptr);
BOOST_TEST((chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("spending")))) == nullptr);
// Delete trading auth, now it should succeed since it doesn't have any children anymore
chain.delete_authority(name("alice"), name("trading"), { permission_level{name("alice"), name("active")} }, { new_active_priv_key });
BOOST_TEST((chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("trading")))) == nullptr);
BOOST_TEST((chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("trading")))) == nullptr);

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) {
try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( update_auth_unknown_private_key, TESTER, validating_testers ) { try {
TESTER chain;
chain.create_account(name("alice"));

// public key with no corresponding private key
Expand All @@ -242,7 +249,7 @@ BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) {
// Ensure the permission is updated
permission_object::id_type owner_id;
{
auto obj = chain.find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("owner")));
auto obj = chain.template find<permission_object, by_owner>(boost::make_tuple(name("alice"), name("owner")));
BOOST_TEST(obj != nullptr);
BOOST_TEST(obj->owner == name("alice"));
BOOST_TEST(obj->name == name("owner"));
Expand All @@ -258,8 +265,8 @@ BOOST_AUTO_TEST_CASE(update_auth_unknown_private_key) {
} FC_LOG_AND_RETHROW()
}

BOOST_AUTO_TEST_CASE(link_auths) { try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( link_auths, TESTER, validating_testers ) { try {
TESTER chain;

chain.create_accounts({name("alice"),name("bob")});

Expand Down Expand Up @@ -301,8 +308,8 @@ BOOST_AUTO_TEST_CASE(link_auths) { try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(link_then_update_auth) { try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( link_then_update_auth, TESTER, validating_testers ) { try {
TESTER chain;

chain.create_account(name("alice"));

Expand All @@ -327,21 +334,20 @@ BOOST_AUTO_TEST_CASE(link_then_update_auth) { try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(create_account) {
try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( create_account, TESTER, validating_testers ) { try {
TESTER chain;
chain.create_account(name("joe"));
chain.produce_block();

// Verify account created properly
const auto& joe_owner_authority = chain.get<permission_object, by_owner>(boost::make_tuple(name("joe"), name("owner")));
const auto& joe_owner_authority = chain.template get<permission_object, by_owner>(boost::make_tuple(name("joe"), name("owner")));
BOOST_TEST(joe_owner_authority.auth.threshold == 1u);
BOOST_TEST(joe_owner_authority.auth.accounts.size() == 1u);
BOOST_TEST(joe_owner_authority.auth.keys.size() == 1u);
BOOST_TEST(joe_owner_authority.auth.keys[0].key.to_string({}) == chain.get_public_key(name("joe"), "owner").to_string({}));
BOOST_TEST(joe_owner_authority.auth.keys[0].weight == 1u);

const auto& joe_active_authority = chain.get<permission_object, by_owner>(boost::make_tuple(name("joe"), name("active")));
const auto& joe_active_authority = chain.template get<permission_object, by_owner>(boost::make_tuple(name("joe"), name("active")));
BOOST_TEST(joe_active_authority.auth.threshold == 1u);
BOOST_TEST(joe_active_authority.auth.accounts.size() == 1u);
BOOST_TEST(joe_active_authority.auth.keys.size() == 1u);
Expand All @@ -366,8 +372,8 @@ try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE( any_auth ) { try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( any_auth, TESTER, validating_testers ) { try {
TESTER chain;
chain.create_accounts( {name("alice"), name("bob")} );
chain.produce_block();

Expand Down Expand Up @@ -401,7 +407,9 @@ BOOST_AUTO_TEST_CASE( any_auth ) { try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(no_double_billing) {
// This test does not apply to Savanna testing for now, as setup_policy::preactivate_feature_and_new_bios
// does not load up bios contract for setfinalizer
BOOST_AUTO_TEST_CASE( no_double_billing ) {
try {
fc::temp_directory tempdir;
validating_tester chain( tempdir, true );
Expand Down Expand Up @@ -461,9 +469,9 @@ try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(stricter_auth) {
BOOST_AUTO_TEST_CASE_TEMPLATE( stricter_auth, TESTER, validating_testers ) {
try {
validating_tester chain;
TESTER chain;

chain.produce_block();

Expand Down Expand Up @@ -511,8 +519,8 @@ try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE( linkauth_special ) { try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( linkauth_special, TESTER, validating_testers ) { try {
TESTER chain;

const auto& tester_account = "tester"_n;
std::vector<transaction_id_type> ids;
Expand Down Expand Up @@ -552,8 +560,8 @@ BOOST_AUTO_TEST_CASE( linkauth_special ) { try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(delete_auth) { try {
validating_tester chain;
BOOST_AUTO_TEST_CASE_TEMPLATE( delete_auth, TESTER, validating_testers ) { try {
TESTER chain;

const auto& tester_account = "tester"_n;

Expand Down

0 comments on commit 1874c5f

Please sign in to comment.