[][src]Struct exonum_testkit::TestKit

pub struct TestKit { /* fields omitted */ }

Testkit for testing blockchain services. It offers simple network configuration emulation (with no real network setup).

Methods

impl TestKit[src]

pub fn for_service<S>(service: S) -> Self where
    S: Into<Box<dyn Service>>, 
[src]

Creates a new TestKit with a single validator with the given service.

pub fn api(&self) -> TestKitApi[src]

Creates an instance of TestKitApi to test the API provided by services.

pub fn poll_events(&mut self)[src]

Polls the existing events from the event loop until exhaustion. Does not wait until new events arrive.

pub fn snapshot(&self) -> Box<dyn Snapshot>[src]

Returns a snapshot of the current blockchain state.

pub fn blockchain(&self) -> &Blockchain[src]

Returns a reference to the blockchain used by the testkit.

pub fn blockchain_mut(&mut self) -> &mut Blockchain[src]

Returns a blockchain instance for low level manipulations with storage.

pub fn checkpoint(&mut self)[src]

Sets a checkpoint for a future rollback.

pub fn rollback(&mut self)[src]

Rolls the blockchain back to the latest checkpoint.

Examples

Rollbacks are useful in testing alternative scenarios (e.g., transactions executed in different order and/or in different blocks) that require an expensive setup:




let mut testkit = TestKitBuilder::validator()
    .with_service(MyService)
    .create();
expensive_setup(&mut testkit);
let (pubkey, key) = exonum::crypto::gen_keypair();
let tx_a = MyTransaction::sign(&pubkey, "foo", &key);
let tx_b = MyTransaction::sign(&pubkey, "bar", &key);

testkit.checkpoint();
testkit.create_block_with_transactions(txvec![tx_a.clone(), tx_b.clone()]);
assert_something_about(&testkit);
testkit.rollback();

testkit.checkpoint();
testkit.create_block_with_transactions(txvec![tx_a.clone()]);
testkit.create_block_with_transactions(txvec![tx_b.clone()]);
assert_something_about(&testkit);
testkit.rollback();

pub fn probe_all<I>(&mut self, transactions: I) -> Box<dyn Snapshot> where
    I: IntoIterator<Item = Signed<RawTransaction>>, 
[src]

Executes a list of transactions given the current state of the blockchain, but does not commit execution results to the blockchain. The execution result is the same as if transactions were included into a new block; for example, transactions included into one of previous blocks do not lead to any state changes.

pub fn probe(
    &mut self,
    transaction: Signed<RawTransaction>
) -> Box<dyn Snapshot>
[src]

Executes a transaction given the current state of the blockchain but does not commit execution results to the blockchain. The execution result is the same as if a transaction was included into a new block; for example, a transaction included into one of previous blocks does not lead to any state changes.

pub fn next_configuration(&self) -> Option<&TestNetworkConfiguration>[src]

Returns a reference to the scheduled configuration proposal, or None if there is no such proposal.

pub fn create_block_with_transactions<I>(
    &mut self,
    txs: I
) -> BlockWithTransactions where
    I: IntoIterator<Item = Signed<RawTransaction>>, 
[src]

Creates a block with the given transactions. Transactions that are in the pool will be ignored.

Return value

Returns information about the created block.

Panics

  • Panics if any of transactions has been already committed to the blockchain.

pub fn create_block_with_transaction(
    &mut self,
    tx: Signed<RawTransaction>
) -> BlockWithTransactions
[src]

Creates a block with the given transaction. Transactions that are in the pool will be ignored.

Return value

Returns information about the created block.

Panics

  • Panics if given transaction has been already committed to the blockchain.

pub fn create_block_with_tx_hashes(
    &mut self,
    tx_hashes: &[Hash]
) -> BlockWithTransactions
[src]

Creates block with the specified transactions. The transactions must be previously sent to the node via API or directly put into the channel().

Return value

Returns information about the created block.

Panics

  • Panics in the case any of transaction hashes are not in the pool.

pub fn create_block(&mut self) -> BlockWithTransactions[src]

Creates block with all transactions in the pool.

Return value

Returns information about the created block.

pub fn add_tx(&mut self, transaction: Signed<RawTransaction>)[src]

Adds transaction into persistent pool.

pub fn is_tx_in_pool(&self, tx_hash: &Hash) -> bool[src]

Checks if transaction can be found in pool

pub fn create_blocks_until(&mut self, height: Height)[src]

Creates a chain of blocks until a given height.

Example

let mut testkit = TestKitBuilder::validator().create();
testkit.create_blocks_until(Height(5));
assert_eq!(Height(5), testkit.height());

pub fn last_block_hash(&self) -> Hash[src]

Returns the hash of latest committed block.

pub fn height(&self) -> Height[src]

Returns the height of latest committed block.

pub fn explorer(&self) -> BlockchainExplorer[src]

Returns the blockchain explorer instance.

pub fn actual_configuration(&self) -> StoredConfiguration[src]

Returns the actual blockchain configuration.

pub fn validator(&self, id: ValidatorId) -> &TestNode[src]

Returns reference to validator with the given identifier.

Panics

  • Panics if validator with the given id is absent in test network.

pub fn majority_count(&self) -> usize[src]

Returns sufficient number of validators for the Byzantine Fault Tolerance consensus.

pub fn leader(&self) -> &TestNode[src]

Returns the leader on the current height. At the moment first validator.

pub fn network(&self) -> &TestNetwork[src]

Returns the reference to test network.

pub fn network_mut(&mut self) -> &mut TestNetwork[src]

Returns the mutable reference to test network for manual modifications.

pub fn configuration_change_proposal(&self) -> TestNetworkConfiguration[src]

Returns a copy of the actual configuration of the testkit. The returned configuration could be modified for use with commit_configuration_change method.

pub fn commit_configuration_change(
    &mut self,
    proposal: TestNetworkConfiguration
)
[src]

Adds a new configuration proposal. Remember, to add this proposal to the blockchain, you should create at least one block.

Panics

  • Panics if actual_from is less than current height or equals.
  • Panics if configuration change has been already proposed but not executed.

Example

extern crate exonum;
extern crate exonum_testkit;
extern crate serde;
extern crate serde_json;

use exonum::blockchain::Schema;
use exonum::crypto::CryptoHash;
use exonum::helpers::{Height, ValidatorId};
use exonum_testkit::TestKitBuilder;

fn main() {
   let mut testkit = TestKitBuilder::auditor().with_validators(3).create();

   let cfg_change_height = Height(5);
   let proposal = {
        let mut cfg = testkit.configuration_change_proposal();
        // Add us to validators.
        let mut validators = cfg.validators().to_vec();
        validators.push(testkit.network().us().clone());
        cfg.set_validators(validators);
        // Change configuration of our service.
        cfg.set_service_config("my_service", "My config");
        // Set the height with which the configuration takes effect.
        cfg.set_actual_from(cfg_change_height);
        cfg
    };
    // Save proposed configuration.
    let stored = proposal.stored_configuration().clone();
    // Commit configuration change proposal to the testkit.
    testkit.commit_configuration_change(proposal);
    // Create blocks up to the height preceding the `actual_from` height.
    testkit.create_blocks_until(cfg_change_height.previous());
    // Check that the proposal has become actual.
    assert_eq!(testkit.network().us().validator_id(), Some(ValidatorId(3)));
    assert_eq!(testkit.validator(ValidatorId(3)), testkit.network().us());
    assert_eq!(testkit.actual_configuration(), stored);
    assert_eq!(
        Schema::new(&testkit.snapshot())
            .previous_configuration()
            .unwrap()
            .hash(),
        stored.previous_cfg_hash
    );
}

pub fn us(&self) -> &TestNode[src]

Returns the node in the emulated network, from whose perspective the testkit operates.

Trait Implementations

impl Debug for TestKit[src]

Auto Trait Implementations

impl Send for TestKit

impl Sync for TestKit

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Erased for T

impl<T> Same for T

type Output = T

Should always be Self