diff --git a/testing/node-driver/src/test/java/net/corda/testing/node/PortAllocationRunner.java b/testing/node-driver/src/test/java/net/corda/testing/node/PortAllocationRunner.java deleted file mode 100644 index 904ca17c1a..0000000000 --- a/testing/node-driver/src/test/java/net/corda/testing/node/PortAllocationRunner.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.corda.testing.node; - -import net.corda.testing.driver.PortAllocation; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; - -public class PortAllocationRunner { - - public static void main(@NotNull String[] args) throws IOException { - /* - * each JVM will be launched with [spinnerFile, reportingIndex] - */ - int reportingIndex = Integer.parseInt(args[1]); - - RandomAccessFile spinnerBackingFile = new RandomAccessFile(args[0], "rw"); - MappedByteBuffer spinnerBuffer = spinnerBackingFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 16); - - /* - * notify back to launching process that we are ready to start using the reporting index we were allocated on launch - */ - spinnerBuffer.putShort(reportingIndex, ((short) 10)); - - /* - * wait for parent process to notify us that all waiting processes are good to go - * do not Thread.sleep as we want to ensure there is as much of an overlap between the ports selected by the spawned processes - * and by sleeping, its frequently the case that one will complete selection before another wakes up resulting in sequential ranges rather than overlapping - */ - while (spinnerBuffer.getShort(0) != 8) { - } - - /* - * allocate ports and print out for later consumption by the spawning test - */ - PortAllocation pa = PortAllocation.getDefaultAllocator(); - int iterCount = Integer.parseInt(args[2]); - for (int i = 0; i < iterCount; i++) { - System.out.println(pa.nextPort()); - } - } - -} diff --git a/testing/node-driver/src/test/kotlin/net/corda/testing/driver/PortAllocationTest.kt b/testing/node-driver/src/test/kotlin/net/corda/testing/driver/PortAllocationTest.kt deleted file mode 100644 index 414c54d5f5..0000000000 --- a/testing/node-driver/src/test/kotlin/net/corda/testing/driver/PortAllocationTest.kt +++ /dev/null @@ -1,113 +0,0 @@ -package net.corda.testing.driver - -import net.corda.core.utilities.Try -import net.corda.core.utilities.contextLogger -import net.corda.testing.node.PortAllocationRunner -import org.assertj.core.util.Files -import org.hamcrest.CoreMatchers.`is` -import org.hamcrest.core.IsNot.not -import org.hamcrest.number.OrderingComparison -import org.junit.Assert -import org.junit.Assume.assumeFalse -import org.junit.Test -import java.io.RandomAccessFile -import java.nio.channels.FileChannel -import java.util.concurrent.TimeUnit -import kotlin.streams.toList - -class PortAllocationTest { - - companion object { - val logger = contextLogger() - } - - @Test - fun `should allocate a port whilst cycling back round if exceeding start of ephemeral range`() { - val startingPoint = PortAllocation.DEFAULT_START_PORT - val portAllocator = PortAllocation.defaultAllocator - - var previous = portAllocator.nextPort() - (0 until 50_000).forEach { _ -> - val next = portAllocator.nextPort() - Assert.assertThat(next, `is`(not(previous))) - Assert.assertThat(next, `is`(OrderingComparison.lessThan(PortAllocation.FIRST_EPHEMERAL_PORT))) - - if (next == startingPoint) { - Assert.assertThat(previous, `is`(PortAllocation.FIRST_EPHEMERAL_PORT - 1)) - } else { - Assert.assertTrue(next >= previous + 1) - } - previous = next - } - } - - @Test(timeout = 120_000) - fun `should support multiprocess port allocation`() { - assumeFalse(System.getProperty("os.name").toLowerCase().contains("windows")) - - logger.info("Starting multiprocess port allocation test") - val spinnerFile = Files.newTemporaryFile().also { it.deleteOnExit() }.absolutePath - val iterCount = 8_000 // Default port range 10000-30000 since we will have 2 processes we want to make sure there is enough leg room - // If we rollover, we may well receive the ports that were already given to a different process - val process1 = buildJvmProcess(spinnerFile, 1, iterCount) - val process2 = buildJvmProcess(spinnerFile, 2, iterCount) - - logger.info("Started child processes") - - val processes = listOf(process1, process2) - - val spinnerBackingFile = RandomAccessFile(spinnerFile, "rw") - logger.info("Mapped spinner file at: $spinnerFile") - val spinnerBuffer = spinnerBackingFile.channel.map(FileChannel.MapMode.READ_WRITE, 0, 512) - logger.info("Created spinner buffer") - - var timeWaited = 0L - - while (spinnerBuffer.getShort(1) != 10.toShort() && spinnerBuffer.getShort(2) != 10.toShort() && timeWaited < 60_000) { - logger.info("Waiting to childProcesses to report back. waited ${timeWaited}ms") - Thread.sleep(1000) - timeWaited += 1000 - } - - //GO! - logger.info("Instructing child processes to start allocating ports") - spinnerBuffer.putShort(0, 8) - logger.info("Waiting for child processes to terminate") - val terminationStatuses = processes.parallelStream().map { if (it.waitFor(1, TimeUnit.MINUTES)) "OK" else "STILL RUNNING" }.toList() - logger.info("child processes terminated: $terminationStatuses") - - fun List.setOfPorts(): Set { - // May include warnings when ports are busy - return map { Try.on { Integer.parseInt(it) } }.filter { it.isSuccess }.map { it.getOrThrow() }.toSet() - } - - val lines1 = process1.inputStream.reader().readLines() - val portsAllocated1 = lines1.setOfPorts() - val lines2 = process2.inputStream.reader().readLines() - val portsAllocated2 = lines2.setOfPorts() - - logger.info("child process out captured") - - Assert.assertThat(lines1.joinToString(), portsAllocated1.size, `is`(iterCount)) - Assert.assertThat(lines2.joinToString(), portsAllocated2.size, `is`(iterCount)) - - //there should be no overlap between the outputs as each process should have been allocated a unique set of ports - val intersect = portsAllocated1.intersect(portsAllocated2) - Assert.assertThat(intersect.joinToString(), intersect, `is`(emptySet())) - } - - private fun buildJvmProcess(spinnerFile: String, reportingIndex: Int, iterCount: Int): Process { - val separator = System.getProperty("file.separator") - val classpath = System.getProperty("java.class.path") - val path = (System.getProperty("java.home") - + separator + "bin" + separator + "java") - val processBuilder = ProcessBuilder(path, "-cp", - classpath, - PortAllocationRunner::class.java.name, - spinnerFile, - reportingIndex.toString(), - iterCount.toString()) - - return processBuilder.start() - } -} \ No newline at end of file