Merge pull request #7147 from paritytech/pwasm-run
WASM test runner utility upgrade
This commit is contained in:
commit
c544c3e518
@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"caption": "Sample test",
|
"caption": "Sample test",
|
||||||
"wasm": "./res/sample1.wasm",
|
"source": "./res/sample1.wasm",
|
||||||
"address": "0x1000000000000000000000000000000000000001",
|
"address": "0x1000000000000000000000000000000000000001",
|
||||||
"sender": "0x1000000000000000000000000000000000000002",
|
"sender": "0x1000000000000000000000000000000000000002",
|
||||||
"value": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
"value": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
@ -21,11 +21,25 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"caption": "Keccak test",
|
"caption": "Keccak test",
|
||||||
"wasm": "./res/sample2.wasm",
|
"source": "./res/sample2.wasm",
|
||||||
"payload": "0x736f6d657468696e67",
|
"payload": "0x736f6d657468696e67",
|
||||||
"gasLimit": 100000,
|
"gasLimit": 100000,
|
||||||
"asserts": [
|
"asserts": [
|
||||||
{ "Return": "0x68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87" }
|
{ "Return": "0x68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87" }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"caption": "Token total supply",
|
||||||
|
"source": {
|
||||||
|
"constructor": "./res/sample3.wasm",
|
||||||
|
"sender": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
||||||
|
"at": "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||||
|
"arguments": "0x0000000000000000000000000000000000000000000000000000000010000000"
|
||||||
|
},
|
||||||
|
"payload": "0x18160ddd",
|
||||||
|
"gasLimit": 100000,
|
||||||
|
"asserts": [
|
||||||
|
{ "Return": "0x0000000000000000000000000000000000000000000000000000000010000000" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
BIN
ethcore/wasm/run/res/sample3.wasm
Normal file
BIN
ethcore/wasm/run/res/sample3.wasm
Normal file
Binary file not shown.
@ -3,11 +3,32 @@ use ethjson::uint::Uint;
|
|||||||
use ethjson::hash::{Address, H256};
|
use ethjson::hash::{Address, H256};
|
||||||
use ethjson::bytes::Bytes;
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Source {
|
||||||
|
pub fn as_ref(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
Source::Raw(ref r) => r.as_ref(),
|
||||||
|
Source::Constructor { ref source, .. } => source.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Fixture {
|
pub struct Fixture {
|
||||||
pub caption: Cow<'static, String>,
|
pub caption: Cow<'static, String>,
|
||||||
#[serde(rename="wasm")]
|
pub source: Source,
|
||||||
pub wasm_file: Cow<'static, String>,
|
|
||||||
pub address: Option<Address>,
|
pub address: Option<Address>,
|
||||||
pub sender: Option<Address>,
|
pub sender: Option<Address>,
|
||||||
pub value: Option<Uint>,
|
pub value: Option<Uint>,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use fixture::{Fixture, Assert, CallLocator};
|
use fixture::{Fixture, Assert, CallLocator, Source};
|
||||||
use wasm::WasmInterpreter;
|
use wasm::WasmInterpreter;
|
||||||
use vm::{self, Vm, GasLeft, ActionParams, ActionValue};
|
use vm::{self, Vm, GasLeft, ActionParams, ActionValue, ParamsType};
|
||||||
use vm::tests::FakeExt;
|
use vm::tests::FakeExt;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::{fs, path, fmt};
|
use std::{fs, path, fmt};
|
||||||
@ -19,6 +19,11 @@ fn wasm_interpreter() -> WasmInterpreter {
|
|||||||
WasmInterpreter::new().expect("wasm interpreter to create without errors")
|
WasmInterpreter::new().expect("wasm interpreter to create without errors")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SpecNonconformity {
|
||||||
|
Address,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Fail {
|
pub enum Fail {
|
||||||
Return { expected: Vec<u8>, actual: Vec<u8> },
|
Return { expected: Vec<u8>, actual: Vec<u8> },
|
||||||
@ -27,6 +32,7 @@ pub enum Fail {
|
|||||||
Load(io::Error),
|
Load(io::Error),
|
||||||
NoCall(CallLocator),
|
NoCall(CallLocator),
|
||||||
StorageMismatch { key: H256, expected: H256, actual: Option<H256> },
|
StorageMismatch { key: H256, expected: H256, actual: Option<H256> },
|
||||||
|
Nonconformity(SpecNonconformity)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fail {
|
impl Fail {
|
||||||
@ -37,6 +43,10 @@ impl Fail {
|
|||||||
fn load(err: io::Error) -> Vec<Fail> {
|
fn load(err: io::Error) -> Vec<Fail> {
|
||||||
vec![Fail::Load(err)]
|
vec![Fail::Load(err)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nononformity(kind: SpecNonconformity) -> Vec<Fail> {
|
||||||
|
vec![Fail::Nonconformity(kind)]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Fail {
|
impl fmt::Display for Fail {
|
||||||
@ -52,6 +62,7 @@ impl fmt::Display for Fail {
|
|||||||
actual.to_hex(),
|
actual.to_hex(),
|
||||||
actual.len()
|
actual.len()
|
||||||
),
|
),
|
||||||
|
|
||||||
UsedGas { expected, actual } =>
|
UsedGas { expected, actual } =>
|
||||||
write!(f, "Expected to use gas: {}, but got actual gas used: {}", expected, actual),
|
write!(f, "Expected to use gas: {}, but got actual gas used: {}", expected, actual),
|
||||||
|
|
||||||
@ -80,22 +91,69 @@ impl fmt::Display for Fail {
|
|||||||
key.as_ref().to_vec().to_hex(),
|
key.as_ref().to_vec().to_hex(),
|
||||||
expected.as_ref().to_vec().to_hex(),
|
expected.as_ref().to_vec().to_hex(),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
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,
|
||||||
|
) -> 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;
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
match wasm_interpreter().exec(params, ext)? {
|
||||||
|
GasLeft::Known(_) => Vec::new(),
|
||||||
|
GasLeft::NeedsReturn { data, .. } => data.to_vec(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_fixture(fixture: &Fixture) -> Vec<Fail> {
|
pub fn run_fixture(fixture: &Fixture) -> Vec<Fail> {
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
|
|
||||||
params.code = Some(Arc::new(
|
let source = match load_code(fixture.source.as_ref()) {
|
||||||
match load_code(fixture.wasm_file.as_ref()) {
|
|
||||||
Ok(code) => code,
|
Ok(code) => code,
|
||||||
Err(e) => { return Fail::load(e); },
|
Err(e) => { return Fail::load(e); },
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut ext = FakeExt::new();
|
||||||
|
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 address) = fixture.address {
|
if let Some(ref address) = fixture.address {
|
||||||
|
if let Source::Constructor { .. } = fixture.source {
|
||||||
|
return Fail::nononformity(SpecNonconformity::Address);
|
||||||
|
}
|
||||||
|
|
||||||
params.address = address.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 {
|
if let Some(gas_limit) = fixture.gas_limit {
|
||||||
@ -110,7 +168,6 @@ pub fn run_fixture(fixture: &Fixture) -> Vec<Fail> {
|
|||||||
params.value = ActionValue::Transfer(value.clone().into())
|
params.value = ActionValue::Transfer(value.clone().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ext = FakeExt::new();
|
|
||||||
if let Some(ref storage) = fixture.storage {
|
if let Some(ref storage) = fixture.storage {
|
||||||
for storage_entry in storage.iter() {
|
for storage_entry in storage.iter() {
|
||||||
let key: U256 = storage_entry.key.into();
|
let key: U256 = storage_entry.key.into();
|
||||||
|
@ -32,8 +32,8 @@ lazy_static! {
|
|||||||
builder.parse(&log);
|
builder.parse(&log);
|
||||||
}
|
}
|
||||||
|
|
||||||
if builder.init().is_ok() {
|
if !builder.init().is_ok() {
|
||||||
println!("logger initialized");
|
println!("logger initialization failed!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user