Skip to content

Commit

Permalink
Merge pull request #1442 from AntelopeIO/GH-1435-test
Browse files Browse the repository at this point in the history
Test Fix: Controller calls only valid when building a block
  • Loading branch information
heifner authored Jul 24, 2023
2 parents 99c6c21 + 632e728 commit c114ab1
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 164 deletions.
14 changes: 9 additions & 5 deletions plugins/chain_plugin/test/test_trx_retry_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,15 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
std::promise<chain_plugin*> plugin_promise;
std::future<chain_plugin*> plugin_fut = plugin_promise.get_future();
std::thread app_thread( [&]() {
std::vector<const char*> argv = {"test"};
app->initialize( argv.size(), (char**) &argv[0] );
app->startup();
plugin_promise.set_value(app->find_plugin<chain_plugin>());
app->exec();
try {
std::vector<const char*> argv = {"test"};
app->initialize(argv.size(), (char**)&argv[0]);
app->startup();
plugin_promise.set_value(app->find_plugin<chain_plugin>());
app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
} );
(void)plugin_fut.get(); // wait for app to be started

Expand Down
26 changes: 15 additions & 11 deletions plugins/producer_plugin/test/test_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,21 @@ BOOST_AUTO_TEST_CASE(state_dir) {
std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();
std::thread app_thread( [&]() {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test",
"--data-dir", temp_dir_str.c_str(),
"--state-dir", custom_state_dir_str.c_str(),
"--config-dir", temp_dir_str.c_str(),
"-p", "eosio", "-e" };
app->initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
app->startup();
plugin_promise.set_value( {app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()} );
app->exec();
try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test",
"--data-dir", temp_dir_str.c_str(),
"--state-dir", custom_state_dir_str.c_str(),
"--config-dir", temp_dir_str.c_str(),
"-p", "eosio", "-e" };
app->initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
app->startup();
plugin_promise.set_value( {app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()} );
app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
} );

auto[prod_plug, chain_plug] = plugin_fut.get();
Expand Down
22 changes: 13 additions & 9 deletions plugins/producer_plugin/test/test_trx_full.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,19 @@ BOOST_AUTO_TEST_CASE(producer) {
std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();
std::thread app_thread( [&]() {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test", "--data-dir", temp_dir_str.c_str(), "--config-dir", temp_dir_str.c_str(),
"-p", "eosio", "-e", "--disable-subjective-p2p-billing=true" };
app->initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
app->startup();
plugin_promise.set_value(
{app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()} );
app->exec();
try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test", "--data-dir", temp_dir_str.c_str(), "--config-dir", temp_dir_str.c_str(),
"-p", "eosio", "-e", "--disable-subjective-p2p-billing=true" };
app->initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
app->startup();
plugin_promise.set_value(
{app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()} );
app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
} );

auto[prod_plug, chain_plug] = plugin_fut.get();
Expand Down
179 changes: 95 additions & 84 deletions tests/test_read_only_trx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,90 +88,101 @@ BOOST_AUTO_TEST_CASE(not_check_configs_if_no_read_only_threads) {
}

void test_trxs_common(std::vector<const char*>& specific_args, bool test_disable_tierup = false) {
fc::scoped_exit<std::function<void()>> on_exit = []() {
chain::wasm_interface_collection::test_disable_tierup = false;
};
chain::wasm_interface_collection::test_disable_tierup = test_disable_tierup;

using namespace std::chrono_literals;
fc::temp_directory temp;
appbase::scoped_app app;
auto temp_dir_str = temp.path().string();
producer_plugin::set_test_mode(true);

std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();
std::thread app_thread( [&]() {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv = {"test", "--data-dir", temp_dir_str.c_str(), "--config-dir", temp_dir_str.c_str()};
argv.insert( argv.end(), specific_args.begin(), specific_args.end() );
app->initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
app->find_plugin<chain_plugin>()->chain();
app->startup();
plugin_promise.set_value( {app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()} );
app->exec();
} );

auto[prod_plug, chain_plug] = plugin_fut.get();

activate_protocol_features_set_bios_contract(app, chain_plug);

std::atomic<size_t> next_calls = 0;
std::atomic<size_t> num_get_account_calls = 0;
std::atomic<size_t> num_posts = 0;
std::atomic<size_t> trace_with_except = 0;
std::atomic<bool> trx_match = true;
const size_t num_pushes = 4242;

for( size_t i = 1; i <= num_pushes; ++i ) {
auto ptrx = i % 3 == 0 ? make_unique_trx() : make_bios_ro_trx(chain_plug->chain());
app->executor().post( priority::low, exec_queue::read_only, [&chain_plug=chain_plug, &num_get_account_calls]() {
chain_plug->get_read_only_api(fc::seconds(90)).get_account(chain_apis::read_only::get_account_params{.account_name=config::system_account_name}, fc::time_point::now()+fc::seconds(90));
++num_get_account_calls;
});
app->executor().post( priority::low, exec_queue::read_only, [ptrx, &next_calls, &num_posts, &trace_with_except, &trx_match, &app]() {
++num_posts;
bool return_failure_traces = true;
app->get_method<plugin_interface::incoming::methods::transaction_async>()(ptrx,
false, // api_trx
transaction_metadata::trx_type::read_only, // trx_type
return_failure_traces,
[ptrx, &next_calls, &trace_with_except, &trx_match, return_failure_traces]
(const next_function_variant<transaction_trace_ptr>& result) {
if( !std::holds_alternative<fc::exception_ptr>( result ) && !std::get<chain::transaction_trace_ptr>( result )->except ) {
if( std::get<chain::transaction_trace_ptr>( result )->id != ptrx->id() ) {
elog( "trace not for trx ${id}: ${t}",
("id", ptrx->id())("t", fc::json::to_pretty_string(*std::get<chain::transaction_trace_ptr>(result))) );
trx_match = false;
}
} else if( !return_failure_traces && !std::holds_alternative<fc::exception_ptr>( result ) && std::get<chain::transaction_trace_ptr>( result )->except ) {
elog( "trace with except ${e}",
("e", fc::json::to_pretty_string( *std::get<chain::transaction_trace_ptr>( result ) )) );
++trace_with_except;
}
++next_calls;
});
});
app->executor().post( priority::low, exec_queue::read_only, [&chain_plug=chain_plug]() {
chain_plug->get_read_only_api(fc::seconds(90)).get_consensus_parameters(chain_apis::read_only::get_consensus_parameters_params{}, fc::time_point::now()+fc::seconds(90));
});
}

// Wait long enough such that all transactions are executed
auto start = fc::time_point::now();
auto hard_deadline = start + fc::seconds(10); // To protect against waiting forever
while ( (next_calls < num_pushes || num_get_account_calls < num_pushes) && fc::time_point::now() < hard_deadline ){
std::this_thread::sleep_for( 100ms );;
}

app->quit();
app_thread.join();

BOOST_CHECK_EQUAL( trace_with_except, 0 ); // should not have any traces with except in it
BOOST_CHECK_EQUAL( num_pushes, num_posts );
BOOST_CHECK_EQUAL( num_pushes, next_calls.load() );
BOOST_CHECK_EQUAL( num_pushes, num_get_account_calls.load() );
BOOST_CHECK( trx_match.load() ); // trace should match the transaction
try {
fc::scoped_exit<std::function<void()>> on_exit = []() {
chain::wasm_interface_collection::test_disable_tierup = false;
};
chain::wasm_interface_collection::test_disable_tierup = test_disable_tierup;

using namespace std::chrono_literals;
fc::temp_directory temp;
appbase::scoped_app app;
auto temp_dir_str = temp.path().string();
producer_plugin::set_test_mode(true);

std::atomic<size_t> next_calls = 0;
std::atomic<size_t> num_get_account_calls = 0;
std::atomic<size_t> num_posts = 0;
std::atomic<size_t> trace_with_except = 0;
std::atomic<bool> trx_match = true;
const size_t num_pushes = 4242;

{
std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();
std::thread app_thread( [&]() {
try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv = {"test", "--data-dir", temp_dir_str.c_str(), "--config-dir", temp_dir_str.c_str()};
argv.insert(argv.end(), specific_args.begin(), specific_args.end());
app->initialize<chain_plugin, producer_plugin>(argv.size(), (char**)&argv[0]);
app->find_plugin<chain_plugin>()->chain();
app->startup();
plugin_promise.set_value({app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()});
app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
} );
fc::scoped_exit<std::function<void()>> on_except = [&](){
if (app_thread.joinable())
app_thread.join();
};

auto[prod_plug, chain_plug] = plugin_fut.get();

activate_protocol_features_set_bios_contract(app, chain_plug);

for( size_t i = 1; i <= num_pushes; ++i ) {
auto ptrx = i % 3 == 0 ? make_unique_trx() : make_bios_ro_trx(chain_plug->chain());
app->executor().post( priority::low, exec_queue::read_only, [&chain_plug=chain_plug, &num_get_account_calls]() {
chain_plug->get_read_only_api(fc::seconds(90)).get_account(chain_apis::read_only::get_account_params{.account_name=config::system_account_name}, fc::time_point::now()+fc::seconds(90));
++num_get_account_calls;
});
app->executor().post( priority::low, exec_queue::read_only, [ptrx, &next_calls, &num_posts, &trace_with_except, &trx_match, &app]() {
++num_posts;
bool return_failure_traces = true;
app->get_method<plugin_interface::incoming::methods::transaction_async>()(ptrx,
false, // api_trx
transaction_metadata::trx_type::read_only, // trx_type
return_failure_traces,
[ptrx, &next_calls, &trace_with_except, &trx_match, return_failure_traces]
(const next_function_variant<transaction_trace_ptr>& result) {
if( !std::holds_alternative<fc::exception_ptr>( result ) && !std::get<chain::transaction_trace_ptr>( result )->except ) {
if( std::get<chain::transaction_trace_ptr>( result )->id != ptrx->id() ) {
elog( "trace not for trx ${id}: ${t}",
("id", ptrx->id())("t", fc::json::to_pretty_string(*std::get<chain::transaction_trace_ptr>(result))) );
trx_match = false;
}
} else if( !return_failure_traces && !std::holds_alternative<fc::exception_ptr>( result ) && std::get<chain::transaction_trace_ptr>( result )->except ) {
elog( "trace with except ${e}",
("e", fc::json::to_pretty_string( *std::get<chain::transaction_trace_ptr>( result ) )) );
++trace_with_except;
}
++next_calls;
});
});
app->executor().post( priority::low, exec_queue::read_only, [&chain_plug=chain_plug]() {
chain_plug->get_read_only_api(fc::seconds(90)).get_consensus_parameters(chain_apis::read_only::get_consensus_parameters_params{}, fc::time_point::now()+fc::seconds(90));
});
}

// Wait long enough such that all transactions are executed
auto start = fc::time_point::now();
auto hard_deadline = start + fc::seconds(10); // To protect against waiting forever
while ( (next_calls < num_pushes || num_get_account_calls < num_pushes) && fc::time_point::now() < hard_deadline ){
std::this_thread::sleep_for( 100ms );
}

app->quit();
}

BOOST_CHECK_EQUAL( trace_with_except, 0 ); // should not have any traces with except in it
BOOST_CHECK_EQUAL( num_pushes, num_posts );
BOOST_CHECK_EQUAL( num_pushes, next_calls.load() );
BOOST_CHECK_EQUAL( num_pushes, num_get_account_calls.load() );
BOOST_CHECK( trx_match.load() ); // trace should match the transaction
} FC_LOG_AND_RETHROW()
}

// test read-only trxs on main thread (no --read-only-threads)
Expand Down
22 changes: 13 additions & 9 deletions tests/test_snapshot_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,19 @@ BOOST_AUTO_TEST_CASE(snapshot_scheduler_test) {
std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();

std::thread app_thread([&]() {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test", "--data-dir", temp.c_str(), "--config-dir", temp.c_str(),
"-p", "eosio", "-e"};
app->initialize<chain_plugin, producer_plugin>(argv.size(), (char**) &argv[0]);
app->startup();
plugin_promise.set_value(
{app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()});
app->exec();
try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
std::vector<const char*> argv =
{"test", "--data-dir", temp.c_str(), "--config-dir", temp.c_str(),
"-p", "eosio", "-e"};
app->initialize<chain_plugin, producer_plugin>(argv.size(), (char**) &argv[0]);
app->startup();
plugin_promise.set_value(
{app->find_plugin<producer_plugin>(), app->find_plugin<chain_plugin>()});
app->exec();
return;
} FC_LOG_AND_DROP()
BOOST_CHECK(!"app threw exception see logged error");
});

auto [prod_plug, chain_plug] = plugin_fut.get();
Expand Down
Loading

0 comments on commit c114ab1

Please sign in to comment.