@@ -143,6 +143,124 @@ struct PeerTests {
143143 typealias EphemeralHandler = MockEphemeralStreamHandler
144144 }
145145
146+ @Test
147+ func reopenUpStream( ) async throws {
148+ let handler2 = MockPresentStreamHandler ( )
149+ var messageData = Data ( " reopen up stream " . utf8)
150+ let peer1 = try Peer (
151+ options: PeerOptions < MockStreamHandler > (
152+ role: . validator,
153+ listenAddress: NetAddr ( ipAddress: " 127.0.0.1 " , port: 0 ) !,
154+ genesisHeader: Data32 ( ) ,
155+ secretKey: Ed25519 . SecretKey ( from: Data32 . random ( ) ) ,
156+ presistentStreamHandler: MockPresentStreamHandler ( ) ,
157+ ephemeralStreamHandler: MockEphemeralStreamHandler ( ) ,
158+ serverSettings: . defaultSettings,
159+ clientSettings: . defaultSettings
160+ )
161+ )
162+ let peer2 = try Peer (
163+ options: PeerOptions < MockStreamHandler > (
164+ role: . validator,
165+ listenAddress: NetAddr ( ipAddress: " 127.0.0.1 " , port: 0 ) !,
166+ genesisHeader: Data32 ( ) ,
167+ secretKey: Ed25519 . SecretKey ( from: Data32 . random ( ) ) ,
168+ presistentStreamHandler: handler2,
169+ ephemeralStreamHandler: MockEphemeralStreamHandler ( ) ,
170+ serverSettings: . defaultSettings,
171+ clientSettings: . defaultSettings
172+ )
173+ )
174+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
175+
176+ let connection = try peer1. connect (
177+ to: peer2. listenAddress ( ) , role: . validator
178+ )
179+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
180+
181+ peer1. broadcast (
182+ kind: . uniqueA, message: . init( kind: . uniqueA, data: messageData)
183+ )
184+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
185+ let lastReceivedData = await handler2. lastReceivedData
186+ #expect( lastReceivedData == messageData)
187+
188+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
189+ // Simulate abnormal close stream
190+ let stream = connection. presistentStreams. read { presistentStreams in
191+ presistentStreams [ . uniqueA]
192+ }
193+ stream!. close ( abort: true )
194+ // Wait to simulate downtime & reopen up stream 3~5s
195+ try ? await Task . sleep ( for: . milliseconds( 3000 ) )
196+ messageData = Data ( " reopen up stream data " . utf8)
197+ peer1. broadcast (
198+ kind: . uniqueA, message: . init( kind: . uniqueA, data: messageData)
199+ )
200+ try await Task . sleep ( for: . milliseconds( 1000 ) )
201+ let lastReceivedData2 = await handler2. lastReceivedData
202+ #expect( lastReceivedData2 == messageData)
203+ }
204+
205+ @Test
206+ func regularClosedStream( ) async throws {
207+ let handler2 = MockPresentStreamHandler ( )
208+ var messageData = Data ( " reopen up stream " . utf8)
209+ let peer1 = try Peer (
210+ options: PeerOptions < MockStreamHandler > (
211+ role: . validator,
212+ listenAddress: NetAddr ( ipAddress: " 127.0.0.1 " , port: 0 ) !,
213+ genesisHeader: Data32 ( ) ,
214+ secretKey: Ed25519 . SecretKey ( from: Data32 . random ( ) ) ,
215+ presistentStreamHandler: MockPresentStreamHandler ( ) ,
216+ ephemeralStreamHandler: MockEphemeralStreamHandler ( ) ,
217+ serverSettings: . defaultSettings,
218+ clientSettings: . defaultSettings
219+ )
220+ )
221+ let peer2 = try Peer (
222+ options: PeerOptions < MockStreamHandler > (
223+ role: . validator,
224+ listenAddress: NetAddr ( ipAddress: " 127.0.0.1 " , port: 0 ) !,
225+ genesisHeader: Data32 ( ) ,
226+ secretKey: Ed25519 . SecretKey ( from: Data32 . random ( ) ) ,
227+ presistentStreamHandler: handler2,
228+ ephemeralStreamHandler: MockEphemeralStreamHandler ( ) ,
229+ serverSettings: . defaultSettings,
230+ clientSettings: . defaultSettings
231+ )
232+ )
233+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
234+
235+ let connection = try peer1. connect (
236+ to: peer2. listenAddress ( ) , role: . validator
237+ )
238+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
239+
240+ peer1. broadcast (
241+ kind: . uniqueA, message: . init( kind: . uniqueA, data: messageData)
242+ )
243+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
244+ let lastReceivedData = await handler2. lastReceivedData
245+ #expect( lastReceivedData == messageData)
246+
247+ try ? await Task . sleep ( for: . milliseconds( 100 ) )
248+ // Simulate regular close stream
249+ let stream = connection. presistentStreams. read { presistentStreams in
250+ presistentStreams [ . uniqueA]
251+ }
252+ stream!. close ( abort: false )
253+ // Wait to simulate downtime
254+ try ? await Task . sleep ( for: . milliseconds( 3000 ) )
255+ messageData = Data ( " close up stream " . utf8)
256+ peer1. broadcast (
257+ kind: . uniqueA, message: . init( kind: . uniqueA, data: messageData)
258+ )
259+ try await Task . sleep ( for: . milliseconds( 1000 ) )
260+ let lastReceivedData2 = await handler2. lastReceivedData
261+ #expect( lastReceivedData2 != messageData)
262+ }
263+
146264 @Test
147265 func concurrentPeerConnection( ) async throws {
148266 let peer1 = try Peer (
@@ -611,10 +729,11 @@ struct PeerTests {
611729 data: Data ( " Message from peer \( i) " . utf8)
612730 )
613731 peer. broadcast ( kind: message. kind, message: message)
732+ try ? await Task . sleep ( for: . milliseconds( 50 ) )
614733 }
615734
616735 // Wait for message propagation
617- try ? await Task . sleep ( for: . milliseconds( 100 ) )
736+ try ? await Task . sleep ( for: . milliseconds( 1000 ) )
618737
619738 // everyone should receive two messages
620739 for (idx, handler) in handlers. enumerated ( ) {
0 commit comments