From 5b3ee105e2ef04a09e827fb62bf38fefb7dbb5c6 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Wed, 14 Feb 2018 09:45:00 -0500 Subject: [PATCH 01/12] Beginnings of a test case --- tests/cli/main.cpp | 203 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 tests/cli/main.cpp diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp new file mode 100644 index 0000000000..32a6b35fba --- /dev/null +++ b/tests/cli/main.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define BOOST_TEST_MODULE Test Application +#include + +using namespace graphene; + +// hack: import create_example_genesis() even though it's a way, way +// specific internal detail +namespace graphene { namespace app { namespace detail { + graphene::chain::genesis_state_type create_example_genesis(); +} } } // graphene::app::detail + +boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { + boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; + fc::path genesis_out = genesis_path; + graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); + std::cerr << "Creating example genesis state in file " << genesis_out.generic_string() << "\n"; + fc::json::save_to_file(genesis_state, genesis_out); + return genesis_path; +} + +/** + * Start a server and connect using the same calls as the CLI + */ +BOOST_AUTO_TEST_CASE( cli_connect ) +{ + using namespace graphene::chain; + using namespace graphene::app; + graphene::app::application app1; + try { + BOOST_TEST_MESSAGE( "Creating temporary files" ); + + fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); + + BOOST_TEST_MESSAGE( "Creating and initializing app1" ); + + app1.register_plugin(); + app1.register_plugin< graphene::market_history::market_history_plugin >(); + app1.register_plugin< graphene::witness_plugin::witness_plugin >(); + app1.startup_plugins(); + boost::program_options::variables_map cfg; + cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + app1.initialize(app_dir.path(), cfg); + + BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); + app1.startup(); + fc::usleep(fc::milliseconds(500)); + + // connect to the server + graphene::wallet::wallet_data wdata; + wdata.chain_id = app1.chain_database()->get_chain_id(); + wdata.ws_server = "ws://127.0.0.1:8090"; + wdata.ws_user = ""; + wdata.ws_password = ""; + fc::http::websocket_client client; + auto con = client.connect( wdata.ws_server ); + + auto apic = std::make_shared(*con); + + auto remote_api = apic->get_remote_api< login_api >(1); + BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); + + fc::mutable_variant_object settings = remote_api->get_server_information(); + std::cout << "Server Version: " << settings["server_version"].as() << std::endl; + std::cout << "Server SHA Version: " << settings["server_sha_version"].as() << std::endl; + std::cout << "Server Version Timestamp: " << settings["server_version_timestamp"].as() << std::endl; + std::cout << "SSL Version: " << settings["ssl_version"].as() << std::endl; + std::cout << "Boost Version: " << settings["boost_version"].as() << std::endl; + std::cout << "Websocket++ Version: " << settings["websocket_version"].as() << std::endl; + BOOST_CHECK(settings["server_version"].as() != ""); + BOOST_CHECK(settings["server_sha_version"].as() != ""); + BOOST_CHECK(settings["server_version_timestamp"].as() != ""); + BOOST_CHECK(settings["ssl_version"].as() != ""); + BOOST_CHECK(settings["boost_version"].as() != ""); + BOOST_CHECK(settings["websocket_version"].as() != ""); + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } + app1.shutdown(); +} + +/** + * Start a server and connect using the same calls as the CLI + */ +BOOST_AUTO_TEST_CASE( cli_vote ) +{ + using namespace graphene::chain; + using namespace graphene::app; + graphene::app::application app1; + try { + BOOST_TEST_MESSAGE( "Creating temporary files" ); + + fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); + + BOOST_TEST_MESSAGE( "Creating and initializing app1" ); + + app1.register_plugin(); + app1.register_plugin< graphene::market_history::market_history_plugin >(); + app1.register_plugin< graphene::witness_plugin::witness_plugin >(); + app1.startup_plugins(); + boost::program_options::variables_map cfg; + cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + app1.initialize(app_dir.path(), cfg); + + BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); + app1.startup(); + fc::usleep(fc::milliseconds(500)); + + // connect to the server + graphene::wallet::wallet_data wdata; + wdata.chain_id = app1.chain_database()->get_chain_id(); + wdata.ws_server = "ws://127.0.0.1:8090"; + wdata.ws_user = ""; + wdata.ws_password = ""; + fc::http::websocket_client client; + auto con = client.connect( wdata.ws_server ); + + auto apic = std::make_shared(*con); + + auto remote_api = apic->get_remote_api< login_api >(1); + BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); + + auto wapiptr = std::make_shared(wdata, remote_api); + std::stringstream wallet_filename; + wallet_filename << app_dir.path().generic_string() << "/wallet.json"; + //wapiptr->set_wallet_filename(wallet_filename.str()); + wapiptr->load_wallet_file(wallet_filename.str()); + + fc::api wapi(wapiptr); + + auto wallet_cli = std::make_shared(); + for( auto& name_formatter : wapiptr->get_result_formatters() ) + wallet_cli->format_result( name_formatter.first, name_formatter.second ); + + boost::signals2::scoped_connection closed_connection(con->closed.connect([=]{ + cerr << "Server has disconnected us.\n"; + wallet_cli->stop(); + })); + (void)(closed_connection); + + BOOST_CHECK_EQUAL("nathan", wapiptr->get_account("nathan").name); + + fc::api ah = wallet_cli->get_remote_api(api_id); + + /* + graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); + BOOST_CHECK(!bki.brain_priv_key.empty()); + + wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + */ + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } + app1.shutdown(); +} From 8f2d468b1b8516696f2d23851874de14b697af0e Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Thu, 15 Feb 2018 16:33:16 -0500 Subject: [PATCH 02/12] Modified test case to replicate the problem --- tests/cli/main.cpp | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 32a6b35fba..206210ef6e 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -105,6 +105,7 @@ BOOST_AUTO_TEST_CASE( cli_connect ) auto remote_api = apic->get_remote_api< login_api >(1); BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); + /* fc::mutable_variant_object settings = remote_api->get_server_information(); std::cout << "Server Version: " << settings["server_version"].as() << std::endl; std::cout << "Server SHA Version: " << settings["server_sha_version"].as() << std::endl; @@ -118,6 +119,7 @@ BOOST_AUTO_TEST_CASE( cli_connect ) BOOST_CHECK(settings["ssl_version"].as() != ""); BOOST_CHECK(settings["boost_version"].as() != ""); BOOST_CHECK(settings["websocket_version"].as() != ""); + */ } catch( fc::exception& e ) { edump((e.to_detail_string())); throw; @@ -128,7 +130,7 @@ BOOST_AUTO_TEST_CASE( cli_connect ) /** * Start a server and connect using the same calls as the CLI */ -BOOST_AUTO_TEST_CASE( cli_vote ) +BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) { using namespace graphene::chain; using namespace graphene::app; @@ -147,6 +149,7 @@ BOOST_AUTO_TEST_CASE( cli_vote ) boost::program_options::variables_map cfg; cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + //cfg.emplace("genesis-json", boost::program_options::variable_value(boost::filesystem::path{"/Users/JohnJones/Development2/cpp/bitshares-core/genesis.json"}, false)); app1.initialize(app_dir.path(), cfg); BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); @@ -170,8 +173,8 @@ BOOST_AUTO_TEST_CASE( cli_vote ) auto wapiptr = std::make_shared(wdata, remote_api); std::stringstream wallet_filename; wallet_filename << app_dir.path().generic_string() << "/wallet.json"; - //wapiptr->set_wallet_filename(wallet_filename.str()); - wapiptr->load_wallet_file(wallet_filename.str()); + wapiptr->set_wallet_filename(wallet_filename.str()); + //wapiptr->load_wallet_file(wallet_filename.str()); fc::api wapi(wapiptr); @@ -185,16 +188,41 @@ BOOST_AUTO_TEST_CASE( cli_vote ) })); (void)(closed_connection); - BOOST_CHECK_EQUAL("nathan", wapiptr->get_account("nathan").name); + BOOST_TEST_MESSAGE("Setting wallet password"); + wapiptr->set_password("supersecret"); + wapiptr->unlock("supersecret"); - fc::api ah = wallet_cli->get_remote_api(api_id); + BOOST_TEST_MESSAGE("Importing nathan key"); + // import Nathan account + std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; + BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); + BOOST_CHECK(wapiptr->import_key("nathan", nathan_keys[0])); - /* + BOOST_TEST_MESSAGE("Importing nathan's balance"); + std::vector import_txs = wapiptr->import_balance("nathan", nathan_keys, true); + + account_object nathan_acct_before_upgrade = wapiptr->get_account("nathan"); + + // upgrade nathan + signed_transaction upgrade_tx = wapiptr->upgrade_account("nathan", true); + + account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); + + BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); + + // create a new account graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); BOOST_CHECK(!bki.brain_priv_key.empty()); + signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + + // attempt to give jmjatlanta some bitsahres + signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); + + BOOST_TEST_MESSAGE("About to set voting proxy."); + // set the voting proxy to nathan + signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); - wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); - */ + fc::usleep(fc::milliseconds(1000)); } catch( fc::exception& e ) { edump((e.to_detail_string())); throw; From bc6c4708ed996171fdc42f1bd743f7f4e329058a Mon Sep 17 00:00:00 2001 From: John Jones Date: Sun, 18 Feb 2018 19:11:40 -0500 Subject: [PATCH 03/12] Modified tests to send votes --- tests/CMakeLists.txt | 4 ++++ tests/cli/main.cpp | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7edc54bd41..4065455eca 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,6 +25,10 @@ file(GLOB APP_SOURCES "app/*.cpp") add_executable( app_test ${APP_SOURCES} ) target_link_libraries( app_test graphene_app graphene_account_history graphene_net graphene_chain graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +file(GLOB CLI_SOURCES "cli/*.cpp") +add_executable( cli_test ${CLI_SOURCES} ) +target_link_libraries( cli_test graphene_app graphene_wallet graphene_witness graphene_account_history graphene_net graphene_chain graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) + file(GLOB INTENSE_SOURCES "intense/*.cpp") add_executable( intense_test ${INTENSE_SOURCES} ${COMMON_SOURCES} ) target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 206210ef6e..704fced9b1 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE( cli_connect ) /** * Start a server and connect using the same calls as the CLI */ -BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) +BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) { using namespace graphene::chain; using namespace graphene::app; @@ -149,7 +149,6 @@ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) boost::program_options::variables_map cfg; cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); - //cfg.emplace("genesis-json", boost::program_options::variable_value(boost::filesystem::path{"/Users/JohnJones/Development2/cpp/bitshares-core/genesis.json"}, false)); app1.initialize(app_dir.path(), cfg); BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); @@ -174,7 +173,6 @@ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) std::stringstream wallet_filename; wallet_filename << app_dir.path().generic_string() << "/wallet.json"; wapiptr->set_wallet_filename(wallet_filename.str()); - //wapiptr->load_wallet_file(wallet_filename.str()); fc::api wapi(wapiptr); @@ -209,17 +207,45 @@ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); + BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); // create a new account graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); BOOST_CHECK(!bki.brain_priv_key.empty()); signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + // save the private key for this new account in the wallet file + BOOST_CHECK(wapiptr->import_key("jmjatlanta", bki.wif_priv_key)); + wapiptr->save_wallet_file(wallet_filename.str()); + // attempt to give jmjatlanta some bitsahres signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); - BOOST_TEST_MESSAGE("About to set voting proxy."); + // get the details for init1 + witness_object init1_obj = wapiptr->get_witness("init1"); + int init1_start_votes = init1_obj.total_votes; + // Vote for a witness + signed_transaction vote_witness1_tx = wapiptr->vote_for_witness("jmjatlanta", "init1", true, true); + // wait for a maintenance interval + fc::usleep(fc::minutes(3)); + // Verify that the vote is there + init1_obj = wapiptr->get_witness("init1"); + int init1_middle_votes = init1_obj.total_votes; + BOOST_CHECK(init1_middle_votes > init1_start_votes); + // Vote for a 2nd witness + witness_object init2_obj = wapiptr->get_witness("init2"); + int init2_start_votes = init2_obj.total_votes; + signed_transaction vote_witness2_tx = wapiptr->vote_for_witness("jmjatlanta", "init2", true, true); + fc::usleep(fc::minutes(3)); + // Verify that both the first vote and the 2nd are there + init2_obj = wapiptr->get_witness("init2"); + init1_obj = wapiptr->get_witness("init1"); + int init2_middle_votes = init2_obj.total_votes; + BOOST_CHECK(init2_middle_votes > init2_start_votes); + int init1_last_votes = init1_obj.total_votes; + BOOST_CHECK(init1_middle_votes == init1_last_votes); // set the voting proxy to nathan + BOOST_TEST_MESSAGE("About to set voting proxy."); signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); fc::usleep(fc::milliseconds(1000)); From c544f5aa185071dbd106f44b36d04975567e7baf Mon Sep 17 00:00:00 2001 From: John Jones Date: Sun, 18 Feb 2018 21:41:53 -0500 Subject: [PATCH 04/12] testing and displaying results for debugging --- tests/cli/main.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 704fced9b1..061c095c8c 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -226,20 +226,49 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) int init1_start_votes = init1_obj.total_votes; // Vote for a witness signed_transaction vote_witness1_tx = wapiptr->vote_for_witness("jmjatlanta", "init1", true, true); + std::cout << "Displaying transaction for initial vote: " << std::endl; + //display_account_update_tx(vote_witness1_tx, wapiptr->get_result_formatters()); + std::cout << fc::json::to_pretty_string( vote_witness1_tx ) << std::endl; // wait for a maintenance interval - fc::usleep(fc::minutes(3)); + fc::usleep(fc::seconds(20)); + // send a block to trigger maintenance interval + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + auto db = app1.chain_database(); + auto block_1 = db->generate_block( + db->get_slot_time(1), + db->get_scheduled_witness(1), + committee_key, + database::skip_nothing); + // Verify that the vote is there init1_obj = wapiptr->get_witness("init1"); + witness_object init2_obj = wapiptr->get_witness("init2"); + std::cout << "After first maintenance, here is the init1 witness: " << std::endl; + std::cout << fc::json::to_pretty_string( init1_obj) << std::endl; + std::cout << "After first maintenance, here is the init2 witness: " << std::endl; + std::cout << fc::json::to_pretty_string( init2_obj) << std::endl; int init1_middle_votes = init1_obj.total_votes; BOOST_CHECK(init1_middle_votes > init1_start_votes); // Vote for a 2nd witness - witness_object init2_obj = wapiptr->get_witness("init2"); int init2_start_votes = init2_obj.total_votes; signed_transaction vote_witness2_tx = wapiptr->vote_for_witness("jmjatlanta", "init2", true, true); - fc::usleep(fc::minutes(3)); + std::cout << "Displaying transaction for init2 vote: " << std::endl; + //display_account_update_tx(vote_witness2_tx, wapiptr->get_result_formatters()); + std::cout << fc::json::to_pretty_string( vote_witness2_tx ) << std::endl; + fc::usleep(fc::seconds(20)); + // send anoter block to trigger maintenance interval + block_1 = db->generate_block( + db->get_slot_time(1), + db->get_scheduled_witness(1), + committee_key, + database::skip_nothing); // Verify that both the first vote and the 2nd are there init2_obj = wapiptr->get_witness("init2"); init1_obj = wapiptr->get_witness("init1"); + std::cout << "After second maintenance, here is the init1 witness: " << std::endl; + std::cout << fc::json::to_pretty_string( init1_obj) << std::endl; + std::cout << "After second maintenance, here is the init2 witness: " << std::endl; + std::cout << fc::json::to_pretty_string( init2_obj) << std::endl; int init2_middle_votes = init2_obj.total_votes; BOOST_CHECK(init2_middle_votes > init2_start_votes); int init1_last_votes = init1_obj.total_votes; From 4f6b0f843f748af619cff2aeb53e7619ae121896 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 19 Feb 2018 07:21:07 -0500 Subject: [PATCH 05/12] test code cleanup --- tests/cli/main.cpp | 168 ++++++++++++++++++++------------------------- 1 file changed, 76 insertions(+), 92 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 061c095c8c..3b4e981edd 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -24,9 +24,6 @@ #include #include -#include -#include - #include #include @@ -46,7 +43,9 @@ #define BOOST_TEST_MODULE Test Application #include -using namespace graphene; +/********************* + * Helper Methods + *********************/ // hack: import create_example_genesis() even though it's a way, way // specific internal detail @@ -63,6 +62,52 @@ boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { return genesis_path; } +/*** + * @brief Start the application, listening on port 8090 + * @param app_dir the temporary directory to use + * @returns the application object + */ +std::shared_ptr start_application(fc::temp_directory& app_dir) { + std::shared_ptr app1(new graphene::app::application{}); + + app1->register_plugin(); + app1->register_plugin< graphene::market_history::market_history_plugin >(); + app1->register_plugin< graphene::witness_plugin::witness_plugin >(); + app1->startup_plugins(); + boost::program_options::variables_map cfg; + cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + app1->initialize(app_dir.path(), cfg); + + app1->startup(); + fc::usleep(fc::milliseconds(500)); + return app1; +} + +/**** + * Send a block to the db + * @param app the application + * @returns true on success + */ +bool generate_block(graphene::app::application& app) { + try { + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + auto db = app.chain_database(); + auto block_1 = db->generate_block( + db->get_slot_time(1), + db->get_scheduled_witness(1), + committee_key, + database::skip_nothing); + return true; + } catch (exception &e) { + return false; + } +} + +/**************************** + * Tests + ****************************/ + /** * Start a server and connect using the same calls as the CLI */ @@ -70,61 +115,30 @@ BOOST_AUTO_TEST_CASE( cli_connect ) { using namespace graphene::chain; using namespace graphene::app; - graphene::app::application app1; + std::shared_ptr app1; try { - BOOST_TEST_MESSAGE( "Creating temporary files" ); - - fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); - - BOOST_TEST_MESSAGE( "Creating and initializing app1" ); + fc::temp_directory app_dir ( graphene::utilities::temp_directory_path() ); - app1.register_plugin(); - app1.register_plugin< graphene::market_history::market_history_plugin >(); - app1.register_plugin< graphene::witness_plugin::witness_plugin >(); - app1.startup_plugins(); - boost::program_options::variables_map cfg; - cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); - cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); - app1.initialize(app_dir.path(), cfg); - - BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); - app1.startup(); - fc::usleep(fc::milliseconds(500)); + app1 = start_application(app_dir); // connect to the server graphene::wallet::wallet_data wdata; - wdata.chain_id = app1.chain_database()->get_chain_id(); + wdata.chain_id = app1->chain_database()->get_chain_id(); wdata.ws_server = "ws://127.0.0.1:8090"; wdata.ws_user = ""; wdata.ws_password = ""; fc::http::websocket_client client; - auto con = client.connect( wdata.ws_server ); - auto apic = std::make_shared(*con); + auto apic = std::make_shared(*(client.connect(wdata.ws_server))); auto remote_api = apic->get_remote_api< login_api >(1); BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); - /* - fc::mutable_variant_object settings = remote_api->get_server_information(); - std::cout << "Server Version: " << settings["server_version"].as() << std::endl; - std::cout << "Server SHA Version: " << settings["server_sha_version"].as() << std::endl; - std::cout << "Server Version Timestamp: " << settings["server_version_timestamp"].as() << std::endl; - std::cout << "SSL Version: " << settings["ssl_version"].as() << std::endl; - std::cout << "Boost Version: " << settings["boost_version"].as() << std::endl; - std::cout << "Websocket++ Version: " << settings["websocket_version"].as() << std::endl; - BOOST_CHECK(settings["server_version"].as() != ""); - BOOST_CHECK(settings["server_sha_version"].as() != ""); - BOOST_CHECK(settings["server_version_timestamp"].as() != ""); - BOOST_CHECK(settings["ssl_version"].as() != ""); - BOOST_CHECK(settings["boost_version"].as() != ""); - BOOST_CHECK(settings["websocket_version"].as() != ""); - */ } catch( fc::exception& e ) { edump((e.to_detail_string())); throw; } - app1.shutdown(); + app1->shutdown(); } /** @@ -134,30 +148,16 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) { using namespace graphene::chain; using namespace graphene::app; - graphene::app::application app1; + std::shared_ptr app1; try { - BOOST_TEST_MESSAGE( "Creating temporary files" ); fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); - BOOST_TEST_MESSAGE( "Creating and initializing app1" ); - - app1.register_plugin(); - app1.register_plugin< graphene::market_history::market_history_plugin >(); - app1.register_plugin< graphene::witness_plugin::witness_plugin >(); - app1.startup_plugins(); - boost::program_options::variables_map cfg; - cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); - cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); - app1.initialize(app_dir.path(), cfg); - - BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); - app1.startup(); - fc::usleep(fc::milliseconds(500)); + app1 = start_application(app_dir); // connect to the server graphene::wallet::wallet_data wdata; - wdata.chain_id = app1.chain_database()->get_chain_id(); + wdata.chain_id = app1->chain_database()->get_chain_id(); wdata.ws_server = "ws://127.0.0.1:8090"; wdata.ws_user = ""; wdata.ws_password = ""; @@ -190,22 +190,22 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) wapiptr->set_password("supersecret"); wapiptr->unlock("supersecret"); - BOOST_TEST_MESSAGE("Importing nathan key"); // import Nathan account + BOOST_TEST_MESSAGE("Importing nathan key"); std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); BOOST_CHECK(wapiptr->import_key("nathan", nathan_keys[0])); BOOST_TEST_MESSAGE("Importing nathan's balance"); std::vector import_txs = wapiptr->import_balance("nathan", nathan_keys, true); - account_object nathan_acct_before_upgrade = wapiptr->get_account("nathan"); // upgrade nathan + BOOST_TEST_MESSAGE("Upgrading Nathan to LTM"); signed_transaction upgrade_tx = wapiptr->upgrade_account("nathan", true); - account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); + // verify that the upgrade was successful BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); @@ -213,12 +213,12 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); BOOST_CHECK(!bki.brain_priv_key.empty()); signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); - // save the private key for this new account in the wallet file BOOST_CHECK(wapiptr->import_key("jmjatlanta", bki.wif_priv_key)); wapiptr->save_wallet_file(wallet_filename.str()); // attempt to give jmjatlanta some bitsahres + BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta"); signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); // get the details for init1 @@ -226,61 +226,45 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) int init1_start_votes = init1_obj.total_votes; // Vote for a witness signed_transaction vote_witness1_tx = wapiptr->vote_for_witness("jmjatlanta", "init1", true, true); - std::cout << "Displaying transaction for initial vote: " << std::endl; - //display_account_update_tx(vote_witness1_tx, wapiptr->get_result_formatters()); - std::cout << fc::json::to_pretty_string( vote_witness1_tx ) << std::endl; + // wait for a maintenance interval + // NOTE: For this to work consistently, your maintenance interval must be less than 20 seconds fc::usleep(fc::seconds(20)); // send a block to trigger maintenance interval - fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - auto db = app1.chain_database(); - auto block_1 = db->generate_block( - db->get_slot_time(1), - db->get_scheduled_witness(1), - committee_key, - database::skip_nothing); + BOOST_CHECK(generate_block(*app1.get())); // Verify that the vote is there init1_obj = wapiptr->get_witness("init1"); witness_object init2_obj = wapiptr->get_witness("init2"); - std::cout << "After first maintenance, here is the init1 witness: " << std::endl; - std::cout << fc::json::to_pretty_string( init1_obj) << std::endl; - std::cout << "After first maintenance, here is the init2 witness: " << std::endl; - std::cout << fc::json::to_pretty_string( init2_obj) << std::endl; int init1_middle_votes = init1_obj.total_votes; BOOST_CHECK(init1_middle_votes > init1_start_votes); + // Vote for a 2nd witness int init2_start_votes = init2_obj.total_votes; signed_transaction vote_witness2_tx = wapiptr->vote_for_witness("jmjatlanta", "init2", true, true); - std::cout << "Displaying transaction for init2 vote: " << std::endl; - //display_account_update_tx(vote_witness2_tx, wapiptr->get_result_formatters()); - std::cout << fc::json::to_pretty_string( vote_witness2_tx ) << std::endl; + + // send another block to trigger maintenance interval fc::usleep(fc::seconds(20)); - // send anoter block to trigger maintenance interval - block_1 = db->generate_block( - db->get_slot_time(1), - db->get_scheduled_witness(1), - committee_key, - database::skip_nothing); + BOOST_CHECK(generate_block(*app1.get())); + // Verify that both the first vote and the 2nd are there init2_obj = wapiptr->get_witness("init2"); init1_obj = wapiptr->get_witness("init1"); - std::cout << "After second maintenance, here is the init1 witness: " << std::endl; - std::cout << fc::json::to_pretty_string( init1_obj) << std::endl; - std::cout << "After second maintenance, here is the init2 witness: " << std::endl; - std::cout << fc::json::to_pretty_string( init2_obj) << std::endl; + int init2_middle_votes = init2_obj.total_votes; BOOST_CHECK(init2_middle_votes > init2_start_votes); int init1_last_votes = init1_obj.total_votes; - BOOST_CHECK(init1_middle_votes == init1_last_votes); + BOOST_CHECK(init1_last_votes > init1_start_votes); + // set the voting proxy to nathan BOOST_TEST_MESSAGE("About to set voting proxy."); signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); - fc::usleep(fc::milliseconds(1000)); + // wait for everything to finish up + fc::usleep(fc::seconds(1)); } catch( fc::exception& e ) { edump((e.to_detail_string())); throw; } - app1.shutdown(); + app1->shutdown(); } From f5459413e953d038e84953356a5a9b86f5381a8c Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 22 Feb 2018 07:12:05 -0500 Subject: [PATCH 06/12] separate test for proxy voting --- tests/cli/main.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 3b4e981edd..a5cd3eea32 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -77,6 +77,7 @@ std::shared_ptr start_application(fc::temp_directory boost::program_options::variables_map cfg; cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); app1->initialize(app_dir.path(), cfg); app1->startup(); @@ -229,6 +230,7 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) // wait for a maintenance interval // NOTE: For this to work consistently, your maintenance interval must be less than 20 seconds + // see libraries/chain/include/graphene/chain/config.hpp:L50 GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (seconds) fc::usleep(fc::seconds(20)); // send a block to trigger maintenance interval BOOST_CHECK(generate_block(*app1.get())); @@ -268,3 +270,96 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) } app1->shutdown(); } + +/** + * Start a server and connect using the same calls as the CLI + */ +BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) +{ + using namespace graphene::chain; + using namespace graphene::app; + std::shared_ptr app1; + try { + + fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); + + app1 = start_application(app_dir); + + // connect to the server + graphene::wallet::wallet_data wdata; + wdata.chain_id = app1->chain_database()->get_chain_id(); + wdata.ws_server = "ws://127.0.0.1:8090"; + wdata.ws_user = ""; + wdata.ws_password = ""; + fc::http::websocket_client client; + auto con = client.connect( wdata.ws_server ); + + auto apic = std::make_shared(*con); + + auto remote_api = apic->get_remote_api< login_api >(1); + BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); + + auto wapiptr = std::make_shared(wdata, remote_api); + std::stringstream wallet_filename; + wallet_filename << app_dir.path().generic_string() << "/wallet.json"; + wapiptr->set_wallet_filename(wallet_filename.str()); + + fc::api wapi(wapiptr); + + auto wallet_cli = std::make_shared(); + for( auto& name_formatter : wapiptr->get_result_formatters() ) + wallet_cli->format_result( name_formatter.first, name_formatter.second ); + + boost::signals2::scoped_connection closed_connection(con->closed.connect([=]{ + cerr << "Server has disconnected us.\n"; + wallet_cli->stop(); + })); + (void)(closed_connection); + + BOOST_TEST_MESSAGE("Setting wallet password"); + wapiptr->set_password("supersecret"); + wapiptr->unlock("supersecret"); + + // import Nathan account + BOOST_TEST_MESSAGE("Importing nathan key"); + std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; + BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); + BOOST_CHECK(wapiptr->import_key("nathan", nathan_keys[0])); + + BOOST_TEST_MESSAGE("Importing nathan's balance"); + std::vector import_txs = wapiptr->import_balance("nathan", nathan_keys, true); + account_object nathan_acct_before_upgrade = wapiptr->get_account("nathan"); + + // upgrade nathan + BOOST_TEST_MESSAGE("Upgrading Nathan to LTM"); + signed_transaction upgrade_tx = wapiptr->upgrade_account("nathan", true); + account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); + + // verify that the upgrade was successful + BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); + BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); + + // create a new account + graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); + BOOST_CHECK(!bki.brain_priv_key.empty()); + signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + // save the private key for this new account in the wallet file + BOOST_CHECK(wapiptr->import_key("jmjatlanta", bki.wif_priv_key)); + wapiptr->save_wallet_file(wallet_filename.str()); + + // attempt to give jmjatlanta some bitsahres + BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta"); + signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); + + // set the voting proxy to nathan + BOOST_TEST_MESSAGE("About to set voting proxy."); + signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); + + // wait for everything to finish up + fc::usleep(fc::seconds(1)); + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } + app1->shutdown(); +} From 218a073e15d20ded809333a8b8863e65bda711e8 Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 22 Feb 2018 09:10:34 -0500 Subject: [PATCH 07/12] Added check for maintenance interval --- tests/cli/main.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index a5cd3eea32..d12b763f8d 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -231,6 +231,7 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) // wait for a maintenance interval // NOTE: For this to work consistently, your maintenance interval must be less than 20 seconds // see libraries/chain/include/graphene/chain/config.hpp:L50 GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (seconds) + BOOST_CHECK(GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL <= 20); fc::usleep(fc::seconds(20)); // send a block to trigger maintenance interval BOOST_CHECK(generate_block(*app1.get())); @@ -258,10 +259,6 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) int init1_last_votes = init1_obj.total_votes; BOOST_CHECK(init1_last_votes > init1_start_votes); - // set the voting proxy to nathan - BOOST_TEST_MESSAGE("About to set voting proxy."); - signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); - // wait for everything to finish up fc::usleep(fc::seconds(1)); } catch( fc::exception& e ) { From b6a6dc3a1f3b3af1f8b3e65f2392863fb306670c Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 26 Feb 2018 06:32:54 -0500 Subject: [PATCH 08/12] Generating maint. blocks without modifying default maintenance interval --- tests/cli/main.cpp | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index d12b763f8d..820e919a56 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -90,10 +90,10 @@ std::shared_ptr start_application(fc::temp_directory * @param app the application * @returns true on success */ -bool generate_block(graphene::app::application& app) { +bool generate_block(std::shared_ptr app) { try { fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - auto db = app.chain_database(); + auto db = app->chain_database(); auto block_1 = db->generate_block( db->get_slot_time(1), db->get_scheduled_witness(1), @@ -105,6 +105,28 @@ bool generate_block(graphene::app::application& app) { } } +/**** + * @brief Skip intermediate blocks, and generate a maintenance block + * @param app the application + * @returns true on success + */ +bool generate_maintenance_block(std::shared_ptr app) { + try { + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + uint32_t skip = ~0; + auto db = app->chain_database(); + auto maint_time = db->get_dynamic_global_properties().next_maintenance_time; + auto slots_to_miss = db->get_slot_at_time(maint_time); + db->generate_block(db->get_slot_time(slots_to_miss), + db->get_scheduled_witness(slots_to_miss), + committee_key, + skip); + return true; + } catch (exception& e) { + return false; + } +} + /**************************** * Tests ****************************/ @@ -228,13 +250,10 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) // Vote for a witness signed_transaction vote_witness1_tx = wapiptr->vote_for_witness("jmjatlanta", "init1", true, true); + // generate a block to get things started + BOOST_CHECK(generate_block(app1)); // wait for a maintenance interval - // NOTE: For this to work consistently, your maintenance interval must be less than 20 seconds - // see libraries/chain/include/graphene/chain/config.hpp:L50 GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (seconds) - BOOST_CHECK(GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL <= 20); - fc::usleep(fc::seconds(20)); - // send a block to trigger maintenance interval - BOOST_CHECK(generate_block(*app1.get())); + BOOST_CHECK(generate_maintenance_block(app1)); // Verify that the vote is there init1_obj = wapiptr->get_witness("init1"); @@ -247,8 +266,7 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) signed_transaction vote_witness2_tx = wapiptr->vote_for_witness("jmjatlanta", "init2", true, true); // send another block to trigger maintenance interval - fc::usleep(fc::seconds(20)); - BOOST_CHECK(generate_block(*app1.get())); + BOOST_CHECK(generate_maintenance_block(app1)); // Verify that both the first vote and the 2nd are there init2_obj = wapiptr->get_witness("init2"); From 11fae0a509ccafed34ff2b35ca066e7ec5ab3019 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 26 Feb 2018 10:58:33 -0500 Subject: [PATCH 09/12] checking to be sure set_voting_proxy changed something --- tests/cli/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 820e919a56..8a1013d08b 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -166,6 +166,8 @@ BOOST_AUTO_TEST_CASE( cli_connect ) /** * Start a server and connect using the same calls as the CLI + * Vote for two witnesses, and make sure they both stay there + * after a maintenance block */ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) { @@ -288,6 +290,7 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) /** * Start a server and connect using the same calls as the CLI + * Set a voting proxy and be assured that it sticks */ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) { @@ -366,9 +369,14 @@ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta"); signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); + // grab account for comparison + account_object prior_voting_account = wapiptr->get_account("jmjatlanta"); // set the voting proxy to nathan BOOST_TEST_MESSAGE("About to set voting proxy."); signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); + account_object after_voting_account = wapiptr->get_account("jmjatlanta"); + // see if it changed + BOOST_CHECK(prior_voting_account.options.voting_account != after_voting_account.options.voting_account); // wait for everything to finish up fc::usleep(fc::seconds(1)); From 9bd3e5b6702da7c644474b6b070ff90697c48e69 Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 15 Mar 2018 10:01:45 -0500 Subject: [PATCH 10/12] tests use random rpc port, wrapped client connect code in class --- tests/cli/main.cpp | 228 +++++++++++++++++++++++---------------------- 1 file changed, 118 insertions(+), 110 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 8a1013d08b..e14eac6988 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * Copyright (c) 2018 John Jones, and contributors. * * The MIT License * @@ -38,6 +38,10 @@ #include #include +#include +#include +#include + #include #define BOOST_TEST_MODULE Test Application @@ -57,17 +61,38 @@ boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; fc::path genesis_out = genesis_path; graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); - std::cerr << "Creating example genesis state in file " << genesis_out.generic_string() << "\n"; fc::json::save_to_file(genesis_state, genesis_out); return genesis_path; } +////// +// @brief attempt to find an available port on localhost +// @returns an available port number, or -1 on error +///// +int get_available_port() +{ + struct sockaddr_in sin; + int socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (socket_fd == -1) + return -1; + sin.sin_family = AF_INET; + sin.sin_port = 0; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1) + return -1; + socklen_t len = sizeof(sin); + if (getsockname(socket_fd, (struct sockaddr *)&sin, &len) == -1) + return -1; + //return ntohs(sin.sin_port); + return sin.sin_port; +} + /*** * @brief Start the application, listening on port 8090 * @param app_dir the temporary directory to use * @returns the application object */ -std::shared_ptr start_application(fc::temp_directory& app_dir) { +std::shared_ptr start_application(fc::temp_directory& app_dir, int& server_port_number) { std::shared_ptr app1(new graphene::app::application{}); app1->register_plugin(); @@ -75,7 +100,9 @@ std::shared_ptr start_application(fc::temp_directory app1->register_plugin< graphene::witness_plugin::witness_plugin >(); app1->startup_plugins(); boost::program_options::variables_map cfg; - cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:8090"), false)); + server_port_number = get_available_port(); + //server_port_number = 8090; + cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:" + std::to_string(server_port_number)), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); app1->initialize(app_dir.path(), cfg); @@ -127,6 +154,50 @@ bool generate_maintenance_block(std::shared_ptr app) } } +class client_connection +{ +public: + client_connection(std::shared_ptr app, const fc::temp_directory& data_dir, const int server_port_number) + { + wallet_data.chain_id = app->chain_database()->get_chain_id(); + wallet_data.ws_server = "ws://127.0.0.1:" + std::to_string(server_port_number); + wallet_data.ws_user = ""; + wallet_data.ws_password = ""; + websocket_connection = websocket_client.connect( wallet_data.ws_server ); + + api_connection = std::make_shared(*websocket_connection); + + remote_login_api = api_connection->get_remote_api< graphene::app::login_api >(1); + BOOST_CHECK(remote_login_api->login( wallet_data.ws_user, wallet_data.ws_password ) ); + + wallet_api_ptr = std::make_shared(wallet_data, remote_login_api); + wallet_filename = data_dir.path().generic_string() + "/wallet.json"; + wallet_api_ptr->set_wallet_filename(wallet_filename); + + wallet_api = fc::api(wallet_api_ptr); + + wallet_cli = std::make_shared(); + for( auto& name_formatter : wallet_api_ptr->get_result_formatters() ) + wallet_cli->format_result( name_formatter.first, name_formatter.second ); + + boost::signals2::scoped_connection closed_connection(websocket_connection->closed.connect([=]{ + cerr << "Server has disconnected us.\n"; + wallet_cli->stop(); + })); + (void)(closed_connection); + } +public: + fc::http::websocket_client websocket_client; + graphene::wallet::wallet_data wallet_data; + fc::http::websocket_connection_ptr websocket_connection; + std::shared_ptr api_connection; + fc::api remote_login_api; + std::shared_ptr wallet_api_ptr; + fc::api wallet_api; + std::shared_ptr wallet_cli; + std::string wallet_filename; +}; + /**************************** * Tests ****************************/ @@ -142,20 +213,11 @@ BOOST_AUTO_TEST_CASE( cli_connect ) try { fc::temp_directory app_dir ( graphene::utilities::temp_directory_path() ); - app1 = start_application(app_dir); + int server_port_number = 0; + app1 = start_application(app_dir, server_port_number); // connect to the server - graphene::wallet::wallet_data wdata; - wdata.chain_id = app1->chain_database()->get_chain_id(); - wdata.ws_server = "ws://127.0.0.1:8090"; - wdata.ws_user = ""; - wdata.ws_password = ""; - fc::http::websocket_client client; - - auto apic = std::make_shared(*(client.connect(wdata.ws_server))); - - auto remote_api = apic->get_remote_api< login_api >(1); - BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); + client_connection con(app1, app_dir, server_port_number); } catch( fc::exception& e ) { edump((e.to_detail_string())); @@ -178,79 +240,52 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); - app1 = start_application(app_dir); + int server_port_number = 0; + app1 = start_application(app_dir, server_port_number); // connect to the server - graphene::wallet::wallet_data wdata; - wdata.chain_id = app1->chain_database()->get_chain_id(); - wdata.ws_server = "ws://127.0.0.1:8090"; - wdata.ws_user = ""; - wdata.ws_password = ""; - fc::http::websocket_client client; - auto con = client.connect( wdata.ws_server ); - - auto apic = std::make_shared(*con); - - auto remote_api = apic->get_remote_api< login_api >(1); - BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); - - auto wapiptr = std::make_shared(wdata, remote_api); - std::stringstream wallet_filename; - wallet_filename << app_dir.path().generic_string() << "/wallet.json"; - wapiptr->set_wallet_filename(wallet_filename.str()); - - fc::api wapi(wapiptr); - - auto wallet_cli = std::make_shared(); - for( auto& name_formatter : wapiptr->get_result_formatters() ) - wallet_cli->format_result( name_formatter.first, name_formatter.second ); - - boost::signals2::scoped_connection closed_connection(con->closed.connect([=]{ - cerr << "Server has disconnected us.\n"; - wallet_cli->stop(); - })); - (void)(closed_connection); + client_connection con(app1, app_dir, server_port_number); BOOST_TEST_MESSAGE("Setting wallet password"); - wapiptr->set_password("supersecret"); - wapiptr->unlock("supersecret"); + con.wallet_api_ptr->set_password("supersecret"); + con.wallet_api_ptr->unlock("supersecret"); // import Nathan account BOOST_TEST_MESSAGE("Importing nathan key"); std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); - BOOST_CHECK(wapiptr->import_key("nathan", nathan_keys[0])); + BOOST_CHECK(con.wallet_api_ptr->import_key("nathan", nathan_keys[0])); BOOST_TEST_MESSAGE("Importing nathan's balance"); - std::vector import_txs = wapiptr->import_balance("nathan", nathan_keys, true); - account_object nathan_acct_before_upgrade = wapiptr->get_account("nathan"); + std::vector import_txs = con.wallet_api_ptr->import_balance("nathan", nathan_keys, true); + account_object nathan_acct_before_upgrade = con.wallet_api_ptr->get_account("nathan"); // upgrade nathan BOOST_TEST_MESSAGE("Upgrading Nathan to LTM"); - signed_transaction upgrade_tx = wapiptr->upgrade_account("nathan", true); - account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); + signed_transaction upgrade_tx = con.wallet_api_ptr->upgrade_account("nathan", true); + account_object nathan_acct_after_upgrade = con.wallet_api_ptr->get_account("nathan"); // verify that the upgrade was successful BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); // create a new account - graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); + graphene::wallet::brain_key_info bki = con.wallet_api_ptr->suggest_brain_key(); BOOST_CHECK(!bki.brain_priv_key.empty()); - signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + signed_transaction create_acct_tx = con.wallet_api_ptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); // save the private key for this new account in the wallet file - BOOST_CHECK(wapiptr->import_key("jmjatlanta", bki.wif_priv_key)); - wapiptr->save_wallet_file(wallet_filename.str()); + BOOST_CHECK(con.wallet_api_ptr->import_key("jmjatlanta", bki.wif_priv_key)); + con.wallet_api_ptr->save_wallet_file(con.wallet_filename); // attempt to give jmjatlanta some bitsahres BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta"); - signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); + signed_transaction transfer_tx = con.wallet_api_ptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); // get the details for init1 - witness_object init1_obj = wapiptr->get_witness("init1"); + witness_object init1_obj = con.wallet_api_ptr->get_witness("init1"); int init1_start_votes = init1_obj.total_votes; // Vote for a witness - signed_transaction vote_witness1_tx = wapiptr->vote_for_witness("jmjatlanta", "init1", true, true); + signed_transaction vote_witness1_tx = con.wallet_api_ptr->vote_for_witness("jmjatlanta", "init1", true, true); // generate a block to get things started BOOST_CHECK(generate_block(app1)); @@ -258,21 +293,21 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) BOOST_CHECK(generate_maintenance_block(app1)); // Verify that the vote is there - init1_obj = wapiptr->get_witness("init1"); - witness_object init2_obj = wapiptr->get_witness("init2"); + init1_obj = con.wallet_api_ptr->get_witness("init1"); + witness_object init2_obj = con.wallet_api_ptr->get_witness("init2"); int init1_middle_votes = init1_obj.total_votes; BOOST_CHECK(init1_middle_votes > init1_start_votes); // Vote for a 2nd witness int init2_start_votes = init2_obj.total_votes; - signed_transaction vote_witness2_tx = wapiptr->vote_for_witness("jmjatlanta", "init2", true, true); + signed_transaction vote_witness2_tx = con.wallet_api_ptr->vote_for_witness("jmjatlanta", "init2", true, true); // send another block to trigger maintenance interval BOOST_CHECK(generate_maintenance_block(app1)); // Verify that both the first vote and the 2nd are there - init2_obj = wapiptr->get_witness("init2"); - init1_obj = wapiptr->get_witness("init1"); + init2_obj = con.wallet_api_ptr->get_witness("init2"); + init1_obj = con.wallet_api_ptr->get_witness("init1"); int init2_middle_votes = init2_obj.total_votes; BOOST_CHECK(init2_middle_votes > init2_start_votes); @@ -301,80 +336,53 @@ BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); - app1 = start_application(app_dir); + int server_port_number; + app1 = start_application(app_dir, server_port_number); // connect to the server - graphene::wallet::wallet_data wdata; - wdata.chain_id = app1->chain_database()->get_chain_id(); - wdata.ws_server = "ws://127.0.0.1:8090"; - wdata.ws_user = ""; - wdata.ws_password = ""; - fc::http::websocket_client client; - auto con = client.connect( wdata.ws_server ); - - auto apic = std::make_shared(*con); - - auto remote_api = apic->get_remote_api< login_api >(1); - BOOST_CHECK(remote_api->login( wdata.ws_user, wdata.ws_password ) ); - - auto wapiptr = std::make_shared(wdata, remote_api); - std::stringstream wallet_filename; - wallet_filename << app_dir.path().generic_string() << "/wallet.json"; - wapiptr->set_wallet_filename(wallet_filename.str()); - - fc::api wapi(wapiptr); - - auto wallet_cli = std::make_shared(); - for( auto& name_formatter : wapiptr->get_result_formatters() ) - wallet_cli->format_result( name_formatter.first, name_formatter.second ); - - boost::signals2::scoped_connection closed_connection(con->closed.connect([=]{ - cerr << "Server has disconnected us.\n"; - wallet_cli->stop(); - })); - (void)(closed_connection); + client_connection con(app1, app_dir, server_port_number); BOOST_TEST_MESSAGE("Setting wallet password"); - wapiptr->set_password("supersecret"); - wapiptr->unlock("supersecret"); + con.wallet_api_ptr->set_password("supersecret"); + con.wallet_api_ptr->unlock("supersecret"); // import Nathan account BOOST_TEST_MESSAGE("Importing nathan key"); std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); - BOOST_CHECK(wapiptr->import_key("nathan", nathan_keys[0])); + BOOST_CHECK(con.wallet_api_ptr->import_key("nathan", nathan_keys[0])); BOOST_TEST_MESSAGE("Importing nathan's balance"); - std::vector import_txs = wapiptr->import_balance("nathan", nathan_keys, true); - account_object nathan_acct_before_upgrade = wapiptr->get_account("nathan"); + std::vector import_txs = con.wallet_api_ptr->import_balance("nathan", nathan_keys, true); + account_object nathan_acct_before_upgrade = con.wallet_api_ptr->get_account("nathan"); // upgrade nathan BOOST_TEST_MESSAGE("Upgrading Nathan to LTM"); - signed_transaction upgrade_tx = wapiptr->upgrade_account("nathan", true); - account_object nathan_acct_after_upgrade = wapiptr->get_account("nathan"); + signed_transaction upgrade_tx = con.wallet_api_ptr->upgrade_account("nathan", true); + account_object nathan_acct_after_upgrade = con.wallet_api_ptr->get_account("nathan"); // verify that the upgrade was successful BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); // create a new account - graphene::wallet::brain_key_info bki = wapiptr->suggest_brain_key(); + graphene::wallet::brain_key_info bki = con.wallet_api_ptr->suggest_brain_key(); BOOST_CHECK(!bki.brain_priv_key.empty()); - signed_transaction create_acct_tx = wapiptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); + signed_transaction create_acct_tx = con.wallet_api_ptr->create_account_with_brain_key(bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true); // save the private key for this new account in the wallet file - BOOST_CHECK(wapiptr->import_key("jmjatlanta", bki.wif_priv_key)); - wapiptr->save_wallet_file(wallet_filename.str()); + BOOST_CHECK(con.wallet_api_ptr->import_key("jmjatlanta", bki.wif_priv_key)); + con.wallet_api_ptr->save_wallet_file(con.wallet_filename); // attempt to give jmjatlanta some bitsahres BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta"); - signed_transaction transfer_tx = wapiptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); + signed_transaction transfer_tx = con.wallet_api_ptr->transfer("nathan", "jmjatlanta", "10000", "BTS", "Here are some BTS for your new account", true); // grab account for comparison - account_object prior_voting_account = wapiptr->get_account("jmjatlanta"); + account_object prior_voting_account = con.wallet_api_ptr->get_account("jmjatlanta"); // set the voting proxy to nathan BOOST_TEST_MESSAGE("About to set voting proxy."); - signed_transaction voting_tx = wapiptr->set_voting_proxy("jmjatlanta", "nathan", true); - account_object after_voting_account = wapiptr->get_account("jmjatlanta"); + signed_transaction voting_tx = con.wallet_api_ptr->set_voting_proxy("jmjatlanta", "nathan", true); + account_object after_voting_account = con.wallet_api_ptr->get_account("jmjatlanta"); // see if it changed BOOST_CHECK(prior_voting_account.options.voting_account != after_voting_account.options.voting_account); From aaee5adb0095ee6e922940eaad9df226ea40b9bd Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 15 Mar 2018 14:15:24 -0500 Subject: [PATCH 11/12] Replace tabs with spaces --- tests/cli/main.cpp | 202 ++++++++++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 83 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index e14eac6988..abc07722d5 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -51,18 +51,49 @@ * Helper Methods *********************/ -// hack: import create_example_genesis() even though it's a way, way -// specific internal detail +///////// +// @brief forward declaration, using as a hack to generate a genesis.json file +// for testing +///////// namespace graphene { namespace app { namespace detail { - graphene::chain::genesis_state_type create_example_genesis(); + graphene::chain::genesis_state_type create_example_genesis(); } } } // graphene::app::detail +///////// +// @brief create a genesis_json file +// @param directory the directory to place the file "genesis.json" +// @returns the full path to the file +//////// boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { - boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; - fc::path genesis_out = genesis_path; - graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); - fc::json::save_to_file(genesis_state, genesis_out); - return genesis_path; + boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; + fc::path genesis_out = genesis_path; + graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); + + /* Work In Progress: Place some accounts in the Genesis file so as to pre-make some accounts to play with + std::string test_prefix = "test"; + // helper lambda + auto get_test_key = [&]( std::string prefix, uint32_t i ) -> public_key_type + { + return fc::ecc::private_key::regenerate( fc::sha256::hash( test_prefix + prefix + std::to_string(i) ) ).get_public_key(); + }; + + // create 2 accounts to use + for (int i = 1; i <= 2; ++i ) + { + genesis_state_type::initial_account_type dev_account( + test_prefix + std::to_string(i), + get_test_key("owner-", i), + get_test_key("active-", i), + false); + + genesis_state.initial_accounts.push_back(dev_account); + // give her some coin + + } + */ + + fc::json::save_to_file(genesis_state, genesis_out); + return genesis_path; } ////// @@ -83,80 +114,86 @@ int get_available_port() socklen_t len = sizeof(sin); if (getsockname(socket_fd, (struct sockaddr *)&sin, &len) == -1) return -1; - //return ntohs(sin.sin_port); return sin.sin_port; } -/*** - * @brief Start the application, listening on port 8090 - * @param app_dir the temporary directory to use - * @returns the application object - */ +/////////// +// @brief Start the application +// @param app_dir the temporary directory to use +// @param server_port_number to be filled with the rpc endpoint port number +// @returns the application object +////////// std::shared_ptr start_application(fc::temp_directory& app_dir, int& server_port_number) { - std::shared_ptr app1(new graphene::app::application{}); - - app1->register_plugin(); - app1->register_plugin< graphene::market_history::market_history_plugin >(); - app1->register_plugin< graphene::witness_plugin::witness_plugin >(); - app1->startup_plugins(); - boost::program_options::variables_map cfg; - server_port_number = get_available_port(); - //server_port_number = 8090; - cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:" + std::to_string(server_port_number)), false)); - cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); - cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); - app1->initialize(app_dir.path(), cfg); - - app1->startup(); - fc::usleep(fc::milliseconds(500)); + std::shared_ptr app1(new graphene::app::application{}); + + app1->register_plugin(); + app1->register_plugin< graphene::market_history::market_history_plugin >(); + app1->register_plugin< graphene::witness_plugin::witness_plugin >(); + app1->startup_plugins(); + boost::program_options::variables_map cfg; + server_port_number = get_available_port(); + cfg.emplace("rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:" + std::to_string(server_port_number)), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); + app1->initialize(app_dir.path(), cfg); + + app1->startup(); + fc::usleep(fc::milliseconds(500)); return app1; } -/**** - * Send a block to the db - * @param app the application - * @returns true on success - */ +/////////// +// Send a block to the db +// @param app the application +// @returns true on success +/////////// bool generate_block(std::shared_ptr app) { - try { - fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - auto db = app->chain_database(); - auto block_1 = db->generate_block( - db->get_slot_time(1), - db->get_scheduled_witness(1), - committee_key, - database::skip_nothing); - return true; - } catch (exception &e) { - return false; - } + try { + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + auto db = app->chain_database(); + auto block_1 = db->generate_block( + db->get_slot_time(1), + db->get_scheduled_witness(1), + committee_key, + database::skip_nothing); + return true; + } catch (exception &e) { + return false; + } } -/**** - * @brief Skip intermediate blocks, and generate a maintenance block - * @param app the application - * @returns true on success - */ +/////////// +// @brief Skip intermediate blocks, and generate a maintenance block +// @param app the application +// @returns true on success +/////////// bool generate_maintenance_block(std::shared_ptr app) { - try { - fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - uint32_t skip = ~0; - auto db = app->chain_database(); - auto maint_time = db->get_dynamic_global_properties().next_maintenance_time; - auto slots_to_miss = db->get_slot_at_time(maint_time); - db->generate_block(db->get_slot_time(slots_to_miss), - db->get_scheduled_witness(slots_to_miss), - committee_key, - skip); - return true; - } catch (exception& e) { - return false; - } + try { + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + uint32_t skip = ~0; + auto db = app->chain_database(); + auto maint_time = db->get_dynamic_global_properties().next_maintenance_time; + auto slots_to_miss = db->get_slot_at_time(maint_time); + db->generate_block(db->get_slot_time(slots_to_miss), + db->get_scheduled_witness(slots_to_miss), + committee_key, + skip); + return true; + } catch (exception& e) + { + return false; + } } +/////////// +// @brief a class to make connecting to the application server easier +/////////// class client_connection { public: + ///////// + // @brief constructor + ///////// client_connection(std::shared_ptr app, const fc::temp_directory& data_dir, const int server_port_number) { wallet_data.chain_id = app->chain_database()->get_chain_id(); @@ -198,20 +235,20 @@ class client_connection std::string wallet_filename; }; -/**************************** - * Tests - ****************************/ +/////////////////////////////// +// Tests +/////////////////////////////// -/** - * Start a server and connect using the same calls as the CLI - */ +//////////////// +// Start a server and connect using the same calls as the CLI +//////////////// BOOST_AUTO_TEST_CASE( cli_connect ) { using namespace graphene::chain; using namespace graphene::app; std::shared_ptr app1; try { - fc::temp_directory app_dir ( graphene::utilities::temp_directory_path() ); + fc::temp_directory app_dir ( graphene::utilities::temp_directory_path() ); int server_port_number = 0; app1 = start_application(app_dir, server_port_number); @@ -226,18 +263,17 @@ BOOST_AUTO_TEST_CASE( cli_connect ) app1->shutdown(); } -/** - * Start a server and connect using the same calls as the CLI - * Vote for two witnesses, and make sure they both stay there - * after a maintenance block - */ +/////////////////////// +// Start a server and connect using the same calls as the CLI +// Vote for two witnesses, and make sure they both stay there +// after a maintenance block +/////////////////////// BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) { using namespace graphene::chain; using namespace graphene::app; std::shared_ptr app1; try { - fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); int server_port_number = 0; @@ -323,10 +359,10 @@ BOOST_AUTO_TEST_CASE( cli_vote_for_2_witnesses ) app1->shutdown(); } -/** - * Start a server and connect using the same calls as the CLI - * Set a voting proxy and be assured that it sticks - */ +/////////////////// +// Start a server and connect using the same calls as the CLI +// Set a voting proxy and be assured that it sticks +/////////////////// BOOST_AUTO_TEST_CASE( cli_set_voting_proxy ) { using namespace graphene::chain; From f8edc2829a31e29de95a95131fc88db842ba022a Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 21 Mar 2018 08:45:24 -0500 Subject: [PATCH 12/12] adjusted comments for doxygen compatibility --- tests/cli/main.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index abc07722d5..f0511a9653 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -52,17 +52,17 @@ *********************/ ///////// -// @brief forward declaration, using as a hack to generate a genesis.json file -// for testing +/// @brief forward declaration, using as a hack to generate a genesis.json file +/// for testing ///////// namespace graphene { namespace app { namespace detail { graphene::chain::genesis_state_type create_example_genesis(); } } } // graphene::app::detail ///////// -// @brief create a genesis_json file -// @param directory the directory to place the file "genesis.json" -// @returns the full path to the file +/// @brief create a genesis_json file +/// @param directory the directory to place the file "genesis.json" +/// @returns the full path to the file //////// boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; @@ -97,8 +97,8 @@ boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { } ////// -// @brief attempt to find an available port on localhost -// @returns an available port number, or -1 on error +/// @brief attempt to find an available port on localhost +/// @returns an available port number, or -1 on error ///// int get_available_port() { @@ -118,10 +118,10 @@ int get_available_port() } /////////// -// @brief Start the application -// @param app_dir the temporary directory to use -// @param server_port_number to be filled with the rpc endpoint port number -// @returns the application object +/// @brief Start the application +/// @param app_dir the temporary directory to use +/// @param server_port_number to be filled with the rpc endpoint port number +/// @returns the application object ////////// std::shared_ptr start_application(fc::temp_directory& app_dir, int& server_port_number) { std::shared_ptr app1(new graphene::app::application{}); @@ -143,9 +143,9 @@ std::shared_ptr start_application(fc::temp_directory } /////////// -// Send a block to the db -// @param app the application -// @returns true on success +/// Send a block to the db +/// @param app the application +/// @returns true on success /////////// bool generate_block(std::shared_ptr app) { try { @@ -163,9 +163,9 @@ bool generate_block(std::shared_ptr app) { } /////////// -// @brief Skip intermediate blocks, and generate a maintenance block -// @param app the application -// @returns true on success +/// @brief Skip intermediate blocks, and generate a maintenance block +/// @param app the application +/// @returns true on success /////////// bool generate_maintenance_block(std::shared_ptr app) { try { @@ -186,13 +186,13 @@ bool generate_maintenance_block(std::shared_ptr app) } /////////// -// @brief a class to make connecting to the application server easier +/// @brief a class to make connecting to the application server easier /////////// class client_connection { public: ///////// - // @brief constructor + // constructor ///////// client_connection(std::shared_ptr app, const fc::temp_directory& data_dir, const int server_port_number) {