From 05f7e85d301c8400df7635c0236ca845d0237670 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 3 Dec 2015 05:44:35 +0100 Subject: [PATCH] rlp tests, the beginning --- json-tests/json/rlp/README.md | 39 +++++++++++++++++++++++++ json-tests/json/rlp/catdog.json | 18 ++++++++++++ json-tests/src/lib.rs | 2 ++ json-tests/src/rlp.rs | 52 +++++++++++++++++++++++++++++++++ json-tests/src/trie.rs | 33 ++++----------------- json-tests/src/util.rs | 8 +++++ src/trie.rs | 2 +- 7 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 json-tests/json/rlp/README.md create mode 100644 json-tests/json/rlp/catdog.json create mode 100644 json-tests/src/rlp.rs create mode 100644 json-tests/src/util.rs diff --git a/json-tests/json/rlp/README.md b/json-tests/json/rlp/README.md new file mode 100644 index 000000000..89cb072c7 --- /dev/null +++ b/json-tests/json/rlp/README.md @@ -0,0 +1,39 @@ +# Rlp tests guideline + +Rlp can be tested in various ways. It can encode/decode a value or an array of values. Let's start with encoding. + +Each operation must have field: + +- `operation` - `append`, `append_list`, `append_empty` or `append_raw` + +Additionally `append` and `append_raw` must additionally define a `value` field: + +- `value` - data + +Also `append_raw` and `append_list` requires `len` field + +- `len` - integer + +### Encoding Test Example + +```json +{ + "input": + [ + { + "operation": "append_list", + "len": 2 + }, + { + "operation": "append", + "value": "cat" + }, + { + "operation": "append", + "value": "dog" + } + ] + "output": "0xc88363617183646f67" +} +``` + diff --git a/json-tests/json/rlp/catdog.json b/json-tests/json/rlp/catdog.json new file mode 100644 index 000000000..352b24892 --- /dev/null +++ b/json-tests/json/rlp/catdog.json @@ -0,0 +1,18 @@ +{ + "input": + [ + { + "operation": "append_list", + "len": 2 + }, + { + "operation": "append", + "value": "cat" + }, + { + "operation": "append", + "value": "dog" + } + ] + "output": "0xc88363617183646f67" +} diff --git a/json-tests/src/lib.rs b/json-tests/src/lib.rs index 8a800e8f9..0fb1b091a 100644 --- a/json-tests/src/lib.rs +++ b/json-tests/src/lib.rs @@ -8,7 +8,9 @@ use std::fs::File; use glob::glob; use rustc_serialize::*; +mod util; pub mod trie; +pub mod rlp; pub trait JsonTest: Sized { type Input; diff --git a/json-tests/src/rlp.rs b/json-tests/src/rlp.rs new file mode 100644 index 000000000..bf6131b5b --- /dev/null +++ b/json-tests/src/rlp.rs @@ -0,0 +1,52 @@ +//! json rlp tests +use rustc_serialize::*; +use super::{JsonTest, JsonLoader}; +use util::*; + +pub enum Operation { + Append(Vec), + AppendList(usize), + AppendRaw(Vec, usize), + AppendEmpty +} + +impl Into for json::Json { + fn into(self) -> Operation { + let obj = self.as_object().unwrap(); + match obj["operation"].as_string().unwrap().as_ref() { + "append" => Operation::Append(hex_or_string(obj["value"].as_string().unwrap())), + "append_list" => Operation::AppendList(obj["len"].as_u64().unwrap() as usize), + "append_raw" => Operation::AppendRaw(hex_or_string(obj["value"].as_string().unwrap()), obj["len"].as_u64().unwrap() as usize), + "append_empty" => Operation::AppendEmpty, + other => { panic!("Unsupported opertation: {}", other); } + } + } +} + +pub struct RlpStreamTest { + loader: JsonLoader +} + +impl JsonTest for RlpStreamTest { + type Input = Vec; + type Output = Vec; + + fn new(data: &[u8]) -> Self { + RlpStreamTest { + loader: JsonLoader::new(data) + } + } + + fn input(&self) -> Self::Input { + self.loader.input().as_array().unwrap() + .iter() + .cloned() + .map(|i| i.into()) + .collect() + } + + fn output(&self) -> Self::Output { + hex_or_string(self.loader.output().as_string().unwrap()) + } +} + diff --git a/json-tests/src/trie.rs b/json-tests/src/trie.rs index 827bf8c9a..bc65e9db9 100644 --- a/json-tests/src/trie.rs +++ b/json-tests/src/trie.rs @@ -1,27 +1,12 @@ //! json trie tests use std::collections::HashMap; use rustc_serialize::*; -use rustc_serialize::hex::FromHex; use super::{JsonTest, JsonLoader}; - -enum OperationType { - Insert, - Remove -} - -impl Decodable for OperationType { - fn decode(d: &mut D) -> Result where D: Decoder { - match try!(String::decode(d)).as_ref() { - "insert" => Ok(OperationType::Insert), - "remove" => Ok(OperationType::Remove), - other => panic!("invalid operation type: {}", other) - } - } -} +use util::*; #[derive(RustcDecodable)] struct RawOperation { - operation: OperationType, + operation: String, key: String, value: Option } @@ -31,18 +16,12 @@ pub enum Operation { Remove(Vec) } -fn hex_or_string(s: &str) -> Vec { - match s.starts_with("0x") { - true => s[2..].from_hex().unwrap(), - false => From::from(s) - } -} - impl Into for RawOperation { fn into(self) -> Operation { - match self.operation { - OperationType::Insert => Operation::Insert(hex_or_string(&self.key), hex_or_string(&self.value.unwrap())), - OperationType::Remove => Operation::Remove(hex_or_string(&self.key)) + match self.operation.as_ref() { + "insert" => Operation::Insert(hex_or_string(&self.key), hex_or_string(&self.value.unwrap())), + "remove" => Operation::Remove(hex_or_string(&self.key)), + other => panic!("invalid operation type: {}", other) } } } diff --git a/json-tests/src/util.rs b/json-tests/src/util.rs new file mode 100644 index 000000000..f9d1e4eab --- /dev/null +++ b/json-tests/src/util.rs @@ -0,0 +1,8 @@ +use rustc_serialize::hex::FromHex; + +pub fn hex_or_string(s: &str) -> Vec { + match s.starts_with("0x") { + true => s[2..].from_hex().unwrap(), + false => From::from(s) + } +} diff --git a/src/trie.rs b/src/trie.rs index 081fcfcff..9dd12d8a5 100644 --- a/src/trie.rs +++ b/src/trie.rs @@ -742,7 +742,7 @@ impl Trie for TrieDB { #[cfg(test)] mod tests { extern crate json_tests; - use self::json_tests::*; + use self::json_tests::{trie, execute_tests_from_directory}; use rustc_serialize::hex::FromHex; use triehash::*; use hash::*;