* Retire MockServiceHubInternal (#1909)

* Introduce rigorousMock
* Add test-utils and node-driver to generated documentation
This commit is contained in:
Andrzej Cichocki 2017-10-20 10:06:53 +01:00 committed by GitHub
parent 342090db62
commit 005ce349a7
20 changed files with 166 additions and 207 deletions

View File

@ -1,7 +1,7 @@
package net.corda.client.jackson
import com.fasterxml.jackson.databind.SerializationFeature
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.Amount
import net.corda.core.cordapp.CordappProvider
@ -9,10 +9,7 @@ import net.corda.core.crypto.*
import net.corda.core.node.ServiceHub
import net.corda.core.transactions.SignedTransaction
import net.corda.finance.USD
import net.corda.testing.ALICE_PUBKEY
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.MINI_CORP
import net.corda.testing.TestDependencyInjectionBase
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract
import org.junit.Before
import org.junit.Test
@ -32,9 +29,9 @@ class JacksonSupportTest : TestDependencyInjectionBase() {
@Before
fun setup() {
services = mock()
cordappProvider = mock()
whenever(services.cordappProvider).thenReturn(cordappProvider)
services = rigorousMock()
cordappProvider = rigorousMock()
doReturn(cordappProvider).whenever(services).cordappProvider
}
@Test
@ -91,8 +88,7 @@ class JacksonSupportTest : TestDependencyInjectionBase() {
@Test
fun writeTransaction() {
val attachmentRef = SecureHash.randomSHA256()
whenever(cordappProvider.getContractAttachmentID(DummyContract.PROGRAM_ID))
.thenReturn(attachmentRef)
doReturn(attachmentRef).whenever(cordappProvider).getContractAttachmentID(DummyContract.PROGRAM_ID)
fun makeDummyTx(): SignedTransaction {
val wtx = DummyContract.generateInitial(1, DUMMY_NOTARY, MINI_CORP.ref(1))
.toWireTransaction(services)

View File

@ -3,6 +3,7 @@ package net.corda.core.concurrent
import com.nhaarman.mockito_kotlin.*
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.utilities.getOrThrow
import net.corda.testing.rigorousMock
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
import org.slf4j.Logger
@ -16,7 +17,10 @@ class ConcurrencyUtilsTest {
private val f1 = openFuture<Int>()
private val f2 = openFuture<Double>()
private var invocations = 0
private val log = mock<Logger>()
private val log = rigorousMock<Logger>().also {
doNothing().whenever(it).error(any(), any<Throwable>())
}
@Test
fun `firstOf short circuit`() {
// Order not significant in this case:

View File

@ -3,6 +3,7 @@ package net.corda.core.internal.concurrent
import com.nhaarman.mockito_kotlin.*
import net.corda.core.concurrent.CordaFuture
import net.corda.core.utilities.getOrThrow
import net.corda.testing.rigorousMock
import org.assertj.core.api.Assertions
import org.junit.Test
import org.slf4j.Logger
@ -31,7 +32,7 @@ class CordaFutureTest {
fun `if a listener fails its throwable is logged`() {
val f = CordaFutureImpl<Int>()
val x = Exception()
val log = mock<Logger>()
val log = rigorousMock<Logger>()
val flag = AtomicBoolean()
f.thenImpl(log) { throw x }
f.thenImpl(log) { flag.set(true) } // Must not be affected by failure of previous listener.
@ -57,7 +58,7 @@ class CordaFutureTest {
Assertions.assertThatThrownBy { g.getOrThrow() }.isSameAs(x)
}
run {
val block = mock<(Any?) -> Any?>()
val block = rigorousMock<(Any?) -> Any?>()
val f = CordaFutureImpl<Int>()
val g = f.map(block)
val x = Exception()
@ -90,7 +91,7 @@ class CordaFutureTest {
Assertions.assertThatThrownBy { g.getOrThrow() }.isSameAs(x)
}
run {
val block = mock<(Any?) -> CordaFuture<*>>()
val block = rigorousMock<(Any?) -> CordaFuture<*>>()
val f = CordaFutureImpl<Int>()
val g = f.flatMap(block)
val x = Exception()
@ -102,7 +103,8 @@ class CordaFutureTest {
@Test
fun `andForget works`() {
val log = mock<Logger>()
val log = rigorousMock<Logger>()
doNothing().whenever(log).error(any(), any<Throwable>())
val throwable = Exception("Boom")
val executor = Executors.newSingleThreadExecutor()
executor.fork { throw throwable }.andForget(log)

View File

@ -5,13 +5,17 @@ dependencies {
compile rootProject
}
ext {
// TODO: Add '../client/jfx/src/main/kotlin' and '../client/mock/src/main/kotlin' if we decide to make them into public API
dokkaSourceDirs = files('../core/src/main/kotlin', '../client/rpc/src/main/kotlin', '../finance/src/main/kotlin', '../client/jackson/src/main/kotlin',
'../testing/test-utils/src/main/kotlin', '../testing/node-driver/src/main/kotlin')
}
dokka {
moduleName = 'corda'
outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/kotlin")
processConfigurations = ['compile']
// TODO: Re-add '../testing/node-driver/src/main/kotlin', '../testing/test-utils/src/main/kotlin' when they're API stable
// TODO: Add '../client/jfx/src/main/kotlin' and '../client/mock/src/main/kotlin' if we decide to make them into public API
sourceDirs = files('../core/src/main/kotlin', '../client/rpc/src/main/kotlin', '../finance/src/main/kotlin', '../client/jackson/src/main/kotlin')
sourceDirs = dokkaSourceDirs
includes = ['packages.md']
jdkVersion = 8
@ -31,8 +35,7 @@ task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) {
outputFormat = "javadoc"
outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/javadoc")
processConfigurations = ['compile']
// TODO: Make this a copy of the list above programmatically.
sourceDirs = files('../core/src/main/kotlin', '../client/rpc/src/main/kotlin', '../finance/src/main/kotlin', '../client/jackson/src/main/kotlin')
sourceDirs = dokkaSourceDirs
includes = ['packages.md']
jdkVersion = 8

View File

@ -1,6 +1,6 @@
package net.corda.nodeapi.internal
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash
@ -17,10 +17,7 @@ import net.corda.nodeapi.DummyContractBackdoor
import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl
import net.corda.nodeapi.internal.serialization.attachmentsClassLoaderEnabledPropertyName
import net.corda.nodeapi.internal.serialization.withTokenContext
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.MEGA_CORP
import net.corda.testing.TestDependencyInjectionBase
import net.corda.testing.kryoSpecific
import net.corda.testing.*
import net.corda.testing.node.MockAttachmentStorage
import net.corda.testing.node.MockServices
import org.apache.commons.io.IOUtils
@ -41,8 +38,8 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() {
private const val ISOLATED_CONTRACT_CLASS_NAME = "net.corda.finance.contracts.isolated.AnotherDummyContract"
private fun SerializationContext.withAttachmentStorage(attachmentStorage: AttachmentStorage): SerializationContext {
val serviceHub = mock<ServiceHub>()
whenever(serviceHub.attachments).thenReturn(attachmentStorage)
val serviceHub = rigorousMock<ServiceHub>()
doReturn(attachmentStorage).whenever(serviceHub).attachments
return this.withServiceHub(serviceHub)
}

View File

@ -5,14 +5,13 @@ import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.util.DefaultClassResolver
import com.esotericsoftware.kryo.util.MapReferenceResolver
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import com.nhaarman.mockito_kotlin.*
import net.corda.core.node.services.AttachmentStorage
import net.corda.core.serialization.*
import net.corda.nodeapi.internal.AttachmentsClassLoader
import net.corda.nodeapi.internal.AttachmentsClassLoaderTests
import net.corda.testing.node.MockAttachmentStorage
import net.corda.testing.rigorousMock
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
@ -241,10 +240,11 @@ class CordaClassResolverTests {
@Test
fun `Kotlin EmptyList registers as Java emptyList`() {
val javaEmptyListClass = Collections.emptyList<Any>().javaClass
val kryo = mock<Kryo>()
val kryo = rigorousMock<Kryo>()
val resolver = CordaClassResolver(allButBlacklistedContext).apply { setKryo(kryo) }
whenever(kryo.getDefaultSerializer(javaEmptyListClass)).thenReturn(DefaultSerializableSerializer())
doReturn(DefaultSerializableSerializer()).whenever(kryo).getDefaultSerializer(javaEmptyListClass)
doReturn(false).whenever(kryo).references
doReturn(false).whenever(kryo).references = any()
val registration = resolver.registerImplicit(emptyListClass)
assertNotNull(registration)
assertEquals(javaEmptyListClass, registration.type)
@ -262,10 +262,11 @@ class CordaClassResolverTests {
@Test
fun `Kotlin EmptySet registers as Java emptySet`() {
val javaEmptySetClass = Collections.emptySet<Any>().javaClass
val kryo = mock<Kryo>()
val kryo = rigorousMock<Kryo>()
val resolver = CordaClassResolver(allButBlacklistedContext).apply { setKryo(kryo) }
whenever(kryo.getDefaultSerializer(javaEmptySetClass)).thenReturn(DefaultSerializableSerializer())
doReturn(DefaultSerializableSerializer()).whenever(kryo).getDefaultSerializer(javaEmptySetClass)
doReturn(false).whenever(kryo).references
doReturn(false).whenever(kryo).references = any()
val registration = resolver.registerImplicit(emptySetClass)
assertNotNull(registration)
assertEquals(javaEmptySetClass, registration.type)
@ -283,10 +284,11 @@ class CordaClassResolverTests {
@Test
fun `Kotlin EmptyMap registers as Java emptyMap`() {
val javaEmptyMapClass = Collections.emptyMap<Any, Any>().javaClass
val kryo = mock<Kryo>()
val kryo = rigorousMock<Kryo>()
val resolver = CordaClassResolver(allButBlacklistedContext).apply { setKryo(kryo) }
whenever(kryo.getDefaultSerializer(javaEmptyMapClass)).thenReturn(DefaultSerializableSerializer())
doReturn(DefaultSerializableSerializer()).whenever(kryo).getDefaultSerializer(javaEmptyMapClass)
doReturn(false).whenever(kryo).references
doReturn(false).whenever(kryo).references = any()
val registration = resolver.registerImplicit(emptyMapClass)
assertNotNull(registration)
assertEquals(javaEmptyMapClass, registration.type)

View File

@ -3,10 +3,10 @@ package net.corda.nodeapi.internal.serialization
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.io.Output
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.serialization.*
import net.corda.core.utilities.OpaqueBytes
import net.corda.testing.TestDependencyInjectionBase
import net.corda.testing.rigorousMock
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
@ -35,8 +35,7 @@ class SerializationTokenTest : TestDependencyInjectionBase() {
override fun equals(other: Any?) = other is LargeTokenizable && other.bytes.size == this.bytes.size
}
private fun serializeAsTokenContext(toBeTokenized: Any) = SerializeAsTokenContextImpl(toBeTokenized, factory, context, mock())
private fun serializeAsTokenContext(toBeTokenized: Any) = SerializeAsTokenContextImpl(toBeTokenized, factory, context, rigorousMock())
@Test
fun `write token and read tokenizable`() {
val tokenizableBefore = LargeTokenizable()

View File

@ -1,5 +1,6 @@
package net.corda.node.services
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.ContractState
@ -58,7 +59,7 @@ class BFTNotaryServiceTests {
replicaIds.forEach { replicaId ->
mockNet.createNode(configOverrides = {
val notary = NotaryConfig(validating = false, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses, exposeRaces = exposeRaces))
whenever(it.notary).thenReturn(notary)
doReturn(notary).whenever(it).notary
})
}
mockNet.runNetwork() // Exchange initial network map registration messages.

View File

@ -1,5 +1,6 @@
package net.corda.services.messaging
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.random63BitValue
@ -61,8 +62,8 @@ class P2PSecurityTest : NodeBasedTest() {
val config = testNodeConfiguration(
baseDirectory = baseDirectory(legalName),
myLegalName = legalName).also {
whenever(it.networkMapService).thenReturn(NetworkMapInfo(networkMapNode.internals.configuration.p2pAddress, networkMapNode.info.chooseIdentity().name))
whenever(it.activeMQServer).thenReturn(ActiveMqServerConfiguration(BridgeConfiguration(1001, 2, 3.4)))
doReturn(NetworkMapInfo(networkMapNode.internals.configuration.p2pAddress, networkMapNode.info.chooseIdentity().name)).whenever(it).networkMapService
doReturn(ActiveMqServerConfiguration(BridgeConfiguration(1001, 2, 3.4))).whenever(it).activeMQServer
}
config.configureWithDevSSLCertificate() // This creates the node's TLS cert with the CN as the legal name
return SimpleNode(config, trustRoot = trustRoot).apply { start() }
@ -73,6 +74,6 @@ class P2PSecurityTest : NodeBasedTest() {
val nodeInfo = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(legalIdentity), 1, serial = 1)
val registration = NodeRegistration(nodeInfo, System.currentTimeMillis(), AddOrRemove.ADD, Instant.MAX)
val request = RegistrationRequest(registration.toWire(keyService, identity.public), network.myAddress)
return network.sendRequest<NetworkMapService.RegistrationResponse>(NetworkMapService.REGISTER_TOPIC, request, networkMapNode.network.myAddress)
return network.sendRequest(NetworkMapService.REGISTER_TOPIC, request, networkMapNode.network.myAddress)
}
}

View File

@ -1,7 +1,6 @@
package net.corda.node
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.nhaarman.mockito_kotlin.mock
import net.corda.client.jackson.JacksonSupport
import net.corda.core.contracts.Amount
import net.corda.core.crypto.SecureHash
@ -17,6 +16,7 @@ import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_IDENTITY
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
import net.corda.testing.rigorousMock
import org.junit.After
import org.junit.Before
import org.junit.Test
@ -83,5 +83,5 @@ class InteractiveShellTest {
@Test
fun party() = check("party: \"${MEGA_CORP.name}\"", MEGA_CORP.name.toString())
class DummyFSM(val flowA: FlowA) : FlowStateMachine<Any?> by mock()
class DummyFSM(val flowA: FlowA) : FlowStateMachine<Any?> by rigorousMock()
}

View File

@ -1,6 +1,5 @@
package net.corda.node.internal.cordapp
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.node.services.AttachmentStorage
import net.corda.testing.node.MockAttachmentStorage
import org.junit.Assert
@ -40,7 +39,7 @@ class CordappProviderImplTests {
@Test
fun `test that we find a cordapp class that is loaded into the store`() {
val loader = CordappLoader.createDevMode(listOf(isolatedJAR))
val provider = CordappProviderImpl(loader, mock())
val provider = CordappProviderImpl(loader, attachmentStore)
val className = "net.corda.finance.contracts.isolated.AnotherDummyContract"
val expected = provider.cordapps.first()

View File

@ -1,6 +1,8 @@
package net.corda.node.services.events
import co.paralleluniverse.fibers.Suspendable
import com.codahale.metrics.MetricRegistry
import com.nhaarman.mockito_kotlin.*
import net.corda.core.contracts.*
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRef
@ -8,36 +10,39 @@ import net.corda.core.flows.FlowLogicRefFactory
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.days
import net.corda.node.internal.FlowStarterImpl
import net.corda.node.internal.StateLoaderImpl
import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.internal.cordapp.CordappProviderImpl
import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.api.MonitoringService
import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.persistence.DBCheckpointStorage
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.services.vault.NodeVaultService
import net.corda.node.testing.MockServiceHubInternal
import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.configureDatabase
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockKeyManagementService
import net.corda.testing.node.*
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
import net.corda.testing.node.TestClock
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import java.nio.file.Paths
import java.security.PublicKey
import java.time.Clock
import java.time.Instant
import java.util.concurrent.CountDownLatch
@ -46,20 +51,26 @@ import java.util.concurrent.TimeUnit
import kotlin.test.assertTrue
class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
companion object {
private val myInfo = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L)
}
private val realClock: Clock = Clock.systemUTC()
private val stoppedClock: Clock = Clock.fixed(realClock.instant(), realClock.zone)
private val testClock = TestClock(stoppedClock)
private val schedulerGatedExecutor = AffinityExecutor.Gate(true)
private lateinit var services: MockServiceHubInternal
abstract class Services : ServiceHubInternal, TestReference
private lateinit var services: Services
private lateinit var scheduler: NodeSchedulerService
private lateinit var smmExecutor: AffinityExecutor.ServiceAffinityExecutor
private lateinit var database: CordaPersistence
private lateinit var countDown: CountDownLatch
private lateinit var smmHasRemovedAllFlows: CountDownLatch
private lateinit var kms: MockKeyManagementService
private lateinit var mockSMM: StateMachineManager
var calls: Int = 0
/**
@ -81,35 +92,35 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
val databaseProperties = makeTestDatabaseProperties()
database = configureDatabase(dataSourceProps, databaseProperties, ::makeTestIdentityService)
val identityService = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT)
val kms = MockKeyManagementService(identityService, ALICE_KEY)
kms = MockKeyManagementService(identityService, ALICE_KEY)
val configuration = testNodeConfiguration(Paths.get("."), CordaX500Name("Alice", "London", "GB"))
val validatedTransactions = MockTransactionStorage()
val stateLoader = StateLoaderImpl(validatedTransactions)
database.transaction {
val nullIdentity = CordaX500Name(organisation = "None", locality = "None", country = "GB")
val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(
false,
InMemoryMessagingNetwork.PeerHandle(0, nullIdentity),
AffinityExecutor.ServiceAffinityExecutor("test", 1),
database)
services = object : MockServiceHubInternal(
database,
testNodeConfiguration(Paths.get("."), CordaX500Name(organisation = "Alice", locality = "London", country = "GB")),
overrideClock = testClock,
keyManagement = kms,
network = mockMessagingService), TestReference {
override val vaultService: VaultServiceInternal = NodeVaultService(testClock, kms, stateLoader, database.hibernateConfig)
override val testReference = this@NodeSchedulerServiceTest
override val cordappProvider = CordappProviderImpl(CordappLoader.createWithTestPackages(listOf("net.corda.testing.contracts")), attachments)
services = rigorousMock<Services>().also {
doReturn(configuration).whenever(it).configuration
doReturn(MonitoringService(MetricRegistry())).whenever(it).monitoringService
doReturn(validatedTransactions).whenever(it).validatedTransactions
doReturn(NetworkMapCacheImpl(MockNetworkMapCache(database, configuration), identityService)).whenever(it).networkMapCache
doCallRealMethod().whenever(it).signInitialTransaction(any(), any<PublicKey>())
doReturn(myInfo).whenever(it).myInfo
doReturn(kms).whenever(it).keyManagementService
doReturn(CordappProviderImpl(CordappLoader.createWithTestPackages(listOf("net.corda.testing.contracts")), MockAttachmentStorage())).whenever(it).cordappProvider
doCallRealMethod().whenever(it).recordTransactions(any<SignedTransaction>())
doCallRealMethod().whenever(it).recordTransactions(any<Boolean>(), any<SignedTransaction>())
doCallRealMethod().whenever(it).recordTransactions(any(), any<Iterable<SignedTransaction>>())
doReturn(NodeVaultService(testClock, kms, stateLoader, database.hibernateConfig)).whenever(it).vaultService
doReturn(this@NodeSchedulerServiceTest).whenever(it).testReference
}
smmExecutor = AffinityExecutor.ServiceAffinityExecutor("test", 1)
val mockSMM = StateMachineManager(services, DBCheckpointStorage(), smmExecutor, database)
scheduler = NodeSchedulerService(testClock, database, FlowStarterImpl(smmExecutor, mockSMM), services.stateLoader, schedulerGatedExecutor, serverThread = smmExecutor)
mockSMM = StateMachineManager(services, DBCheckpointStorage(), smmExecutor, database)
scheduler = NodeSchedulerService(testClock, database, FlowStarterImpl(smmExecutor, mockSMM), stateLoader, schedulerGatedExecutor, serverThread = smmExecutor)
mockSMM.changes.subscribe { change ->
if (change is StateMachineManager.Change.Removed && mockSMM.allStateMachines.isEmpty()) {
smmHasRemovedAllFlows.countDown()
}
}
mockSMM.start()
services.smm = mockSMM
scheduler.start()
}
}
@ -117,7 +128,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
@After
fun tearDown() {
// We need to make sure the StateMachineManager is done before shutting down executors.
if (services.smm.allStateMachines.isNotEmpty()) {
if (mockSMM.allStateMachines.isNotEmpty()) {
smmHasRemovedAllFlows.await()
}
smmExecutor.shutdown()
@ -126,7 +137,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
resetTestSerialization()
}
class TestState(val flowLogicRef: FlowLogicRef, val instant: Instant, val myIdentity: Party) : LinearState, SchedulableState {
class TestState(private val flowLogicRef: FlowLogicRef, val instant: Instant, private val myIdentity: Party) : LinearState, SchedulableState {
override val participants: List<AbstractParty>
get() = listOf(myIdentity)
@ -137,7 +148,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
}
}
class TestFlowLogic(val increment: Int = 1) : FlowLogic<Unit>() {
class TestFlowLogic(private val increment: Int = 1) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
(serviceHub as TestReference).testReference.calls += increment
@ -280,8 +291,8 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
var scheduledRef: ScheduledStateRef? = null
database.transaction {
apply {
val freshKey = services.keyManagementService.freshKey()
val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant, services.myInfo.chooseIdentity())
val freshKey = kms.freshKey()
val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant, myInfo.chooseIdentity())
val builder = TransactionBuilder(null).apply {
addOutputState(state, DummyContract.PROGRAM_ID, DUMMY_NOTARY)
addCommand(Command(), freshKey)

View File

@ -1,7 +1,6 @@
package net.corda.node.services.messaging
import com.codahale.metrics.MetricRegistry
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.generateKeyPair
import net.corda.core.internal.concurrent.doneFuture
@ -74,7 +73,7 @@ class ArtemisMessagingTests : TestDependencyInjectionBase() {
LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
networkMapRegistrationFuture = doneFuture(Unit)
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, config), mock())
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, config), rigorousMock())
}
@After

View File

@ -1,9 +1,7 @@
package net.corda.node.services.vault
import co.paralleluniverse.fibers.Suspendable
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.verifyNoMoreInteractions
import com.nhaarman.mockito_kotlin.*
import net.corda.core.contracts.*
import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
@ -32,6 +30,7 @@ import net.corda.node.services.config.NodeConfiguration
import net.corda.nodeapi.internal.ServiceInfo
import net.corda.testing.chooseIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.rigorousMock
import org.junit.After
import org.junit.Test
import java.math.BigInteger
@ -81,7 +80,9 @@ private class NodePair(private val mockNet: MockNetwork) {
}
class VaultSoftLockManagerTest {
private val mockVault: VaultServiceInternal = mock()
private val mockVault = rigorousMock<VaultServiceInternal>().also {
doNothing().whenever(it).softLockRelease(any(), anyOrNull())
}
private val mockNet = MockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = object : MockNetwork.Factory<MockNetwork.MockNode> {
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, id: Int, notaryIdentity: Pair<ServiceInfo, KeyPair>?, entropyRoot: BigInteger): MockNetwork.MockNode {
return object : MockNetwork.MockNode(config, network, networkMapAddr, id, notaryIdentity, entropyRoot) {

View File

@ -1,8 +1,6 @@
package net.corda.node.utilities.registration
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.*
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name
@ -11,6 +9,7 @@ import net.corda.node.utilities.X509Utilities
import net.corda.node.utilities.getX509Certificate
import net.corda.node.utilities.loadKeyStore
import net.corda.testing.ALICE
import net.corda.testing.rigorousMock
import net.corda.testing.testNodeConfiguration
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.style.BCStyle
@ -38,10 +37,9 @@ class NetworkRegistrationHelperTest {
.map { CordaX500Name(commonName = it, organisation = "R3 Ltd", locality = "London", country = "GB") }
val certs = identities.stream().map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
.map { it.cert }.toTypedArray()
val certService: NetworkRegistrationService = mock {
on { submitRequest(any()) }.then { id }
on { retrieveCertificates(eq(id)) }.then { certs }
val certService = rigorousMock<NetworkRegistrationService>().also {
doReturn(id).whenever(it).submitRequest(any())
doReturn(certs).whenever(it).retrieveCertificates(eq(id))
}
val config = testNodeConfiguration(

View File

@ -1,80 +0,0 @@
package net.corda.node.testing
import com.codahale.metrics.MetricRegistry
import net.corda.core.flows.FlowLogic
import net.corda.core.node.NodeInfo
import net.corda.core.node.StateLoader
import net.corda.core.node.services.*
import net.corda.core.serialization.SerializeAsToken
import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StateLoaderImpl
import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.internal.cordapp.CordappProviderImpl
import net.corda.node.internal.cordapp.CordappProviderInternal
import net.corda.node.serialization.NodeClock
import net.corda.node.services.api.*
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.utilities.CordaPersistence
import net.corda.testing.DUMMY_IDENTITY_1
import net.corda.testing.MOCK_HOST_AND_PORT
import net.corda.testing.MOCK_IDENTITY_SERVICE
import net.corda.testing.node.MockAttachmentStorage
import net.corda.testing.node.MockNetworkMapCache
import net.corda.testing.node.MockStateMachineRecordedTransactionMappingStorage
import net.corda.testing.node.MockTransactionStorage
import java.nio.file.Paths
import java.sql.Connection
import java.time.Clock
open class MockServiceHubInternal(
override val database: CordaPersistence,
override val configuration: NodeConfiguration,
val customVault: VaultServiceInternal? = null,
val keyManagement: KeyManagementService? = null,
val network: MessagingService? = null,
val identity: IdentityService? = MOCK_IDENTITY_SERVICE,
override val attachments: AttachmentStorage = MockAttachmentStorage(),
override val validatedTransactions: WritableTransactionStorage = MockTransactionStorage(),
override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage(),
val mapCache: NetworkMapCacheInternal? = null,
val overrideClock: Clock? = NodeClock(),
val customContractUpgradeService: ContractUpgradeService? = null,
val customTransactionVerifierService: TransactionVerifierService? = InMemoryTransactionVerifierService(2),
override val cordappProvider: CordappProviderInternal = CordappProviderImpl(CordappLoader.createDefault(Paths.get(".")), attachments),
val stateLoader: StateLoaderImpl = StateLoaderImpl(validatedTransactions)
) : ServiceHubInternal, StateLoader by stateLoader {
override val transactionVerifierService: TransactionVerifierService
get() = customTransactionVerifierService ?: throw UnsupportedOperationException()
override val vaultService: VaultServiceInternal
get() = customVault ?: throw UnsupportedOperationException()
override val contractUpgradeService: ContractUpgradeService
get() = customContractUpgradeService ?: throw UnsupportedOperationException()
override val keyManagementService: KeyManagementService
get() = keyManagement ?: throw UnsupportedOperationException()
override val identityService: IdentityService
get() = identity ?: throw UnsupportedOperationException()
override val networkService: MessagingService
get() = network ?: throw UnsupportedOperationException()
override val networkMapCache: NetworkMapCacheInternal
get() = mapCache ?: NetworkMapCacheImpl(MockNetworkMapCache(database, configuration), identityService)
override val clock: Clock
get() = overrideClock ?: throw UnsupportedOperationException()
override val myInfo: NodeInfo
get() = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L) // Required to get a dummy platformVersion when required for tests.
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
override val rpcFlows: List<Class<out FlowLogic<*>>>
get() = throw UnsupportedOperationException()
override val schemaService get() = throw UnsupportedOperationException()
override val auditService: AuditService = DummyAuditService()
lateinit var smm: StateMachineManager
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T = throw UnsupportedOperationException()
override fun getFlowFactory(initiatingFlowClass: Class<out FlowLogic<*>>): InitiatedFlowFactory<*>? = null
override fun jdbcSession(): Connection = database.createSession()
}

View File

@ -2,14 +2,17 @@
package net.corda.testing
import com.nhaarman.mockito_kotlin.spy
import com.nhaarman.mockito_kotlin.doCallRealMethod
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.ServiceHub
import net.corda.core.transactions.TransactionBuilder
import net.corda.node.services.config.CertChainPolicyConfig
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.VerifierType
import net.corda.nodeapi.User
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
@ -57,23 +60,29 @@ fun testNodeConfiguration(
myLegalName: CordaX500Name,
notaryConfig: NotaryConfig? = null): NodeConfiguration {
abstract class MockableNodeConfiguration : NodeConfiguration // Otherwise Mockito is defeated by val getters.
val nc = spy<MockableNodeConfiguration>()
whenever(nc.baseDirectory).thenReturn(baseDirectory)
whenever(nc.myLegalName).thenReturn(myLegalName)
whenever(nc.minimumPlatformVersion).thenReturn(1)
whenever(nc.keyStorePassword).thenReturn("cordacadevpass")
whenever(nc.trustStorePassword).thenReturn("trustpass")
whenever(nc.rpcUsers).thenReturn(emptyList())
whenever(nc.notary).thenReturn(notaryConfig)
whenever(nc.dataSourceProperties).thenReturn(makeTestDataSourceProperties(myLegalName.organisation))
whenever(nc.database).thenReturn(makeTestDatabaseProperties())
whenever(nc.emailAddress).thenReturn("")
whenever(nc.exportJMXto).thenReturn("")
whenever(nc.devMode).thenReturn(true)
whenever(nc.certificateSigningService).thenReturn(URL("http://localhost"))
whenever(nc.certificateChainCheckPolicies).thenReturn(emptyList())
whenever(nc.verifierType).thenReturn(VerifierType.InMemory)
whenever(nc.messageRedeliveryDelaySeconds).thenReturn(5)
return nc
return rigorousMock<MockableNodeConfiguration>().also {
doReturn(baseDirectory).whenever(it).baseDirectory
doReturn(myLegalName).whenever(it).myLegalName
doReturn(1).whenever(it).minimumPlatformVersion
doReturn("cordacadevpass").whenever(it).keyStorePassword
doReturn("trustpass").whenever(it).trustStorePassword
doReturn(emptyList<User>()).whenever(it).rpcUsers
doReturn(notaryConfig).whenever(it).notary
doReturn(makeTestDataSourceProperties(myLegalName.organisation)).whenever(it).dataSourceProperties
doReturn(makeTestDatabaseProperties()).whenever(it).database
doReturn("").whenever(it).emailAddress
doReturn("").whenever(it).exportJMXto
doReturn(true).whenever(it).devMode
doReturn(URL("http://localhost")).whenever(it).certificateSigningService
doReturn(emptyList<CertChainPolicyConfig>()).whenever(it).certificateChainCheckPolicies
doReturn(VerifierType.InMemory).whenever(it).verifierType
doReturn(5).whenever(it).messageRedeliveryDelaySeconds
doReturn(0L).whenever(it).additionalNodeInfoPollingFrequencyMsec
doReturn(null).whenever(it).networkMapService
doCallRealMethod().whenever(it).certificatesDirectory
doCallRealMethod().whenever(it).trustStoreFile
doCallRealMethod().whenever(it).sslKeystore
doCallRealMethod().whenever(it).nodeKeystore
doReturn(false).whenever(it).noNetworkMapServiceMode
}
}

View File

@ -2,13 +2,13 @@ package net.corda.testing.node
import com.google.common.jimfs.Configuration.unix
import com.google.common.jimfs.Jimfs
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.cert
import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.createDirectories
import net.corda.core.internal.createDirectory
@ -31,7 +31,6 @@ import net.corda.node.services.api.SchemaService
import net.corda.node.services.config.BFTSMaRtConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.E2ETestKeyManagementService
import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.network.InMemoryNetworkMapService
@ -41,7 +40,6 @@ import net.corda.node.services.transactions.BFTSMaRt
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
import net.corda.node.utilities.CertificateAndKeyPair
import net.corda.nodeapi.internal.ServiceInfo
import net.corda.testing.*
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
@ -53,7 +51,6 @@ import java.math.BigInteger
import java.nio.file.Path
import java.security.KeyPair
import java.security.PublicKey
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
@ -353,7 +350,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
val config = testNodeConfiguration(
baseDirectory = baseDirectory(id).createDirectories(),
myLegalName = legalName ?: CordaX500Name(organisation = "Mock Company $id", locality = "London", country = "GB")).also {
whenever(it.dataSourceProperties).thenReturn(makeTestDataSourceProperties("node_${id}_net_$networkId"))
doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties
configOverrides(it)
}
return nodeFactory.create(config, this, networkMapAddress, id, notaryIdentity, entropyRoot).apply {
@ -391,7 +388,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
@JvmOverloads
fun createNotaryNode(legalName: CordaX500Name = DUMMY_NOTARY.name, validating: Boolean = true): StartedNode<MockNode> {
return createNode(legalName = legalName, configOverrides = {
whenever(it.notary).thenReturn(NotaryConfig(validating))
doReturn(NotaryConfig(validating)).whenever(it).notary
})
}
@ -399,7 +396,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
validating: Boolean = true,
nodeFactory: Factory<N>): StartedNode<N> {
return createNode(legalName = legalName, nodeFactory = nodeFactory, configOverrides = {
whenever(it.notary).thenReturn(NotaryConfig(validating))
doReturn(NotaryConfig(validating)).whenever(it).notary
})
}

View File

@ -3,6 +3,7 @@
package net.corda.testing
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.contracts.StateRef
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.generateKeyPair
@ -24,6 +25,8 @@ import net.corda.node.utilities.CertificateType
import net.corda.node.utilities.X509Utilities
import net.corda.nodeapi.config.SSLConfiguration
import net.corda.nodeapi.internal.serialization.AMQP_ENABLED
import org.mockito.internal.stubbing.answers.ThrowsException
import org.mockito.stubbing.Answer
import java.nio.file.Files
import java.security.KeyPair
import java.security.PublicKey
@ -177,3 +180,19 @@ fun NodeInfo.singleIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCe
fun NodeInfo.singleIdentity(): Party = singleIdentityAndCert().party
/** Returns the identity of the first notary found on the network */
fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first()
/**
* A method on a mock was called, but no behaviour was previously specified for that method.
* You can use [com.nhaarman.mockito_kotlin.doReturn] or similar to specify behaviour, see Mockito documentation for details.
*/
class UndefinedMockBehaviorException(message: String) : RuntimeException(message)
/**
* Create a Mockito mock that has [UndefinedMockBehaviorException] as the default behaviour of all methods.
* @param T the type to mock. Note if you want to use [com.nhaarman.mockito_kotlin.doCallRealMethod] on a Kotlin interface,
* it won't work unless you mock a (trivial) abstract implementation of that interface instead.
*/
inline fun <reified T : Any> rigorousMock() = mock<T>(Answer {
// Use ThrowsException to hack the stack trace, and lazily so we can customise the message:
ThrowsException(UndefinedMockBehaviorException("Please specify what should happen when '${it.method}' is called, or don't call it.")).answer(it)
})

View File

@ -1,9 +1,12 @@
package net.corda.demobench.pty
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import net.corda.testing.rigorousMock
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.*
import java.io.ByteArrayOutputStream
import java.io.OutputStream
import java.nio.charset.StandardCharsets.UTF_8
@ -15,10 +18,8 @@ class ZeroFilterTest {
@Before
fun setup() {
output = ByteArrayOutputStream()
val process = mock(Process::class.java)
`when`(process.outputStream).thenReturn(output)
val process = rigorousMock<Process>()
doReturn(output).whenever(process).outputStream
filter = process.zeroFiltered().outputStream
verify(process).outputStream
}