@@ -66,6 +66,14 @@ func writeLeiosNotifyTestSegment(
6666 require .NoError (t , err )
6767}
6868
69+ type leiosNotifyFailWriteConn struct {
70+ net.Conn
71+ }
72+
73+ func (leiosNotifyFailWriteConn ) Write ([]byte ) (int , error ) {
74+ return 0 , errors .New ("test: forced transport write failure" )
75+ }
76+
6977func TestNewServer (t * testing.T ) {
7078 connId := connection.ConnectionId {
7179 LocalAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
@@ -112,6 +120,165 @@ func TestHandleRequestNext_CallbackIsCalled(t *testing.T) {
112120 assert .True (t , called , "expected RequestNextFunc to be called" )
113121}
114122
123+ func TestHandleRequestNextReportsSuccessfulSend (t * testing.T ) {
124+ connId := connection.ConnectionId {
125+ LocalAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
126+ RemoteAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
127+ }
128+ connA , connB := net .Pipe ()
129+ defer connA .Close ()
130+ defer connB .Close ()
131+ m := muxer .New (connA )
132+ defer m .Stop ()
133+
134+ response := NewMsgBlockAnnouncement (cbor.RawMessage {0x82 , 0x01 , 0x02 })
135+ type sendResult struct {
136+ msg protocol.Message
137+ err error
138+ }
139+ resultCh := make (chan sendResult , 1 )
140+ cfg := NewConfig (
141+ WithRequestNextFunc (func (CallbackContext ) (protocol.Message , error ) {
142+ return response , nil
143+ }),
144+ WithResponseSentFunc (func (
145+ _ CallbackContext ,
146+ msg protocol.Message ,
147+ err error ,
148+ ) {
149+ resultCh <- sendResult {msg : msg , err : err }
150+ }),
151+ )
152+ server := NewServer (protocol.ProtocolOptions {
153+ ConnectionId : connId ,
154+ Muxer : m ,
155+ }, & cfg )
156+ server .Start ()
157+ defer server .Protocol .Stop ()
158+ m .Start ()
159+
160+ requestData , err := cbor .Encode (NewMsgNotificationRequestNext ())
161+ require .NoError (t , err )
162+ writeLeiosNotifyTestSegment (
163+ t ,
164+ connB ,
165+ muxer .NewSegment (ProtocolId , requestData , false ),
166+ )
167+ require .NoError (t , connB .SetReadDeadline (time .Now ().Add (time .Second )))
168+ _ , err = readLeiosNotifyTestSegment (t , connB )
169+ require .NoError (t , err )
170+
171+ select {
172+ case result := <- resultCh :
173+ require .Same (t , response , result .msg )
174+ require .NoError (t , result .err )
175+ case <- time .After (time .Second ):
176+ t .Fatal ("timed out waiting for response send callback" )
177+ }
178+ }
179+
180+ func TestHandleRequestNextReportsFailedSend (t * testing.T ) {
181+ connId := connection.ConnectionId {
182+ LocalAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
183+ RemoteAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
184+ }
185+ resultCh := make (chan error , 1 )
186+ connA , connB := net .Pipe ()
187+ defer connA .Close ()
188+ defer connB .Close ()
189+ m := muxer .New (leiosNotifyFailWriteConn {Conn : connA })
190+ defer m .Stop ()
191+ cfg := NewConfig (
192+ WithRequestNextFunc (func (CallbackContext ) (protocol.Message , error ) {
193+ return NewMsgBlockAnnouncement (cbor.RawMessage {0x81 , 0x01 }), nil
194+ }),
195+ WithResponseSentFunc (func (
196+ _ CallbackContext ,
197+ _ protocol.Message ,
198+ err error ,
199+ ) {
200+ resultCh <- err
201+ }),
202+ )
203+ server := NewServer (protocol.ProtocolOptions {
204+ ConnectionId : connId ,
205+ Muxer : m ,
206+ }, & cfg )
207+ server .Start ()
208+ defer server .Protocol .Stop ()
209+ m .Start ()
210+
211+ requestData , err := cbor .Encode (NewMsgNotificationRequestNext ())
212+ require .NoError (t , err )
213+ writeLeiosNotifyTestSegment (
214+ t ,
215+ connB ,
216+ muxer .NewSegment (ProtocolId , requestData , false ),
217+ )
218+
219+ select {
220+ case sendErr := <- resultCh :
221+ require .Error (t , sendErr )
222+ case <- time .After (time .Second ):
223+ t .Fatal ("timed out waiting for failed response send callback" )
224+ }
225+ }
226+
227+ func TestHandleRequestNextReportsShutdownBeforeDelivery (t * testing.T ) {
228+ connId := connection.ConnectionId {
229+ LocalAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
230+ RemoteAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
231+ }
232+ connA , connB := net .Pipe ()
233+ defer connA .Close ()
234+ defer connB .Close ()
235+ m := muxer .New (connA )
236+ defer m .Stop ()
237+
238+ requestCalled := make (chan struct {})
239+ resultCh := make (chan error , 1 )
240+ cfg := NewConfig (
241+ WithRequestNextFunc (func (CallbackContext ) (protocol.Message , error ) {
242+ close (requestCalled )
243+ return NewMsgBlockAnnouncement (cbor.RawMessage {0x81 , 0x01 }), nil
244+ }),
245+ WithResponseSentFunc (func (
246+ _ CallbackContext ,
247+ _ protocol.Message ,
248+ err error ,
249+ ) {
250+ resultCh <- err
251+ }),
252+ )
253+ server := NewServer (protocol.ProtocolOptions {
254+ ConnectionId : connId ,
255+ Muxer : m ,
256+ }, & cfg )
257+ server .Start ()
258+ m .Start ()
259+
260+ requestData , err := cbor .Encode (NewMsgNotificationRequestNext ())
261+ require .NoError (t , err )
262+ writeLeiosNotifyTestSegment (
263+ t ,
264+ connB ,
265+ muxer .NewSegment (ProtocolId , requestData , false ),
266+ )
267+ select {
268+ case <- requestCalled :
269+ case <- time .After (time .Second ):
270+ t .Fatal ("timed out waiting for request callback" )
271+ }
272+ server .Protocol .Stop ()
273+
274+ select {
275+ case sendErr := <- resultCh :
276+ require .ErrorIs (t , sendErr , protocol .ErrProtocolShuttingDown )
277+ case <- time .After (time .Second ):
278+ t .Fatal ("timed out waiting for shutdown delivery callback" )
279+ }
280+ }
281+
115282func TestHandleRequestNext_NilCallback (t * testing.T ) {
116283 connId := connection.ConnectionId {
117284 LocalAddr : & net.TCPAddr {IP : net .IPv4 (127 , 0 , 0 , 1 ), Port : 0 },
0 commit comments