1- use hotfix:: message:: { FixMessage , RawFixMessage } ;
1+ use hotfix:: message:: FixMessage ;
22use hotfix:: session:: SessionRef ;
33use hotfix:: transport:: FixConnection ;
44use hotfix:: transport:: reader:: ReaderRef ;
55use hotfix:: transport:: writer:: { WriterMessage , WriterRef } ;
6- use std:: sync :: Arc ;
7- use std :: time :: { Duration , Instant } ;
8- use tokio :: sync :: mpsc :: Receiver ;
9- use tokio :: sync :: { Mutex , mpsc , oneshot } ;
6+ use std:: time :: Duration ;
7+ use tokio :: sync :: { mpsc , oneshot } ;
8+
9+ const DEFAULT_TIMEOUT : Duration = Duration :: from_secs ( 1 ) ;
1010
1111pub struct MockCounterparty {
12- received_messages : Arc < Mutex < Vec < RawFixMessage > > > ,
12+ // Receiver-End of the channel
13+ receiver : mpsc:: UnboundedReceiver < WriterMessage > ,
14+ // History of Received messages from the client
15+ messages : Vec < WriterMessage > ,
1316 _connection : FixConnection ,
1417 _dc_sender : oneshot:: Sender < ( ) > ,
1518}
1619
17- type MessageStore = Arc < Mutex < Vec < RawFixMessage > > > ;
18-
1920impl MockCounterparty {
2021 pub async fn start ( session_ref : SessionRef < impl FixMessage > ) -> Self {
21- let ( writer_ref, received_messages ) = Self :: spawn_writer ( ) ;
22+ let ( writer_ref, receiver ) = Self :: spawn_writer ( ) ;
2223 let ( reader_ref, dc_sender) = Self :: create_reader ( ) ;
2324 let connection = FixConnection :: new ( writer_ref, reader_ref) ;
2425
2526 session_ref. register_writer ( connection. get_writer ( ) ) . await ;
2627
2728 Self {
28- received_messages,
29+ receiver,
30+ messages : vec ! [ ] ,
2931 _connection : connection,
3032 _dc_sender : dc_sender,
3133 }
3234 }
3335
34- pub async fn assert_message_count ( & self , expected_count : usize , timeout_secs : f32 ) {
35- let timeout_duration = Duration :: from_secs_f32 ( timeout_secs) ;
36- let start_time = Instant :: now ( ) ;
37-
38- loop {
39- {
40- let messages = self . received_messages . lock ( ) . await ;
41- if messages. len ( ) >= expected_count {
42- return ;
43- }
44- }
36+ /// Listen to the next message on the channel
37+ pub async fn get_next ( & mut self , timeout : Option < Duration > ) -> Option < & WriterMessage > {
38+ let timeout = timeout. unwrap_or ( DEFAULT_TIMEOUT ) ;
39+ let msg = tokio:: time:: timeout ( timeout, self . receiver . recv ( ) )
40+ . await
41+ . unwrap_or_else ( |_| panic ! ( "Message not received in less than {timeout:?}" ) ) ;
42+ if let Some ( msg) = msg {
43+ self . messages . push ( msg) ;
44+ self . messages . last ( )
45+ } else {
46+ None
47+ }
48+ }
4549
46- if start_time. elapsed ( ) >= timeout_duration {
47- let current_count = self . received_messages . lock ( ) . await . len ( ) ;
48- panic ! (
49- "Expected {expected_count} messages, but only received {current_count} within {timeout_secs} seconds"
50- ) ;
51- }
50+ pub async fn assert_next < F > ( & mut self , timeout : Option < Duration > , assertion : F )
51+ where
52+ F : FnOnce ( Option < & WriterMessage > ) -> bool ,
53+ {
54+ let msg = self . get_next ( timeout) . await ;
55+ assert ! ( assertion( msg) ) ;
56+ }
5257
53- tokio:: time:: sleep ( Duration :: from_millis ( 1 ) ) . await ;
54- }
58+ pub async fn assert_disconnected ( & mut self ) {
59+ self . assert_next ( None , |msg| matches ! ( msg, Some ( & WriterMessage :: Disconnect ) ) )
60+ . await ;
61+ assert ! ( self . receiver. is_closed( ) ) ;
5562 }
5663
57- fn spawn_writer ( ) -> ( WriterRef , MessageStore ) {
64+ fn spawn_writer ( ) -> ( WriterRef , mpsc :: UnboundedReceiver < WriterMessage > ) {
5865 // mock implementation to receive messages from the session
5966 // and hold on to them for test assertions
60- let received_messages : MessageStore = Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ;
67+ let ( tx , rx ) = mpsc :: unbounded_channel ( ) ;
6168 let ( sender, mailbox) = mpsc:: channel ( 10 ) ;
62- tokio:: spawn ( Self :: run_writer ( mailbox, received_messages . clone ( ) ) ) ;
69+ tokio:: spawn ( Self :: run_writer ( mailbox, tx ) ) ;
6370
64- ( WriterRef :: new ( sender) , received_messages )
71+ ( WriterRef :: new ( sender) , rx )
6572 }
6673
6774 fn create_reader ( ) -> ( ReaderRef , oneshot:: Sender < ( ) > ) {
@@ -70,19 +77,18 @@ impl MockCounterparty {
7077 }
7178
7279 async fn run_writer (
73- mut mailbox : Receiver < WriterMessage > ,
74- received_messages : Arc < Mutex < Vec < RawFixMessage > > > ,
80+ mut mailbox : mpsc :: Receiver < WriterMessage > ,
81+ received_messages : mpsc :: UnboundedSender < WriterMessage > ,
7582 ) {
7683 while let Some ( msg) = mailbox. recv ( ) . await {
77- match msg {
78- WriterMessage :: SendMessage ( fix_message) => {
79- println ! ( "Received message from session: {fix_message:?}" ) ;
80- received_messages. lock ( ) . await . push ( fix_message) ;
81- }
82- WriterMessage :: Disconnect => {
83- println ! ( "Disconnecting" ) ;
84- break ;
85- }
84+ println ! ( "Received message from session: {msg:?}" ) ;
85+ let disconnect = matches ! ( msg, WriterMessage :: Disconnect ) ;
86+ if let Err ( e) = received_messages. send ( msg) {
87+ panic ! ( "Failed to send message. Error: {e:?}" ) ;
88+ }
89+ if disconnect {
90+ println ! ( "Disconnecting" ) ;
91+ break ;
8692 }
8793 }
8894 }
0 commit comments