Skip to content

Commit

Permalink
Merge pull request #181 from AntelopeIO/unittests_part7
Browse files Browse the repository at this point in the history
Update token_tests, payloadless_tests, and special_accounts_tests to run in Legacy and Savanna
  • Loading branch information
linh2931 authored May 21, 2024
2 parents 68e7a88 + f27499e commit 317da53
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 83 deletions.
143 changes: 77 additions & 66 deletions unittests/eosio.token_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,34 @@ using namespace std;

using mvo = fc::mutable_variant_object;

class eosio_token_tester : public tester {
template<typename T>
class eosio_token_tester : public T {
public:

eosio_token_tester() {
produce_blocks( 2 );
T::produce_blocks( 2 );

create_accounts( { "alice"_n, "bob"_n, "carol"_n, "eosio.token"_n } );
produce_blocks( 2 );
T::create_accounts( { "alice"_n, "bob"_n, "carol"_n, "eosio.token"_n } );
T::produce_blocks( 2 );

set_code( "eosio.token"_n, test_contracts::eosio_token_wasm() );
set_abi( "eosio.token"_n, test_contracts::eosio_token_abi() );
T::set_code( "eosio.token"_n, test_contracts::eosio_token_wasm() );
T::set_abi( "eosio.token"_n, test_contracts::eosio_token_abi() );

produce_blocks();
T::produce_blocks();

const auto& accnt = control->db().get<account_object,by_name>( "eosio.token"_n );
const auto& accnt = T::control->db().template get<account_object,by_name>( "eosio.token"_n );
abi_def abi;
BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true);
abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( abi_serializer_max_time ));
abi_ser.set_abi(std::move(abi), abi_serializer::create_yield_function( T::abi_serializer_max_time ));
}

action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) {
T::action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) {
string action_type_name = abi_ser.get_action_type(name);

action act;
act.account = "eosio.token"_n;
act.name = name;
act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function( abi_serializer_max_time ) );
act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) );

return base_tester::push_action( std::move(act), signer.to_uint64_t() );
}
Expand All @@ -52,19 +53,19 @@ class eosio_token_tester : public tester {
{
auto symb = eosio::chain::symbol::from_string(symbolname);
auto symbol_code = symb.to_symbol_code().value;
vector<char> data = get_row_by_account( "eosio.token"_n, name(symbol_code), "stat"_n, name(symbol_code) );
return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function( abi_serializer_max_time ) );
vector<char> data = T::get_row_by_account( "eosio.token"_n, name(symbol_code), "stat"_n, name(symbol_code) );
return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) );
}

fc::variant get_account( account_name acc, const string& symbolname)
{
auto symb = eosio::chain::symbol::from_string(symbolname);
auto symbol_code = symb.to_symbol_code().value;
vector<char> data = get_row_by_account( "eosio.token"_n, acc, "accounts"_n, name(symbol_code) );
return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer::create_yield_function( abi_serializer_max_time ) );
vector<char> data = T::get_row_by_account( "eosio.token"_n, acc, "accounts"_n, name(symbol_code) );
return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) );
}

action_result create( account_name issuer,
T::action_result create( account_name issuer,
asset maximum_supply ) {

return push_action( "eosio.token"_n, "create"_n, mvo()
Expand All @@ -73,15 +74,15 @@ class eosio_token_tester : public tester {
);
}

action_result issue( account_name issuer, account_name to, asset quantity, string memo ) {
T::action_result issue( account_name issuer, account_name to, asset quantity, string memo ) {
return push_action( issuer, "issue"_n, mvo()
( "to", to)
( "quantity", quantity)
( "memo", memo)
);
}

action_result transfer( account_name from,
T::action_result transfer( account_name from,
account_name to,
asset quantity,
string memo ) {
Expand All @@ -96,56 +97,63 @@ class eosio_token_tester : public tester {
abi_serializer abi_ser;
};

using eosio_token_testers = boost::mpl::list<eosio_token_tester<legacy_tester>,
eosio_token_tester<savanna_tester>>;

BOOST_AUTO_TEST_SUITE(eosio_token_tests)

BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( create_tests, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("1000.000 TKN"));
auto stats = get_stats("3,TKN");
auto token = chain.create( "alice"_n, asset::from_string("1000.000 TKN"));
auto stats = chain.get_stats("3,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "0.000 TKN")
("max_supply", "1000.000 TKN")
("issuer", "alice")
);
produce_blocks(1);
chain.produce_blocks(1);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( create_negative_max_supply, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( create_negative_max_supply, T, eosio_token_testers ) try {
T chain;

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "max-supply must be positive" ),
create( "alice"_n, asset::from_string("-1000.000 TKN"))
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "max-supply must be positive" ),
chain.create( "alice"_n, asset::from_string("-1000.000 TKN"))
);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( symbol_already_exists, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("100 TKN"));
auto stats = get_stats("0,TKN");
auto token = chain.create( "alice"_n, asset::from_string("100 TKN"));
auto stats = chain.get_stats("0,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "0 TKN")
("max_supply", "100 TKN")
("issuer", "alice")
);
produce_blocks(1);
chain.produce_blocks(1);

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "token with symbol already exists" ),
create( "alice"_n, asset::from_string("100 TKN"))
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "token with symbol already exists" ),
chain.create( "alice"_n, asset::from_string("100 TKN"))
);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( create_max_supply, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("4611686018427387903 TKN"));
auto stats = get_stats("0,TKN");
auto token = chain.create( "alice"_n, asset::from_string("4611686018427387903 TKN"));
auto stats = chain.get_stats("0,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "0 TKN")
("max_supply", "4611686018427387903 TKN")
("issuer", "alice")
);
produce_blocks(1);
chain.produce_blocks(1);

asset max(10, symbol(SY(0, NKT)));
share_type amount = 4611686018427387904;
Expand All @@ -154,23 +162,24 @@ BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try {
// OK to cast as this is a test and it is a hack to construct an invalid amount
memcpy((char*)&max, (char*)&amount, sizeof(share_type)); // hack in an invalid amount.

BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) {
BOOST_CHECK_EXCEPTION( chain.create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) {
return expect_assert_message(e, "magnitude of asset amount must be less than 2^62");
});


} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( create_max_decimals, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("1.000000000000000000 TKN"));
auto stats = get_stats("18,TKN");
auto token = chain.create( "alice"_n, asset::from_string("1.000000000000000000 TKN"));
auto stats = chain.get_stats("18,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "0.000000000000000000 TKN")
("max_supply", "1.000000000000000000 TKN")
("issuer", "alice")
);
produce_blocks(1);
chain.produce_blocks(1);

asset max(10, symbol(SY(0, NKT)));
//1.0000000000000000000 => 0x8ac7230489e80000L
Expand All @@ -180,87 +189,89 @@ BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try {
// OK to cast as this is a test and it is a hack to construct an invalid amount
memcpy((char*)&max, (char*)&amount, sizeof(share_type)); // hack in an invalid amount

BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) {
BOOST_CHECK_EXCEPTION( chain.create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) {
return expect_assert_message(e, "magnitude of asset amount must be less than 2^62");
});

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( issue_tests, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("1000.000 TKN"));
produce_blocks(1);
auto token = chain.create( "alice"_n, asset::from_string("1000.000 TKN"));
chain.produce_blocks(1);

issue( "alice"_n, "alice"_n, asset::from_string("500.000 TKN"), "hola" );
chain.issue( "alice"_n, "alice"_n, asset::from_string("500.000 TKN"), "hola" );

auto stats = get_stats("3,TKN");
auto stats = chain.get_stats("3,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "500.000 TKN")
("max_supply", "1000.000 TKN")
("issuer", "alice")
);

auto alice_balance = get_account("alice"_n, "3,TKN");
auto alice_balance = chain.get_account("alice"_n, "3,TKN");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "500.000 TKN")
);

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "quantity exceeds available supply" ),
issue( "alice"_n, "alice"_n, asset::from_string("500.001 TKN"), "hola" )
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "quantity exceeds available supply" ),
chain.issue( "alice"_n, "alice"_n, asset::from_string("500.001 TKN"), "hola" )
);

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must issue positive quantity" ),
issue( "alice"_n, "alice"_n, asset::from_string("-1.000 TKN"), "hola" )
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "must issue positive quantity" ),
chain.issue( "alice"_n, "alice"_n, asset::from_string("-1.000 TKN"), "hola" )
);

BOOST_REQUIRE_EQUAL( success(),
issue( "alice"_n, "alice"_n, asset::from_string("1.000 TKN"), "hola" )
BOOST_REQUIRE_EQUAL( chain.success(),
chain.issue( "alice"_n, "alice"_n, asset::from_string("1.000 TKN"), "hola" )
);


} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try {
BOOST_AUTO_TEST_CASE_TEMPLATE( transfer_tests, T, eosio_token_testers ) try {
T chain;

auto token = create( "alice"_n, asset::from_string("1000 CERO"));
produce_blocks(1);
auto token = chain.create( "alice"_n, asset::from_string("1000 CERO"));
chain.produce_blocks(1);

issue( "alice"_n, "alice"_n, asset::from_string("1000 CERO"), "hola" );
chain.issue( "alice"_n, "alice"_n, asset::from_string("1000 CERO"), "hola" );

auto stats = get_stats("0,CERO");
auto stats = chain.get_stats("0,CERO");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "1000 CERO")
("max_supply", "1000 CERO")
("issuer", "alice")
);

auto alice_balance = get_account("alice"_n, "0,CERO");
auto alice_balance = chain.get_account("alice"_n, "0,CERO");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "1000 CERO")
);

transfer( "alice"_n, "bob"_n, asset::from_string("300 CERO"), "hola" );
chain.transfer( "alice"_n, "bob"_n, asset::from_string("300 CERO"), "hola" );

alice_balance = get_account("alice"_n, "0,CERO");
alice_balance = chain.get_account("alice"_n, "0,CERO");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "700 CERO")
("frozen", 0)
("whitelist", 1)
);

auto bob_balance = get_account("bob"_n, "0,CERO");
auto bob_balance = chain.get_account("bob"_n, "0,CERO");
REQUIRE_MATCHING_OBJECT( bob_balance, mvo()
("balance", "300 CERO")
("frozen", 0)
("whitelist", 1)
);

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "overdrawn balance" ),
transfer( "alice"_n, "bob"_n, asset::from_string("701 CERO"), "hola" )
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "overdrawn balance" ),
chain.transfer( "alice"_n, "bob"_n, asset::from_string("701 CERO"), "hola" )
);

BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must transfer positive quantity" ),
transfer( "alice"_n, "bob"_n, asset::from_string("-1000 CERO"), "hola" )
BOOST_REQUIRE_EQUAL( chain.wasm_assert_msg( "must transfer positive quantity" ),
chain.transfer( "alice"_n, "bob"_n, asset::from_string("-1000 CERO"), "hola" )
);


Expand Down
34 changes: 20 additions & 14 deletions unittests/payloadless_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,36 @@ using namespace eosio::chain;
using namespace eosio::testing;
using namespace fc;

class payloadless_tester : public validating_tester {
template<typename T>
class payloadless_tester : public T {

};

using payloadless_testers = boost::mpl::list<payloadless_tester<legacy_validating_tester>,
payloadless_tester<savanna_validating_tester>>;

BOOST_AUTO_TEST_SUITE(payloadless_tests)

BOOST_FIXTURE_TEST_CASE( test_doit, payloadless_tester ) {
BOOST_AUTO_TEST_CASE_TEMPLATE( test_doit, T, payloadless_testers ) {
T chain;

create_accounts( {"payloadless"_n} );
set_code( "payloadless"_n, test_contracts::payloadless_wasm() );
set_abi( "payloadless"_n, test_contracts::payloadless_abi() );
chain.create_accounts( {"payloadless"_n} );
chain.set_code( "payloadless"_n, test_contracts::payloadless_wasm() );
chain.set_abi( "payloadless"_n, test_contracts::payloadless_abi() );

auto trace = push_action("payloadless"_n, "doit"_n, "payloadless"_n, mutable_variant_object());
auto trace = chain.push_action("payloadless"_n, "doit"_n, "payloadless"_n, mutable_variant_object());
auto msg = trace->action_traces.front().console;
BOOST_CHECK_EQUAL(msg == "Im a payloadless action", true);
}

// test GH#3916 - contract api action with no parameters fails when called from cleos
// abi_serializer was failing when action data was empty.
BOOST_FIXTURE_TEST_CASE( test_abi_serializer, payloadless_tester ) {
BOOST_AUTO_TEST_CASE_TEMPLATE( test_abi_serializer, T, payloadless_testers ) {
T chain;

create_accounts( {"payloadless"_n} );
set_code( "payloadless"_n, test_contracts::payloadless_wasm() );
set_abi( "payloadless"_n, test_contracts::payloadless_abi() );
chain.create_accounts( {"payloadless"_n} );
chain.set_code( "payloadless"_n, test_contracts::payloadless_wasm() );
chain.set_abi( "payloadless"_n, test_contracts::payloadless_abi() );

fc::variant pretty_trx = fc::mutable_variant_object()
("actions", fc::variants({
Expand All @@ -60,11 +66,11 @@ BOOST_FIXTURE_TEST_CASE( test_abi_serializer, payloadless_tester ) {

signed_transaction trx;
// from_variant is key to this test as abi_serializer was explicitly not allowing empty "data"
abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function( abi_serializer_max_time ));
set_transaction_headers(trx);
abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function( chain.abi_serializer_max_time ));
chain.set_transaction_headers(trx);

trx.sign( get_private_key( "payloadless"_n, "active" ), control->get_chain_id() );
auto trace = push_transaction( trx );
trx.sign( chain.get_private_key( "payloadless"_n, "active" ), chain.control->get_chain_id() );
auto trace = chain.push_transaction( trx );
auto msg = trace->action_traces.front().console;
BOOST_CHECK_EQUAL(msg == "Im a payloadless action", true);
}
Expand Down
6 changes: 3 additions & 3 deletions unittests/special_accounts_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

using namespace eosio;
using namespace chain;
using tester = eosio::testing::tester;
using namespace eosio::testing;

BOOST_AUTO_TEST_SUITE(special_account_tests)

//Check special accounts exits in genesis
BOOST_FIXTURE_TEST_CASE(accounts_exists, tester)
BOOST_AUTO_TEST_CASE_TEMPLATE( accounts_exists, T, testers )
{ try {

tester test;
T test;
chain::controller *control = test.control.get();
const chain::database& chain1_db = control->db();

Expand Down

0 comments on commit 317da53

Please sign in to comment.