peerplays_migrated/tests/common/database_fixture.hpp

298 lines
13 KiB
C++
Raw Normal View History

2015-06-08 15:50:35 +00:00
/*
2015-10-12 17:48:40 +00:00
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
2015-10-12 17:48:40 +00:00
*
* 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:
2015-10-12 17:48:40 +00:00
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
2015-10-12 17:02:59 +00:00
*
* 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.
2015-06-08 15:50:35 +00:00
*/
#pragma once
#include <graphene/app/application.hpp>
#include <graphene/chain/database.hpp>
#include <fc/io/json.hpp>
#include <fc/smart_ref_impl.hpp>
2015-06-08 15:50:35 +00:00
2016-02-15 19:58:01 +00:00
#include <graphene/chain/operation_history_object.hpp>
#include <iostream>
2015-06-08 15:50:35 +00:00
using namespace graphene::db;
extern uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP;
#define PUSH_TX \
graphene::chain::test::_push_transaction
#define PUSH_BLOCK \
graphene::chain::test::_push_block
2015-06-08 15:50:35 +00:00
// See below
#define REQUIRE_OP_VALIDATION_SUCCESS( op, field, value ) \
{ \
const auto temp = op.field; \
op.field = value; \
op.validate(); \
op.field = temp; \
}
#define REQUIRE_OP_EVALUATION_SUCCESS( op, field, value ) \
2015-06-08 15:50:35 +00:00
{ \
const auto temp = op.field; \
op.field = value; \
trx.operations.back() = op; \
2015-06-08 15:50:35 +00:00
op.field = temp; \
db.push_transaction( trx, ~0 ); \
2015-06-08 15:50:35 +00:00
}
#define GRAPHENE_REQUIRE_THROW( expr, exc_type ) \
{ \
std::string req_throw_info = fc::json::to_string( \
fc::mutable_variant_object() \
("source_file", __FILE__) \
("source_lineno", __LINE__) \
("expr", #expr) \
("exc_type", #exc_type) \
); \
if( fc::enable_record_assert_trip ) \
std::cout << "GRAPHENE_REQUIRE_THROW begin " \
<< req_throw_info << std::endl; \
BOOST_REQUIRE_THROW( expr, exc_type ); \
if( fc::enable_record_assert_trip ) \
std::cout << "GRAPHENE_REQUIRE_THROW end " \
<< req_throw_info << std::endl; \
}
#define GRAPHENE_CHECK_THROW( expr, exc_type ) \
{ \
std::string req_throw_info = fc::json::to_string( \
fc::mutable_variant_object() \
("source_file", __FILE__) \
("source_lineno", __LINE__) \
("expr", #expr) \
("exc_type", #exc_type) \
); \
if( fc::enable_record_assert_trip ) \
std::cout << "GRAPHENE_CHECK_THROW begin " \
<< req_throw_info << std::endl; \
BOOST_CHECK_THROW( expr, exc_type ); \
if( fc::enable_record_assert_trip ) \
std::cout << "GRAPHENE_CHECK_THROW end " \
<< req_throw_info << std::endl; \
}
#define REQUIRE_OP_VALIDATION_FAILURE_2( op, field, value, exc_type ) \
2015-06-08 15:50:35 +00:00
{ \
const auto temp = op.field; \
op.field = value; \
GRAPHENE_REQUIRE_THROW( op.validate(), exc_type ); \
2015-06-08 15:50:35 +00:00
op.field = temp; \
}
#define REQUIRE_OP_VALIDATION_FAILURE( op, field, value ) \
REQUIRE_OP_VALIDATION_FAILURE_2( op, field, value, fc::exception )
#define REQUIRE_THROW_WITH_VALUE_2(op, field, value, exc_type) \
2015-06-08 15:50:35 +00:00
{ \
auto bak = op.field; \
op.field = value; \
trx.operations.back() = op; \
op.field = bak; \
GRAPHENE_REQUIRE_THROW(db.push_transaction(trx, ~0), exc_type); \
2015-06-08 15:50:35 +00:00
}
#define REQUIRE_THROW_WITH_VALUE( op, field, value ) \
REQUIRE_THROW_WITH_VALUE_2( op, field, value, fc::exception )
2015-06-08 15:50:35 +00:00
///This simply resets v back to its default-constructed value. Requires v to have a working assingment operator and
/// default constructor.
#define RESET(v) v = decltype(v)()
///This allows me to build consecutive test cases. It's pretty ugly, but it works well enough for unit tests.
/// i.e. This allows a test on update_account to begin with the database at the end state of create_account.
#define INVOKE(test) ((struct test*)this)->test_method(); trx.clear()
2015-06-12 15:15:11 +00:00
#define PREP_ACTOR(name) \
fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \
public_key_type name ## _public_key = name ## _private_key.get_public_key();
2015-06-12 15:15:11 +00:00
#define ACTOR(name) \
PREP_ACTOR(name) \
const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _public_key); \
account_id_type name ## _id = name.id; (void)name ## _id;
2015-06-08 15:50:35 +00:00
#define GET_ACTOR(name) \
fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \
const account_object& name = get_account(BOOST_PP_STRINGIZE(name)); \
account_id_type name ## _id = name.id; \
(void)name ##_id
2015-06-08 15:50:35 +00:00
#define ACTORS_IMPL(r, data, elem) ACTOR(elem)
#define ACTORS(names) BOOST_PP_SEQ_FOR_EACH(ACTORS_IMPL, ~, names)
namespace graphene { namespace chain {
struct database_fixture {
// the reason we use an app is to exercise the indexes of built-in
// plugins
graphene::app::application app;
genesis_state_type genesis_state;
2015-06-08 15:50:35 +00:00
chain::database &db;
signed_transaction trx;
public_key_type committee_key;
account_id_type committee_account;
2015-06-08 15:50:35 +00:00
fc::ecc::private_key private_key = fc::ecc::private_key::generate();
fc::ecc::private_key init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) );
public_key_type init_account_pub_key;
2015-06-08 15:50:35 +00:00
optional<fc::temp_directory> data_dir;
bool skip_key_index_test = false;
uint32_t anon_acct_count;
database_fixture();
~database_fixture();
static fc::ecc::private_key generate_private_key(string seed);
string generate_anon_acct_name();
static void verify_asset_supplies( const database& db );
2015-06-08 15:50:35 +00:00
void verify_account_history_plugin_index( )const;
void open_database();
signed_block generate_block(uint32_t skip = ~0,
const fc::ecc::private_key& key = generate_private_key("null_key"),
2015-06-08 15:50:35 +00:00
int miss_blocks = 0);
/**
* @brief Generates block_count blocks
* @param block_count number of blocks to generate
*/
2015-06-15 21:28:20 +00:00
void generate_blocks(uint32_t block_count);
2015-06-08 15:50:35 +00:00
/**
* @brief Generates blocks until the head block time matches or exceeds timestamp
* @param timestamp target time to generate blocks until
*/
void generate_blocks(fc::time_point_sec timestamp, bool miss_intermediate_blocks = true, uint32_t skip = ~0);
2015-06-08 15:50:35 +00:00
account_create_operation make_account(
const std::string& name = "nathan",
public_key_type = public_key_type()
2015-06-08 15:50:35 +00:00
);
account_create_operation make_account(
const std::string& name,
const account_object& registrar,
const account_object& referrer,
uint8_t referrer_percent = 100,
public_key_type key = public_key_type()
2015-06-08 15:50:35 +00:00
);
2015-06-19 20:36:37 +00:00
void force_global_settle(const asset_object& what, const price& p);
operation_result force_settle(account_id_type who, asset what)
{ return force_settle(who(db), what); }
operation_result force_settle(const account_object& who, asset what);
void update_feed_producers(asset_id_type mia, flat_set<account_id_type> producers)
{ update_feed_producers(mia(db), producers); }
2015-06-19 20:36:37 +00:00
void update_feed_producers(const asset_object& mia, flat_set<account_id_type> producers);
void publish_feed(asset_id_type mia, account_id_type by, const price_feed& f)
{ publish_feed(mia(db), by(db), f); }
2015-06-19 20:36:37 +00:00
void publish_feed(const asset_object& mia, const account_object& by, const price_feed& f);
const call_order_object* borrow(account_id_type who, asset what, asset collateral)
{ return borrow(who(db), what, collateral); }
const call_order_object* borrow(const account_object& who, asset what, asset collateral);
void cover(account_id_type who, asset what, asset collateral_freed)
{ cover(who(db), what, collateral_freed); }
void cover(const account_object& who, asset what, asset collateral_freed);
2015-06-08 15:50:35 +00:00
const asset_object& get_asset( const string& symbol )const;
const account_object& get_account( const string& name )const;
const asset_object& create_bitasset(const string& name,
2015-09-21 21:17:30 +00:00
account_id_type issuer = GRAPHENE_WITNESS_ACCOUNT,
2015-06-08 15:50:35 +00:00
uint16_t market_fee_percent = 100 /*1%*/,
uint16_t flags = charge_market_fee);
const asset_object& create_prediction_market(const string& name,
2015-09-21 21:17:30 +00:00
account_id_type issuer = GRAPHENE_WITNESS_ACCOUNT,
uint16_t market_fee_percent = 100 /*1%*/,
uint16_t flags = charge_market_fee);
2015-06-08 15:50:35 +00:00
const asset_object& create_user_issued_asset( const string& name );
const asset_object& create_user_issued_asset( const string& name,
const account_object& issuer,
uint16_t flags );
2015-06-08 15:50:35 +00:00
void issue_uia( const account_object& recipient, asset amount );
void issue_uia( account_id_type recipient_id, asset amount );
2015-06-08 15:50:35 +00:00
const account_object& create_account(
const string& name,
const public_key_type& key = public_key_type()
2015-06-08 15:50:35 +00:00
);
const account_object& create_account(
const string& name,
const account_object& registrar,
const account_object& referrer,
uint8_t referrer_percent = 100,
const public_key_type& key = public_key_type()
2015-06-08 15:50:35 +00:00
);
const account_object& create_account(
const string& name,
const private_key_type& key,
const account_id_type& registrar_id = account_id_type(),
const account_id_type& referrer_id = account_id_type(),
uint8_t referrer_percent = 100
);
const committee_member_object& create_committee_member( const account_object& owner );
2015-06-08 15:50:35 +00:00
const witness_object& create_witness(account_id_type owner,
const fc::ecc::private_key& signing_private_key = generate_private_key("null_key"));
2015-06-08 15:50:35 +00:00
const witness_object& create_witness(const account_object& owner,
const fc::ecc::private_key& signing_private_key = generate_private_key("null_key"));
2015-06-08 15:50:35 +00:00
uint64_t fund( const account_object& account, const asset& amount = asset(500000) );
2015-08-06 16:41:45 +00:00
digest_type digest( const transaction& tx );
void sign( signed_transaction& trx, const fc::ecc::private_key& key );
2015-06-08 15:50:35 +00:00
const limit_order_object* create_sell_order( account_id_type user, const asset& amount, const asset& recv );
const limit_order_object* create_sell_order( const account_object& user, const asset& amount, const asset& recv );
asset cancel_limit_order( const limit_order_object& order );
void transfer( account_id_type from, account_id_type to, const asset& amount, const asset& fee = asset() );
void transfer( const account_object& from, const account_object& to, const asset& amount, const asset& fee = asset() );
void fund_fee_pool( const account_object& from, const asset_object& asset_to_fund, const share_type amount );
2015-07-09 12:22:04 +00:00
void enable_fees();
void change_fees( const flat_set< fee_parameters >& new_params, uint32_t new_scale = 0 );
void upgrade_to_lifetime_member( account_id_type account );
void upgrade_to_lifetime_member( const account_object& account );
2015-06-15 21:28:20 +00:00
void upgrade_to_annual_member( account_id_type account );
void upgrade_to_annual_member( const account_object& account );
2015-06-08 15:50:35 +00:00
void print_market( const string& syma, const string& symb )const;
string pretty( const asset& a )const;
void print_limit_order( const limit_order_object& cur )const;
void print_call_orders( )const;
void print_joint_market( const string& syma, const string& symb )const;
int64_t get_balance( account_id_type account, asset_id_type a )const;
int64_t get_balance( const account_object& account, const asset_object& a )const;
int64_t get_dividend_pending_payout_balance(asset_id_type dividend_holder_asset_type,
account_id_type dividend_holder_account_id,
asset_id_type dividend_payout_asset_type) const;
2016-02-15 19:58:01 +00:00
vector< operation_history_object > get_operation_history( account_id_type account_id )const;
2015-06-08 15:50:35 +00:00
};
namespace test {
/// set a reasonable expiration time for the transaction
void set_expiration( const database& db, transaction& tx );
bool _push_block( database& db, const signed_block& b, uint32_t skip_flags = 0 );
processed_transaction _push_transaction( database& db, const signed_transaction& tx, uint32_t skip_flags = 0 );
}
2015-06-08 15:50:35 +00:00
} }