#![cfg(all(feature = "native-db", feature = "bebop"))]
mod common;
use std::sync::Arc;
use std::time::Duration;
use atomic_websocket::common::set_setting;
use atomic_websocket::external::bebop::Record;
use atomic_websocket::external::native_db::{Builder, Models};
use atomic_websocket::schema::ServerConnectInfo;
use atomic_websocket::server_sender::{
get_internal_connect, ClientOptions, SenderStatus, ServerSender, ServerSenderTrait,
};
use atomic_websocket::types::{save_key, RwServerSender, DB};
use atomic_websocket::Settings;
use tempfile::NamedTempFile;
use tokio::sync::{Mutex, RwLock};
use common::{wait_for_status, TestServer};
fn make_native_db() -> (NamedTempFile, DB) {
let mut models = Models::new();
models.define::<Settings>().unwrap();
let models: &'static Models = Box::leak(Box::new(models));
let temp = NamedTempFile::new().unwrap();
let db = Builder::new().create(models, temp.path()).unwrap();
(temp, Arc::new(Mutex::new(db)))
}
async fn make_server_sender(db: DB, options: ClientOptions) -> RwServerSender {
let mut ss: RwServerSender = Arc::new(RwLock::new(ServerSender::new(
db,
"".into(),
options,
)));
let clone = ss.clone();
ServerSenderTrait::regist(&mut ss, clone).await;
ss
}
async fn store_server_ip(db: &DB, server_ip: &str, port: &str) {
let mut buf = Vec::new();
ServerConnectInfo { server_ip, port }
.serialize(&mut buf)
.unwrap();
set_setting(
db.clone(),
Settings {
key: save_key::SERVER_CONNECT_INFO.to_owned(),
value: buf,
},
)
.await
.unwrap();
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn no_auto_scan_when_discovery_disabled() {
let (_temp, db) = make_native_db();
let options = ClientOptions::default(); let ss = make_server_sender(db.clone(), options.clone()).await;
let mut rx = ss.get_status_receiver().await.expect("status receiver");
let port = "9000".to_string();
let call = get_internal_connect(
Some(ServerConnectInfo {
server_ip: "",
port: &port,
}),
db.clone(),
ss.clone(),
options.clone(),
);
tokio::time::timeout(Duration::from_secs(3), call)
.await
.expect("get_internal_connect hung — auto-scan regression?")
.expect("get_internal_connect returned Err");
let got_disconnected = wait_for_status(
&mut rx,
SenderStatus::Disconnected,
Duration::from_secs(2),
)
.await;
assert!(
got_disconnected,
"expected Disconnected when discovery is disabled and no IP is known"
);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn direct_fixed_ip_connects() {
let port = common::find_available_port().await;
let server = TestServer::start(port).await;
let (_temp, db) = make_native_db();
let options = ClientOptions::default();
let ss = make_server_sender(db.clone(), options.clone()).await;
let url = format!("ws://127.0.0.1:{port}");
let port_str = port.to_string();
store_server_ip(&db, &url, &port_str).await;
let mut rx = ss.get_status_receiver().await.expect("status receiver");
get_internal_connect(
Some(ServerConnectInfo {
server_ip: "",
port: &port_str,
}),
db.clone(),
ss.clone(),
options.clone(),
)
.await
.expect("get_internal_connect returned Err");
let connected =
wait_for_status(&mut rx, SenderStatus::Connected, Duration::from_secs(5)).await;
assert!(connected, "direct fixed-IP connect should reach Connected");
server.shutdown().await;
}