Skip to content

Commit e1ad8e7

Browse files
committed
Leverage session info API to improve test case for peer timeout
1 parent 9a770cc commit e1ad8e7

5 files changed

Lines changed: 44 additions & 5 deletions

File tree

crates/hotfix/src/session.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@ use crate::message::sequence_reset::SequenceReset;
3232
use crate::message::test_request::TestRequest;
3333
use crate::message_utils::is_admin;
3434
use crate::session::event::AwaitingActiveSessionResponse;
35-
use crate::session::info::SessionInfo;
3635
use crate::session::state::{AwaitingResendState, TestRequestId};
3736
use crate::session_schedule::SessionSchedule;
3837
use event::SessionEvent;
3938
use hotfix_message::parsed_message::ParsedMessage;
4039
use state::SessionState;
4140

41+
pub use info::{SessionInfo, Status};
42+
4243
const SCHEDULE_CHECK_INTERVAL: u64 = 1;
4344

4445
#[derive(Clone)]

crates/hotfix/src/session/info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct SessionInfo {
1313
///
1414
/// These roughly correspond to the `SessionState` variants but don't contain
1515
/// internal state.
16-
#[derive(Clone, Debug)]
16+
#[derive(Clone, Debug, PartialEq)]
1717
pub enum Status {
1818
AwaitingLogon,
1919
AwaitingResend,

crates/hotfix/tests/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod mock_application;
22
pub mod mock_counterparty;
3+
pub mod session_assertions;
34
pub mod test_messages;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::common::test_messages::TestMessage;
2+
use hotfix::session::{SessionRef, Status};
3+
use std::time::Duration;
4+
5+
pub trait SessionAssertions {
6+
async fn assert_status(&self, expected_status: Status);
7+
async fn assert_status_with_timeout(&self, expected_status: Status, timeout: Duration);
8+
}
9+
10+
impl SessionAssertions for SessionRef<TestMessage> {
11+
async fn assert_status(&self, expected_status: Status) {
12+
self.assert_status_with_timeout(expected_status, Duration::from_millis(10))
13+
.await;
14+
}
15+
16+
async fn assert_status_with_timeout(&self, expected_status: Status, timeout: Duration) {
17+
let deadline = tokio::time::Instant::now() + timeout;
18+
let retry_interval = Duration::from_millis(1);
19+
20+
let mut session_info = self.get_session_info().await;
21+
while tokio::time::Instant::now() < deadline {
22+
if session_info.status == expected_status {
23+
return;
24+
}
25+
tokio::time::sleep(retry_interval).await;
26+
session_info = self.get_session_info().await;
27+
}
28+
29+
let actual_status = session_info.status;
30+
panic!(
31+
"session did not reach expected status within timeout. Expected: {expected_status:?}, Actual: {actual_status:?}"
32+
);
33+
}
34+
}

crates/hotfix/tests/session_tests.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::common::mock_application::MockApplication;
22
use crate::common::mock_counterparty::MockCounterparty;
3+
use crate::common::session_assertions::SessionAssertions;
34
use crate::common::test_messages::TestMessage;
45
use hotfix::application::ApplicationRef;
56
use hotfix::config::SessionConfig;
6-
use hotfix::session::SessionRef;
7+
use hotfix::session::{SessionRef, Status};
78
use hotfix::store::in_memory::InMemoryMessageStore;
89
use hotfix_message::Part;
910
use hotfix_message::fix44::MSG_TYPE;
@@ -56,16 +57,18 @@ async fn test_heartbeats() {
5657
/// if no response is received within the timeout period.
5758
#[tokio::test(start_paused = true)]
5859
async fn test_peer_timeout() {
59-
let (_session, mut mock_counterparty) = setup().await;
60+
let (session, mut mock_counterparty) = setup().await;
6061
let peer_interval = (1.2 * HEARTBEAT_INTERVAL as f64) as u64 + 1;
6162

6263
// assert that a logon message is received (type 'A')
6364
mock_counterparty
6465
.assert_next(|msg| assert_eq!(msg.header().get::<&str>(MSG_TYPE).unwrap(), "A"))
6566
.await;
67+
session.assert_status(Status::AwaitingLogon).await;
68+
6669
// counterparty responds with a logon to establish a happy session
6770
mock_counterparty.send_logon().await;
68-
tokio::task::yield_now().await;
71+
session.assert_status(Status::Active).await;
6972

7073
// let's wait enough time for a heartbeat and assert that the heartbeat was sent
7174
tokio::time::advance(std::time::Duration::from_secs(HEARTBEAT_INTERVAL + 1)).await;

0 commit comments

Comments
 (0)