use std::{path::PathBuf, sync::Arc};
use chrono;
use crate::{
core::{config::Config, supported_message::SupportedMessage},
server::{
address_space::{address_space::*, variable::*},
builder::ServerBuilder,
config::ServerConfig,
session::*,
subscriptions::*,
},
sync::*,
types::{status_code::StatusCode, *},
};
mod address_space;
mod events;
mod services;
mod subscriptions;
fn make_test_file(filename: &str) -> PathBuf {
let mut path = std::env::temp_dir();
path.push(filename);
path
}
fn make_sample_address_space() -> Arc<RwLock<AddressSpace>> {
let address_space = Arc::new(RwLock::new(AddressSpace::new()));
add_sample_vars_to_address_space(address_space.clone());
address_space
}
fn add_sample_vars_to_address_space(address_space: Arc<RwLock<AddressSpace>>) {
let mut address_space = trace_write_lock!(address_space);
let ns = address_space.register_namespace("urn:test").unwrap();
let sample_folder_id = address_space
.add_folder("Sample", "Sample", &NodeId::objects_folder_id())
.unwrap();
let vars = vec![
Variable::new(&NodeId::new(ns, "v1"), "v1", "v1", 30i32),
Variable::new(&NodeId::new(ns, 300), "v2", "v2", true),
Variable::new(
&NodeId::new(ns, "v3"),
"v3",
"v3",
UAString::from("Hello world"),
),
Variable::new(&NodeId::new(ns, "v4"), "v4", "v4", 100.123f64),
];
let _ = address_space.add_variables(vars, &sample_folder_id);
}
#[test]
pub fn server_config_sample_save() {
let config = ServerBuilder::new_sample().config();
let mut path = std::env::current_dir().unwrap();
path.push("..");
path.push("samples");
path.push("server.conf");
println!("Path is {:?}", path);
assert!(config.save(&path).is_ok());
}
#[test]
pub fn server_config_save() {
let path = make_test_file("server_config.yaml");
let config = ServerBuilder::new_anonymous("foo").config();
assert!(config.save(&path).is_ok());
if let Ok(config2) = ServerConfig::load(&path) {
assert_eq!(config, config2);
} else {
panic!("Cannot load config from file");
}
}
#[test]
pub fn server_config_invalid() {
let mut config = ServerBuilder::new_anonymous("foo").config();
assert!(config.is_valid());
config.endpoints.clear();
assert_eq!(config.is_valid(), false);
config = ServerBuilder::new_anonymous("foo").config();
config
.endpoints
.get_mut("none")
.unwrap()
.user_token_ids
.insert("hello".to_string());
assert_eq!(config.is_valid(), false);
}
#[test]
pub fn expired_publish_requests() {
let now = chrono::Utc::now();
let now_plus_5s = now + chrono::Duration::seconds(5);
let now = DateTime::from(now.clone());
let mut pr1 = PublishRequestEntry {
request_id: 1,
request: PublishRequest {
request_header: RequestHeader::new(&NodeId::null(), &now, 1000),
subscription_acknowledgements: None,
},
results: None,
};
pr1.request.request_header.timeout_hint = 5001;
let mut pr2 = PublishRequestEntry {
request_id: 2,
request: PublishRequest {
request_header: RequestHeader::new(&NodeId::null(), &now, 2000),
subscription_acknowledgements: None,
},
results: None,
};
pr2.request.request_header.timeout_hint = 3000;
let mut session = Session::new_no_certificate_store();
{
let publish_request_queue = session.subscriptions_mut().publish_request_queue();
publish_request_queue.clear();
publish_request_queue.push_back(pr1);
publish_request_queue.push_back(pr2);
publish_request_queue
};
session.expire_stale_publish_requests(&now_plus_5s);
{
let publish_request_queue = session.subscriptions_mut().publish_request_queue();
assert_eq!(publish_request_queue.len(), 1);
assert_eq!(
publish_request_queue[0]
.request
.request_header
.request_handle,
1000
);
}
{
let publish_response_queue = session.subscriptions_mut().publish_response_queue();
assert_eq!(publish_response_queue.len(), 1);
let r1 = &publish_response_queue[0];
if let SupportedMessage::ServiceFault(ref response_header) = r1.response {
assert_eq!(response_header.response_header.request_handle, 2000);
assert_eq!(
response_header.response_header.service_result,
StatusCode::BadTimeout
);
} else {
panic!("Expected service faults for timed out publish requests")
}
}
}