Skip to content

Commit

Permalink
Reenable ServerSocket tests
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 committed Apr 20, 2021
1 parent 33d52b6 commit d8b4596
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 d8b4596

Please sign in to comment.