sdk_relay/tests/functional_ws.rs

71 lines
2.6 KiB
Rust

use futures_util::{SinkExt, StreamExt};
use serde_json::json;
use tokio_tungstenite::connect_async;
use std::time::Duration;
async fn ws_available(url: &str) -> bool {
match connect_async(url).await {
Ok((_ws, _)) => true,
Err(_) => false,
}
}
async fn http_healthy() -> bool {
let base = std::env::var("SDK_RELAY_HTTP").unwrap_or_else(|_| "http://localhost:8091".to_string());
let client = match reqwest::Client::builder().timeout(Duration::from_millis(500)).build() {
Ok(c) => c,
Err(_) => return false,
};
match client.get(format!("{}/health", base)).send().await {
Ok(resp) => resp.status().is_success(),
Err(_) => false,
}
}
#[tokio::test]
async fn websocket_ping_pong_should_work() {
let url = std::env::var("SDK_RELAY_WS").unwrap_or_else(|_| "ws://localhost:8090".to_string());
if !http_healthy().await || !ws_available(&url).await {
eprintln!("sdk_relay WS indisponible, test ping/pong ignoré");
return;
}
let (mut ws, _) = connect_async(url).await.expect("connect ws");
let ping = json!({"type":"ping","client_id":"functional-test","timestamp":1703001600u64}).to_string();
ws.send(tokio_tungstenite::tungstenite::Message::Text(ping))
.await
.expect("send ping");
let msg = ws.next().await.expect("no response").expect("ws err");
let txt = msg.into_text().expect("not text");
let json: serde_json::Value = serde_json::from_str(&txt).expect("invalid json");
assert_eq!(json.get("type").and_then(|v| v.as_str()).unwrap_or(""), "pong");
}
#[tokio::test]
async fn websocket_subscribe_should_ack() {
let url = std::env::var("SDK_RELAY_WS").unwrap_or_else(|_| "ws://localhost:8090".to_string());
if !http_healthy().await || !ws_available(&url).await {
eprintln!("sdk_relay WS indisponible, test subscribe ignoré");
return;
}
let (mut ws, _) = connect_async(url).await.expect("connect ws");
let subscribe = json!({
"type":"subscribe",
"subscriptions":["notifications","health","metrics"],
"client_id":"functional-test",
"timestamp":1703001600u64
}).to_string();
ws.send(tokio_tungstenite::tungstenite::Message::Text(subscribe))
.await
.expect("send subscribe");
let msg = ws.next().await.expect("no response").expect("ws err");
let txt = msg.into_text().expect("not text");
let json: serde_json::Value = serde_json::from_str(&txt).expect("invalid json");
assert_eq!(json.get("type").and_then(|v| v.as_str()).unwrap_or(""), "subscribe_response");
assert_eq!(json.get("status").and_then(|v| v.as_str()).unwrap_or(""), "subscribed");
}