use std::sync::Arc;
use tokio::sync::oneshot;
use opendeviationbar_streaming::gap::{GapFillCommand, GapFillResult, gap_fill_channel};
#[tokio::test]
async fn test_command_channel_roundtrip() {
let (tx, mut rx) = gap_fill_channel(16);
let (response_tx, response_rx) = oneshot::channel();
let cmd = GapFillCommand {
symbol: Arc::from("BTCUSDT"),
from_tid: 1000,
to_tid: 2000,
response_tx,
};
tx.send(cmd).await.unwrap();
let received = rx.recv().await.unwrap();
assert_eq!(&*received.symbol, "BTCUSDT");
assert_eq!(received.from_tid, 1000);
assert_eq!(received.to_tid, 2000);
received
.response_tx
.send(GapFillResult {
trades_fetched: 1000,
bars_produced: 42,
duration_ms: 850,
partial: false,
})
.unwrap();
let result = response_rx.await.unwrap();
assert_eq!(result.trades_fetched, 1000);
assert_eq!(result.bars_produced, 42);
assert_eq!(result.duration_ms, 850);
assert!(!result.partial);
}
#[tokio::test]
async fn test_command_channel_multiple_symbols() {
let (btc_tx, mut btc_rx) = gap_fill_channel(4);
let (eth_tx, mut eth_rx) = gap_fill_channel(4);
let (resp_tx, _) = oneshot::channel();
btc_tx
.send(GapFillCommand {
symbol: Arc::from("BTCUSDT"),
from_tid: 100,
to_tid: 200,
response_tx: resp_tx,
})
.await
.unwrap();
let (resp_tx, _) = oneshot::channel();
eth_tx
.send(GapFillCommand {
symbol: Arc::from("ETHUSDT"),
from_tid: 500,
to_tid: 600,
response_tx: resp_tx,
})
.await
.unwrap();
let btc_cmd = btc_rx.recv().await.unwrap();
assert_eq!(&*btc_cmd.symbol, "BTCUSDT");
let eth_cmd = eth_rx.recv().await.unwrap();
assert_eq!(&*eth_cmd.symbol, "ETHUSDT");
}
#[tokio::test]
async fn test_command_channel_sender_cloneable() {
let (tx, mut rx) = gap_fill_channel(4);
let tx2 = tx.clone();
let (resp_tx, _) = oneshot::channel();
tx2.send(GapFillCommand {
symbol: Arc::from("BTCUSDT"),
from_tid: 1,
to_tid: 10,
response_tx: resp_tx,
})
.await
.unwrap();
let cmd = rx.recv().await.unwrap();
assert_eq!(cmd.from_tid, 1);
}
#[tokio::test]
async fn test_command_channel_caller_dropped() {
let (tx, mut rx) = gap_fill_channel(4);
let (resp_tx, resp_rx) = oneshot::channel();
tx.send(GapFillCommand {
symbol: Arc::from("BTCUSDT"),
from_tid: 1,
to_tid: 10,
response_tx: resp_tx,
})
.await
.unwrap();
drop(resp_rx);
let cmd = rx.recv().await.unwrap();
let send_result = cmd.response_tx.send(GapFillResult {
trades_fetched: 0,
bars_produced: 0,
duration_ms: 0,
partial: false,
});
assert!(send_result.is_err());
}