CORDA-806 Remove initialiseSerialization from rpcDriver (#2084)

and fix a leak or two
This commit is contained in:
Andrzej Cichocki
2017-11-29 17:42:39 +00:00
committed by GitHub
parent 2525fb52be
commit 3c31fdf31d
12 changed files with 117 additions and 46 deletions

View File

@ -1,26 +1,50 @@
package net.corda.testing
import com.nhaarman.mockito_kotlin.doNothing
import com.nhaarman.mockito_kotlin.whenever
import com.nhaarman.mockito_kotlin.*
import net.corda.client.rpc.internal.KryoClientSerializationScheme
import net.corda.core.internal.staticField
import net.corda.core.serialization.internal.*
import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.nodeapi.internal.serialization.*
import net.corda.nodeapi.internal.serialization.amqp.AMQPClientSerializationScheme
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
import net.corda.testing.common.internal.asContextEnv
import net.corda.testing.internal.testThreadFactory
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnector
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
private val inVMExecutors = ConcurrentHashMap<SerializationEnvironment, ExecutorService>()
/** @param inheritable whether new threads inherit the environment, use sparingly. */
class SerializationEnvironmentRule(private val inheritable: Boolean = false) : TestRule {
companion object {
init {
// Can't turn it off, and it creates threads that do serialization, so hack it:
InVMConnector::class.staticField<ExecutorService>("threadPoolExecutor").value = rigorousMock<ExecutorService>().also {
doAnswer {
inVMExecutors.computeIfAbsent(effectiveSerializationEnv) {
Executors.newCachedThreadPool(testThreadFactory(true)) // Close enough to what InVMConnector makes normally.
}.execute(it.arguments[0] as Runnable)
}.whenever(it).execute(any())
}
}
}
lateinit var env: SerializationEnvironment
override fun apply(base: Statement, description: Description): Statement {
env = createTestSerializationEnv(description.toString())
return object : Statement() {
override fun evaluate() = env.asContextEnv(inheritable) {
base.evaluate()
override fun evaluate() {
try {
env.asContextEnv(inheritable) { base.evaluate() }
} finally {
inVMExecutors.remove(env)
}
}
}
}
@ -59,6 +83,7 @@ fun setGlobalSerialization(armed: Boolean): GlobalSerializationEnvironment {
object : GlobalSerializationEnvironment, SerializationEnvironment by createTestSerializationEnv("<global>") {
override fun unset() {
_globalSerializationEnv.set(null)
inVMExecutors.remove(this)
}
}.also {
_globalSerializationEnv.set(it)

View File

@ -0,0 +1,15 @@
package net.corda.testing.internal
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicInteger
private val familyToNextPoolNumber = ConcurrentHashMap<String, AtomicInteger>()
fun Any.testThreadFactory(useEnclosingClassName: Boolean = false): ThreadFactory {
val poolFamily = javaClass.let { (if (useEnclosingClassName) it.enclosingClass else it).simpleName }
val poolNumber = familyToNextPoolNumber.computeIfAbsent(poolFamily) { AtomicInteger(1) }.getAndIncrement()
val nextThreadNumber = AtomicInteger(1)
return ThreadFactory { task ->
Thread(task, "$poolFamily-$poolNumber-${nextThreadNumber.getAndIncrement()}")
}
}