CORDA-654 Make MOCK_IDENTITIES less special (#2114)

* Make rigorousMock usable from Java
* Show args in mock failure message
This commit is contained in:
Andrzej Cichocki
2017-11-28 11:35:59 +00:00
committed by GitHub
parent 614779d4ec
commit ff9e7474b1
4 changed files with 31 additions and 28 deletions

View File

@ -20,6 +20,7 @@ import net.corda.finance.contracts.DealState;
import net.corda.finance.contracts.asset.Cash; import net.corda.finance.contracts.asset.Cash;
import net.corda.finance.contracts.asset.CashUtilities; import net.corda.finance.contracts.asset.CashUtilities;
import net.corda.finance.schemas.CashSchemaV1; import net.corda.finance.schemas.CashSchemaV1;
import net.corda.node.services.identity.InMemoryIdentityService;
import net.corda.node.utilities.CordaPersistence; import net.corda.node.utilities.CordaPersistence;
import net.corda.node.utilities.DatabaseTransaction; import net.corda.node.utilities.DatabaseTransaction;
import net.corda.testing.SerializationEnvironmentRule; import net.corda.testing.SerializationEnvironmentRule;
@ -36,7 +37,6 @@ import rx.Observable;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -50,7 +50,6 @@ import static net.corda.finance.contracts.asset.CashUtilities.*;
import static net.corda.testing.CoreTestUtils.*; import static net.corda.testing.CoreTestUtils.*;
import static net.corda.testing.TestConstants.*; import static net.corda.testing.TestConstants.*;
import static net.corda.testing.node.MockServices.makeTestDatabaseAndMockServices; import static net.corda.testing.node.MockServices.makeTestDatabaseAndMockServices;
import static net.corda.testing.node.MockServices.makeTestIdentityService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class VaultQueryJavaTests { public class VaultQueryJavaTests {
@ -64,18 +63,18 @@ public class VaultQueryJavaTests {
@Before @Before
public void setUp() throws CertificateException, InvalidAlgorithmParameterException { public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName()); List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
ArrayList<KeyPair> keys = new ArrayList<>(); IdentityService identitySvc = new InMemoryIdentityService(
keys.add(getMEGA_CORP_KEY()); Arrays.asList(getMEGA_CORP_IDENTITY(), getDUMMY_CASH_ISSUER_IDENTITY(), getDUMMY_NOTARY_IDENTITY()),
keys.add(getDUMMY_NOTARY_KEY()); Collections.emptySet(),
IdentityService identitySvc = makeTestIdentityService(); getDEV_TRUST_ROOT());
@SuppressWarnings("unchecked") Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(keys, identitySvc, cordappPackages); Arrays.asList(getMEGA_CORP_KEY(), getDUMMY_NOTARY_KEY()),
identitySvc,
cordappPackages);
issuerServices = new MockServices(cordappPackages, getDUMMY_CASH_ISSUER_NAME(), getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY()); issuerServices = new MockServices(cordappPackages, getDUMMY_CASH_ISSUER_NAME(), getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY());
database = databaseAndServices.getFirst(); database = databaseAndServices.getFirst();
services = databaseAndServices.getSecond(); services = databaseAndServices.getSecond();
vaultService = services.getVaultService(); vaultService = services.getVaultService();
services.getIdentityService().verifyAndRegisterIdentity(getDUMMY_CASH_ISSUER_IDENTITY());
services.getIdentityService().verifyAndRegisterIdentity(getDUMMY_NOTARY_IDENTITY());
} }
@After @After

View File

@ -1,12 +1,17 @@
package net.corda.node.services.persistence package net.corda.node.services.persistence
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.StatesToRecord import net.corda.core.node.StatesToRecord
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultService import net.corda.core.node.services.VaultService
import net.corda.core.schemas.CommonSchemaV1 import net.corda.core.schemas.CommonSchemaV1
@ -17,10 +22,7 @@ import net.corda.core.utilities.toBase58String
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.POUNDS import net.corda.finance.POUNDS
import net.corda.finance.SWISS_FRANCS import net.corda.finance.SWISS_FRANCS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.*
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_KEY
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER_NAME
import net.corda.finance.contracts.asset.DummyFungibleContract
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2 import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3 import net.corda.finance.schemas.SampleCashSchemaV3
@ -37,7 +39,6 @@ import net.corda.testing.contracts.fillWithSomeTestDeals
import net.corda.testing.contracts.fillWithSomeTestLinearStates import net.corda.testing.contracts.fillWithSomeTestLinearStates
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
import net.corda.testing.schemas.DummyLinearStateSchemaV1 import net.corda.testing.schemas.DummyLinearStateSchemaV1
import net.corda.testing.schemas.DummyLinearStateSchemaV2 import net.corda.testing.schemas.DummyLinearStateSchemaV2
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
@ -84,7 +85,14 @@ class HibernateConfigurationTest {
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY) issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY)
notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val dataSourceProps = makeTestDataSourceProperties() val dataSourceProps = makeTestDataSourceProperties()
database = configureDatabase(dataSourceProps, DatabaseConfig(), makeTestIdentityService()) val identityService = rigorousMock<IdentityService>().also { mock ->
doReturn(null).whenever(mock).wellKnownPartyFromAnonymous(any<AbstractParty>())
listOf(DUMMY_CASH_ISSUER_IDENTITY.party, DUMMY_NOTARY).forEach {
doReturn(it).whenever(mock).wellKnownPartyFromAnonymous(it)
doReturn(it).whenever(mock).wellKnownPartyFromX500Name(it.name)
}
}
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService)
database.transaction { database.transaction {
hibernateConfig = database.hibernateConfig hibernateConfig = database.hibernateConfig
// `consumeCash` expects we can self-notarise transactions // `consumeCash` expects we can self-notarise transactions

View File

@ -77,12 +77,7 @@ open class MockServices(
return props return props
} }
/** private fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DEV_TRUST_ROOT)
* Creates an instance of [InMemoryIdentityService] with [MOCK_IDENTITIES].
*/
@JvmStatic
fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DEV_TRUST_ROOT)
/** /**
* Makes database and mock services appropriate for unit tests. * Makes database and mock services appropriate for unit tests.
* @param keys a list of [KeyPair] instances to be used by [MockServices]. Defaults to [MEGA_CORP_KEY] * @param keys a list of [KeyPair] instances to be used by [MockServices]. Defaults to [MEGA_CORP_KEY]
@ -149,7 +144,7 @@ open class MockServices(
final override val attachments = MockAttachmentStorage() final override val attachments = MockAttachmentStorage()
val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage() val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage()
override val identityService: IdentityService = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DEV_TRUST_ROOT) override val identityService: IdentityService = makeTestIdentityService()
override val keyManagementService: KeyManagementService by lazy { MockKeyManagementService(identityService, *keys) } override val keyManagementService: KeyManagementService by lazy { MockKeyManagementService(identityService, *keys) }
override val vaultService: VaultService get() = throw UnsupportedOperationException() override val vaultService: VaultService get() = throw UnsupportedOperationException()

View File

@ -3,7 +3,6 @@
package net.corda.testing package net.corda.testing
import com.nhaarman.mockito_kotlin.mock
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
@ -23,11 +22,12 @@ import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.serialization.amqp.AMQP_ENABLED import net.corda.nodeapi.internal.serialization.amqp.AMQP_ENABLED
import org.mockito.Mockito.mock
import org.mockito.internal.stubbing.answers.ThrowsException import org.mockito.internal.stubbing.answers.ThrowsException
import org.mockito.stubbing.Answer
import java.nio.file.Files import java.nio.file.Files
import java.security.KeyPair import java.security.KeyPair
import java.security.PublicKey import java.security.PublicKey
import java.util.*
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
/** /**
@ -178,12 +178,13 @@ fun NodeInfo.singleIdentity(): Party = singleIdentityAndCert().party
*/ */
class UndefinedMockBehaviorException(message: String) : RuntimeException(message) class UndefinedMockBehaviorException(message: String) : RuntimeException(message)
inline fun <reified T : Any> rigorousMock() = rigorousMock(T::class.java)
/** /**
* Create a Mockito mock that has [UndefinedMockBehaviorException] as the default behaviour of all methods. * 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, * @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. * it won't work unless you mock a (trivial) abstract implementation of that interface instead.
*/ */
inline fun <reified T : Any> rigorousMock() = mock<T>(Answer { fun <T> rigorousMock(clazz: Class<T>): T = mock(clazz) {
// Use ThrowsException to hack the stack trace, and lazily so we can customise the message: // 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) ThrowsException(UndefinedMockBehaviorException("Please specify what should happen when '${it.method}' is called, or don't call it. Args: ${Arrays.toString(it.arguments)}")).answer(it)
}) }