mirror of
https://github.com/fluencelabs/aquavm
synced 2025-04-24 23:02:16 +00:00
260 lines
8.9 KiB
Rust
260 lines
8.9 KiB
Rust
/*
|
|
* 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::prelude::*;
|
|
|
|
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 |params| -> CallServiceResult {
|
|
let result = json!(params.tetraplets);
|
|
*arg_tetraplets_inner.borrow_mut() = params.tetraplets;
|
|
|
|
CallServiceResult::ok(result)
|
|
});
|
|
|
|
(host_function, arg_tetraplets)
|
|
}
|
|
|
|
#[test]
|
|
fn simple_fold() {
|
|
let return_numbers_call_service: CallServiceClosure = Box::new(|_| -> CallServiceResult {
|
|
CallServiceResult::ok(json!(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]))
|
|
});
|
|
|
|
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 result = checked_call_vm!(set_variable_vm, init_peer_id.clone(), script.clone(), "", "");
|
|
let mut data = result.data;
|
|
|
|
let first_arg_triplet = ResolvedTriplet {
|
|
peer_pk: set_variable_vm_peer_id,
|
|
service_id,
|
|
function_name,
|
|
};
|
|
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_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 result = checked_call_vm!(client_vms[i].0, init_peer_id.clone(), script.clone(), "", data);
|
|
data = result.data;
|
|
|
|
assert_eq!(client_vms[i].1, expected_tetraplets);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn fold_json_path() {
|
|
let return_numbers_call_service: CallServiceClosure = Box::new(|_| -> CallServiceResult {
|
|
CallServiceResult::ok(json!({"args": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]}))
|
|
});
|
|
|
|
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.$.args 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 result = checked_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_tetraplet = SecurityTetraplet {
|
|
triplet: first_arg_triplet,
|
|
json_path: String::from(".args"),
|
|
};
|
|
|
|
let second_arg_triplet = ResolvedTriplet {
|
|
peer_pk: init_peer_id.clone(),
|
|
service_id: String::new(),
|
|
function_name: String::new(),
|
|
};
|
|
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));
|
|
checked_call_vm!(client_vm, init_peer_id.clone(), script.clone(), "", result.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_test_utils::trace_from_result;
|
|
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]
|
|
#[ignore]
|
|
fn tetraplet_with_wasm_modules() {
|
|
use marine_rs_sdk::CallParameters;
|
|
use marine_rs_sdk::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 |params| -> CallServiceResult {
|
|
let tetraplets = serde_json::to_vec(¶ms.tetraplets).expect("default serializer shouldn't fail");
|
|
let tetraplets: Vec<Vec<SDKTetraplet>> =
|
|
serde_json::from_slice(&tetraplets).expect("default deserializer shouldn't fail");
|
|
|
|
let mut call_parameters = CallParameters::default();
|
|
call_parameters.init_peer_id = ADMIN_PEER_PK.to_string();
|
|
call_parameters.tetraplets = tetraplets;
|
|
|
|
let mut service = services_inner.borrow_mut();
|
|
let service: &mut AppService = service.get_mut(params.service_id.as_str()).unwrap();
|
|
|
|
let result = service
|
|
.call(params.function_name, JValue::Array(params.arguments), call_parameters)
|
|
.unwrap();
|
|
|
|
CallServiceResult::ok(result)
|
|
});
|
|
|
|
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 = checked_call_vm!(vm, ADMIN_PEER_PK, script, "", "");
|
|
let actual_trace = trace_from_result(&result);
|
|
let expected_state = executed_state::scalar_string("Ok");
|
|
|
|
assert_eq!(actual_trace[1], expected_state)
|
|
}
|