mirror of
https://github.com/corda/corda.git
synced 2024-12-24 07:06:44 +00:00
multiprocess port allocator is no longer used, so we can remove the tests as they add a significant amount of time to run (2-3 min) (#5663)
This commit is contained in:
parent
91e6c9783f
commit
e4e920eee9
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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<String>.setOfPorts(): Set<Int> {
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user