205 lines
7.7 KiB
Rust
Raw Normal View History

2021-02-18 17:30:14 +03:00
/*
* 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::prelude::*;
2021-02-18 17:30:14 +03:00
use std::cell::RefCell;
use std::rc::Rc;
type ClosureSettableVar<T> = Rc<RefCell<T>>;
#[derive(Default, Clone, Debug, PartialEq, Eq)]
struct ClosureCallArgs {
pub(self) service_id_var: Rc<RefCell<String>>,
pub(self) function_name_var: ClosureSettableVar<String>,
pub(self) args_var: ClosureSettableVar<Vec<i32>>,
pub(self) tetraplets: ClosureSettableVar<Vec<Vec<String>>>,
}
fn create_check_service_closure(closure_call_args: ClosureCallArgs) -> CallServiceClosure {
Box::new(move |params| -> CallServiceResult {
2021-02-18 17:30:14 +03:00
use std::ops::Deref;
*closure_call_args.service_id_var.deref().borrow_mut() = params.service_id.clone();
*closure_call_args.function_name_var.deref().borrow_mut() = params.function_name.clone();
2021-02-18 17:30:14 +03:00
let call_args: Vec<i32> =
serde_json::from_value(JValue::Array(params.arguments)).expect("json deserialization shouldn't fail");
2021-02-18 17:30:14 +03:00
*closure_call_args.args_var.deref().borrow_mut() = call_args;
CallServiceResult::ok(json!(""))
2021-02-18 17:30:14 +03:00
})
}
#[test]
fn flattening_scalar_arrays() {
let scalar_array = json!({"iterable": [
{"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]},
{"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [2, 3]},
]});
let set_variable_peer_id = "set_variable";
let mut set_variable_vm = create_avm(set_variable_call_service(scalar_array), set_variable_peer_id);
2021-02-18 17:30:14 +03:00
let closure_call_args = ClosureCallArgs::default();
let local_peer_id = "local_peer_id";
let mut local_vm = create_avm(create_check_service_closure(closure_call_args.clone()), local_peer_id);
2021-02-18 17:30:14 +03:00
2022-03-10 16:06:43 +03:00
let script = f!(r#"
2021-02-18 17:30:14 +03:00
(seq
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] scalar_array)
2021-02-18 17:30:14 +03:00
(fold scalar_array.$.iterable! v
(seq
(call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args.[0]! v.$.args.[1]!])
2021-02-18 17:30:14 +03:00
(next v)
)
)
)
2022-03-10 16:06:43 +03:00
"#);
2021-02-18 17:30:14 +03:00
2022-04-20 23:05:37 +03:00
let result = checked_call_vm!(set_variable_vm, <_>::default(), script.clone(), "", "");
let result = call_vm!(local_vm, <_>::default(), script.clone(), "", result.data);
2021-02-18 17:30:14 +03:00
2021-12-21 11:37:35 +03:00
assert!(is_interpreter_succeded(&result));
2021-02-18 17:30:14 +03:00
assert_eq!(
closure_call_args.service_id_var,
Rc::new(RefCell::new("local_service_id".to_string()))
);
assert_eq!(
closure_call_args.function_name_var,
Rc::new(RefCell::new("local_function_name".to_string()))
);
assert_eq!(closure_call_args.args_var, Rc::new(RefCell::new(vec![2, 3])));
}
#[test]
2021-08-24 16:14:15 +03:00
#[ignore]
2021-02-18 17:30:14 +03:00
fn flattening_streams() {
let stream_value = json!(
{"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]}
);
let set_variable_peer_id = "set_variable";
let mut set_variable_vm = create_avm(set_variable_call_service(stream_value), set_variable_peer_id);
2021-02-18 17:30:14 +03:00
let closure_call_args = ClosureCallArgs::default();
let local_peer_id = "local_peer_id";
let mut local_vm = create_avm(create_check_service_closure(closure_call_args.clone()), local_peer_id);
2021-02-18 17:30:14 +03:00
2022-03-10 16:06:43 +03:00
let script = f!(r#"
2021-02-18 17:30:14 +03:00
(seq
(seq
(seq
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] $stream)
(call "{set_variable_peer_id}" ("" "") [] $stream)
2021-02-18 17:30:14 +03:00
)
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] $stream)
2021-02-18 17:30:14 +03:00
)
(fold $stream.$.[0,1,2] v
2021-02-18 17:30:14 +03:00
(seq
(call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args[0]! v.$.args[1]!])
(next v)
)
)
)
2022-03-10 16:06:43 +03:00
"#);
2021-02-18 17:30:14 +03:00
2022-04-20 23:05:37 +03:00
let result = checked_call_vm!(set_variable_vm, <_>::default(), script.clone(), "", "");
let result = call_vm!(local_vm, <_>::default(), script.clone(), "", result.data);
2021-02-18 17:30:14 +03:00
2021-12-21 11:37:35 +03:00
assert!(is_interpreter_succeded(&result));
2021-02-18 17:30:14 +03:00
assert_eq!(
closure_call_args.service_id_var,
Rc::new(RefCell::new("local_service_id".to_string()))
);
assert_eq!(
closure_call_args.function_name_var,
Rc::new(RefCell::new("local_function_name".to_string()))
);
assert_eq!(closure_call_args.args_var, Rc::new(RefCell::new(vec![0, 1])));
}
2021-06-01 18:43:11 +03:00
#[test]
fn flattening_empty_values() {
let stream_value = json!(
{"args": []}
);
let set_variable_peer_id = "set_variable";
let mut set_variable_vm = create_avm(set_variable_call_service(stream_value), set_variable_peer_id);
let closure_call_args = ClosureCallArgs::default();
let local_peer_id = "local_peer_id";
let mut local_vm = create_avm(create_check_service_closure(closure_call_args.clone()), local_peer_id);
2022-03-10 16:06:43 +03:00
let script = f!(r#"
2021-06-01 18:43:11 +03:00
(seq
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] $stream)
(call "{local_peer_id}" ("" "") [$stream.$.[1]!]) ; here $stream.$.[1] returns an empty array
2021-06-01 18:43:11 +03:00
)
2022-03-10 16:06:43 +03:00
"#);
2021-06-01 18:43:11 +03:00
2022-04-20 23:05:37 +03:00
let result = checked_call_vm!(set_variable_vm, <_>::default(), script.clone(), "", "");
let result = checked_call_vm!(local_vm, <_>::default(), script.clone(), "", result.data);
2021-06-01 18:43:11 +03:00
2021-12-21 11:37:35 +03:00
assert!(is_interpreter_succeded(&result));
2021-06-01 18:43:11 +03:00
assert_eq!(closure_call_args.args_var, Rc::new(RefCell::new(vec![])));
}
2021-02-18 17:30:14 +03:00
#[test]
2021-08-24 16:14:15 +03:00
#[ignore]
2021-02-18 17:30:14 +03:00
fn test_handling_non_flattening_values() {
let stream_value = json!(
{"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]}
);
let set_variable_peer_id = "set_variable";
let mut set_variable_vm = create_avm(set_variable_call_service(stream_value), set_variable_peer_id);
2021-02-18 17:30:14 +03:00
let closure_call_args = ClosureCallArgs::default();
let local_peer_id = "local_peer_id";
let mut local_vm = create_avm(create_check_service_closure(closure_call_args.clone()), local_peer_id);
2021-02-18 17:30:14 +03:00
2022-03-10 16:06:43 +03:00
let script = f!(r#"
2021-02-18 17:30:14 +03:00
(seq
(seq
(seq
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] $stream)
(call "{set_variable_peer_id}" ("" "") [] $stream)
2021-02-18 17:30:14 +03:00
)
2022-03-10 16:06:43 +03:00
(call "{set_variable_peer_id}" ("" "") [] $stream)
2021-02-18 17:30:14 +03:00
)
(fold $stream.$.[0,1,2]! v
2021-02-18 17:30:14 +03:00
(seq
(call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args[0]! v.$.args[1]!])
(next v)
)
)
)
2022-03-10 16:06:43 +03:00
"#);
2021-02-18 17:30:14 +03:00
2022-04-20 23:05:37 +03:00
let result = checked_call_vm!(set_variable_vm, <_>::default(), &script, "", "");
let result = call_vm!(local_vm, <_>::default(), &script, "", result.data);
2021-02-18 17:30:14 +03:00
2021-08-24 16:14:15 +03:00
assert_eq!(result.ret_code, 1017);
2021-02-18 17:30:14 +03:00
assert_eq!(
2021-08-24 16:14:15 +03:00
result.error_message,
2021-02-18 17:30:14 +03:00
String::from(
2021-06-01 18:43:11 +03:00
r#"jvalue '[{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]},{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]},{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]}]' can't be flattened, to be flattened a jvalue should have an array type and consist of zero or one values"#
2021-02-18 17:30:14 +03:00
)
);
}