Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
test_trx_full.cpp File Reference
Include dependency graph for test_trx_full.cpp:

Go to the source code of this file.

Classes

struct  sysio::test::detail::testit
 

Namespaces

namespace  sysio
 
namespace  sysio::test
 
namespace  sysio::test::detail
 

Macros

#define BOOST_TEST_MODULE   full_producer_trxs
 

Functions

 BOOST_AUTO_TEST_CASE (producer)
 

Macro Definition Documentation

◆ BOOST_TEST_MODULE

#define BOOST_TEST_MODULE   full_producer_trxs

Definition at line 1 of file test_trx_full.cpp.

Function Documentation

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( producer )

Definition at line 102 of file test_trx_full.cpp.

102 {
103 boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
104
105 try {
106 std::promise<std::tuple<producer_plugin*, chain_plugin*>> plugin_promise;
107 std::future<std::tuple<producer_plugin*, chain_plugin*>> plugin_fut = plugin_promise.get_future();
108 std::thread app_thread( [&]() {
110 std::vector<const char*> argv =
111 {"test", "--data-dir", temp.c_str(), "--config-dir", temp.c_str(),
112 "-p", "sysio", "-e", "--max-transaction-time", "475", "--disable-subjective-billing=true" };
113 appbase::app().initialize<chain_plugin, producer_plugin>( argv.size(), (char**) &argv[0] );
115 plugin_promise.set_value(
117 appbase::app().exec();
118 } );
119
120 auto[prod_plug, chain_plug] = plugin_fut.get();
121 auto chain_id = chain_plug->get_chain_id();
122
123 std::deque<block_state_ptr> all_blocks;
124 std::promise<void> empty_blocks_promise;
125 std::future<void> empty_blocks_fut = empty_blocks_promise.get_future();
126 auto ab = chain_plug->chain().accepted_block.connect( [&](const block_state_ptr& bsp) {
127 static int num_empty = std::numeric_limits<int>::max();
128 all_blocks.push_back( bsp );
129 if( bsp->block->transactions.empty() ) {
130 --num_empty;
131 if( num_empty == 0 ) empty_blocks_promise.set_value();
132 } else { // we want a few empty blocks after we have some non-empty blocks
133 num_empty = 10;
134 }
135 } );
136 auto bs = chain_plug->chain().block_start.connect( [&]( uint32_t bn ) {
137 } );
138
139 std::deque<packed_transaction_ptr> trxs;
140 std::atomic<size_t> next_calls = 0;
141 std::atomic<size_t> num_posts = 0;
142 std::atomic<size_t> trace_with_except = 0;
143 std::atomic<bool> trx_match = true;
144 const size_t num_pushes = 4242;
145 for( size_t i = 1; i <= num_pushes; ++i ) {
146 auto ptrx = make_unique_trx( chain_id );
147 dlog( "posting ${id}", ("id", ptrx->id()) );
148 app().post( priority::low, [ptrx, &next_calls, &num_posts, &trace_with_except, &trx_match, &trxs]() {
149 ++num_posts;
150 bool return_failure_traces = false; // 2.2.x+ = num_posts % 2 == 0;
152 false, // persist_until_expiried
153 false, // read_only
154 false, // return_failure_traces
155 [ptrx, &next_calls, &trace_with_except, &trx_match, &trxs, return_failure_traces]
156 (const std::variant<fc::exception_ptr, transaction_trace_ptr>& result) {
157 if( !std::holds_alternative<fc::exception_ptr>( result ) && !std::get<chain::transaction_trace_ptr>( result )->except ) {
158 if( std::get<chain::transaction_trace_ptr>( result )->id == ptrx->id() ) {
159 trxs.push_back( ptrx );
160 } else {
161 elog( "trace not for trx ${id}: ${t}",
162 ("id", ptrx->id())("t", fc::json::to_pretty_string(*std::get<chain::transaction_trace_ptr>(result))) );
163 trx_match = false;
164 }
165 } else if( !return_failure_traces && !std::holds_alternative<fc::exception_ptr>( result ) && std::get<chain::transaction_trace_ptr>( result )->except ) {
166 elog( "trace with except ${e}",
167 ("e", fc::json::to_pretty_string( *std::get<chain::transaction_trace_ptr>( result ) )) );
168 ++trace_with_except;
169 }
170 ++next_calls;
171 });
172 });
173 if( i % (num_pushes/3) == 0 ) {
174 // need to sleep or a fast machine might put all trxs in one block
175 usleep( config::block_interval_us / 2 );
176 }
177 if( i % 200 == 0 ) {
178 // get_integrity_hash aborts block and places aborted trxs into unapplied_transaction_queue
179 // verifying that aborting block does not lose transactions
180 app().post(priority::high, [](){
181 app().find_plugin<producer_plugin>()->get_integrity_hash();
182 });
183 }
184 }
185
186 empty_blocks_fut.wait_for(std::chrono::seconds(15));
187
188 BOOST_CHECK_EQUAL( trace_with_except, 0 ); // should not have any traces with except in it
189 BOOST_CHECK( all_blocks.size() > 3 ); // should have a few blocks otherwise test is running too fast
190 BOOST_CHECK_EQUAL( num_pushes, num_posts );
191 BOOST_CHECK_EQUAL( num_pushes, next_calls );
192 BOOST_CHECK( trx_match.load() );
193
194 appbase::app().quit();
195 app_thread.join();
196
197 BOOST_REQUIRE( verify_equal(trxs, all_blocks ) );
198
199 } catch ( ... ) {
200 bfs::remove_all( temp );
201 throw;
202 }
203 bfs::remove_all( temp );
204}
abstract_plugin * find_plugin(const string &name) const
bool initialize(int argc, char **argv)
Looks for the –plugin commandline / config option and calls initialize on those plugins.
auto post(int priority, Func &&func)
auto get_method() -> std::enable_if_t< is_method_decl< MethodDecl >::value, typename MethodDecl::method_type & >
static string to_pretty_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
Definition json.cpp:775
logger & set_log_level(log_level e)
Definition logger.cpp:100
static logger get(const fc::string &name=DEFAULT_LOGGER)
Definition logger.cpp:88
char ** argv
#define dlog(FORMAT,...)
Definition logger.hpp:101
#define DEFAULT_LOGGER
Definition logger.hpp:7
#define elog(FORMAT,...)
Definition logger.hpp:130
application & app()
Definition bn.h:56
std::shared_ptr< block_state > block_state_ptr
unsigned int uint32_t
Definition stdint.h:126
static constexpr int high
Here is the call graph for this function: