mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 23:20:18 +00:00
Refactor tests (#104)
This commit is contained in:
parent
b96ee517f3
commit
7cb636a02e
@ -26,7 +26,7 @@ jobs:
|
||||
(cd air-interpreter; marine build --features marine)
|
||||
|
||||
# build Wasm binaries for tests
|
||||
(cd air/tests/; ./build_test_binaries.sh)
|
||||
(cd air/tests/test_module/integration; ./build_test_binaries.sh)
|
||||
|
||||
cargo fmt --all -- --check --color always
|
||||
cargo check
|
||||
|
2
.github/workflows/publish_interpreter.yml
vendored
2
.github/workflows/publish_interpreter.yml
vendored
@ -133,7 +133,7 @@ jobs:
|
||||
run: |
|
||||
PATH="~/.cargo/bin:$PATH"
|
||||
(
|
||||
cd interpreter
|
||||
cd air-interpreter
|
||||
toml set Cargo.toml package.version "${{ env.FINAL_VERSION }}" | sponge Cargo.toml
|
||||
)
|
||||
(
|
||||
|
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -84,8 +84,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "air-test-utils"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"air",
|
||||
"avm-server",
|
||||
"fluence",
|
||||
"serde_json",
|
||||
|
@ -11,8 +11,8 @@ members = [
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"air/tests/security_tetraplets/auth_module",
|
||||
"air/tests/security_tetraplets/log_storage",
|
||||
"air/tests/test_module/integration/security_tetraplets/auth_module",
|
||||
"air/tests/test_module/integration/security_tetraplets/log_storage",
|
||||
"crates/air-interpreter-wasm",
|
||||
]
|
||||
|
||||
|
@ -7,6 +7,7 @@ edition = "2018"
|
||||
[lib]
|
||||
name = "air"
|
||||
path = "src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
air-parser = { path = "../crates/air-parser" }
|
||||
|
@ -18,6 +18,7 @@ mod executed_state;
|
||||
|
||||
pub use executed_state::CallResult;
|
||||
pub use executed_state::ExecutedState;
|
||||
pub use executed_state::ParResult;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
@ -20,6 +20,10 @@ use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ParResult(pub usize, pub usize);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CallResult {
|
||||
@ -36,17 +40,23 @@ pub enum CallResult {
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecutedState {
|
||||
Par(usize, usize),
|
||||
Par(ParResult),
|
||||
Call(CallResult),
|
||||
}
|
||||
|
||||
impl ExecutedState {
|
||||
pub fn par(left: usize, right: usize) -> Self {
|
||||
Self::Par(ParResult(left, right))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ExecutedState {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use CallResult::*;
|
||||
use ExecutedState::*;
|
||||
|
||||
match self {
|
||||
Par(left, right) => write!(f, "Par({}, {})", left, right),
|
||||
Par(ParResult(left, right)) => write!(f, "Par({}, {})", left, right),
|
||||
Call(RequestSentBy(peer_id)) => write!(f, "RequestSentBy({})", peer_id),
|
||||
Call(Executed(result)) => write!(f, "Executed({:?})", result),
|
||||
Call(CallServiceFailed(ret_code, err_msg)) => write!(f, "CallServiceFailed({}, {})", ret_code, err_msg),
|
||||
|
@ -22,6 +22,7 @@ pub mod execution_trace {
|
||||
pub use super::execution_trace_context::ExecutedState;
|
||||
pub use super::execution_trace_context::ExecutionTrace;
|
||||
pub(crate) use super::execution_trace_context::ExecutionTraceCtx;
|
||||
pub use super::execution_trace_context::ParResult;
|
||||
}
|
||||
|
||||
pub(crate) mod execution {
|
||||
|
@ -65,178 +65,3 @@ fn set_last_error<'i>(
|
||||
exec_ctx.last_error = Some(last_error);
|
||||
exec_ctx.last_error_could_be_set = false;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contexts::execution_trace::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
use air_test_utils::unit_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
// Check that %init_peer_id% alias works correctly (by comparing result with it and explicit peer id).
|
||||
// Additionally, check that empty string for data does the same as empty call path.
|
||||
#[test]
|
||||
fn current_peer_id_call() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let vm_peer_id = String::from("test_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), vm_peer_id.clone());
|
||||
|
||||
let service_id = String::from("local_service_id");
|
||||
let function_name = String::from("local_fn_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(call %init_peer_id% ("{}" "{}") [] result_name)
|
||||
"#,
|
||||
service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, vm_peer_id.clone(), script.clone(), "[]", "[]");
|
||||
let call_path: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
let executed_call_state = Call(Executed(Rc::new(JValue::String(String::from("test")))));
|
||||
assert_eq!(call_path.len(), 1);
|
||||
assert_eq!(call_path[0], executed_call_state);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(call "{}" ("{}" "{}") [] result_name)
|
||||
"#,
|
||||
vm_peer_id, service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||
|
||||
// test that empty string for data works
|
||||
let res_with_empty_string = call_vm!(vm, "asd", script, "", "");
|
||||
assert_eq!(res_with_empty_string, res);
|
||||
}
|
||||
|
||||
// Check that specifying remote peer id in call will result its appearing in next_peer_pks.
|
||||
#[test]
|
||||
fn remote_peer_id_call() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let some_local_peer_id = String::from("some_local_peer_id");
|
||||
let mut vm = create_avm(echo_string_call_service(), some_local_peer_id.clone());
|
||||
|
||||
let remote_peer_id = String::from("some_remote_peer_id");
|
||||
let script = format!(
|
||||
r#"(call "{}" ("local_service_id" "local_fn_name") ["arg"] result_name)"#,
|
||||
remote_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let call_path: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
assert_eq!(call_path.len(), 1);
|
||||
assert_eq!(call_path[0], Call(RequestSentBy(some_local_peer_id)));
|
||||
assert_eq!(res.next_peer_pks, vec![remote_peer_id]);
|
||||
}
|
||||
|
||||
// Check that setting variables works as expected.
|
||||
#[test]
|
||||
fn variables() {
|
||||
let mut vm = create_avm(unit_call_service(), "remote_peer_id");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#""remote_peer_id""#), "set_variable");
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("some_service_id" "local_fn_name") [] remote_peer_id)
|
||||
(call remote_peer_id ("some_service_id" "local_fn_name") [] result_name)
|
||||
)
|
||||
"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
// Check that duplicate variables are impossible.
|
||||
#[test]
|
||||
fn duplicate_variables() {
|
||||
let mut vm = create_avm(unit_call_service(), "some_peer_id");
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "some_peer_id" ("some_service_id" "local_fn_name") [] modules)
|
||||
(call "some_peer_id" ("some_service_id" "local_fn_name") [] modules)
|
||||
)
|
||||
"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", "");
|
||||
|
||||
assert_eq!(res.ret_code, 1005);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
// Check that string literals can be used as call parameters.
|
||||
#[test]
|
||||
fn string_parameters() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let call_service: CallServiceClosure = Box::new(|_, args| -> Option<IValue> {
|
||||
let arg = match &args[2] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(arg.clone())]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let vm_peer_id = String::from("A");
|
||||
let mut vm = create_avm(call_service, vm_peer_id.clone());
|
||||
|
||||
let set_variable_vm_peer_id = String::from("set_variable");
|
||||
let mut set_variable_vm = create_avm(
|
||||
set_variable_call_service(r#""arg3_value""#),
|
||||
set_variable_vm_peer_id.clone(),
|
||||
);
|
||||
|
||||
let service_id = String::from("some_service_id");
|
||||
let function_name = String::from("local_fn_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("{}" "{}") [] arg3)
|
||||
(call "{}" ("{}" "{}") ["arg1" "arg2" arg3] result)
|
||||
)
|
||||
"#,
|
||||
set_variable_vm_peer_id, service_id, function_name, vm_peer_id, service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
let call_path: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
assert_eq!(call_path.len(), 2);
|
||||
assert_eq!(
|
||||
call_path[1],
|
||||
Call(Executed(Rc::new(JValue::Array(vec![
|
||||
JValue::String(String::from("arg1")),
|
||||
JValue::String(String::from("arg2")),
|
||||
JValue::String(String::from("arg3_value")),
|
||||
]))))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -153,402 +153,3 @@ fn cleanup_variables(exec_ctx: &mut ExecutionCtx<'_>, iterator: &str) {
|
||||
exec_ctx.data_cache.extend(upper_fold_values);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contexts::execution_trace::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_number_call_service;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
use air_test_utils::AVMError;
|
||||
use air_test_utils::InterpreterOutcome;
|
||||
|
||||
use serde_json::json;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn lfold() {
|
||||
env_logger::try_init().ok();
|
||||
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let lfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", lfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", lfold, "[]", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 6);
|
||||
assert_eq!(res[0], Call(Executed(Rc::new(json!(["1", "2", "3", "4", "5"])))));
|
||||
|
||||
for i in 1..=5 {
|
||||
assert_eq!(res[i], Call(Executed(Rc::new(JValue::Number(i.into())))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rfold() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let rfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(next i)
|
||||
(call "A" ("" "") [i] $acc)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", rfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", rfold, "[]", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 6);
|
||||
assert_eq!(res[0], Call(Executed(Rc::new(json!(["1", "2", "3", "4", "5"])))));
|
||||
|
||||
for i in 1..=5 {
|
||||
assert_eq!(res[i], Call(Executed(Rc::new(JValue::Number((6 - i).into())))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inner_fold() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable1)
|
||||
(call "set_variable" ("" "") [] Iterable2)
|
||||
)
|
||||
(fold Iterable1 i
|
||||
(seq
|
||||
(fold Iterable2 j
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", script, "[]", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 27);
|
||||
assert_eq!(res[0], Call(Executed(Rc::new(json!(["1", "2", "3", "4", "5"])))));
|
||||
assert_eq!(res[1], Call(Executed(Rc::new(json!(["1", "2", "3", "4", "5"])))));
|
||||
|
||||
for i in 1..=5 {
|
||||
for j in 1..=5 {
|
||||
assert_eq!(
|
||||
res[1 + 5 * (i - 1) + j],
|
||||
Call(Executed(Rc::new(JValue::Number(i.into()))))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inner_fold_with_same_iterator() {
|
||||
let mut vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable1)
|
||||
(call "set_variable" ("" "") [] Iterable2)
|
||||
)
|
||||
(fold Iterable1 i
|
||||
(seq
|
||||
(fold Iterable2 i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
assert_eq!(res.ret_code, 1012);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_fold() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"[]"#), "set_variable");
|
||||
|
||||
let empty_fold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", empty_fold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", empty_fold, "[]", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 1);
|
||||
assert_eq!(res[0], Call(Executed(Rc::new(json!([])))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_fold_json_path() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"{ "messages": [] }"#), "set_variable");
|
||||
|
||||
let empty_fold = r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] messages)
|
||||
(fold messages.$.messages! i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#;
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", empty_fold, "", "");
|
||||
let res = call_vm!(vm, "", empty_fold, "", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 1);
|
||||
assert_eq!(res[0], Call(Executed(Rc::new(json!({ "messages": [] })))));
|
||||
}
|
||||
|
||||
// Check that fold works with the join behaviour without hanging up.
|
||||
#[test]
|
||||
fn fold_with_join() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
|
||||
let fold_with_join = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable)
|
||||
(par
|
||||
(call "unknown_peer" ("" "") [] lazy_def_variable)
|
||||
(fold iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [lazy_def_variable.$.hash!] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", &fold_with_join, "", "");
|
||||
let res = call_vm!(vm, "", fold_with_join, "", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_path() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(
|
||||
set_variable_call_service(r#"{ "array": ["1","2","3","4","5"] }"#),
|
||||
"set_variable",
|
||||
);
|
||||
|
||||
let lfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable)
|
||||
(fold iterable.$.array! i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", lfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", lfold, "[]", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 6);
|
||||
assert_eq!(
|
||||
res[0],
|
||||
Call(Executed(Rc::new(json!({ "array": ["1", "2", "3", "4", "5"] }))))
|
||||
);
|
||||
|
||||
for i in 1..=5 {
|
||||
assert_eq!(res[i], Call(Executed(Rc::new(JValue::Number(i.into())))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shadowing() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let mut set_variables_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
let mut vm_a = create_avm(echo_string_call_service(), "A");
|
||||
let mut vm_b = create_avm(echo_string_call_service(), "B");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable1)
|
||||
(call "set_variable" ("" "") [] iterable2)
|
||||
)
|
||||
(fold iterable1 i
|
||||
(seq
|
||||
(seq
|
||||
(fold iterable2 j
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") [i] local_j)
|
||||
(call "B" ("" "") [local_j])
|
||||
)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(par
|
||||
(call "A" ("" "") [i] local_i)
|
||||
(call "B" ("" "") [i])
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variables_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script, "[]", res.data);
|
||||
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 12);
|
||||
for i in 2..11 {
|
||||
assert!(matches!(res[i], Call(Executed(_))) || matches!(res[i], Par(..)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shadowing_scope() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
fn execute_script(script: String) -> Result<InterpreterOutcome, AVMError> {
|
||||
let mut set_variables_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
let mut vm_a = create_avm(echo_string_call_service(), "A");
|
||||
let mut vm_b = create_avm(echo_string_call_service(), "B");
|
||||
|
||||
let res = call_vm!(set_variables_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
|
||||
vm_a.call_with_prev_data("", script, "[]", res.data)
|
||||
}
|
||||
|
||||
let variable_shadowing_script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable1)
|
||||
(call "set_variable" ("" "") [] iterable2)
|
||||
)
|
||||
(fold iterable1 i
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") ["value"] local_j)
|
||||
(seq
|
||||
(fold iterable2 j
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") [i] local_j)
|
||||
(call "B" ("" "") [local_j])
|
||||
)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(call "A" ("" "") [local_j])
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = execute_script(variable_shadowing_script).unwrap();
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 11);
|
||||
for i in 0..10 {
|
||||
assert!(matches!(res[i], Call(Executed(_))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,253 +40,3 @@ impl<'i> super::ExecutableInstruction<'i> for Match<'i> {
|
||||
self.instruction.execute(exec_ctx, trace_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contexts::execution_trace::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::{call_vm, set_variable_call_service};
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn match_equal() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(xor
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_1")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_not_equal() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(xor
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_2")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_string() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(xor
|
||||
(match value_1 "value_1"
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_1")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_init_peer_id() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["{1}"] value_1)
|
||||
(xor
|
||||
(match value_1 %init_peer_id%
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, local_peer_id, script.clone(), "", "");
|
||||
let res = call_vm!(vm, local_peer_id, script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_1")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_equal_numbers() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = "
|
||||
(xor
|
||||
(match 1 1
|
||||
(null)
|
||||
)
|
||||
(null)
|
||||
)";
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", "");
|
||||
assert_eq!(res.ret_code, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_without_xor() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script.clone(), "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1015);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1015);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_two_xors() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(
|
||||
set_variable_call_service(serde_json::json!(false).to_string()),
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let local_peer_id_2 = "local_peer_id_2";
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("getDataSrv" "condition") [] condition)
|
||||
(call "{0}" ("getDataSrv" "relay") [] relay)
|
||||
)
|
||||
(xor
|
||||
(match condition true
|
||||
(call "{0}" ("println" "print") ["it is true"])
|
||||
)
|
||||
(call "{1}" ("println" "print") ["it is false"])
|
||||
)
|
||||
)
|
||||
(call "{0}" ("errorHandlingSrv" "error") [%last_error%])
|
||||
)
|
||||
"#,
|
||||
local_peer_id, local_peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "", "");
|
||||
let mut trace: ExecutionTrace =
|
||||
serde_json::from_slice(&res.data).expect("the interpreter should provide correct trace");
|
||||
|
||||
let expected_executed_call_result = Call(RequestSentBy(local_peer_id.to_string()));
|
||||
assert_eq!(res.ret_code, 0);
|
||||
assert_eq!(trace.pop_back().unwrap(), expected_executed_call_result);
|
||||
}
|
||||
}
|
||||
|
@ -40,202 +40,3 @@ impl<'i> super::ExecutableInstruction<'i> for MisMatch<'i> {
|
||||
self.instruction.execute(exec_ctx, trace_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contexts::execution_trace::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn mismatch_equal() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(xor
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_2")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_not_equal() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(xor
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_1")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_with_string() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(xor
|
||||
(mismatch value_1 "value_1"
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_2")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_without_xor() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script.clone(), "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1016);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1016);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_with_two_xors() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(
|
||||
set_variable_call_service(serde_json::json!(false).to_string()),
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let local_peer_id_2 = "local_peer_id_2";
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("getDataSrv" "condition") [] condition)
|
||||
(call "{0}" ("getDataSrv" "relay") [] relay)
|
||||
)
|
||||
(xor
|
||||
(mismatch condition true
|
||||
(call "{1}" ("println" "print") ["it is false"])
|
||||
)
|
||||
(call "{0}" ("println" "print") ["it is true"])
|
||||
)
|
||||
)
|
||||
(call "{0}" ("errorHandlingSrv" "error") [%last_error%])
|
||||
)
|
||||
"#,
|
||||
local_peer_id, local_peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "", "");
|
||||
let mut trace: ExecutionTrace =
|
||||
serde_json::from_slice(&res.data).expect("the interpreter should provide correct trace");
|
||||
|
||||
let expected_executed_call_result = Call(RequestSentBy(local_peer_id.to_string()));
|
||||
assert_eq!(res.ret_code, 0);
|
||||
assert_eq!(trace.pop_back().unwrap(), expected_executed_call_result);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use super::ExecutionResult;
|
||||
use super::ExecutionTraceCtx;
|
||||
use super::Instruction;
|
||||
use crate::contexts::execution_trace::ExecutedState;
|
||||
use crate::contexts::execution_trace::ParResult;
|
||||
use crate::log_instruction;
|
||||
use crate::log_targets::EXECUTED_STATE_CHANGING;
|
||||
|
||||
@ -48,7 +49,7 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> {
|
||||
let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(trace_ctx)?;
|
||||
|
||||
let par_pos = trace_ctx.new_trace.len();
|
||||
trace_ctx.new_trace.push_back(ExecutedState::Par(0, 0));
|
||||
trace_ctx.new_trace.push_back(ExecutedState::par(0, 0));
|
||||
|
||||
// execute a left subtree of this par
|
||||
execute_subtree(&self.0, left_subtree_size, exec_ctx, trace_ctx, par_pos, Left)?;
|
||||
@ -82,7 +83,7 @@ fn extract_subtree_sizes(trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<(
|
||||
|
||||
// unwrap is safe here because of length's been checked
|
||||
match trace_ctx.current_trace.pop_front().unwrap() {
|
||||
ExecutedState::Par(left, right) => Ok((left, right)),
|
||||
ExecutedState::Par(ParResult(left, right)) => Ok((left, right)),
|
||||
state => crate::exec_err!(InvalidExecutedState(String::from("par"), state)),
|
||||
}
|
||||
}
|
||||
@ -146,7 +147,7 @@ fn update_par_state(
|
||||
// unwrap is safe here, because this par is added at the beginning of this par instruction.
|
||||
let par_state = trace_ctx.new_trace.get_mut(current_par_pos).unwrap();
|
||||
match par_state {
|
||||
ExecutedState::Par(left, right) => {
|
||||
ExecutedState::Par(ParResult(left, right)) => {
|
||||
if let SubtreeType::Left = subtree_type {
|
||||
*left = new_subtree_size;
|
||||
} else {
|
||||
@ -163,52 +164,3 @@ fn update_par_state(
|
||||
_ => unreachable!("current_pas_pos must point to a par state"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::unit_call_service;
|
||||
|
||||
#[test]
|
||||
fn par_remote_remote() {
|
||||
use std::collections::HashSet;
|
||||
|
||||
let mut vm = create_avm(unit_call_service(), "");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(par
|
||||
(call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let mut res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
let peers_result: HashSet<_> = res.next_peer_pks.drain(..).collect();
|
||||
let peers_right: HashSet<_> =
|
||||
maplit::hashset!(String::from("remote_peer_id_1"), String::from("remote_peer_id_2"));
|
||||
|
||||
assert_eq!(peers_result, peers_right);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn par_local_remote() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(par
|
||||
(call "{}" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_2")]);
|
||||
}
|
||||
}
|
||||
|
@ -35,50 +35,3 @@ impl<'i> super::ExecutableInstruction<'i> for Seq<'i> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::unit_call_service;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn seq_remote_remote() {
|
||||
let mut vm = create_avm(unit_call_service(), "");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_1")]);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", json!([{"call": {"executed": ""}}]).to_string());
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_2")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn seq_local_remote() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let remote_peer_id = String::from("remote_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "{}" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
local_peer_id, remote_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
assert_eq!(res.next_peer_pks, vec![remote_peer_id]);
|
||||
}
|
||||
}
|
||||
|
@ -56,206 +56,3 @@ fn print_xor_log(e: &ExecutionError) {
|
||||
e => log::warn!("xor caught an error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::contexts::execution_trace::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::fallible_call_service;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn xor() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let fallible_service_id = String::from("service_id_1");
|
||||
let mut vm = create_avm(fallible_call_service(fallible_service_id), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("res")))));
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(
|
||||
actual_trace[0],
|
||||
Call(CallServiceFailed(1, Rc::new(String::from(r#"error"#))))
|
||||
);
|
||||
assert_eq!(actual_trace[1], executed_call_result);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
|
||||
assert_eq!(actual_trace.len(), 1);
|
||||
assert_eq!(actual_trace[0], executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_var_not_found() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(par
|
||||
(call "unknown_peer" ("service_id_1" "local_fn_name") [] lazy_defined_variable)
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [lazy_defined_variable] result)
|
||||
)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") ["expected"] result)
|
||||
)"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
assert_eq!(actual_trace[0], Par(1, 0));
|
||||
assert_eq!(actual_trace[1], Call(RequestSentBy(String::from("local_peer_id"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_multiple_variables_found() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
|
||||
let set_variables_peer_id = "set_variables_peer_id";
|
||||
let mut set_variables_vm = create_avm(echo_string_call_service(), set_variables_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let test_string_1 = String::from("some_string");
|
||||
let test_string_2 = String::from("expected_string");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("service_id_1" "local_fn_name") ["{2}"] result_1)
|
||||
(xor
|
||||
(call "{1}" ("service_id_1" "local_fn_name") [""] result_1)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["{3}"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variables_peer_id, local_peer_id, test_string_1, test_string_2
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variables_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[0], Call(Executed(Rc::new(JValue::String(test_string_1)))));
|
||||
assert_eq!(actual_trace[1], Call(Executed(Rc::new(JValue::String(test_string_2)))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_par() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
|
||||
let fallible_service_id = String::from("service_id_1");
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(fallible_call_service(fallible_service_id.clone()), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(par
|
||||
(seq
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_2)
|
||||
)
|
||||
(par
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_3)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_4)
|
||||
)
|
||||
)
|
||||
(seq
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_4)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_5)
|
||||
)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let result = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&result.data).expect("should be valid json");
|
||||
|
||||
let res = String::from("res");
|
||||
let executed_call_result = Rc::new(JValue::String(res));
|
||||
|
||||
let expected_trace = vec![
|
||||
Par(2, 2),
|
||||
Call(Executed(executed_call_result.clone())),
|
||||
Call(Executed(executed_call_result.clone())),
|
||||
Par(1, 0),
|
||||
Call(CallServiceFailed(1, Rc::new(String::from(r#"error"#)))),
|
||||
Call(Executed(executed_call_result.clone())),
|
||||
Call(Executed(executed_call_result.clone())),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
|
||||
let result = call_vm!(vm, "asd", script, "[]", result.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&result.data).expect("should be valid json");
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_error_with_xor() {
|
||||
use crate::contexts::execution_trace::CallResult::*;
|
||||
use crate::contexts::execution_trace::ExecutedState::*;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
|
||||
let faillible_peer_id = "failible_peer_id";
|
||||
let mut faillible_vm = create_avm(fallible_call_service("service_id_1"), faillible_peer_id);
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") [%last_error%] result)
|
||||
)"#,
|
||||
faillible_peer_id, local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(faillible_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
|
||||
let expected_state = Call(Executed(Rc::new(JValue::String(String::from(
|
||||
"{\"error\":\"Local service error: ret_code is 1, error message is \'error\'\",\"instruction\":\"call \\\"failible_peer_id\\\" (\\\"service_id_1\\\" \\\"local_fn_name\\\") [] result\"}"
|
||||
)))));
|
||||
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ pub mod execution_trace {
|
||||
pub use crate::contexts::execution_trace::CallResult;
|
||||
pub use crate::contexts::execution_trace::ExecutedState;
|
||||
pub use crate::contexts::execution_trace::ExecutionTrace;
|
||||
pub use crate::contexts::execution_trace::ParResult;
|
||||
}
|
||||
|
||||
pub mod parser {
|
||||
|
@ -18,6 +18,7 @@ use super::CallResult;
|
||||
use super::DataMergingError;
|
||||
use super::ExecutedState;
|
||||
use super::ExecutionTrace;
|
||||
use super::ParResult;
|
||||
use crate::log_targets::EXECUTED_TRACE_MERGE;
|
||||
|
||||
type MergeResult<T> = Result<T, DataMergingError>;
|
||||
@ -75,10 +76,10 @@ fn merge_subtree(
|
||||
let resulted_call = merge_call(prev_call, call)?;
|
||||
result_trace.push_back(Call(resulted_call));
|
||||
}
|
||||
(Some(Par(prev_left, prev_right)), Some(Par(current_left, current_right))) => {
|
||||
(Some(Par(ParResult(prev_left, prev_right))), Some(Par(ParResult(current_left, current_right)))) => {
|
||||
let par_position = result_trace.len();
|
||||
// place temporary Par value to avoid insert in the middle
|
||||
result_trace.push_back(Par(0, 0));
|
||||
result_trace.push_back(ExecutedState::par(0, 0));
|
||||
|
||||
let before_result_len = result_trace.len();
|
||||
|
||||
@ -89,7 +90,7 @@ fn merge_subtree(
|
||||
let right_par_size = result_trace.len() - left_par_size - before_result_len;
|
||||
|
||||
// update temporary Par with final values
|
||||
result_trace[par_position] = Par(left_par_size, right_par_size);
|
||||
result_trace[par_position] = ExecutedState::par(left_par_size, right_par_size);
|
||||
|
||||
prev_subtree_size -= prev_left + prev_right;
|
||||
current_subtree_size -= current_left + current_right;
|
||||
@ -156,135 +157,3 @@ fn merge_call(prev_call_result: CallResult, current_call_result: CallResult) ->
|
||||
(Executed(..), CallServiceFailed(..)) => Err(IncompatibleCallResults(prev_call_result, current_call_result)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::merge_execution_traces;
|
||||
use super::CallResult;
|
||||
use super::ExecutedState;
|
||||
use super::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_1() {
|
||||
use CallResult::*;
|
||||
use ExecutedState::*;
|
||||
|
||||
let mut prev_trace = ExecutionTrace::new();
|
||||
prev_trace.push_back(Par(1, 1));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
prev_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
prev_trace.push_back(Par(1, 1));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_3"))));
|
||||
prev_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
|
||||
let mut current_trace = ExecutionTrace::new();
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_2"))));
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_4"))));
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace, current_trace).expect("merging should be successful");
|
||||
|
||||
let mut expected_merged_trace = ExecutionTrace::new();
|
||||
expected_merged_trace.push_back(Par(1, 1));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Par(1, 1));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_2() {
|
||||
use CallResult::*;
|
||||
use ExecutedState::*;
|
||||
|
||||
let mut prev_trace = ExecutionTrace::new();
|
||||
prev_trace.push_back(Par(1, 0));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
prev_trace.push_back(Par(1, 1));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_2"))));
|
||||
prev_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
|
||||
let mut current_trace = ExecutionTrace::new();
|
||||
current_trace.push_back(Par(2, 2));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_2"))));
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace, current_trace).expect("merging should be successful");
|
||||
|
||||
let mut expected_merged_trace = ExecutionTrace::new();
|
||||
expected_merged_trace.push_back(Par(2, 2));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
expected_merged_trace.push_back(Par(1, 1));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_3() {
|
||||
use CallResult::*;
|
||||
use ExecutedState::*;
|
||||
|
||||
let mut prev_trace = ExecutionTrace::new();
|
||||
prev_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
prev_trace.push_back(Par(2, 0));
|
||||
prev_trace.push_back(Par(1, 0));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
prev_trace.push_back(Par(1, 2));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
prev_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
prev_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
|
||||
let mut current_trace = ExecutionTrace::new();
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Par(3, 3));
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
current_trace.push_back(Par(1, 1));
|
||||
current_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
current_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace, current_trace).expect("merging should be successful");
|
||||
|
||||
let mut expected_merged_trace = ExecutionTrace::new();
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Par(3, 3));
|
||||
expected_merged_trace.push_back(Par(1, 1));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Par(1, 1));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
expected_merged_trace.push_back(Par(1, 2));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(Executed(Rc::new(JValue::Null))));
|
||||
expected_merged_trace.push_back(Call(RequestSentBy(String::from("peer_1"))));
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
mod data_merging;
|
||||
mod errors;
|
||||
mod preparation;
|
||||
#[cfg(tests)]
|
||||
mod tests;
|
||||
|
||||
pub(crate) use errors::DataMergingError;
|
||||
pub(crate) use errors::PreparationError;
|
||||
@ -28,4 +30,5 @@ pub(self) use crate::contexts::execution_trace::CallResult;
|
||||
pub(self) use crate::contexts::execution_trace::ExecutedState;
|
||||
pub(self) use crate::contexts::execution_trace::ExecutionTrace;
|
||||
pub(self) use crate::contexts::execution_trace::ExecutionTraceCtx;
|
||||
pub(self) use crate::contexts::execution_trace::ParResult;
|
||||
pub(self) use data_merging::merge_execution_traces;
|
||||
|
128
air/src/preparation/tests.rs
Normal file
128
air/src/preparation/tests.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use super::merge_execution_traces;
|
||||
use crate::JValue;
|
||||
|
||||
use air_test_utils::executed_state::*;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_1() {
|
||||
let mut prev_trace = vec![
|
||||
par(1, 1),
|
||||
request_sent_by("peer_1"),
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(1, 1),
|
||||
request_sent_by("peer_3"),
|
||||
scalar_jvalue(JValue::Null),
|
||||
];
|
||||
|
||||
let current_trace = vec![
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_2"),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_4"),
|
||||
];
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace.into(), current_trace.into()).expect("merging should be successful");
|
||||
|
||||
let expected_merged_trace = vec![
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
];
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_2() {
|
||||
let prev_trace = vec![
|
||||
par(1, 0),
|
||||
request_sent_by("peer_1"),
|
||||
par(1, 1),
|
||||
request_sent_by("peer_2"),
|
||||
scalar_jvalue(JValue::Null),
|
||||
];
|
||||
|
||||
let current_trace = vec![
|
||||
par(2, 2),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_2"),
|
||||
];
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace.into(), current_trace.into()).expect("merging should be successful");
|
||||
|
||||
let expected_merged_trace = vec![
|
||||
par(2, 2),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
];
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_call_states_3() {
|
||||
let prev_trace = vec![
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(2, 0),
|
||||
par(1, 0),
|
||||
request_sent_by("peer_1"),
|
||||
par(1, 2),
|
||||
request_sent_by("peer_1"),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
];
|
||||
|
||||
let current_trace = vec![
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(3, 3),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
];
|
||||
|
||||
let actual_merged_trace =
|
||||
merge_execution_traces(prev_trace.into(), current_trace.into()).expect("merging should be successful");
|
||||
|
||||
let expected_merged_trace = vec![
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(3, 3),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
par(1, 1),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
par(1, 2),
|
||||
scalar_jvalue(JValue::Null),
|
||||
scalar_jvalue(JValue::Null),
|
||||
request_sent_by("peer_1"),
|
||||
];
|
||||
|
||||
assert_eq!(actual_merged_trace, expected_merged_trace);
|
||||
}
|
@ -1,428 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_number_call_service;
|
||||
use air_test_utils::unit_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
|
||||
#[test]
|
||||
fn executed_trace_seq_par_call() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(par
|
||||
(call "{0}" ("local_service_id" "local_fn_name") [] result_1)
|
||||
(call "remote_peer_id" ("service_id" "fn_name") [] g)
|
||||
)
|
||||
(call "{0}" ("local_service_id" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let initial_state = json!([
|
||||
{ "par": [1,1] },
|
||||
{ "call": {"executed": "test"} },
|
||||
{ "call": {"executed": "test"} },
|
||||
])
|
||||
.to_string();
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", initial_state);
|
||||
let actual_trace: Vec<ExecutedState> =
|
||||
serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let test_string = String::from("test");
|
||||
let expected_trace = vec![
|
||||
Par(1, 1),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(Executed(Rc::new(JValue::String(test_string)))),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_par_par_call() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(par
|
||||
(par
|
||||
(call "local_peer_id" ("local_service_id" "local_fn_name") [] result_1)
|
||||
(call "remote_peer_id" ("service_id" "fn_name") [] g)
|
||||
)
|
||||
(call "{}" ("local_service_id" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let initial_state = json!([
|
||||
{ "par": [3,0] },
|
||||
{ "par": [1,0] },
|
||||
{ "call": {"request_sent_by": "peer_id_1"} },
|
||||
{ "call": {"executed": "test"} },
|
||||
])
|
||||
.to_string();
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", initial_state);
|
||||
let actual_trace: Vec<ExecutedState> =
|
||||
serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let test_string = String::from("test");
|
||||
let expected_trace = vec![
|
||||
Par(3, 1),
|
||||
Par(1, 1),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(RequestSentBy(local_peer_id.to_string())),
|
||||
Call(Executed(Rc::new(JValue::String(test_string)))),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_seq_seq() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let peer_id_1 = String::from("12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er");
|
||||
let peer_id_2 = String::from("12D3KooWAzJcYitiZrerycVB4Wryrx22CFKdDGx7c4u31PFdfTbR");
|
||||
let mut vm1 = create_avm(unit_call_service(), peer_id_1.clone());
|
||||
let mut vm2 = create_avm(unit_call_service(), peer_id_2.clone());
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("identity" "") [] void0)
|
||||
(seq
|
||||
(call "{}" ("add_blueprint" "") [] blueprint_id)
|
||||
(call "{}" ("addBlueprint-14d8488e-d10d-474d-96b2-878f6a7d74c8" "") [] void1)
|
||||
)
|
||||
)
|
||||
"#,
|
||||
peer_id_1, peer_id_1, peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm2, "asd", script.clone(), "[]", "[]");
|
||||
assert_eq!(res.next_peer_pks, vec![peer_id_1.clone()]);
|
||||
|
||||
let res = call_vm!(vm1, "asd", script.clone(), "[]", res.data);
|
||||
assert_eq!(res.next_peer_pks, vec![peer_id_2.clone()]);
|
||||
|
||||
let res = call_vm!(vm2, "asd", script, "[]", res.data);
|
||||
|
||||
let actual_trace: Vec<ExecutedState> =
|
||||
serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let test_string = String::from("test");
|
||||
let expected_trace = vec![
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(Executed(Rc::new(JValue::String(test_string)))),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_create_service() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let module = "greeting";
|
||||
let module_config = json!(
|
||||
{
|
||||
"name": module,
|
||||
"mem_pages_count": 100,
|
||||
"logger_enabled": true,
|
||||
"wasi": {
|
||||
"envs": json!({}),
|
||||
"preopened_files": vec!["/tmp"],
|
||||
"mapped_dirs": json!({}),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let module_bytes = json!([1, 2]);
|
||||
let blueprint = json!({ "name": "blueprint", "dependencies": [module]});
|
||||
|
||||
let add_module_response = String::from("add_module response");
|
||||
let add_blueprint_response = String::from("add_blueprint response");
|
||||
let create_response = String::from("create response");
|
||||
|
||||
let call_service: CallServiceClosure = Box::new(move |_, args| -> Option<IValue> {
|
||||
let builtin_service = match &args[0] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let response = match builtin_service.as_str() {
|
||||
"add_module" => add_module_response.clone(),
|
||||
"add_blueprint" => add_blueprint_response.clone(),
|
||||
"create" => create_response.clone(),
|
||||
_ => String::from("unknown response"),
|
||||
};
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(format!("\"{}\"", response))]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let mut vm = create_avm(call_service, "A");
|
||||
|
||||
let script = include_str!("./scripts/create_service.clj");
|
||||
|
||||
let add_module_response = String::from("add_module response");
|
||||
let add_blueprint_response = String::from("add_blueprint response");
|
||||
let create_response = String::from("create response");
|
||||
let expected_trace = vec![
|
||||
Call(Executed(Rc::new(module_bytes))),
|
||||
Call(Executed(Rc::new(module_config))),
|
||||
Call(Executed(Rc::new(blueprint))),
|
||||
Call(Executed(Rc::new(JValue::String(add_module_response)))),
|
||||
Call(Executed(Rc::new(JValue::String(add_blueprint_response)))),
|
||||
Call(Executed(Rc::new(JValue::String(create_response)))),
|
||||
Call(Executed(Rc::new(JValue::String(String::from("test"))))),
|
||||
];
|
||||
|
||||
let res = call_vm!(vm, "init_peer_id", script, "[]", json!(expected_trace).to_string());
|
||||
|
||||
let actual_trace: Vec<ExecutedState> = serde_json::from_slice(&res.data).expect("should be a correct json");
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_par_seq_fold_call() {
|
||||
let return_numbers_call_service: CallServiceClosure = Box::new(|_, _| -> Option<IValue> {
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![
|
||||
IValue::S32(0),
|
||||
IValue::String(String::from(
|
||||
"[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\"]",
|
||||
)),
|
||||
])
|
||||
.unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let mut vm1 = create_avm(return_numbers_call_service, "some_peer_id_1");
|
||||
let mut vm2 = create_avm(echo_number_call_service(), "some_peer_id_2");
|
||||
let mut vm3 = create_avm(unit_call_service(), "some_peer_id_3");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(par
|
||||
(seq
|
||||
(call "some_peer_id_1" ("local_service_id" "local_fn_name") [] IterableResultPeer1)
|
||||
(fold IterableResultPeer1 i
|
||||
(par
|
||||
(call "some_peer_id_2" ("local_service_id" "local_fn_name") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
(call "some_peer_id_3" ("local_service_id" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm2, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm1, "asd", script.clone(), "[]", res.data);
|
||||
let mut data = res.data;
|
||||
|
||||
for _ in 0..100 {
|
||||
let res = call_vm!(vm2, "asd", script.clone(), "[]", data);
|
||||
data = res.data;
|
||||
}
|
||||
|
||||
let res = call_vm!(vm3, "asd", script, "[]", data);
|
||||
let actual_trace: JValue = serde_json::from_slice(&res.data).expect("a valid json");
|
||||
|
||||
let expected_json = json!( [
|
||||
{ "par": [21,1] },
|
||||
{ "call": { "executed": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] } },
|
||||
{ "par": [1,18] },
|
||||
{ "call": { "executed": 1 } },
|
||||
{ "par": [1,16] },
|
||||
{ "call": { "executed": 2 } },
|
||||
{ "par": [1,14] },
|
||||
{ "call": { "executed": 3 } },
|
||||
{ "par": [1,12] },
|
||||
{ "call": { "executed": 4 } },
|
||||
{ "par": [1,10] },
|
||||
{ "call": { "executed": 5 } },
|
||||
{ "par": [1,8] },
|
||||
{ "call": { "executed": 6 } },
|
||||
{ "par": [1,6] },
|
||||
{ "call": { "executed": 7 } },
|
||||
{ "par": [1,4] },
|
||||
{ "call": { "executed": 8 } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": 9 } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": 10 } },
|
||||
{ "call": { "executed": "test" } },
|
||||
]);
|
||||
|
||||
assert_eq!(actual_trace, expected_json);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_par_seq_fold_in_cycle_call() {
|
||||
let return_numbers_call_service: CallServiceClosure = Box::new(|_, _| -> Option<IValue> {
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![
|
||||
IValue::S32(0),
|
||||
IValue::String(String::from(
|
||||
"[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\"]",
|
||||
)),
|
||||
])
|
||||
.unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let mut vm1 = create_avm(return_numbers_call_service, "some_peer_id_1");
|
||||
let mut vm2 = create_avm(echo_number_call_service(), "some_peer_id_2");
|
||||
let mut vm3 = create_avm(unit_call_service(), "some_peer_id_3");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(par
|
||||
(seq
|
||||
(call "some_peer_id_1" ("local_service_id" "local_fn_name") [] IterableResultPeer1)
|
||||
(fold IterableResultPeer1 i
|
||||
(par
|
||||
(call "some_peer_id_2" ("local_service_id" "local_fn_name") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
(call "some_peer_id_3" ("local_service_id" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let mut data = vec![];
|
||||
|
||||
for _ in 0..100 {
|
||||
let res = call_vm!(vm1, "asd", script.clone(), "[]", data);
|
||||
let res = call_vm!(vm2, "asd", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm3, "asd", script.clone(), "[]", res.data);
|
||||
data = res.data;
|
||||
}
|
||||
|
||||
let resulted_json: JValue = serde_json::from_slice(&data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json = json!( [
|
||||
{ "par": [21,1] },
|
||||
{ "call": { "executed": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] } },
|
||||
{ "par": [1,18] },
|
||||
{ "call": { "executed": 1 } },
|
||||
{ "par": [1,16] },
|
||||
{ "call": { "executed": 2 } },
|
||||
{ "par": [1,14] },
|
||||
{ "call": { "executed": 3 } },
|
||||
{ "par": [1,12] },
|
||||
{ "call": { "executed": 4 } },
|
||||
{ "par": [1,10] },
|
||||
{ "call": { "executed": 5 } },
|
||||
{ "par": [1,8] },
|
||||
{ "call": { "executed": 6 } },
|
||||
{ "par": [1,6] },
|
||||
{ "call": { "executed": 7 } },
|
||||
{ "par": [1,4] },
|
||||
{ "call": { "executed": 8 } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": 9 } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": 10 } },
|
||||
{ "call": { "executed": "test" } },
|
||||
]);
|
||||
|
||||
assert_eq!(resulted_json, expected_json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executed_trace_seq_par_seq_seq() {
|
||||
let peer_id_1 = String::from("12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er");
|
||||
let peer_id_2 = String::from("12D3KooWAzJcYitiZrerycVB4Wryrx22CFKdDGx7c4u31PFdfTbR");
|
||||
let mut vm1 = create_avm(unit_call_service(), peer_id_1.clone());
|
||||
let mut vm2 = create_avm(unit_call_service(), peer_id_2.clone());
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(par
|
||||
(seq
|
||||
(call "{}" ("" "") [] result_1)
|
||||
(call "{}" ("" "") [] result_2)
|
||||
)
|
||||
(seq
|
||||
(call "{}" ("" "") [] result_3)
|
||||
(call "{}" ("" "") [] result_4)
|
||||
)
|
||||
)
|
||||
(call "{}" ("" "") [] result_5)
|
||||
)
|
||||
"#,
|
||||
peer_id_1, peer_id_2, peer_id_2, peer_id_1, peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm2, "asd", script.clone(), "[]", "[]");
|
||||
assert_eq!(res.next_peer_pks, vec![peer_id_1.clone()]);
|
||||
|
||||
let res = call_vm!(vm1, "asd", script.clone(), "[]", res.data);
|
||||
assert_eq!(res.next_peer_pks, vec![peer_id_2.clone()]);
|
||||
|
||||
let res = call_vm!(vm2, "asd", script, "[]", res.data);
|
||||
|
||||
let resulted_json: JValue = serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json = json!( [
|
||||
{ "par": [2,2] },
|
||||
{ "call": {"executed" : "test" } },
|
||||
{ "call": {"executed" : "test" } },
|
||||
{ "call": {"executed" : "test" } },
|
||||
{ "call": {"executed" : "test" } },
|
||||
{ "call": {"executed" : "test" } },
|
||||
]);
|
||||
|
||||
assert_eq!(resulted_json, expected_json);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air::ResolvedTriplet;
|
||||
use air::SecurityTetraplet;
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
type ArgTetraplets = Vec<Vec<SecurityTetraplet>>;
|
||||
|
||||
fn arg_host_function() -> (CallServiceClosure, Rc<RefCell<ArgTetraplets>>) {
|
||||
let arg_tetraplets = Rc::new(RefCell::new(ArgTetraplets::new()));
|
||||
|
||||
let arg_tetraplets_inner = arg_tetraplets.clone();
|
||||
let host_function: CallServiceClosure = Box::new(move |_, args| -> Option<IValue> {
|
||||
let tetraplets = match &args[3] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let de_tetraplets: ArgTetraplets =
|
||||
serde_json::from_str(tetraplets).expect("json deserialization shouldn't fail");
|
||||
*arg_tetraplets_inner.borrow_mut() = de_tetraplets;
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(tetraplets.clone())]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
(host_function, arg_tetraplets)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_fold() {
|
||||
let return_numbers_call_service: CallServiceClosure = Box::new(|_, _| -> Option<IValue> {
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![
|
||||
IValue::S32(0),
|
||||
IValue::String(String::from(
|
||||
"[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\"]",
|
||||
)),
|
||||
])
|
||||
.unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let set_variable_vm_peer_id = String::from("some_peer_id_1");
|
||||
let mut set_variable_vm = create_avm(return_numbers_call_service, set_variable_vm_peer_id.clone());
|
||||
|
||||
let mut client_vms = Vec::new();
|
||||
for i in 1..=10 {
|
||||
let (arg_host_func, arg_tetraplets) = arg_host_function();
|
||||
let vm = create_avm(arg_host_func, i.to_string());
|
||||
client_vms.push((vm, arg_tetraplets))
|
||||
}
|
||||
|
||||
let service_id = String::from("some_service_id");
|
||||
let function_name = String::from("some_function_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("{}" "{}") [] IterableResultPeer1)
|
||||
(fold IterableResultPeer1 i
|
||||
(par
|
||||
(call i ("local_service_id" "local_fn_name") [i "some_text_literal"] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
"#,
|
||||
set_variable_vm_peer_id, service_id, function_name
|
||||
);
|
||||
|
||||
let init_peer_id = String::from("some_init_peer_id");
|
||||
let res = call_vm!(set_variable_vm, init_peer_id.clone(), script.clone(), "", "");
|
||||
let mut data = res.data;
|
||||
|
||||
let first_arg_triplet = ResolvedTriplet {
|
||||
peer_pk: set_variable_vm_peer_id,
|
||||
service_id,
|
||||
function_name,
|
||||
};
|
||||
let first_arg_triplet = Rc::new(first_arg_triplet);
|
||||
let first_arg_tetraplet = SecurityTetraplet {
|
||||
triplet: first_arg_triplet,
|
||||
json_path: String::new(),
|
||||
};
|
||||
|
||||
let second_arg_triplet = ResolvedTriplet {
|
||||
peer_pk: init_peer_id.clone(),
|
||||
service_id: String::new(),
|
||||
function_name: String::new(),
|
||||
};
|
||||
let second_arg_triplet = Rc::new(second_arg_triplet);
|
||||
let second_arg_tetraplet = SecurityTetraplet {
|
||||
triplet: second_arg_triplet,
|
||||
json_path: String::new(),
|
||||
};
|
||||
|
||||
let expected_tetraplets = vec![vec![first_arg_tetraplet], vec![second_arg_tetraplet]];
|
||||
let expected_tetraplets = Rc::new(RefCell::new(expected_tetraplets));
|
||||
for i in 0..10 {
|
||||
let res = call_vm!(client_vms[i].0, init_peer_id.clone(), script.clone(), "[]", data);
|
||||
data = res.data;
|
||||
|
||||
assert_eq!(client_vms[i].1, expected_tetraplets);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fold_json_path() {
|
||||
let return_numbers_call_service: CallServiceClosure = Box::new(|_, _| -> Option<IValue> {
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![
|
||||
IValue::S32(0),
|
||||
IValue::String(String::from(
|
||||
"{\"arg\": [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\"]}",
|
||||
)),
|
||||
])
|
||||
.unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let set_variable_vm_peer_id = String::from("some_peer_id_1");
|
||||
let mut set_variable_vm = create_avm(return_numbers_call_service, set_variable_vm_peer_id.clone());
|
||||
|
||||
let (arg_host_func, arg_tetraplets) = arg_host_function();
|
||||
let client_peer_id = String::from("client_id");
|
||||
let mut client_vm = create_avm(arg_host_func, client_peer_id.clone());
|
||||
|
||||
let service_id = String::from("some_service_id");
|
||||
let function_name = String::from("some_function_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("{}" "{}") [] IterableResultPeer1)
|
||||
(fold IterableResultPeer1.$.arg i
|
||||
(par
|
||||
(call "{}" ("local_service_id" "local_fn_name") [i "some_text_literal"] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
"#,
|
||||
set_variable_vm_peer_id, service_id, function_name, client_peer_id
|
||||
);
|
||||
|
||||
let init_peer_id = String::from("some_init_peer_id");
|
||||
let res = call_vm!(set_variable_vm, init_peer_id.clone(), script.clone(), "", "");
|
||||
|
||||
let first_arg_triplet = ResolvedTriplet {
|
||||
peer_pk: set_variable_vm_peer_id,
|
||||
service_id,
|
||||
function_name,
|
||||
};
|
||||
let first_arg_triplet = Rc::new(first_arg_triplet);
|
||||
let first_arg_tetraplet = SecurityTetraplet {
|
||||
triplet: first_arg_triplet,
|
||||
json_path: String::from("$.arg"),
|
||||
};
|
||||
|
||||
let second_arg_triplet = ResolvedTriplet {
|
||||
peer_pk: init_peer_id.clone(),
|
||||
service_id: String::new(),
|
||||
function_name: String::new(),
|
||||
};
|
||||
let second_arg_triplet = Rc::new(second_arg_triplet);
|
||||
let second_arg_tetraplet = SecurityTetraplet {
|
||||
triplet: second_arg_triplet,
|
||||
json_path: String::new(),
|
||||
};
|
||||
|
||||
let expected_tetraplets = vec![vec![first_arg_tetraplet], vec![second_arg_tetraplet]];
|
||||
let expected_tetraplets = Rc::new(RefCell::new(expected_tetraplets));
|
||||
call_vm!(client_vm, init_peer_id.clone(), script.clone(), "[]", res.data);
|
||||
assert_eq!(arg_tetraplets, expected_tetraplets);
|
||||
}
|
||||
|
||||
use fluence_app_service::AppService;
|
||||
use fluence_app_service::AppServiceConfig;
|
||||
use fluence_app_service::FaaSConfig;
|
||||
use fluence_app_service::ModuleDescriptor;
|
||||
|
||||
use air::execution_trace::CallResult;
|
||||
use air::execution_trace::ExecutedState;
|
||||
use air::execution_trace::ExecutionTrace;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn construct_service_config(module_name: impl Into<String>) -> AppServiceConfig {
|
||||
let module_name = module_name.into();
|
||||
let module_path = format!("./tests/security_tetraplets/{}/target/wasm32-wasi/debug/", module_name);
|
||||
|
||||
let module_descriptor = ModuleDescriptor {
|
||||
file_name: module_name.clone() + ".wasm",
|
||||
import_name: module_name,
|
||||
..<_>::default()
|
||||
};
|
||||
|
||||
let faas_config = FaaSConfig {
|
||||
modules_dir: Some(PathBuf::from(module_path)),
|
||||
modules_config: vec![module_descriptor],
|
||||
default_modules_config: None,
|
||||
};
|
||||
|
||||
let service_base_dir = std::env::temp_dir();
|
||||
|
||||
let config = AppServiceConfig {
|
||||
service_base_dir,
|
||||
faas_config,
|
||||
};
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tetraplet_with_wasm_modules() {
|
||||
use fluence::CallParameters;
|
||||
use fluence::SecurityTetraplet as SDKTetraplet;
|
||||
|
||||
let auth_module_name = String::from("auth_module");
|
||||
let auth_service_config = construct_service_config(auth_module_name.clone());
|
||||
let auth_service = AppService::new(auth_service_config, auth_module_name.clone(), <_>::default()).unwrap();
|
||||
|
||||
let log_module_name = String::from("log_storage");
|
||||
let log_service_config = construct_service_config(log_module_name.clone());
|
||||
let log_service = AppService::new(log_service_config, log_module_name.clone(), <_>::default()).unwrap();
|
||||
|
||||
let services = maplit::hashmap!(
|
||||
"auth" => auth_service,
|
||||
"log_storage" => log_service,
|
||||
);
|
||||
let services = Rc::new(RefCell::new(services));
|
||||
|
||||
let services_inner = services.clone();
|
||||
const ADMIN_PEER_PK: &str = "12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE1";
|
||||
let host_func: CallServiceClosure = Box::new(move |_, args: Vec<IValue>| -> Option<IValue> {
|
||||
let service_id = match &args[0] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let function_name = match &args[1] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let service_args = match &args[2] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let tetraplets = match &args[3] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let tetraplets: Vec<Vec<SDKTetraplet>> = serde_json::from_str(tetraplets).unwrap();
|
||||
|
||||
let mut call_parameters = CallParameters::default();
|
||||
call_parameters.init_peer_id = ADMIN_PEER_PK.to_string();
|
||||
call_parameters.tetraplets = tetraplets;
|
||||
|
||||
let service_args = serde_json::from_str(service_args).unwrap();
|
||||
let mut service = services_inner.borrow_mut();
|
||||
let service: &mut AppService = service.get_mut(service_id.as_str()).unwrap();
|
||||
|
||||
let result = service.call(function_name, service_args, call_parameters).unwrap();
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(result.to_string())]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("auth" "is_authorized") [] auth_result)
|
||||
(call "{0}" ("log_storage" "delete") [auth_result.$.is_authorized "1"])
|
||||
)
|
||||
"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let mut vm = create_avm(host_func, local_peer_id);
|
||||
|
||||
let result = call_vm!(vm, ADMIN_PEER_PK, script, "", "");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&result.data).unwrap();
|
||||
let expected_state = ExecutedState::Call(CallResult::Executed(Rc::new(serde_json::Value::String(String::from(
|
||||
"Ok",
|
||||
)))));
|
||||
|
||||
assert_eq!(actual_trace[1], expected_state)
|
||||
}
|
173
air/tests/test_module/instructions/call.rs
Normal file
173
air/tests/test_module/instructions/call.rs
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
use air_test_utils::unit_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
// Check that %init_peer_id% alias works correctly (by comparing result with it and explicit peer id).
|
||||
// Additionally, check that empty string for data does the same as empty call path.
|
||||
#[test]
|
||||
fn current_peer_id_call() {
|
||||
let vm_peer_id = String::from("test_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), vm_peer_id.clone());
|
||||
|
||||
let service_id = String::from("local_service_id");
|
||||
let function_name = String::from("local_fn_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(call %init_peer_id% ("{}" "{}") [] result_name)
|
||||
"#,
|
||||
service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, vm_peer_id.clone(), script.clone(), "[]", "[]");
|
||||
let call_path: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
let expected_state = executed_state::scalar_string("test");
|
||||
|
||||
assert_eq!(call_path.len(), 1);
|
||||
assert_eq!(call_path[0], expected_state);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(call "{}" ("{}" "{}") [] result_name)
|
||||
"#,
|
||||
vm_peer_id, service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||
|
||||
// test that empty string for data works
|
||||
let res_with_empty_string = call_vm!(vm, "asd", script, "", "");
|
||||
assert_eq!(res_with_empty_string, res);
|
||||
}
|
||||
|
||||
// Check that specifying remote peer id in call will result its appearing in next_peer_pks.
|
||||
#[test]
|
||||
fn remote_peer_id_call() {
|
||||
let some_local_peer_id = String::from("some_local_peer_id");
|
||||
let mut vm = create_avm(echo_string_call_service(), some_local_peer_id.clone());
|
||||
|
||||
let remote_peer_id = String::from("some_remote_peer_id");
|
||||
let script = format!(
|
||||
r#"(call "{}" ("local_service_id" "local_fn_name") ["arg"] result_name)"#,
|
||||
remote_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
let expected_state = executed_state::request_sent_by(some_local_peer_id);
|
||||
|
||||
assert_eq!(actual_trace.len(), 1);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
assert_eq!(res.next_peer_pks, vec![remote_peer_id]);
|
||||
}
|
||||
|
||||
// Check that setting variables works as expected.
|
||||
#[test]
|
||||
fn variables() {
|
||||
let mut vm = create_avm(unit_call_service(), "remote_peer_id");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#""remote_peer_id""#), "set_variable");
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("some_service_id" "local_fn_name") [] remote_peer_id)
|
||||
(call remote_peer_id ("some_service_id" "local_fn_name") [] result_name)
|
||||
)
|
||||
"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
// Check that duplicate variables are impossible.
|
||||
#[test]
|
||||
fn duplicate_variables() {
|
||||
let mut vm = create_avm(unit_call_service(), "some_peer_id");
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "some_peer_id" ("some_service_id" "local_fn_name") [] modules)
|
||||
(call "some_peer_id" ("some_service_id" "local_fn_name") [] modules)
|
||||
)
|
||||
"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", "");
|
||||
|
||||
assert_eq!(res.ret_code, 1005);
|
||||
assert!(res.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
// Check that string literals can be used as call parameters.
|
||||
#[test]
|
||||
fn string_parameters() {
|
||||
let call_service: CallServiceClosure = Box::new(|_, args| -> Option<IValue> {
|
||||
let arg = match &args[2] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(arg.clone())]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let vm_peer_id = String::from("A");
|
||||
let mut vm = create_avm(call_service, vm_peer_id.clone());
|
||||
|
||||
let set_variable_vm_peer_id = String::from("set_variable");
|
||||
let mut set_variable_vm = create_avm(
|
||||
set_variable_call_service(r#""arg3_value""#),
|
||||
set_variable_vm_peer_id.clone(),
|
||||
);
|
||||
|
||||
let service_id = String::from("some_service_id");
|
||||
let function_name = String::from("local_fn_name");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("{}" "{}") [] arg3)
|
||||
(call "{}" ("{}" "{}") ["arg1" "arg2" arg3] result)
|
||||
)
|
||||
"#,
|
||||
set_variable_vm_peer_id, service_id, function_name, vm_peer_id, service_id, function_name
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a valid json");
|
||||
|
||||
let expected_state = executed_state::scalar_string_array(vec!["arg1", "arg2", "arg3_value"]);
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
}
|
413
air/tests/test_module/instructions/fold.rs
Normal file
413
air/tests/test_module/instructions/fold.rs
Normal file
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_number_call_service;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
use air_test_utils::AVMError;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
use air_test_utils::InterpreterOutcome;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn lfold() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let lfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", lfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", lfold, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
|
||||
|
||||
assert_eq!(actual_trace.len(), 6);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
|
||||
for i in 1..=5 {
|
||||
let expected_state = executed_state::stream_number(i, "$acc");
|
||||
assert_eq!(actual_trace[i], expected_state);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rfold() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let rfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(next i)
|
||||
(call "A" ("" "") [i] $acc)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", rfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", rfold, "[]", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
assert_eq!(actual_trace.len(), 6);
|
||||
|
||||
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
|
||||
for i in 1..=5 {
|
||||
let expected_state = executed_state::stream_number(6 - i, "$acc");
|
||||
assert_eq!(actual_trace[i], expected_state);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inner_fold() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable1)
|
||||
(call "set_variable" ("" "") [] Iterable2)
|
||||
)
|
||||
(fold Iterable1 i
|
||||
(seq
|
||||
(fold Iterable2 j
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", script, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(actual_trace.len(), 27);
|
||||
|
||||
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
|
||||
for i in 1..=5 {
|
||||
for j in 1..=5 {
|
||||
let expected_state = executed_state::stream_number(i, "$acc");
|
||||
assert_eq!(actual_trace[1 + 5 * (i - 1) + j], expected_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inner_fold_with_same_iterator() {
|
||||
let mut vm = create_avm(set_variable_call_service(r#"["1","2","3","4","5"]"#), "set_variable");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable1)
|
||||
(call "set_variable" ("" "") [] Iterable2)
|
||||
)
|
||||
(fold Iterable1 i
|
||||
(seq
|
||||
(fold Iterable2 i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
assert_eq!(res.ret_code, 1012);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_fold() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"[]"#), "set_variable");
|
||||
|
||||
let empty_fold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] Iterable)
|
||||
(fold Iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", empty_fold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", empty_fold, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
let expected_state = executed_state::scalar_jvalue(json!([]));
|
||||
|
||||
assert_eq!(actual_trace.len(), 1);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_fold_json_path() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"{ "messages": [] }"#), "set_variable");
|
||||
|
||||
let empty_fold = r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] messages)
|
||||
(fold messages.$.messages! i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#;
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", empty_fold, "", "");
|
||||
let res = call_vm!(vm, "", empty_fold, "", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 1);
|
||||
assert_eq!(res[0], executed_state::scalar_jvalue(json!({ "messages": [] })));
|
||||
}
|
||||
|
||||
// Check that fold works with the join behaviour without hanging up.
|
||||
#[test]
|
||||
fn fold_with_join() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
|
||||
let fold_with_join = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable)
|
||||
(par
|
||||
(call "unknown_peer" ("" "") [] lazy_def_variable)
|
||||
(fold iterable i
|
||||
(seq
|
||||
(call "A" ("" "") [lazy_def_variable.$.hash!] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", &fold_with_join, "", "");
|
||||
let res = call_vm!(vm, "", fold_with_join, "", res.data);
|
||||
let res: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
|
||||
assert_eq!(res.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_path() {
|
||||
let mut vm = create_avm(echo_number_call_service(), "A");
|
||||
let mut set_variable_vm = create_avm(
|
||||
set_variable_call_service(r#"{ "array": ["1","2","3","4","5"] }"#),
|
||||
"set_variable",
|
||||
);
|
||||
|
||||
let lfold = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable)
|
||||
(fold iterable.$.array! i
|
||||
(seq
|
||||
(call "A" ("" "") [i] $acc)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", lfold.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "", lfold, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
let expected_state = executed_state::scalar_jvalue(json!({ "array": ["1", "2", "3", "4", "5"] }));
|
||||
|
||||
assert_eq!(actual_trace.len(), 6);
|
||||
assert_eq!(actual_trace[0], expected_state);
|
||||
|
||||
for i in 1..=5 {
|
||||
let expected_state = executed_state::stream_number(i, "$acc");
|
||||
assert_eq!(actual_trace[i], expected_state);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shadowing() {
|
||||
use executed_state::*;
|
||||
|
||||
let mut set_variables_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
let mut vm_a = create_avm(echo_string_call_service(), "A");
|
||||
let mut vm_b = create_avm(echo_string_call_service(), "B");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable1)
|
||||
(call "set_variable" ("" "") [] iterable2)
|
||||
)
|
||||
(fold iterable1 i
|
||||
(seq
|
||||
(seq
|
||||
(fold iterable2 j
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") [i] local_j)
|
||||
(call "B" ("" "") [local_j])
|
||||
)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(par
|
||||
(call "A" ("" "") [i] local_i)
|
||||
(call "B" ("" "") [i])
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variables_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script, "[]", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
let expected_trace = vec![
|
||||
scalar_string_array(vec!["1", "2"]),
|
||||
scalar_string_array(vec!["1", "2"]),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
par(1, 1),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("2"),
|
||||
scalar_string("2"),
|
||||
request_sent_by("B"),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shadowing_scope() {
|
||||
use executed_state::*;
|
||||
|
||||
fn execute_script(script: String) -> Result<InterpreterOutcome, AVMError> {
|
||||
let mut set_variables_vm = create_avm(set_variable_call_service(r#"["1","2"]"#), "set_variable");
|
||||
let mut vm_a = create_avm(echo_string_call_service(), "A");
|
||||
let mut vm_b = create_avm(echo_string_call_service(), "B");
|
||||
|
||||
let res = call_vm!(set_variables_vm, "", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_a, "", script.clone(), "[]", res.data);
|
||||
let res = call_vm!(vm_b, "", script.clone(), "[]", res.data);
|
||||
|
||||
vm_a.call_with_prev_data("", script, "[]", res.data)
|
||||
}
|
||||
|
||||
let variable_shadowing_script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "set_variable" ("" "") [] iterable1)
|
||||
(call "set_variable" ("" "") [] iterable2)
|
||||
)
|
||||
(fold iterable1 i
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") ["value"] local_j)
|
||||
(seq
|
||||
(fold iterable2 j
|
||||
(seq
|
||||
(seq
|
||||
(call "A" ("" "") [i] local_j)
|
||||
(call "B" ("" "") [local_j])
|
||||
)
|
||||
(next j)
|
||||
)
|
||||
)
|
||||
(call "A" ("" "") [local_j])
|
||||
)
|
||||
)
|
||||
(next i)
|
||||
)
|
||||
)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = execute_script(variable_shadowing_script).unwrap();
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid executed trace");
|
||||
let expected_trace = vec![
|
||||
scalar_string_array(vec!["1", "2"]),
|
||||
scalar_string_array(vec!["1", "2"]),
|
||||
scalar_string("value"),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("1"),
|
||||
scalar_string("value"),
|
||||
scalar_string("value"),
|
||||
scalar_string("2"),
|
||||
request_sent_by("A"),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
}
|
246
air/tests/test_module/instructions/match_.rs
Normal file
246
air/tests/test_module/instructions/match_.rs
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
|
||||
#[test]
|
||||
fn match_equal() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(xor
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_1");
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_not_equal() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(xor
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_2");
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_string() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(xor
|
||||
(match value_1 "value_1"
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_1");
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_init_peer_id() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["{1}"] value_1)
|
||||
(xor
|
||||
(match value_1 %init_peer_id%
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, local_peer_id, script.clone(), "", "");
|
||||
let res = call_vm!(vm, local_peer_id, script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_executed_call_result = executed_state::scalar_string("result_1");
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_executed_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_equal_numbers() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = "
|
||||
(xor
|
||||
(match 1 1
|
||||
(null)
|
||||
)
|
||||
(null)
|
||||
)";
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", "");
|
||||
assert_eq!(res.ret_code, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_without_xor() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(match value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script.clone(), "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1015);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1015);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_with_two_xors() {
|
||||
use air_test_utils::set_variable_call_service;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(
|
||||
set_variable_call_service(serde_json::json!(false).to_string()),
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let local_peer_id_2 = "local_peer_id_2";
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("getDataSrv" "condition") [] condition)
|
||||
(call "{0}" ("getDataSrv" "relay") [] relay)
|
||||
)
|
||||
(xor
|
||||
(match condition true
|
||||
(call "{0}" ("println" "print") ["it is true"])
|
||||
)
|
||||
(call "{1}" ("println" "print") ["it is false"])
|
||||
)
|
||||
)
|
||||
(call "{0}" ("errorHandlingSrv" "error") [%last_error%])
|
||||
)
|
||||
"#,
|
||||
local_peer_id, local_peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "", "");
|
||||
let mut trace: ExecutionTrace =
|
||||
serde_json::from_slice(&res.data).expect("the interpreter should provide correct trace");
|
||||
|
||||
let expected_executed_call_result = executed_state::request_sent_by(local_peer_id);
|
||||
assert_eq!(res.ret_code, 0);
|
||||
assert_eq!(trace.pop_back().unwrap(), expected_executed_call_result);
|
||||
}
|
197
air/tests/test_module/instructions/mismatch.rs
Normal file
197
air/tests/test_module/instructions/mismatch.rs
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
|
||||
#[test]
|
||||
fn mismatch_equal() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(xor
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_2");
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_not_equal() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_2"] value_2)
|
||||
)
|
||||
(xor
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_1");
|
||||
|
||||
assert_eq!(actual_trace.len(), 3);
|
||||
assert_eq!(actual_trace[2], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_with_string() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(xor
|
||||
(mismatch value_1 "value_1"
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_state = executed_state::scalar_string("result_2");
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_without_xor() {
|
||||
let set_variable_peer_id = "set_variable_peer_id";
|
||||
let mut set_variable_vm = create_avm(echo_string_call_service(), set_variable_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["value_1"] value_1)
|
||||
(call "{0}" ("" "") ["value_1"] value_2)
|
||||
)
|
||||
(mismatch value_1 value_2
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1)
|
||||
)
|
||||
)"#,
|
||||
set_variable_peer_id, local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script.clone(), "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1016);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
|
||||
assert_eq!(res.ret_code, 1016);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatch_with_two_xors() {
|
||||
use air_test_utils::set_variable_call_service;
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(
|
||||
set_variable_call_service(serde_json::json!(false).to_string()),
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let local_peer_id_2 = "local_peer_id_2";
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("getDataSrv" "condition") [] condition)
|
||||
(call "{0}" ("getDataSrv" "relay") [] relay)
|
||||
)
|
||||
(xor
|
||||
(mismatch condition true
|
||||
(call "{1}" ("println" "print") ["it is false"])
|
||||
)
|
||||
(call "{0}" ("println" "print") ["it is true"])
|
||||
)
|
||||
)
|
||||
(call "{0}" ("errorHandlingSrv" "error") [%last_error%])
|
||||
)
|
||||
"#,
|
||||
local_peer_id, local_peer_id_2
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "", "");
|
||||
let mut trace: ExecutionTrace =
|
||||
serde_json::from_slice(&res.data).expect("the interpreter should provide correct trace");
|
||||
|
||||
let expected_executed_call_result = executed_state::request_sent_by(local_peer_id);
|
||||
assert_eq!(res.ret_code, 0);
|
||||
assert_eq!(trace.pop_back().unwrap(), expected_executed_call_result);
|
||||
}
|
23
air/tests/test_module/instructions/mod.rs
Normal file
23
air/tests/test_module/instructions/mod.rs
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod call;
|
||||
mod fold;
|
||||
mod match_;
|
||||
mod mismatch;
|
||||
mod par;
|
||||
mod seq;
|
||||
mod xor;
|
60
air/tests/test_module/instructions/par.rs
Normal file
60
air/tests/test_module/instructions/par.rs
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::unit_call_service;
|
||||
|
||||
#[test]
|
||||
fn par_remote_remote() {
|
||||
use std::collections::HashSet;
|
||||
|
||||
let mut vm = create_avm(unit_call_service(), "");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(par
|
||||
(call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let mut res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
let peers_result: HashSet<_> = res.next_peer_pks.drain(..).collect();
|
||||
let peers_right: HashSet<_> = maplit::hashset!(String::from("remote_peer_id_1"), String::from("remote_peer_id_2"));
|
||||
|
||||
assert_eq!(peers_result, peers_right);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn par_local_remote() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(par
|
||||
(call "{}" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "", script, "[]", "[]");
|
||||
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_2")]);
|
||||
}
|
61
air/tests/test_module/instructions/seq.rs
Normal file
61
air/tests/test_module/instructions/seq.rs
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::unit_call_service;
|
||||
|
||||
#[test]
|
||||
fn seq_remote_remote() {
|
||||
let mut vm = create_avm(unit_call_service(), "");
|
||||
|
||||
let script = String::from(
|
||||
r#"
|
||||
(seq
|
||||
(call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "remote_peer_id_2" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script.clone(), "", "");
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_1")]);
|
||||
|
||||
let initial_data = vec![executed_state::scalar_string("")];
|
||||
let initial_data = serde_json::to_string(&initial_data).expect("default serializer shouldn't fail");
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "", initial_data);
|
||||
assert_eq!(res.next_peer_pks, vec![String::from("remote_peer_id_2")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn seq_local_remote() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let remote_peer_id = String::from("remote_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{}" ("local_service_id" "local_fn_name") [] result_name)
|
||||
(call "{}" ("service_id" "fn_name") [] g)
|
||||
)"#,
|
||||
local_peer_id, remote_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
assert_eq!(res.next_peer_pks, vec![remote_peer_id]);
|
||||
}
|
195
air/tests/test_module/instructions/xor.rs
Normal file
195
air/tests/test_module/instructions/xor.rs
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::echo_string_call_service;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::fallible_call_service;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
|
||||
#[test]
|
||||
fn xor() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let fallible_service_id = String::from("service_id_1");
|
||||
let mut vm = create_avm(fallible_call_service(fallible_service_id), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let expected_call_result = executed_state::scalar_string("res");
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[0], executed_state::service_failed(1, "error"));
|
||||
assert_eq!(actual_trace[1], expected_call_result);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_2)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
|
||||
assert_eq!(actual_trace.len(), 1);
|
||||
assert_eq!(actual_trace[0], expected_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_var_not_found() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(par
|
||||
(call "unknown_peer" ("service_id_1" "local_fn_name") [] lazy_defined_variable)
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [lazy_defined_variable] result)
|
||||
)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") ["expected"] result)
|
||||
)"#,
|
||||
local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
assert_eq!(actual_trace[0], executed_state::par(1, 0));
|
||||
assert_eq!(actual_trace[1], executed_state::request_sent_by(local_peer_id));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_multiple_variables_found() {
|
||||
let set_variables_peer_id = "set_variables_peer_id";
|
||||
let mut set_variables_vm = create_avm(echo_string_call_service(), set_variables_peer_id);
|
||||
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let some_string = String::from("some_string");
|
||||
let expected_string = String::from("expected_string");
|
||||
let script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{0}" ("service_id_1" "local_fn_name") ["{2}"] result_1)
|
||||
(xor
|
||||
(call "{1}" ("service_id_1" "local_fn_name") [""] result_1)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") ["{3}"] result_2)
|
||||
)
|
||||
)"#,
|
||||
set_variables_peer_id, local_peer_id, some_string, expected_string
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variables_vm, "asd", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "asd", script, "[]", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
let some_string_call_result = executed_state::scalar_string(some_string);
|
||||
let expected_string_call_result = executed_state::scalar_string(expected_string);
|
||||
|
||||
assert_eq!(actual_trace.len(), 2);
|
||||
assert_eq!(actual_trace[0], some_string_call_result);
|
||||
assert_eq!(actual_trace[1], expected_string_call_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor_par() {
|
||||
use executed_state::*;
|
||||
|
||||
let fallible_service_id = String::from("service_id_1");
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(fallible_call_service(fallible_service_id.clone()), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(par
|
||||
(seq
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_1)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_2)
|
||||
)
|
||||
(par
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result_3)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_4)
|
||||
)
|
||||
)
|
||||
(seq
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_4)
|
||||
(call "{0}" ("service_id_2" "local_fn_name") [] result_5)
|
||||
)
|
||||
)"#,
|
||||
local_peer_id
|
||||
);
|
||||
|
||||
let result = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&result.data).expect("should be valid json");
|
||||
|
||||
let res = String::from("res");
|
||||
|
||||
let expected_trace = vec![
|
||||
par(2, 2),
|
||||
scalar_string(&res),
|
||||
scalar_string(&res),
|
||||
par(1, 0),
|
||||
service_failed(1, "error"),
|
||||
scalar_string(&res),
|
||||
scalar_string(&res),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
|
||||
let result = call_vm!(vm, "asd", script, "[]", result.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&result.data).expect("should be valid json");
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_error_with_xor() {
|
||||
use air_test_utils::echo_string_call_service;
|
||||
|
||||
let faillible_peer_id = "failible_peer_id";
|
||||
let mut faillible_vm = create_avm(fallible_call_service("service_id_1"), faillible_peer_id);
|
||||
let local_peer_id = "local_peer_id";
|
||||
let mut vm = create_avm(echo_string_call_service(), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{0}" ("service_id_1" "local_fn_name") [] result)
|
||||
(call "{1}" ("service_id_2" "local_fn_name") [%last_error%] result)
|
||||
)"#,
|
||||
faillible_peer_id, local_peer_id,
|
||||
);
|
||||
|
||||
let res = call_vm!(faillible_vm, "asd", script.clone(), "", "");
|
||||
let res = call_vm!(vm, "asd", script, "", res.data);
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json");
|
||||
|
||||
let expected_state = executed_state::scalar_string("{\"error\":\"Local service error: ret_code is 1, error message is \'error\'\",\"instruction\":\"call \\\"failible_peer_id\\\" (\\\"service_id_1\\\" \\\"local_fn_name\\\") [] result\"}");
|
||||
|
||||
assert_eq!(actual_trace[1], expected_state);
|
||||
}
|
@ -14,8 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air::execution_trace::ExecutionTrace;
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::set_variables_call_service;
|
||||
use air_test_utils::unit_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
@ -24,15 +26,8 @@ use air_test_utils::NEVec;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
|
||||
#[test]
|
||||
fn seq_par_call() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let vm_peer_id = String::from("some_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), vm_peer_id.clone());
|
||||
|
||||
@ -49,15 +44,14 @@ fn seq_par_call() {
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let actual_trace: Vec<ExecutedState> =
|
||||
serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let test_string = String::from("test");
|
||||
let test_string = "test";
|
||||
let expected_trace = vec![
|
||||
Par(1, 1),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(RequestSentBy(vm_peer_id)),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
executed_state::par(1, 1),
|
||||
executed_state::scalar_string(test_string),
|
||||
executed_state::request_sent_by(vm_peer_id),
|
||||
executed_state::scalar_string(test_string),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
||||
@ -66,9 +60,6 @@ fn seq_par_call() {
|
||||
|
||||
#[test]
|
||||
fn par_par_call() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let vm_peer_id = String::from("some_peer_id");
|
||||
let mut vm = create_avm(unit_call_service(), vm_peer_id.clone());
|
||||
|
||||
@ -85,16 +76,16 @@ fn par_par_call() {
|
||||
);
|
||||
|
||||
let res = call_vm!(vm, "asd", script, "[]", "[]");
|
||||
let resulted_trace: Vec<ExecutedState> =
|
||||
let resulted_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
let test_string = String::from("test");
|
||||
let test_string = "test";
|
||||
let expected_trace = vec![
|
||||
Par(3, 1),
|
||||
Par(1, 1),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
Call(RequestSentBy(vm_peer_id)),
|
||||
Call(Executed(Rc::new(JValue::String(test_string.clone())))),
|
||||
executed_state::par(3, 1),
|
||||
executed_state::par(1, 1),
|
||||
executed_state::scalar_string(test_string),
|
||||
executed_state::request_sent_by(vm_peer_id),
|
||||
executed_state::scalar_string(test_string),
|
||||
];
|
||||
|
||||
assert_eq!(resulted_trace, expected_trace);
|
||||
@ -103,9 +94,6 @@ fn par_par_call() {
|
||||
|
||||
#[test]
|
||||
fn create_service() {
|
||||
use air::execution_trace::CallResult::*;
|
||||
use air::execution_trace::ExecutedState::{self, *};
|
||||
|
||||
let module = "greeting";
|
||||
let module_config = json!(
|
||||
{
|
||||
@ -160,18 +148,18 @@ fn create_service() {
|
||||
let res = call_vm!(set_variables_vm, "init_peer_id", script.clone(), "[]", "[]");
|
||||
let res = call_vm!(vm, "init_peer_id", script, "[]", res.data);
|
||||
|
||||
let add_module_response = String::from("add_module response");
|
||||
let add_blueprint_response = String::from("add_blueprint response");
|
||||
let create_response = String::from("create response");
|
||||
let actual_trace: Vec<ExecutedState> = serde_json::from_slice(&res.data).expect("should be a correct json");
|
||||
let add_module_response = "add_module response";
|
||||
let add_blueprint_response = "add_blueprint response";
|
||||
let create_response = "create response";
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be a correct json");
|
||||
let expected_trace = vec![
|
||||
Call(Executed(Rc::new(module_bytes))),
|
||||
Call(Executed(Rc::new(module_config))),
|
||||
Call(Executed(Rc::new(blueprint))),
|
||||
Call(Executed(Rc::new(JValue::String(add_module_response)))),
|
||||
Call(Executed(Rc::new(JValue::String(add_blueprint_response)))),
|
||||
Call(Executed(Rc::new(JValue::String(create_response)))),
|
||||
Call(RequestSentBy(String::from("A"))),
|
||||
executed_state::scalar_jvalue(module_bytes),
|
||||
executed_state::scalar_jvalue(module_config),
|
||||
executed_state::scalar_jvalue(blueprint),
|
||||
executed_state::scalar_string(add_module_response),
|
||||
executed_state::scalar_string(add_blueprint_response),
|
||||
executed_state::scalar_string(create_response),
|
||||
executed_state::request_sent_by("A"),
|
||||
];
|
||||
|
||||
assert_eq!(actual_trace, expected_trace);
|
@ -16,8 +16,11 @@
|
||||
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::set_variable_call_service;
|
||||
use air_test_utils::set_variables_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::ExecutionTrace;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
@ -28,6 +31,8 @@ type JValue = serde_json::Value;
|
||||
|
||||
#[test]
|
||||
fn data_merge() {
|
||||
use executed_state::*;
|
||||
|
||||
let neighborhood_call_service1: CallServiceClosure = Box::new(|_, _| -> Option<IValue> {
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(String::from("[\"A\", \"B\"]"))]).unwrap(),
|
||||
@ -77,79 +82,83 @@ fn data_merge() {
|
||||
let res3 = call_vm!(vm1, "asd", script.clone(), res1.data.clone(), res2.data.clone());
|
||||
let res4 = call_vm!(vm2, "asd", script, res1.data.clone(), res2.data.clone());
|
||||
|
||||
let resulted_json1: JValue = serde_json::from_slice(&res1.data).expect("interpreter should return valid json");
|
||||
let actual_trace_1: ExecutionTrace =
|
||||
serde_json::from_slice(&res1.data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json1 = json!( [
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "request_sent_by": "A" } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "request_sent_by": "A" } },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "request_sent_by": "A" } },
|
||||
]);
|
||||
let expected_trace_1 = vec![
|
||||
scalar_string_array(vec!["A", "B"]),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 0),
|
||||
request_sent_by("A"),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
par(1, 0),
|
||||
request_sent_by("A"),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
request_sent_by("A"),
|
||||
];
|
||||
|
||||
assert_eq!(resulted_json1, expected_json1);
|
||||
assert_eq!(actual_trace_1, expected_trace_1);
|
||||
assert_eq!(res1.next_peer_pks, vec![String::from("B")]);
|
||||
|
||||
let resulted_json2: JValue = serde_json::from_slice(&res2.data).expect("interpreter should return valid json");
|
||||
let actual_trace_2: ExecutionTrace =
|
||||
serde_json::from_slice(&res2.data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json2 = json!( [
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "request_sent_by": "B" } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "request_sent_by": "B" } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "request_sent_by": "B" } },
|
||||
]);
|
||||
let expected_trace_2 = vec![
|
||||
scalar_string_array(vec!["A", "B"]),
|
||||
par(1, 2),
|
||||
request_sent_by("B"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 2),
|
||||
request_sent_by("B"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
request_sent_by("B"),
|
||||
];
|
||||
|
||||
assert_eq!(resulted_json2, expected_json2);
|
||||
assert_eq!(actual_trace_2, expected_trace_2);
|
||||
assert_eq!(res2.next_peer_pks, vec![String::from("A")]);
|
||||
|
||||
let resulted_json3: JValue = serde_json::from_slice(&res3.data).expect("interpreter should return valid json");
|
||||
let actual_trace_3: ExecutionTrace =
|
||||
serde_json::from_slice(&res3.data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json3 = json!( [
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "request_sent_by": "A" } },
|
||||
]);
|
||||
let expected_trace_3 = vec![
|
||||
scalar_string_array(vec!["A", "B"]),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
request_sent_by("A"),
|
||||
];
|
||||
|
||||
assert_eq!(resulted_json3, expected_json3);
|
||||
assert_eq!(actual_trace_3, expected_trace_3);
|
||||
assert!(res3.next_peer_pks.is_empty());
|
||||
|
||||
let resulted_json4: JValue = serde_json::from_slice(&res4.data).expect("interpreter should return valid json");
|
||||
let actual_trace_4: ExecutionTrace =
|
||||
serde_json::from_slice(&res4.data).expect("interpreter should return valid json");
|
||||
|
||||
let expected_json4 = json!( [
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,2] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "par": [1,0] },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
{ "call": { "executed": ["A", "B"] } },
|
||||
]);
|
||||
let expected_trace_4 = vec![
|
||||
scalar_string_array(vec!["A", "B"]),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
par(1, 2),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
par(1, 0),
|
||||
stream_string_array(vec!["A", "B"], "$providers"),
|
||||
stream_string_array(vec!["A", "B"], "$void"),
|
||||
scalar_string_array(vec!["A", "B"]),
|
||||
];
|
||||
|
||||
assert_eq!(resulted_json4, expected_json4);
|
||||
assert_eq!(actual_trace_4, expected_trace_4);
|
||||
assert!(res4.next_peer_pks.is_empty());
|
||||
}
|
||||
|
||||
@ -210,3 +219,42 @@ fn acc_merge() {
|
||||
let res = call_vm!(vm1, "asd", script.clone(), "[]", "[]");
|
||||
call_vm!(vm2, "asd", script, "[]", res.data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn fold_merge() {
|
||||
let set_variable_vm_id = "set_variable";
|
||||
let local_vm_id = "local_vm";
|
||||
|
||||
let variables = maplit::hashmap! {
|
||||
"stream1".to_string() => r#"["s1", "s2", "s3"]"#.to_string(),
|
||||
"stream2".to_string() => r#"["s4", "s5", "s6"]"#.to_string(),
|
||||
};
|
||||
|
||||
let local_vm_service_call: CallServiceClosure = Box::new(|_, values| -> Option<IValue> {
|
||||
let args = match &values[2] {
|
||||
IValue::String(str) => str,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
println!("args {:?}", args);
|
||||
|
||||
Some(IValue::Record(
|
||||
NEVec::new(vec![IValue::S32(0), IValue::String(format!("{}", args))]).unwrap(),
|
||||
))
|
||||
});
|
||||
|
||||
let mut set_variable_vm = create_avm(set_variables_call_service(variables), set_variable_vm_id);
|
||||
let mut local_vm = create_avm(local_vm_service_call, local_vm_id);
|
||||
|
||||
let script = format!(
|
||||
include_str!("./scripts/inner_folds_v1.clj"),
|
||||
set_variable_vm_id, local_vm_id
|
||||
);
|
||||
|
||||
let res = call_vm!(set_variable_vm, "", script.clone(), "", "");
|
||||
let res = call_vm!(local_vm, "", script, "", res.data);
|
||||
|
||||
let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("interpreter should return valid json");
|
||||
|
||||
// println!("res is {:?}", actual_trace);
|
||||
}
|
@ -14,18 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air::execution_trace::ExecutionTrace;
|
||||
use air_test_utils::call_vm;
|
||||
use air_test_utils::create_avm;
|
||||
use air_test_utils::executed_state;
|
||||
use air_test_utils::unit_call_service;
|
||||
use air_test_utils::CallServiceClosure;
|
||||
use air_test_utils::IValue;
|
||||
use air_test_utils::NEVec;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::json;
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
|
||||
#[test]
|
||||
fn join_chat() {
|
||||
use std::collections::HashSet;
|
||||
@ -71,43 +70,41 @@ fn join_chat() {
|
||||
|
||||
let client_1_res = call_vm!(client_1, "asd", script.clone(), "[]", "[]");
|
||||
|
||||
let client_1_res_json: JValue =
|
||||
let client_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&client_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let client_1_expected_json = json!([
|
||||
{ "call": {"request_sent_by": "A" } },
|
||||
]);
|
||||
let client_1_expected_trace = vec![executed_state::request_sent_by("A")];
|
||||
|
||||
assert_eq!(client_1_res_json, client_1_expected_json);
|
||||
assert_eq!(client_1_actual_trace, client_1_expected_trace);
|
||||
assert_eq!(client_1_res.next_peer_pks, vec![String::from("Relay1")]);
|
||||
|
||||
let relay_1_res = call_vm!(relay_1, "asd", script.clone(), client_1_res.data, "[]");
|
||||
|
||||
let relay_1_res_json: JValue =
|
||||
let relay_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&relay_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let relay_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "request_sent_by": "Relay1" } },
|
||||
]);
|
||||
let relay_1_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::request_sent_by("Relay1"),
|
||||
];
|
||||
|
||||
assert_eq!(relay_1_res_json, relay_1_expected_json);
|
||||
assert_eq!(relay_1_actual_trace, relay_1_expected_trace);
|
||||
assert_eq!(relay_1_res.next_peer_pks, vec![String::from("Remote")]);
|
||||
|
||||
let remote_res = call_vm!(remote, "asd", script.clone(), relay_1_res.data, "[]");
|
||||
|
||||
let remote_res_json: JValue =
|
||||
let remote_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&remote_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let remote_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "par": [1, 2] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
{ "par": [1, 0] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
]);
|
||||
let remote_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::stream_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]]), "void2"),
|
||||
executed_state::scalar_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]])),
|
||||
executed_state::par(1, 2),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
executed_state::par(1, 0),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
];
|
||||
|
||||
let remote_res_next_peer_pks: HashSet<_> = remote_res.next_peer_pks.iter().map(|s| s.as_str()).collect();
|
||||
let next_peer_pks_right = maplit::hashset! {
|
||||
@ -115,83 +112,82 @@ fn join_chat() {
|
||||
"Relay2",
|
||||
};
|
||||
|
||||
assert_eq!(remote_res_json, remote_expected_json);
|
||||
assert_eq!(remote_actual_trace, remote_expected_trace);
|
||||
assert_eq!(remote_res_next_peer_pks, next_peer_pks_right);
|
||||
|
||||
let relay_1_res = call_vm!(relay_1, "asd", script.clone(), remote_res.data.clone(), "[]");
|
||||
|
||||
let relay_1_res_json: JValue =
|
||||
let relay_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&relay_1_res.data).expect("interpreter should return valid json");
|
||||
let relay_1_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::stream_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]]), "void2"),
|
||||
executed_state::scalar_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]])),
|
||||
executed_state::par(2, 2),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::request_sent_by("Relay1"),
|
||||
executed_state::par(1, 0),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
];
|
||||
|
||||
let relay_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "par": [2, 2] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "request_sent_by" : "Relay1" } },
|
||||
{ "par": [1, 0] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
]);
|
||||
|
||||
assert_eq!(relay_1_res_json, relay_1_expected_json);
|
||||
assert_eq!(relay_1_actual_trace, relay_1_expected_trace);
|
||||
assert_eq!(relay_1_res.next_peer_pks, vec![String::from("A")]);
|
||||
|
||||
let client_1_res = call_vm!(client_1, "asd", script.clone(), relay_1_res.data, "[]");
|
||||
|
||||
let client_1_res_json: JValue =
|
||||
let client_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&client_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let client_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "par": [2, 2] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "par": [1, 0] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
]);
|
||||
let client_1_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::stream_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]]), "void2"),
|
||||
executed_state::scalar_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]])),
|
||||
executed_state::par(2, 2),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::stream_string("test", "void3"),
|
||||
executed_state::par(1, 0),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
];
|
||||
|
||||
assert_eq!(client_1_res_json, client_1_expected_json);
|
||||
assert_eq!(client_1_actual_trace, client_1_expected_trace);
|
||||
assert_eq!(client_1_res.next_peer_pks, Vec::<String>::new());
|
||||
|
||||
let relay_2_res = call_vm!(relay_2, "asd", script.clone(), remote_res.data, "[]");
|
||||
|
||||
let relay_2_res_json: JValue =
|
||||
let relay_2_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&relay_2_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let relay_2_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "par": [1, 3] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
{ "par": [2, 0] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "request_sent_by" : "Relay2" } },
|
||||
]);
|
||||
let relay_2_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::stream_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]]), "void2"),
|
||||
executed_state::scalar_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]])),
|
||||
executed_state::par(1, 3),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
executed_state::par(2, 0),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::request_sent_by("Relay2"),
|
||||
];
|
||||
|
||||
assert_eq!(relay_2_res_json, relay_2_expected_json);
|
||||
assert_eq!(relay_2_actual_trace, relay_2_expected_trace);
|
||||
assert_eq!(relay_2_res.next_peer_pks, vec![String::from("B")]);
|
||||
|
||||
let client_2_res = call_vm!(client_2, "asd", script, relay_2_res.data, "[]");
|
||||
|
||||
let client_2_res_json: JValue =
|
||||
let client_2_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&client_2_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let client_2_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "call": { "executed" : [["A", "Relay1"], ["B", "Relay2"]]} },
|
||||
{ "par": [1, 3] },
|
||||
{ "call": { "request_sent_by" : "Remote" } },
|
||||
{ "par": [2, 0] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
]);
|
||||
let client_2_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::stream_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]]), "void2"),
|
||||
executed_state::scalar_jvalue(json!([["A", "Relay1"], ["B", "Relay2"]])),
|
||||
executed_state::par(1, 3),
|
||||
executed_state::request_sent_by("Remote"),
|
||||
executed_state::par(2, 0),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::stream_string("test", "void3"),
|
||||
];
|
||||
|
||||
assert_eq!(client_2_res_json, client_2_expected_json);
|
||||
assert_eq!(client_2_actual_trace, client_2_expected_trace);
|
||||
assert_eq!(client_2_res.next_peer_pks, Vec::<String>::new());
|
||||
}
|
||||
|
||||
@ -233,21 +229,21 @@ fn join() {
|
||||
let relay_1_res = call_vm!(relay_1, "asd", script.clone(), remote_res.data, "[]");
|
||||
let client_1_res = call_vm!(client_1, "asd", script, relay_1_res.data, "[]");
|
||||
|
||||
let client_1_res_json: JValue =
|
||||
let client_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&client_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let client_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A"], ["B"]]} },
|
||||
{ "par": [2, 3] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "par": [2, 0] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
]);
|
||||
let client_1_expected_trace = vec![
|
||||
executed_state::stream_string("test", "void1"),
|
||||
executed_state::scalar_jvalue(json!([["A"], ["B"]])),
|
||||
executed_state::par(2, 3),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::stream_string("test", "void3"),
|
||||
executed_state::par(2, 0),
|
||||
executed_state::stream_string("test", "void"),
|
||||
executed_state::stream_string("test", "void3"),
|
||||
];
|
||||
|
||||
assert_eq!(client_1_res_json, client_1_expected_json);
|
||||
assert_eq!(client_1_actual_trace, client_1_expected_trace);
|
||||
assert_eq!(client_1_res.next_peer_pks, Vec::<String>::new());
|
||||
}
|
||||
|
||||
@ -313,41 +309,41 @@ fn init_peer_id() {
|
||||
""
|
||||
);
|
||||
|
||||
let client_1_res_json: JValue =
|
||||
let client_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&client_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let client_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A"], ["B"]]} },
|
||||
{ "par": [2, 3] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "par": [2, 0] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "request_sent_by" : "A" } },
|
||||
]);
|
||||
let client_1_expected_trace = vec![
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_jvalue(json!([["A"], ["B"]])),
|
||||
executed_state::par(2, 3),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::par(2, 0),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::request_sent_by("A"),
|
||||
];
|
||||
|
||||
assert_eq!(client_1_res_json, client_1_expected_json);
|
||||
assert_eq!(client_1_actual_trace, client_1_expected_trace);
|
||||
assert_eq!(client_1_res.next_peer_pks, vec![initiator_peer_id.clone()]);
|
||||
|
||||
let initiator_1_res = call_vm!(initiator, initiator_peer_id, script, client_1_res.data, "");
|
||||
|
||||
let initiator_1_res_json: JValue =
|
||||
let initiator_1_actual_trace: ExecutionTrace =
|
||||
serde_json::from_slice(&initiator_1_res.data).expect("interpreter should return valid json");
|
||||
|
||||
let initiator_1_expected_json = json!( [
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : [["A"], ["B"]]} },
|
||||
{ "par": [2, 3] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "par": [2, 0] },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
{ "call": { "executed" : "test" } },
|
||||
]);
|
||||
let initiator_1_expected_trace = vec![
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_jvalue(json!([["A"], ["B"]])),
|
||||
executed_state::par(2, 3),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::par(2, 0),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_string("test"),
|
||||
executed_state::scalar_string("test"),
|
||||
];
|
||||
|
||||
assert_eq!(initiator_1_res_json, initiator_1_expected_json);
|
||||
assert_eq!(initiator_1_actual_trace, initiator_1_expected_trace);
|
||||
assert_eq!(initiator_1_res.next_peer_pks, Vec::<String>::new());
|
||||
}
|
24
air/tests/test_module/integration/mod.rs
Normal file
24
air/tests/test_module/integration/mod.rs
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod air_basic;
|
||||
mod dashboard;
|
||||
mod data_merge;
|
||||
mod flattening;
|
||||
mod join;
|
||||
mod join_behaviour;
|
||||
mod last_error;
|
||||
mod network_explore;
|
33
air/tests/test_module/integration/scripts/inner_folds_v1.clj
Normal file
33
air/tests/test_module/integration/scripts/inner_folds_v1.clj
Normal file
@ -0,0 +1,33 @@
|
||||
(seq
|
||||
(seq
|
||||
(call "{0}" ("" "") ["stream1"] stream1)
|
||||
(call "{0}" ("" "") ["stream2"] stream2)
|
||||
)
|
||||
(fold stream1 v1
|
||||
(seq
|
||||
(fold stream2 v2
|
||||
(seq
|
||||
(call "{1}" ("" "") [v1 v2] stream_out1[])
|
||||
(seq
|
||||
(call "{1}" ("" "") [v1 v2] stream_out2[])
|
||||
(seq
|
||||
|
||||
(next v2)
|
||||
(seq
|
||||
(call "{1}" ("" "") [v1 v2] stream_out3[])
|
||||
(seq
|
||||
(call "{1}" ("" "") [v1 v2] stream_out4[])
|
||||
(seq
|
||||
(call "{1}" ("" "") [v1 v2] stream_out5[])
|
||||
(call "{1}" ("" "") [v1 v2] stream_out6[])
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(next v1)
|
||||
)
|
||||
)
|
||||
)
|
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -145,15 +145,15 @@ checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.2"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -207,9 +207,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.1"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
@ -267,16 +267,6 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fce-timestamp-macro"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c59a6302902583b2c84e87de9d72b949da4396a369baf0aaa49e97021600bb0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
@ -285,13 +275,13 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fluence"
|
||||
version = "0.6.1"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b2f78a2432dcd10e7113f9f08aac004373dee610a3b4ca692d5b12a3e7c867"
|
||||
checksum = "bd1f159a4da6aef89e8e4a0bf061a8031d669d03d9928266942581a52df03f56"
|
||||
dependencies = [
|
||||
"fce-timestamp-macro",
|
||||
"fluence-sdk-macro",
|
||||
"fluence-sdk-main",
|
||||
"marine-macro",
|
||||
"marine-timestamp-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -305,40 +295,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-macro"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb43d2f51f1becb70e2125ef8ca9759597900f95cc22ce7dca981a7d6ccd7dde"
|
||||
dependencies = [
|
||||
"fluence-sdk-wit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.6.1"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a78910d85e3cdcb9c2baf56144f20a99925c67ac445d4156220c005bfd2f9604"
|
||||
checksum = "b3a5d1ca20ada064379d959a9a82f9c006e4d9388533cf06010186fef6dd583b"
|
||||
dependencies = [
|
||||
"fluence-sdk-macro",
|
||||
"log",
|
||||
"marine-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-wit"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab3ed39703b72e0e52bce9e1760746c73f65a5694c8da4dec751d3bfdec15b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@ -352,9 +319,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@ -369,9 +336,9 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -387,9 +354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.1"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
||||
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@ -469,24 +436,57 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.82"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c1652b6ac1bbdde9a66c16c8a2f9cd34d005a1f1b211a538c5b28764faa6ef4"
|
||||
dependencies = [
|
||||
"marine-macro-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro-impl"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80fee75eaf1a97ee9fe2d382c0537c06a79e5d7ab9d81bda6cb263fb8fd1a15a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-timestamp-macro"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6feb612ccd3fd39ec3d50c9a1a96885e1fd32d36a92cf674a0fbe6f7c452613"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
@ -543,9 +543,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6"
|
||||
checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d"
|
||||
|
||||
[[package]]
|
||||
name = "polyplets"
|
||||
@ -563,9 +563,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@ -604,21 +604,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
@ -672,9 +671,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.3"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
|
||||
checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
@ -690,9 +689,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.67"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -721,33 +720,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
@ -776,9 +766,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
@ -786,7 +776,7 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom 0.2.1",
|
||||
"getrandom 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
@ -9,7 +9,7 @@ name = "auth_module"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
air = { path = "../../../../air" }
|
||||
air = { path = "../../../../../../air" }
|
||||
fluence = "0.6.5"
|
||||
|
||||
[workspace]
|
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -137,15 +137,15 @@ checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.2"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -199,9 +199,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.1"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
@ -259,16 +259,6 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fce-timestamp-macro"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c59a6302902583b2c84e87de9d72b949da4396a369baf0aaa49e97021600bb0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
@ -277,13 +267,13 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fluence"
|
||||
version = "0.6.1"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b2f78a2432dcd10e7113f9f08aac004373dee610a3b4ca692d5b12a3e7c867"
|
||||
checksum = "bd1f159a4da6aef89e8e4a0bf061a8031d669d03d9928266942581a52df03f56"
|
||||
dependencies = [
|
||||
"fce-timestamp-macro",
|
||||
"fluence-sdk-macro",
|
||||
"fluence-sdk-main",
|
||||
"marine-macro",
|
||||
"marine-timestamp-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -297,40 +287,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-macro"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb43d2f51f1becb70e2125ef8ca9759597900f95cc22ce7dca981a7d6ccd7dde"
|
||||
dependencies = [
|
||||
"fluence-sdk-wit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.6.1"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a78910d85e3cdcb9c2baf56144f20a99925c67ac445d4156220c005bfd2f9604"
|
||||
checksum = "b3a5d1ca20ada064379d959a9a82f9c006e4d9388533cf06010186fef6dd583b"
|
||||
dependencies = [
|
||||
"fluence-sdk-macro",
|
||||
"log",
|
||||
"marine-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-wit"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab3ed39703b72e0e52bce9e1760746c73f65a5694c8da4dec751d3bfdec15b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@ -344,9 +311,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@ -361,9 +328,9 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -379,9 +346,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.1"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
||||
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@ -461,17 +428,17 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.82"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -483,10 +450,43 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
name = "marine-macro"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "1c1652b6ac1bbdde9a66c16c8a2f9cd34d005a1f1b211a538c5b28764faa6ef4"
|
||||
dependencies = [
|
||||
"marine-macro-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro-impl"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80fee75eaf1a97ee9fe2d382c0537c06a79e5d7ab9d81bda6cb263fb8fd1a15a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-timestamp-macro"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6feb612ccd3fd39ec3d50c9a1a96885e1fd32d36a92cf674a0fbe6f7c452613"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
@ -543,9 +543,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6"
|
||||
checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d"
|
||||
|
||||
[[package]]
|
||||
name = "polyplets"
|
||||
@ -563,9 +563,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@ -604,21 +604,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
@ -672,9 +671,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.3"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
|
||||
checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
@ -690,9 +689,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.67"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -721,33 +720,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
@ -776,9 +766,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
@ -786,7 +776,7 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom 0.2.1",
|
||||
"getrandom 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
@ -9,7 +9,7 @@ name = "log_storage"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
air = { path = "../../../../air" }
|
||||
air = { path = "../../../../../../air" }
|
||||
fluence = "0.6.5"
|
||||
|
||||
[workspace]
|
19
air/tests/test_module/main.rs
Normal file
19
air/tests/test_module/main.rs
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html
|
||||
mod instructions;
|
||||
mod integration;
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "air-test-utils"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
@ -12,4 +12,6 @@ path = "src/lib.rs"
|
||||
[dependencies]
|
||||
fluence = "0.6.5"
|
||||
avm-server = { path = "../../avm/server", features = ["raw-avm-api"] }
|
||||
air = { path = "../../air" }
|
||||
|
||||
serde_json = "1.0.56"
|
||||
|
81
crates/test-utils/src/executed_state.rs
Normal file
81
crates/test-utils/src/executed_state.rs
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::JValue;
|
||||
use air::execution_trace::CallResult;
|
||||
use air::execution_trace::ExecutedState;
|
||||
use air::execution_trace::ParResult;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
pub fn scalar_jvalue(result: JValue) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(result)))
|
||||
}
|
||||
|
||||
pub fn stream_jvalue(result: JValue, _stream_name: impl Into<String>) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(result)))
|
||||
}
|
||||
|
||||
pub fn scalar_string(result: impl Into<String>) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(JValue::String(result.into()))))
|
||||
}
|
||||
|
||||
pub fn scalar_string_array(result: Vec<impl Into<String>>) -> ExecutedState {
|
||||
let result = result
|
||||
.into_iter()
|
||||
.map(|s| JValue::String(s.into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(JValue::Array(result))))
|
||||
}
|
||||
|
||||
pub fn stream_string(result: impl Into<String>, _stream_name: impl Into<String>) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(JValue::String(result.into()))))
|
||||
}
|
||||
|
||||
pub fn stream_number(
|
||||
result: impl Into<serde_json::Number>,
|
||||
_stream_name: impl Into<String>,
|
||||
) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(JValue::Number(result.into()))))
|
||||
}
|
||||
|
||||
pub fn stream_string_array(
|
||||
result: Vec<impl Into<String>>,
|
||||
_stream_name: impl Into<String>,
|
||||
) -> ExecutedState {
|
||||
let result = result
|
||||
.into_iter()
|
||||
.map(|s| JValue::String(s.into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ExecutedState::Call(CallResult::Executed(Rc::new(JValue::Array(result))))
|
||||
}
|
||||
|
||||
pub fn request_sent_by(sender: impl Into<String>) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::RequestSentBy(sender.into()))
|
||||
}
|
||||
|
||||
pub fn par(left: usize, right: usize) -> ExecutedState {
|
||||
ExecutedState::Par(ParResult(left, right))
|
||||
}
|
||||
|
||||
pub fn service_failed(ret_code: i32, error_message: impl Into<String>) -> ExecutedState {
|
||||
ExecutedState::Call(CallResult::CallServiceFailed(
|
||||
ret_code,
|
||||
Rc::new(error_message.into()),
|
||||
))
|
||||
}
|
@ -25,6 +25,8 @@
|
||||
unreachable_patterns
|
||||
)]
|
||||
|
||||
pub mod executed_state;
|
||||
|
||||
pub use avm_server::ne_vec::NEVec;
|
||||
pub use avm_server::AVMConfig;
|
||||
pub use avm_server::AVMError;
|
||||
@ -35,10 +37,12 @@ pub use avm_server::InterpreterOutcome;
|
||||
pub use avm_server::ParticleParameters;
|
||||
pub use avm_server::AVM;
|
||||
|
||||
pub use air::execution_trace::ExecutionTrace;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
pub(self) type JValue = serde_json::Value;
|
||||
|
||||
pub fn create_avm(call_service: CallServiceClosure, current_peer_id: impl Into<String>) -> AVM {
|
||||
let tmp_dir = std::env::temp_dir();
|
||||
|
Loading…
Reference in New Issue
Block a user