Skip to content

Commit

Permalink
Reenable ServerSocket tests (#1777)
Browse files Browse the repository at this point in the history
There are issues with IPv6 loopback addresses on build machines, so we
force IPv4 and use non-blocking socket servers.
  • Loading branch information
t-bast authored Apr 20, 2021
1 parent e092677 commit 4a1dfd2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 31 deletions.
47 changes: 24 additions & 23 deletions eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, ParallelTestExecution, Tag}
import scodec.bits.ByteVector

import java.net.{ServerSocket, Socket}
import java.util.concurrent.Executors
import java.net.InetSocketAddress
import java.nio.channels.ServerSocketChannel
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}

class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with ParallelTestExecution {

import PeerSpec._

val fakeIPAddress: NodeAddress = NodeAddress.fromParts("1.2.3.4", 42000).get

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

ignore("successfully connect to peer at user request") { f =>
test("successfully connect to peer at user request") { f =>
import f._

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

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

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

// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
val res = TestProbe()
Future {
val socket = mockServer.accept()
res.ref ! socket
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
res.expectMsgType[Socket](10 seconds)

awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
mockServer.close()
}

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

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

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

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

// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
val res = TestProbe()
Future {
val socket = mockServer.accept()
res.ref ! socket
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
res.expectMsgType[Socket](10 seconds)

awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
mockServer.close()
}

Expand Down Expand Up @@ -379,3 +368,15 @@ class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with Paralle
assert(init.pushAmount === 100.msat)
}
}

object PeerSpec {

def createMockServer(): (ServerSocketChannel, InetSocketAddress) = {
val mockServer = ServerSocketChannel.open()
// NB: we force 127.0.0.1 (IPv4) because there are issues on ubuntu build machines with IPv6 loopback
mockServer.bind(new InetSocketAddress("127.0.0.1", 0))
mockServer.configureBlocking(false)
(mockServer, mockServer.getLocalAddress.asInstanceOf[InetSocketAddress])
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import fr.acinq.eclair.wire.protocol.{Color, NodeAddress, NodeAnnouncement}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, ParallelTestExecution, Tag}

import java.net.ServerSocket
import scala.concurrent.duration._

class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with ParallelTestExecution {
Expand Down Expand Up @@ -218,12 +217,12 @@ class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike

}

ignore("reconnect using the address from node_announcement") { f =>
test("reconnect using the address from node_announcement") { f =>
import f._

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

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

// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
within(30 seconds) {
mockServer.accept()
}
awaitCond(mockServer.accept() != null, max = 30 seconds, interval = 1 second)
mockServer.close()
}


}

0 comments on commit 4a1dfd2

Please sign in to comment.