#![cfg(feature = "mongodb")]
use std::time::{Duration, Instant};
use mongodb::bson::{Document, doc};
use mongodb::{Client, Collection};
use truefix_log::{Log, MongoLog, MongoLogConfig};
async fn count_with_retry(collection: &Collection<Document>, timeout: Duration) -> u64 {
let start = Instant::now();
loop {
let count = collection.count_documents(doc! {}).await.unwrap();
if count > 0 || start.elapsed() > timeout {
return count;
}
tokio::time::sleep(Duration::from_millis(50)).await;
}
}
#[tokio::test]
async fn mongo_log_persists_messages_and_events_if_available() {
let Ok(uri) = std::env::var("DATABASE_URL_MONGO") else {
eprintln!("skipping: DATABASE_URL_MONGO not set");
return;
};
let config = MongoLogConfig {
incoming_collection: "t031_log_incoming".to_owned(),
outgoing_collection: "t031_log_outgoing".to_owned(),
event_collection: "t031_log_event".to_owned(),
..MongoLogConfig::new(&uri)
};
let log = MongoLog::connect_with_config(config).await.unwrap();
log.on_incoming("8=FIX.4.4\x0135=A\x01");
log.on_outgoing("8=FIX.4.4\x0135=0\x01");
log.on_event("logged on");
let client = Client::with_uri_str(&uri).await.unwrap();
let db = client.database("truefix");
let timeout = Duration::from_secs(5);
let incoming = count_with_retry(&db.collection("t031_log_incoming"), timeout).await;
let outgoing = count_with_retry(&db.collection("t031_log_outgoing"), timeout).await;
let events = count_with_retry(&db.collection("t031_log_event"), timeout).await;
assert_eq!(incoming, 1, "one incoming message logged");
assert_eq!(outgoing, 1, "one outgoing message logged");
assert_eq!(events, 1, "one event logged");
}
#[tokio::test]
async fn mongo_log_documents_carry_logged_at_and_session_id_if_available() {
let Ok(uri) = std::env::var("DATABASE_URL_MONGO") else {
eprintln!("skipping: DATABASE_URL_MONGO not set");
return;
};
let config = MongoLogConfig {
event_collection: "t058_log_event".to_owned(),
session_id: "SERVER->CLIENT".to_owned(),
..MongoLogConfig::new(&uri)
};
let log = MongoLog::connect_with_config(config).await.unwrap();
log.on_event("logged on");
let client = Client::with_uri_str(&uri).await.unwrap();
let db = client.database("truefix");
let collection: Collection<Document> = db.collection("t058_log_event");
let _ = count_with_retry(&collection, Duration::from_secs(5)).await;
let doc = collection.find_one(doc! {}).await.unwrap().unwrap();
let logged_at = doc.get_i64("logged_at").unwrap();
let session_id = doc.get_str("session_id").unwrap();
assert!(logged_at > 0, "expected a nonzero logged_at timestamp");
assert_eq!(session_id, "SERVER->CLIENT");
}
#[tokio::test]
async fn mongo_log_heartbeats_n_filters_heartbeats_if_available() {
let Ok(uri) = std::env::var("DATABASE_URL_MONGO") else {
eprintln!("skipping: DATABASE_URL_MONGO not set");
return;
};
let config = MongoLogConfig {
incoming_collection: "t031_hb_log_incoming".to_owned(),
outgoing_collection: "t031_hb_log_outgoing".to_owned(),
event_collection: "t031_hb_log_event".to_owned(),
include_heartbeats: false,
..MongoLogConfig::new(&uri)
};
let log = MongoLog::connect_with_config(config).await.unwrap();
log.on_incoming("8=FIX.4.4\x0135=0\x01"); log.on_incoming("8=FIX.4.4\x0135=A\x01");
let client = Client::with_uri_str(&uri).await.unwrap();
let db = client.database("truefix");
let incoming = count_with_retry(
&db.collection("t031_hb_log_incoming"),
Duration::from_secs(5),
)
.await;
assert_eq!(incoming, 1, "only the non-heartbeat should be logged");
}