From 2762c34ebe2806ef440a995f2cc5d87cf2b57fad Mon Sep 17 00:00:00 2001 From: Michele Sollecito Date: Mon, 19 Nov 2018 18:06:27 +0000 Subject: [PATCH] [CORDA-1877]: Ensured Driver fails to start when Notary tried to bind an already bound port. (#4246) --- .../corda/node/AddressBindingFailureTests.kt | 21 +++++++++++++++++++ .../testing/node/internal/DriverDSLImpl.kt | 9 ++++++++ 2 files changed, 30 insertions(+) diff --git a/node/src/integration-test/kotlin/net/corda/node/AddressBindingFailureTests.kt b/node/src/integration-test/kotlin/net/corda/node/AddressBindingFailureTests.kt index 8b366f33a9..802893b7a6 100644 --- a/node/src/integration-test/kotlin/net/corda/node/AddressBindingFailureTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/AddressBindingFailureTests.kt @@ -1,11 +1,13 @@ package net.corda.node +import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow import net.corda.core.internal.errors.AddressBindingException import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.driver +import net.corda.testing.node.NotarySpec import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.Test @@ -30,6 +32,25 @@ class AddressBindingFailureTests { @Test fun `H2 address`() = assertBindExceptionForOverrides { address -> mapOf("h2Settings" to mapOf("address" to address.toString()), "dataSourceProperties.dataSource.password" to "password") } + @Test + fun `notary P2P address`() { + ServerSocket(0).use { socket -> + + val notaryName = CordaX500Name.parse("O=Notary Cleaning Service, L=Zurich, C=CH") + val address = InetSocketAddress(socket.localPort).toNetworkHostAndPort() + + assertThatThrownBy { + driver(DriverParameters(startNodesInProcess = false, + notarySpecs = listOf(NotarySpec(notaryName)), + notaryCustomOverrides = mapOf("p2pAddress" to address.toString()), + portAllocation = portAllocation) + ) {} }.isInstanceOfSatisfying(IllegalStateException::class.java) { error -> + + assertThat(error.message).contains("Unable to start notaries") + } + } + } + private fun assertBindExceptionForOverrides(overrides: (NetworkHostAndPort) -> Map) { ServerSocket(0).use { socket -> diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 324f8ca6de..11944cbf3e 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -71,6 +71,7 @@ import java.util.* import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException import java.util.concurrent.atomic.AtomicInteger import kotlin.collections.ArrayList import kotlin.collections.HashMap @@ -396,6 +397,13 @@ class DriverDSLImpl( NotaryHandle(identity, validating, nodeHandlesFuture) } } + try { + _notaries.map { notary -> notary.map { handle -> handle.nodeHandles } }.getOrThrow(notaryHandleTimeout).forEach { future -> future.getOrThrow(notaryHandleTimeout) } + } catch (e: ListenProcessDeathException) { + throw IllegalStateException("Unable to start notaries. A required port might be bound already.", e) + } catch (e: TimeoutException) { + throw IllegalStateException("Unable to start notaries. A required port might be bound already.", e) + } } private fun startNotaryIdentityGeneration(): CordaFuture> { @@ -700,6 +708,7 @@ class DriverDSLImpl( companion object { internal val log = contextLogger() + private val notaryHandleTimeout = Duration.ofMinutes(1) private val defaultRpcUserList = listOf(InternalUser("default", "default", setOf("ALL")).toConfig().root().unwrapped()) private val names = arrayOf(ALICE_NAME, BOB_NAME, DUMMY_BANK_A_NAME) /**