@@ -30,12 +30,12 @@ import scala.concurrent.duration._
30
30
31
31
class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with ParallelTestExecution {
32
32
33
- val fakeIPAddress = NodeAddress .fromParts(" 1.2.3.4" , 42000 ).get
34
- val channels = Map (Peer .FinalChannelId (randomBytes32) -> system.deadLetters)
33
+ private val fakeIPAddress = NodeAddress .fromParts(" 1.2.3.4" , 42000 ).get
34
+ private val channels = Map (Peer .FinalChannelId (randomBytes32) -> system.deadLetters)
35
35
36
- val PeerNothingData = Peer .Nothing
37
- val PeerDisconnectedData = Peer .DisconnectedData (channels)
38
- val PeerConnectedData = Peer .ConnectedData (fakeIPAddress.socketAddress, system.deadLetters, null , null , channels.map { case (k : ChannelId , v) => (k, v) })
36
+ private val PeerNothingData = Peer .Nothing
37
+ private val PeerDisconnectedData = Peer .DisconnectedData (channels)
38
+ private val PeerConnectedData = Peer .ConnectedData (fakeIPAddress.socketAddress, system.deadLetters, null , null , channels.map { case (k : ChannelId , v) => (k, v) })
39
39
40
40
case class FixtureParam (nodeParams : NodeParams , remoteNodeId : PublicKey , reconnectionTask : TestFSMRef [ReconnectionTask .State , ReconnectionTask .Data , ReconnectionTask ], monitor : TestProbe )
41
41
@@ -168,6 +168,56 @@ class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
168
168
assert(waitingData3.nextReconnectionDelay === (waitingData0.nextReconnectionDelay * 8 ))
169
169
}
170
170
171
+ test(" all kind of connection failures should be caught by the reconnection task" , Tag (" auto_reconnect" )) { f =>
172
+ import f ._
173
+
174
+ val peer = TestProbe ()
175
+ nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, fakeIPAddress)
176
+ peer.send(reconnectionTask, Peer .Transition (PeerNothingData , PeerDisconnectedData ))
177
+ val TransitionWithData (ReconnectionTask .IDLE , ReconnectionTask .WAITING , _, _) = monitor.expectMsgType[TransitionWithData ]
178
+ val TransitionWithData (ReconnectionTask .WAITING , ReconnectionTask .CONNECTING , _, connectingData : ReconnectionTask .ConnectingData ) = monitor.expectMsgType[TransitionWithData ]
179
+
180
+ val failures = List (
181
+ PeerConnection .ConnectionResult .ConnectionFailed (connectingData.to),
182
+ PeerConnection .ConnectionResult .NoAddressFound ,
183
+ PeerConnection .ConnectionResult .InitializationFailed (" incompatible features" ),
184
+ PeerConnection .ConnectionResult .AuthenticationFailed (" authentication timeout" )
185
+ )
186
+
187
+ failures.foreach { failure =>
188
+ // we simulate a connection error
189
+ reconnectionTask ! failure
190
+ // a new reconnection task will be scheduled
191
+ val TransitionWithData (ReconnectionTask .CONNECTING , ReconnectionTask .WAITING , _, _) = monitor.expectMsgType[TransitionWithData ]
192
+ // we send the tick manually so we don't wait
193
+ reconnectionTask ! ReconnectionTask .TickReconnect
194
+ // this triggers a reconnection
195
+ val TransitionWithData (ReconnectionTask .WAITING , ReconnectionTask .CONNECTING , _, _) = monitor.expectMsgType[TransitionWithData ]
196
+ }
197
+ }
198
+
199
+ test(" concurrent incoming/outgoing reconnection" , Tag (" auto_reconnect" )) { f =>
200
+ import f ._
201
+
202
+ val peer = TestProbe ()
203
+ nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, fakeIPAddress)
204
+ peer.send(reconnectionTask, Peer .Transition (PeerNothingData , PeerDisconnectedData ))
205
+ val TransitionWithData (ReconnectionTask .IDLE , ReconnectionTask .WAITING , _, _) = monitor.expectMsgType[TransitionWithData ]
206
+ val TransitionWithData (ReconnectionTask .WAITING , ReconnectionTask .CONNECTING , _, _ : ReconnectionTask .ConnectingData ) = monitor.expectMsgType[TransitionWithData ]
207
+
208
+ // at this point, we are attempting to connect to the peer
209
+ // let's assume that an incoming connection arrives from the peer right before our outgoing connection, but we haven't
210
+ // yet received the peer transition
211
+ reconnectionTask ! PeerConnection .ConnectionResult .AlreadyConnected
212
+ // we will schedule a reconnection
213
+ val TransitionWithData (ReconnectionTask .CONNECTING , ReconnectionTask .WAITING , _, _) = monitor.expectMsgType[TransitionWithData ]
214
+ // but immediately after that we finally get notified that the peer is connected
215
+ peer.send(reconnectionTask, Peer .Transition (PeerDisconnectedData , PeerConnectedData ))
216
+ // we cancel the reconnection and go to idle state
217
+ val TransitionWithData (ReconnectionTask .WAITING , ReconnectionTask .IDLE , _, _) = monitor.expectMsgType[TransitionWithData ]
218
+
219
+ }
220
+
171
221
test(" reconnect using the address from node_announcement" ) { f =>
172
222
import f ._
173
223
0 commit comments