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 > ) -> & 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+ . unwrap_or_else ( || panic ! ( "Received message is None" ) ) ;
43+ self . messages . push ( msg) ;
44+ self . messages . last ( ) . unwrap ( )
45+ }
4546
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- }
47+ pub async fn assert_next < F > ( & mut self , timeout : Option < Duration > , assertion : F )
48+ where
49+ F : FnOnce ( & WriterMessage ) -> bool ,
50+ {
51+ let msg = self . get_next ( timeout) . await ;
52+ assert ! ( assertion( msg) ) ;
53+ }
5254
53- tokio:: time:: sleep ( Duration :: from_millis ( 1 ) ) . await ;
54- }
55+ pub async fn assert_disconnected ( & mut self , timeout : Option < Duration > ) {
56+ self . assert_next ( timeout, |msg| matches ! ( msg, & WriterMessage :: Disconnect ) )
57+ . await ;
58+ assert ! ( self . receiver. is_closed( ) ) ;
5559 }
5660
57- fn spawn_writer ( ) -> ( WriterRef , MessageStore ) {
61+ fn spawn_writer ( ) -> ( WriterRef , mpsc :: UnboundedReceiver < WriterMessage > ) {
5862 // mock implementation to receive messages from the session
5963 // and hold on to them for test assertions
60- let received_messages : MessageStore = Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ;
64+ let ( tx , rx ) = mpsc :: unbounded_channel ( ) ;
6165 let ( sender, mailbox) = mpsc:: channel ( 10 ) ;
62- tokio:: spawn ( Self :: run_writer ( mailbox, received_messages . clone ( ) ) ) ;
66+ tokio:: spawn ( Self :: run_writer ( mailbox, tx ) ) ;
6367
64- ( WriterRef :: new ( sender) , received_messages )
68+ ( WriterRef :: new ( sender) , rx )
6569 }
6670
6771 fn create_reader ( ) -> ( ReaderRef , oneshot:: Sender < ( ) > ) {
@@ -70,19 +74,18 @@ impl MockCounterparty {
7074 }
7175
7276 async fn run_writer (
73- mut mailbox : Receiver < WriterMessage > ,
74- received_messages : Arc < Mutex < Vec < RawFixMessage > > > ,
77+ mut mailbox : mpsc :: Receiver < WriterMessage > ,
78+ received_messages : mpsc :: UnboundedSender < WriterMessage > ,
7579 ) {
7680 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- }
81+ println ! ( "Received message from session: {msg:?}" ) ;
82+ let disconnect = matches ! ( msg, WriterMessage :: Disconnect ) ;
83+ if let Err ( e) = received_messages. send ( msg) {
84+ panic ! ( "Failed to send message. Error: {e:?}" ) ;
85+ }
86+ if disconnect {
87+ println ! ( "Disconnecting" ) ;
88+ break ;
8689 }
8790 }
8891 }
0 commit comments