Reformat the source code
This commit is contained in:
@@ -14,73 +14,75 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethjson::{
|
||||
bytes::Bytes,
|
||||
hash::{Address, H256},
|
||||
uint::Uint,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use ethjson::uint::Uint;
|
||||
use ethjson::hash::{Address, H256};
|
||||
use ethjson::bytes::Bytes;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Source {
|
||||
Raw(Cow<'static, String>),
|
||||
Constructor {
|
||||
#[serde(rename = "constructor")]
|
||||
source: Cow<'static, String>,
|
||||
arguments: Bytes,
|
||||
sender: Address,
|
||||
at: Address,
|
||||
},
|
||||
Raw(Cow<'static, String>),
|
||||
Constructor {
|
||||
#[serde(rename = "constructor")]
|
||||
source: Cow<'static, String>,
|
||||
arguments: Bytes,
|
||||
sender: Address,
|
||||
at: Address,
|
||||
},
|
||||
}
|
||||
|
||||
impl Source {
|
||||
pub fn as_ref(&self) -> &str {
|
||||
match *self {
|
||||
Source::Raw(ref r) => r.as_ref(),
|
||||
Source::Constructor { ref source, .. } => source.as_ref(),
|
||||
}
|
||||
}
|
||||
pub fn as_ref(&self) -> &str {
|
||||
match *self {
|
||||
Source::Raw(ref r) => r.as_ref(),
|
||||
Source::Constructor { ref source, .. } => source.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Fixture {
|
||||
pub caption: Cow<'static, String>,
|
||||
pub source: Source,
|
||||
pub address: Option<Address>,
|
||||
pub sender: Option<Address>,
|
||||
pub value: Option<Uint>,
|
||||
pub gas_limit: Option<u64>,
|
||||
pub payload: Option<Bytes>,
|
||||
pub storage: Option<Vec<StorageEntry>>,
|
||||
pub asserts: Vec<Assert>,
|
||||
pub caption: Cow<'static, String>,
|
||||
pub source: Source,
|
||||
pub address: Option<Address>,
|
||||
pub sender: Option<Address>,
|
||||
pub value: Option<Uint>,
|
||||
pub gas_limit: Option<u64>,
|
||||
pub payload: Option<Bytes>,
|
||||
pub storage: Option<Vec<StorageEntry>>,
|
||||
pub asserts: Vec<Assert>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct StorageEntry {
|
||||
pub key: Uint,
|
||||
pub value: Uint,
|
||||
pub key: Uint,
|
||||
pub value: Uint,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CallLocator {
|
||||
pub sender: Option<Address>,
|
||||
pub receiver: Option<Address>,
|
||||
pub value: Option<Uint>,
|
||||
pub data: Option<Bytes>,
|
||||
pub code_address: Option<Address>,
|
||||
pub sender: Option<Address>,
|
||||
pub receiver: Option<Address>,
|
||||
pub value: Option<Uint>,
|
||||
pub data: Option<Bytes>,
|
||||
pub code_address: Option<Address>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct StorageAssert {
|
||||
pub key: H256,
|
||||
pub value: H256,
|
||||
pub key: H256,
|
||||
pub value: H256,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub enum Assert {
|
||||
HasCall(CallLocator),
|
||||
HasStorage(StorageAssert),
|
||||
UsedGas(u64),
|
||||
Return(Bytes),
|
||||
HasCall(CallLocator),
|
||||
HasStorage(StorageAssert),
|
||||
UsedGas(u64),
|
||||
Return(Bytes),
|
||||
}
|
||||
|
||||
@@ -16,47 +16,56 @@
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate ethereum_types;
|
||||
extern crate ethjson;
|
||||
extern crate wasm;
|
||||
extern crate vm;
|
||||
extern crate clap;
|
||||
extern crate rustc_hex;
|
||||
extern crate env_logger;
|
||||
extern crate vm;
|
||||
extern crate wasm;
|
||||
|
||||
mod fixture;
|
||||
mod runner;
|
||||
|
||||
use fixture::Fixture;
|
||||
use clap::{App, Arg};
|
||||
use fixture::Fixture;
|
||||
use std::fs;
|
||||
|
||||
fn main() {
|
||||
::env_logger::init();
|
||||
::env_logger::init();
|
||||
|
||||
let matches = App::new("pwasm-run-test")
|
||||
.arg(Arg::with_name("target")
|
||||
.index(1)
|
||||
.required(true)
|
||||
.multiple(true)
|
||||
.help("JSON fixture"))
|
||||
.get_matches();
|
||||
let matches = App::new("pwasm-run-test")
|
||||
.arg(
|
||||
Arg::with_name("target")
|
||||
.index(1)
|
||||
.required(true)
|
||||
.multiple(true)
|
||||
.help("JSON fixture"),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let mut exit_code = 0;
|
||||
let mut exit_code = 0;
|
||||
|
||||
for target in matches.values_of("target").expect("No target parameter") {
|
||||
let mut f = fs::File::open(target).expect("Failed to open file");
|
||||
let fixtures: Vec<Fixture> = serde_json::from_reader(&mut f).expect("Failed to deserialize json");
|
||||
for target in matches.values_of("target").expect("No target parameter") {
|
||||
let mut f = fs::File::open(target).expect("Failed to open file");
|
||||
let fixtures: Vec<Fixture> =
|
||||
serde_json::from_reader(&mut f).expect("Failed to deserialize json");
|
||||
|
||||
for fixture in fixtures.into_iter() {
|
||||
let fails = runner::run_fixture(&fixture);
|
||||
for fail in fails.iter() {
|
||||
exit_code = 1;
|
||||
println!("Failed assert in test \"{}\" ('{}'): {}", fixture.caption.as_ref(), target, fail);
|
||||
}
|
||||
}
|
||||
}
|
||||
for fixture in fixtures.into_iter() {
|
||||
let fails = runner::run_fixture(&fixture);
|
||||
for fail in fails.iter() {
|
||||
exit_code = 1;
|
||||
println!(
|
||||
"Failed assert in test \"{}\" ('{}'): {}",
|
||||
fixture.caption.as_ref(),
|
||||
target,
|
||||
fail
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::process::exit(exit_code);
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
|
||||
@@ -14,264 +14,332 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use fixture::{Fixture, Assert, CallLocator, Source};
|
||||
use wasm::WasmInterpreter;
|
||||
use vm::{self, Exec, GasLeft, ActionParams, ActionValue, ParamsType};
|
||||
use vm::tests::FakeExt;
|
||||
use std::io::{self, Read};
|
||||
use std::{fs, path, fmt};
|
||||
use std::sync::Arc;
|
||||
use ethereum_types::{U256, H256, H160};
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
use fixture::{Assert, CallLocator, Fixture, Source};
|
||||
use rustc_hex::ToHex;
|
||||
use std::{
|
||||
fmt, fs,
|
||||
io::{self, Read},
|
||||
path,
|
||||
sync::Arc,
|
||||
};
|
||||
use vm::{self, tests::FakeExt, ActionParams, ActionValue, Exec, GasLeft, ParamsType};
|
||||
use wasm::WasmInterpreter;
|
||||
|
||||
fn load_code<P: AsRef<path::Path>>(p: P) -> io::Result<Vec<u8>> {
|
||||
let mut result = Vec::new();
|
||||
let mut f = fs::File::open(p)?;
|
||||
f.read_to_end(&mut result)?;
|
||||
Ok(result)
|
||||
let mut result = Vec::new();
|
||||
let mut f = fs::File::open(p)?;
|
||||
f.read_to_end(&mut result)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn wasm_interpreter(params: ActionParams) -> Box<WasmInterpreter> {
|
||||
Box::new(WasmInterpreter::new(params))
|
||||
Box::new(WasmInterpreter::new(params))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SpecNonconformity {
|
||||
Address,
|
||||
Address,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Fail {
|
||||
Return { expected: Vec<u8>, actual: Vec<u8> },
|
||||
UsedGas { expected: u64, actual: u64 },
|
||||
Runtime(String),
|
||||
Load(io::Error),
|
||||
NoCall(CallLocator),
|
||||
StorageMismatch { key: H256, expected: H256, actual: Option<H256> },
|
||||
Nonconformity(SpecNonconformity)
|
||||
Return {
|
||||
expected: Vec<u8>,
|
||||
actual: Vec<u8>,
|
||||
},
|
||||
UsedGas {
|
||||
expected: u64,
|
||||
actual: u64,
|
||||
},
|
||||
Runtime(String),
|
||||
Load(io::Error),
|
||||
NoCall(CallLocator),
|
||||
StorageMismatch {
|
||||
key: H256,
|
||||
expected: H256,
|
||||
actual: Option<H256>,
|
||||
},
|
||||
Nonconformity(SpecNonconformity),
|
||||
}
|
||||
|
||||
impl Fail {
|
||||
fn runtime(err: vm::Error) -> Vec<Fail> {
|
||||
vec![Fail::Runtime(format!("{}", err))]
|
||||
}
|
||||
fn runtime(err: vm::Error) -> Vec<Fail> {
|
||||
vec![Fail::Runtime(format!("{}", err))]
|
||||
}
|
||||
|
||||
fn load(err: io::Error) -> Vec<Fail> {
|
||||
vec![Fail::Load(err)]
|
||||
}
|
||||
fn load(err: io::Error) -> Vec<Fail> {
|
||||
vec![Fail::Load(err)]
|
||||
}
|
||||
|
||||
fn nononformity(kind: SpecNonconformity) -> Vec<Fail> {
|
||||
vec![Fail::Nonconformity(kind)]
|
||||
}
|
||||
fn nononformity(kind: SpecNonconformity) -> Vec<Fail> {
|
||||
vec![Fail::Nonconformity(kind)]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Fail {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Fail::*;
|
||||
match *self {
|
||||
Return { ref expected, ref actual } =>
|
||||
write!(
|
||||
f,
|
||||
"Expected to return result: 0x{} ({} bytes), but got 0x{} ({} bytes)",
|
||||
expected.to_hex(),
|
||||
expected.len(),
|
||||
actual.to_hex(),
|
||||
actual.len()
|
||||
),
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Fail::*;
|
||||
match *self {
|
||||
Return {
|
||||
ref expected,
|
||||
ref actual,
|
||||
} => write!(
|
||||
f,
|
||||
"Expected to return result: 0x{} ({} bytes), but got 0x{} ({} bytes)",
|
||||
expected.to_hex(),
|
||||
expected.len(),
|
||||
actual.to_hex(),
|
||||
actual.len()
|
||||
),
|
||||
|
||||
UsedGas { expected, actual } =>
|
||||
write!(f, "Expected to use gas: {}, but got actual gas used: {}", expected, actual),
|
||||
UsedGas { expected, actual } => write!(
|
||||
f,
|
||||
"Expected to use gas: {}, but got actual gas used: {}",
|
||||
expected, actual
|
||||
),
|
||||
|
||||
Runtime(ref s) =>
|
||||
write!(f, "WASM Runtime error: {}", s),
|
||||
Runtime(ref s) => write!(f, "WASM Runtime error: {}", s),
|
||||
|
||||
Load(ref e) =>
|
||||
write!(f, "Load i/o error: {}", e),
|
||||
Load(ref e) => write!(f, "Load i/o error: {}", e),
|
||||
|
||||
NoCall(ref call) =>
|
||||
write!(f, "Call not found: {:?}", call),
|
||||
NoCall(ref call) => write!(f, "Call not found: {:?}", call),
|
||||
|
||||
StorageMismatch { ref key, ref expected, actual: Some(ref actual)} =>
|
||||
write!(
|
||||
f,
|
||||
"Storage key {} value mismatch, expected {}, got: {}",
|
||||
key.to_vec().to_hex(),
|
||||
expected.to_vec().to_hex(),
|
||||
actual.to_vec().to_hex(),
|
||||
),
|
||||
StorageMismatch {
|
||||
ref key,
|
||||
ref expected,
|
||||
actual: Some(ref actual),
|
||||
} => write!(
|
||||
f,
|
||||
"Storage key {} value mismatch, expected {}, got: {}",
|
||||
key.to_vec().to_hex(),
|
||||
expected.to_vec().to_hex(),
|
||||
actual.to_vec().to_hex(),
|
||||
),
|
||||
|
||||
StorageMismatch { ref key, ref expected, actual: None} =>
|
||||
write!(
|
||||
f,
|
||||
"No expected storage value for key {} found, expected {}",
|
||||
key.to_vec().to_hex(),
|
||||
expected.to_vec().to_hex(),
|
||||
),
|
||||
StorageMismatch {
|
||||
ref key,
|
||||
ref expected,
|
||||
actual: None,
|
||||
} => write!(
|
||||
f,
|
||||
"No expected storage value for key {} found, expected {}",
|
||||
key.to_vec().to_hex(),
|
||||
expected.to_vec().to_hex(),
|
||||
),
|
||||
|
||||
Nonconformity(SpecNonconformity::Address) =>
|
||||
write!(f, "Cannot use address when constructor is specified!"),
|
||||
}
|
||||
}
|
||||
Nonconformity(SpecNonconformity::Address) => {
|
||||
write!(f, "Cannot use address when constructor is specified!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn construct(
|
||||
ext: &mut vm::Ext,
|
||||
source: Vec<u8>,
|
||||
arguments: Vec<u8>,
|
||||
sender: H160,
|
||||
at: H160,
|
||||
ext: &mut vm::Ext,
|
||||
source: Vec<u8>,
|
||||
arguments: Vec<u8>,
|
||||
sender: H160,
|
||||
at: H160,
|
||||
) -> Result<Vec<u8>, vm::Error> {
|
||||
let mut params = ActionParams::default();
|
||||
params.sender = sender;
|
||||
params.address = at;
|
||||
params.gas = U256::from(100_000_000);
|
||||
params.data = Some(arguments);
|
||||
params.code = Some(Arc::new(source));
|
||||
params.params_type = ParamsType::Separate;
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.sender = sender;
|
||||
params.address = at;
|
||||
params.gas = U256::from(100_000_000);
|
||||
params.data = Some(arguments);
|
||||
params.code = Some(Arc::new(source));
|
||||
params.params_type = ParamsType::Separate;
|
||||
|
||||
Ok(
|
||||
match wasm_interpreter(params).exec(ext).ok().expect("Wasm interpreter always calls with trap=false; trap never happens; qed")? {
|
||||
GasLeft::Known(_) => Vec::new(),
|
||||
GasLeft::NeedsReturn { data, .. } => data.to_vec(),
|
||||
}
|
||||
)
|
||||
Ok(
|
||||
match wasm_interpreter(params)
|
||||
.exec(ext)
|
||||
.ok()
|
||||
.expect("Wasm interpreter always calls with trap=false; trap never happens; qed")?
|
||||
{
|
||||
GasLeft::Known(_) => Vec::new(),
|
||||
GasLeft::NeedsReturn { data, .. } => data.to_vec(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn run_fixture(fixture: &Fixture) -> Vec<Fail> {
|
||||
let mut params = ActionParams::default();
|
||||
let mut params = ActionParams::default();
|
||||
|
||||
let source = match load_code(fixture.source.as_ref()) {
|
||||
Ok(code) => code,
|
||||
Err(e) => { return Fail::load(e); },
|
||||
};
|
||||
let source = match load_code(fixture.source.as_ref()) {
|
||||
Ok(code) => code,
|
||||
Err(e) => {
|
||||
return Fail::load(e);
|
||||
}
|
||||
};
|
||||
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
params.code = Some(Arc::new(
|
||||
if let Source::Constructor { ref arguments, ref sender, ref at, .. } = fixture.source {
|
||||
match construct(&mut ext, source, arguments.clone().into(), sender.clone().into(), at.clone().into()) {
|
||||
Ok(code) => code,
|
||||
Err(e) => { return Fail::runtime(e); }
|
||||
}
|
||||
} else {
|
||||
source
|
||||
}
|
||||
));
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
params.code = Some(Arc::new(
|
||||
if let Source::Constructor {
|
||||
ref arguments,
|
||||
ref sender,
|
||||
ref at,
|
||||
..
|
||||
} = fixture.source
|
||||
{
|
||||
match construct(
|
||||
&mut ext,
|
||||
source,
|
||||
arguments.clone().into(),
|
||||
sender.clone().into(),
|
||||
at.clone().into(),
|
||||
) {
|
||||
Ok(code) => code,
|
||||
Err(e) => {
|
||||
return Fail::runtime(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
source
|
||||
},
|
||||
));
|
||||
|
||||
if let Some(ref sender) = fixture.sender {
|
||||
params.sender = sender.clone().into();
|
||||
}
|
||||
if let Some(ref sender) = fixture.sender {
|
||||
params.sender = sender.clone().into();
|
||||
}
|
||||
|
||||
if let Some(ref address) = fixture.address {
|
||||
if let Source::Constructor { .. } = fixture.source {
|
||||
return Fail::nononformity(SpecNonconformity::Address);
|
||||
}
|
||||
if let Some(ref address) = fixture.address {
|
||||
if let Source::Constructor { .. } = fixture.source {
|
||||
return Fail::nononformity(SpecNonconformity::Address);
|
||||
}
|
||||
|
||||
params.address = address.clone().into();
|
||||
} else if let Source::Constructor { ref at, .. } = fixture.source {
|
||||
params.address = at.clone().into();
|
||||
}
|
||||
params.address = address.clone().into();
|
||||
} else if let Source::Constructor { ref at, .. } = fixture.source {
|
||||
params.address = at.clone().into();
|
||||
}
|
||||
|
||||
if let Some(gas_limit) = fixture.gas_limit {
|
||||
params.gas = U256::from(gas_limit);
|
||||
}
|
||||
if let Some(gas_limit) = fixture.gas_limit {
|
||||
params.gas = U256::from(gas_limit);
|
||||
}
|
||||
|
||||
if let Some(ref data) = fixture.payload {
|
||||
params.data = Some(data.clone().into())
|
||||
}
|
||||
if let Some(ref data) = fixture.payload {
|
||||
params.data = Some(data.clone().into())
|
||||
}
|
||||
|
||||
if let Some(value) = fixture.value {
|
||||
params.value = ActionValue::Transfer(value.clone().into())
|
||||
}
|
||||
if let Some(value) = fixture.value {
|
||||
params.value = ActionValue::Transfer(value.clone().into())
|
||||
}
|
||||
|
||||
if let Some(ref storage) = fixture.storage {
|
||||
for storage_entry in storage.iter() {
|
||||
let key: U256 = storage_entry.key.into();
|
||||
let val: U256 = storage_entry.value.into();
|
||||
ext.store.insert(key.into(), val.into());
|
||||
}
|
||||
}
|
||||
if let Some(ref storage) = fixture.storage {
|
||||
for storage_entry in storage.iter() {
|
||||
let key: U256 = storage_entry.key.into();
|
||||
let val: U256 = storage_entry.value.into();
|
||||
ext.store.insert(key.into(), val.into());
|
||||
}
|
||||
}
|
||||
|
||||
let interpreter = wasm_interpreter(params);
|
||||
let interpreter = wasm_interpreter(params);
|
||||
|
||||
let interpreter_return = match interpreter.exec(&mut ext).ok().expect("Wasm interpreter always calls with trap=false; trap never happens; qed") {
|
||||
Ok(ret) => ret,
|
||||
Err(e) => { return Fail::runtime(e); }
|
||||
};
|
||||
let (gas_left, result) = match interpreter_return {
|
||||
GasLeft::Known(gas) => { (gas, Vec::new()) },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
};
|
||||
let interpreter_return = match interpreter
|
||||
.exec(&mut ext)
|
||||
.ok()
|
||||
.expect("Wasm interpreter always calls with trap=false; trap never happens; qed")
|
||||
{
|
||||
Ok(ret) => ret,
|
||||
Err(e) => {
|
||||
return Fail::runtime(e);
|
||||
}
|
||||
};
|
||||
let (gas_left, result) = match interpreter_return {
|
||||
GasLeft::Known(gas) => (gas, Vec::new()),
|
||||
GasLeft::NeedsReturn {
|
||||
gas_left: gas,
|
||||
data: result,
|
||||
apply_state: _apply,
|
||||
} => (gas, result.to_vec()),
|
||||
};
|
||||
|
||||
let mut fails = Vec::new();
|
||||
let mut fails = Vec::new();
|
||||
|
||||
for assert in fixture.asserts.iter() {
|
||||
match *assert {
|
||||
Assert::Return(ref data) => {
|
||||
if &data[..] != &result[..] {
|
||||
fails.push(Fail::Return { expected: (&data[..]).to_vec(), actual: (&result[..]).to_vec() })
|
||||
}
|
||||
},
|
||||
Assert::UsedGas(gas) => {
|
||||
let used_gas = fixture.gas_limit.unwrap_or(0) - gas_left.low_u64();
|
||||
if gas != used_gas {
|
||||
fails.push(Fail::UsedGas { expected: gas, actual: used_gas });
|
||||
}
|
||||
},
|
||||
Assert::HasCall(ref locator) => {
|
||||
let mut found = false;
|
||||
for assert in fixture.asserts.iter() {
|
||||
match *assert {
|
||||
Assert::Return(ref data) => {
|
||||
if &data[..] != &result[..] {
|
||||
fails.push(Fail::Return {
|
||||
expected: (&data[..]).to_vec(),
|
||||
actual: (&result[..]).to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
Assert::UsedGas(gas) => {
|
||||
let used_gas = fixture.gas_limit.unwrap_or(0) - gas_left.low_u64();
|
||||
if gas != used_gas {
|
||||
fails.push(Fail::UsedGas {
|
||||
expected: gas,
|
||||
actual: used_gas,
|
||||
});
|
||||
}
|
||||
}
|
||||
Assert::HasCall(ref locator) => {
|
||||
let mut found = false;
|
||||
|
||||
for fake_call in ext.calls.iter() {
|
||||
let mut match_ = true;
|
||||
if let Some(ref data) = locator.data {
|
||||
if data.as_ref() != &fake_call.data[..] { match_ = false; }
|
||||
}
|
||||
for fake_call in ext.calls.iter() {
|
||||
let mut match_ = true;
|
||||
if let Some(ref data) = locator.data {
|
||||
if data.as_ref() != &fake_call.data[..] {
|
||||
match_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref code_addr) = locator.code_address {
|
||||
if fake_call.code_address.unwrap_or(H160::zero()) != code_addr.clone().into() { match_ = false }
|
||||
}
|
||||
if let Some(ref code_addr) = locator.code_address {
|
||||
if fake_call.code_address.unwrap_or(H160::zero())
|
||||
!= code_addr.clone().into()
|
||||
{
|
||||
match_ = false
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref sender) = locator.sender {
|
||||
if fake_call.sender_address.unwrap_or(H160::zero()) != sender.clone().into() { match_ = false }
|
||||
}
|
||||
if let Some(ref sender) = locator.sender {
|
||||
if fake_call.sender_address.unwrap_or(H160::zero()) != sender.clone().into()
|
||||
{
|
||||
match_ = false
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref receiver) = locator.receiver {
|
||||
if fake_call.receive_address.unwrap_or(H160::zero()) != receiver.clone().into() { match_ = false }
|
||||
}
|
||||
if let Some(ref receiver) = locator.receiver {
|
||||
if fake_call.receive_address.unwrap_or(H160::zero())
|
||||
!= receiver.clone().into()
|
||||
{
|
||||
match_ = false
|
||||
}
|
||||
}
|
||||
|
||||
if match_ {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if match_ {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
fails.push(Fail::NoCall(locator.clone()))
|
||||
}
|
||||
},
|
||||
Assert::HasStorage(ref storage_entry) => {
|
||||
let expected_storage_key: H256 = storage_entry.key.clone().into();
|
||||
let expected_storage_value: H256 = storage_entry.value.clone().into();
|
||||
let val = ext.store.get(&expected_storage_key);
|
||||
if !found {
|
||||
fails.push(Fail::NoCall(locator.clone()))
|
||||
}
|
||||
}
|
||||
Assert::HasStorage(ref storage_entry) => {
|
||||
let expected_storage_key: H256 = storage_entry.key.clone().into();
|
||||
let expected_storage_value: H256 = storage_entry.value.clone().into();
|
||||
let val = ext.store.get(&expected_storage_key);
|
||||
|
||||
if let Some(val) = val {
|
||||
if val != &expected_storage_value {
|
||||
fails.push(Fail::StorageMismatch {
|
||||
key: expected_storage_key,
|
||||
expected: expected_storage_value,
|
||||
actual: Some(val.clone())
|
||||
})
|
||||
}
|
||||
} else {
|
||||
fails.push(Fail::StorageMismatch {
|
||||
key: expected_storage_key,
|
||||
expected: expected_storage_value,
|
||||
actual: None,
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
fails
|
||||
if let Some(val) = val {
|
||||
if val != &expected_storage_value {
|
||||
fails.push(Fail::StorageMismatch {
|
||||
key: expected_storage_key,
|
||||
expected: expected_storage_value,
|
||||
actual: Some(val.clone()),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
fails.push(Fail::StorageMismatch {
|
||||
key: expected_storage_key,
|
||||
expected: expected_storage_value,
|
||||
actual: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fails
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user