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 .
* /
2021-10-04 10:58:00 +03:00
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 {
2021-10-04 10:58:00 +03:00
Box ::new ( move | params | -> CallServiceResult {
2021-02-18 17:30:14 +03:00
use std ::ops ::Deref ;
2021-10-04 10:58:00 +03:00
* 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
2021-10-04 10:58:00 +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 ;
2021-10-04 10:58:00 +03:00
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 " ;
2021-05-10 14:25:34 +03:00
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 " ;
2021-05-10 14:25:34 +03:00
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
2021-10-18 23:23:30 +03:00
( 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 " ;
2021-05-10 14:25:34 +03:00
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 " ;
2021-05-10 14:25:34 +03:00
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
)
2021-03-26 17:13:28 +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 " ;
2021-05-10 14:25:34 +03:00
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 " ;
2021-05-10 14:25:34 +03:00
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
)
2021-03-26 17:13:28 +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
)
) ;
}