Skip to content

Commit

Permalink
Let integration tests generic over externs (#664)
Browse files Browse the repository at this point in the history
  • Loading branch information
mriise authored Jul 21, 2022
1 parent 158309f commit e9657a7
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 46 deletions.
3 changes: 2 additions & 1 deletion testing/integration/examples/integration.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use fvm::executor::{ApplyKind, Executor};
use fvm_integration_tests::dummy::DummyExterns;
use fvm_integration_tests::tester::{Account, Tester};
use fvm_ipld_blockstore::MemoryBlockstore;
use fvm_ipld_encoding::tuple::*;
Expand Down Expand Up @@ -50,7 +51,7 @@ pub fn main() {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Send message
let message = Message {
Expand Down
24 changes: 17 additions & 7 deletions testing/integration/src/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fvm::externs::{Consensus, Externs, Rand};

use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
pub struct DummyExterns;

impl Externs for DummyExterns {}
Expand All @@ -11,10 +12,13 @@ impl Rand for DummyExterns {
_round: fvm_shared::clock::ChainEpoch,
_entropy: &[u8],
) -> anyhow::Result<[u8; 32]> {
let msg = "mel was here".as_bytes();
let mut out = [0u8; 32];
out[..msg.len()].copy_from_slice(msg);
Ok(out)
let rng: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(32)
.map(char::from)
.collect();

Ok(<[u8; 32]>::try_from(rng.into_bytes()).unwrap())
}

fn get_beacon_randomness(
Expand All @@ -23,7 +27,13 @@ impl Rand for DummyExterns {
_round: fvm_shared::clock::ChainEpoch,
_entropy: &[u8],
) -> anyhow::Result<[u8; 32]> {
todo!()
let rng: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(32)
.map(char::from)
.collect();

Ok(<[u8; 32]>::try_from(rng.into_bytes()).unwrap())
}
}

Expand All @@ -34,6 +44,6 @@ impl Consensus for DummyExterns {
_h2: &[u8],
_extra: &[u8],
) -> anyhow::Result<(Option<fvm_shared::consensus::ConsensusFault>, i64)> {
todo!()
Ok((None, 0))
}
}
2 changes: 1 addition & 1 deletion testing/integration/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod builtin;
mod dummy;
pub mod dummy;
pub mod error;
pub mod tester;
23 changes: 13 additions & 10 deletions testing/integration/src/tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::{anyhow, Context, Result};
use cid::Cid;
use fvm::call_manager::DefaultCallManager;
use fvm::executor::DefaultExecutor;
use fvm::externs::Externs;
use fvm::machine::{DefaultMachine, Engine, Machine, NetworkConfig};
use fvm::state_tree::{ActorState, StateTree};
use fvm::{init_actor, system_actor, DefaultKernel};
Expand All @@ -18,20 +19,18 @@ use multihash::Code;
use crate::builtin::{
fetch_builtin_code_cid, import_builtin_actors, set_init_actor, set_sys_actor,
};
use crate::dummy;
use crate::dummy::DummyExterns;
use crate::error::Error::{FailedToFlushTree, NoManifestInformation, NoRootCid};

const DEFAULT_BASE_FEE: u64 = 100;

pub trait Store: Blockstore + Sized + 'static {}

pub type IntegrationExecutor<B> =
DefaultExecutor<DefaultKernel<DefaultCallManager<DefaultMachine<B, DummyExterns>>>>;
pub type IntegrationExecutor<B, E> =
DefaultExecutor<DefaultKernel<DefaultCallManager<DefaultMachine<B, E>>>>;

pub type Account = (ActorID, Address);

pub struct Tester<B: Blockstore + 'static> {
pub struct Tester<B: Blockstore + 'static, E: Externs + 'static> {
// Network version used in the test
nv: NetworkVersion,
// Builtin actors root Cid used in the Machine
Expand All @@ -41,14 +40,15 @@ pub struct Tester<B: Blockstore + 'static> {
// Custom code cid deployed by developer
code_cids: Vec<Cid>,
// Executor used to interact with deployed actors.
pub executor: Option<IntegrationExecutor<B>>,
pub executor: Option<IntegrationExecutor<B, E>>,
// State tree constructed before instantiating the Machine
pub state_tree: Option<StateTree<B>>,
}

impl<B> Tester<B>
impl<B, E> Tester<B, E>
where
B: Blockstore,
E: Externs,
{
pub fn new(nv: NetworkVersion, stv: StateTreeVersion, blockstore: B) -> Result<Self> {
// Load the builtin actors bundles into the blockstore.
Expand Down Expand Up @@ -152,7 +152,7 @@ where
}

/// Sets the Machine and the Executor in our Tester structure.
pub fn instantiate_machine(&mut self) -> Result<()> {
pub fn instantiate_machine(&mut self, externs: E) -> Result<()> {
// Take the state tree and leave None behind.
let mut state_tree = self.state_tree.take().unwrap();

Expand All @@ -176,10 +176,13 @@ where
&Engine::new_default((&mc.network.clone()).into())?,
&mc,
blockstore,
dummy::DummyExterns,
externs,
)?;

let executor = DefaultExecutor::<DefaultKernel<DefaultCallManager<_>>>::new(machine);
let executor =
DefaultExecutor::<DefaultKernel<DefaultCallManager<DefaultMachine<B, E>>>>::new(
machine,
);
executor
.engine()
.preload(executor.blockstore(), &self.code_cids)?;
Expand Down
5 changes: 3 additions & 2 deletions testing/integration/tests/fil_integer_overflow.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use fvm::executor::{ApplyKind, Executor};
use fvm_integration_tests::dummy::DummyExterns;
use fvm_integration_tests::tester::{Account, Tester};
use fvm_ipld_blockstore::MemoryBlockstore;
use fvm_ipld_encoding::tuple::*;
Expand All @@ -20,7 +21,7 @@ pub struct State {
}

// Utility function to instantiation integration tester
fn instantiate_tester() -> (Account, Tester<MemoryBlockstore>, Address) {
fn instantiate_tester() -> (Account, Tester<MemoryBlockstore, DummyExterns>, Address) {
// Instantiate tester
let mut tester = Tester::new(
NetworkVersion::V15,
Expand Down Expand Up @@ -60,7 +61,7 @@ fn integer_overflow() {
let (sender, mut tester, actor_address) = instantiate_tester();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Params setup
let x: i64 = 10000000000;
Expand Down
9 changes: 6 additions & 3 deletions testing/integration/tests/fil_syscall.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fvm::call_manager::backtrace::Cause;
use fvm::executor::{ApplyFailure, ApplyKind, Executor};
use fvm_integration_tests::dummy::DummyExterns;
use fvm_integration_tests::tester::{Account, Tester};
use fvm_ipld_blockstore::MemoryBlockstore;
use fvm_ipld_encoding::tuple::*;
Expand Down Expand Up @@ -36,7 +37,9 @@ pub struct State {
}

// Utility function to instantiation integration tester
fn instantiate_tester(wasm_bin: &[u8]) -> (Account, Tester<MemoryBlockstore>, Address) {
fn instantiate_tester(
wasm_bin: &[u8],
) -> (Account, Tester<MemoryBlockstore, DummyExterns>, Address) {
// Instantiate tester
let mut tester = Tester::new(
NetworkVersion::V15,
Expand Down Expand Up @@ -70,7 +73,7 @@ fn non_existing_syscall() {
let (sender, mut tester, actor_address) = instantiate_tester(&wasm_bin);

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Params setup
let params = RawBytes::new(Vec::<u8>::new());
Expand Down Expand Up @@ -132,7 +135,7 @@ fn malformed_syscall_parameter() {
let (sender, mut tester, actor_address) = instantiate_tester(&wasm_bin);

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Params setup
let params = RawBytes::new(Vec::<u8>::new());
Expand Down
47 changes: 25 additions & 22 deletions testing/integration/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::rc::Rc;
use anyhow::anyhow;
use cid::Cid;
use fvm::executor::{ApplyKind, Executor, ThreadedExecutor};
use fvm_integration_tests::dummy::DummyExterns;
use fvm_integration_tests::tester::{Account, IntegrationExecutor, Tester};
use fvm_ipld_blockstore::{Blockstore, MemoryBlockstore};
use fvm_ipld_encoding::tuple::*;
Expand Down Expand Up @@ -68,7 +69,7 @@ fn hello_world() {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Send message
let message = Message {
Expand Down Expand Up @@ -120,7 +121,7 @@ fn ipld() {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Send message
let message = Message {
Expand Down Expand Up @@ -178,26 +179,28 @@ fn native_stack_overflow() {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();

let exec_test = |exec: &mut ThreadedExecutor<IntegrationExecutor<MemoryBlockstore>>, method| {
// Send message
let message = Message {
from: sender[0].1,
to: actor_address,
gas_limit: 10_000_000_000,
method_num: method,
sequence: method - 1,
..Message::default()
tester.instantiate_machine(DummyExterns).unwrap();

let exec_test =
|exec: &mut ThreadedExecutor<IntegrationExecutor<MemoryBlockstore, DummyExterns>>,
method| {
// Send message
let message = Message {
from: sender[0].1,
to: actor_address,
gas_limit: 10_000_000_000,
method_num: method,
sequence: method - 1,
..Message::default()
};

let res = exec
.execute_message(message, ApplyKind::Explicit, 100)
.unwrap();

res.msg_receipt.exit_code.value()
};

let res = exec
.execute_message(message, ApplyKind::Explicit, 100)
.unwrap();

res.msg_receipt.exit_code.value()
};

let mut executor = ThreadedExecutor(tester.executor.unwrap());

// on method 0 the test actor should run out of stack
Expand Down Expand Up @@ -242,7 +245,7 @@ fn test_exitcode(wat: &str, code: ExitCode) {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

// Send message
let message = Message {
Expand Down Expand Up @@ -396,7 +399,7 @@ fn backtraces() {
.unwrap();

// Instantiate machine
tester.instantiate_machine().unwrap();
tester.instantiate_machine(DummyExterns).unwrap();

let executor = tester.executor.as_mut().unwrap();

Expand Down

0 comments on commit e9657a7

Please sign in to comment.