#[path = "stub_node_api.rs"]
mod stub_node_api;
use blvm_node::module::api::hub::ModuleApiHub;
use blvm_node::module::ipc::protocol::{MessageType, RequestMessage, RequestPayload};
use blvm_node::module::security::permissions::{Permission, PermissionSet};
use blvm_node::module::traits::ModuleError;
use std::sync::Arc;
use stub_node_api::MockNodeAPI;
#[tokio::test]
async fn test_concurrent_requests() {
let node_api = Arc::new(MockNodeAPI);
let hub = Arc::new(tokio::sync::Mutex::new(ModuleApiHub::new(node_api)));
let mut handles = vec![];
for i in 0..10 {
let hub_clone = hub.clone();
handles.push(tokio::spawn(async move {
let request = RequestMessage {
correlation_id: i,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: format!("test_module_{i}"),
module_name: "Test Module".to_string(),
version: "1.0.0".to_string(),
},
};
let mut hub_guard = hub_clone.lock().await;
hub_guard
.handle_request(&format!("test_module_{i}"), request)
.await
}));
}
let results: Vec<_> = futures::future::join_all(handles)
.await
.into_iter()
.map(|r| r.unwrap())
.collect();
assert_eq!(results.len(), 10);
}
#[tokio::test]
async fn test_permission_edge_cases() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let empty_permissions = PermissionSet::new();
hub.register_module_permissions("test_module".to_string(), empty_permissions.clone());
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: "test_module".to_string(),
module_name: "Test".to_string(),
version: "1.0.0".to_string(),
},
};
let result = hub.handle_request("test_module", request).await;
let _ = result;
let mut all_permissions = PermissionSet::new();
all_permissions.add(Permission::ReadBlockchain);
all_permissions.add(Permission::ReadUTXO);
all_permissions.add(Permission::ReadChainState);
all_permissions.add(Permission::SubscribeEvents);
hub.register_module_permissions("test_module2".to_string(), all_permissions);
let request2 = RequestMessage {
correlation_id: 2,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: "test_module2".to_string(),
module_name: "Test".to_string(),
version: "1.0.0".to_string(),
},
};
let result = hub.handle_request("test_module2", request2).await;
let _ = result;
}
#[tokio::test]
async fn test_error_recovery() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: "wrong_module".to_string(),
module_name: "Test".to_string(),
version: "1.0.0".to_string(),
},
};
let result = hub.handle_request("test_module", request).await;
match result {
Ok(_) => {
}
Err(e) => {
assert!(matches!(
e,
ModuleError::OperationError(_) | ModuleError::PermissionDenied(_)
));
}
}
}