Skip to content

Commit 4a1dfd2

Browse files
authored
Reenable ServerSocket tests (#1777)
There are issues with IPv6 loopback addresses on build machines, so we force IPv4 and use non-blocking socket servers.
1 parent e092677 commit 4a1dfd2

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala

+24-23
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ import org.scalatest.funsuite.FixtureAnyFunSuiteLike
3737
import org.scalatest.{Outcome, ParallelTestExecution, Tag}
3838
import scodec.bits.ByteVector
3939

40-
import java.net.{ServerSocket, Socket}
41-
import java.util.concurrent.Executors
40+
import java.net.InetSocketAddress
41+
import java.nio.channels.ServerSocketChannel
4242
import scala.concurrent.duration._
43-
import scala.concurrent.{ExecutionContext, Future}
4443

4544
class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with ParallelTestExecution {
4645

46+
import PeerSpec._
47+
4748
val fakeIPAddress: NodeAddress = NodeAddress.fromParts("1.2.3.4", 42000).get
4849

4950
case class FixtureParam(nodeParams: NodeParams, remoteNodeId: PublicKey, peer: TestFSMRef[Peer.State, Peer.Data, Peer], peerConnection: TestProbe, channel: TestProbe)
@@ -106,41 +107,35 @@ class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with Paralle
106107
probe.expectMsg(PeerConnection.ConnectionResult.NoAddressFound)
107108
}
108109

109-
ignore("successfully connect to peer at user request") { f =>
110+
test("successfully connect to peer at user request") { f =>
110111
import f._
111112

112113
// this actor listens to connection requests and creates connections
113114
system.actorOf(ClientSpawner.props(nodeParams.keyPair, nodeParams.socksProxy_opt, nodeParams.peerConnectionConf, TestProbe().ref, TestProbe().ref))
114115

115116
// we create a dummy tcp server and update bob's announcement to point to it
116-
val mockServer = new ServerSocket(0, 1) // port will be assigned automatically
117-
val mockAddress = HostAndPort.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort)
117+
val (mockServer, serverAddress) = createMockServer()
118+
val mockAddress = HostAndPort.fromParts(serverAddress.getHostName, serverAddress.getPort)
118119

119120
val probe = TestProbe()
120121
probe.send(peer, Peer.Init(Set.empty))
121122
// we have auto-reconnect=false so we need to manually tell the peer to reconnect
122123
probe.send(peer, Peer.Connect(remoteNodeId, Some(mockAddress)))
123124

124125
// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
125-
val res = TestProbe()
126-
Future {
127-
val socket = mockServer.accept()
128-
res.ref ! socket
129-
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
130-
res.expectMsgType[Socket](10 seconds)
131-
126+
awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
132127
mockServer.close()
133128
}
134129

135-
ignore("successfully reconnect to peer at startup when there are existing channels", Tag("auto_reconnect")) { f =>
130+
test("successfully reconnect to peer at startup when there are existing channels", Tag("auto_reconnect")) { f =>
136131
import f._
137132

138133
// this actor listens to connection requests and creates connections
139134
system.actorOf(ClientSpawner.props(nodeParams.keyPair, nodeParams.socksProxy_opt, nodeParams.peerConnectionConf, TestProbe().ref, TestProbe().ref))
140135

141136
// we create a dummy tcp server and update bob's announcement to point to it
142-
val mockServer = new ServerSocket(0, 1) // port will be assigned automatically
143-
val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get
137+
val (mockServer, serverAddress) = createMockServer()
138+
val mockAddress = NodeAddress.fromParts(serverAddress.getHostName, serverAddress.getPort).get
144139

145140
// we put the server address in the node db
146141
val ann = NodeAnnouncement(randomBytes64, Features.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", mockAddress :: Nil)
@@ -150,13 +145,7 @@ class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with Paralle
150145
probe.send(peer, Peer.Init(Set(ChannelCodecsSpec.normal)))
151146

152147
// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
153-
val res = TestProbe()
154-
Future {
155-
val socket = mockServer.accept()
156-
res.ref ! socket
157-
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
158-
res.expectMsgType[Socket](10 seconds)
159-
148+
awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
160149
mockServer.close()
161150
}
162151

@@ -379,3 +368,15 @@ class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with Paralle
379368
assert(init.pushAmount === 100.msat)
380369
}
381370
}
371+
372+
object PeerSpec {
373+
374+
def createMockServer(): (ServerSocketChannel, InetSocketAddress) = {
375+
val mockServer = ServerSocketChannel.open()
376+
// NB: we force 127.0.0.1 (IPv4) because there are issues on ubuntu build machines with IPv6 loopback
377+
mockServer.bind(new InetSocketAddress("127.0.0.1", 0))
378+
mockServer.configureBlocking(false)
379+
(mockServer, mockServer.getLocalAddress.asInstanceOf[InetSocketAddress])
380+
}
381+
382+
}

eclair-core/src/test/scala/fr/acinq/eclair/io/ReconnectionTaskSpec.scala

+4-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import fr.acinq.eclair.wire.protocol.{Color, NodeAddress, NodeAnnouncement}
2525
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
2626
import org.scalatest.{Outcome, ParallelTestExecution, Tag}
2727

28-
import java.net.ServerSocket
2928
import scala.concurrent.duration._
3029

3130
class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with ParallelTestExecution {
@@ -218,12 +217,12 @@ class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
218217

219218
}
220219

221-
ignore("reconnect using the address from node_announcement") { f =>
220+
test("reconnect using the address from node_announcement") { f =>
222221
import f._
223222

224223
// we create a dummy tcp server and update bob's announcement to point to it
225-
val mockServer = new ServerSocket(0, 1) // port will be assigned automatically
226-
val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get
224+
val (mockServer, serverAddress) = PeerSpec.createMockServer()
225+
val mockAddress = NodeAddress.fromParts(serverAddress.getHostName, serverAddress.getPort).get
227226
val bobAnnouncement = NodeAnnouncement(randomBytes64, Features.empty, 1, remoteNodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", mockAddress :: Nil)
228227
nodeParams.db.network.addNode(bobAnnouncement)
229228

@@ -232,11 +231,8 @@ class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
232231
peer.send(reconnectionTask, Peer.Connect(remoteNodeId, None))
233232

234233
// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
235-
within(30 seconds) {
236-
mockServer.accept()
237-
}
234+
awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
238235
mockServer.close()
239236
}
240237

241-
242238
}

0 commit comments

Comments
 (0)