ENT-11192: Migrate usage of @Test.expected annotation parameter (#7593)

Replaced usage of `@Test.expected` annotation parameter with more specific exception assertions. This is also needed to migrate away from the explicit timeouts in every tests.
This commit is contained in:
Shams Asari 2023-12-06 16:45:51 +00:00 committed by GitHub
parent 755c7b73b0
commit 199e167639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 690 additions and 391 deletions

View File

@ -1,11 +1,16 @@
package net.corda.coretests.contracts package net.corda.coretests.contracts
import net.corda.core.contracts.* import net.corda.core.contracts.CommandData
import net.corda.core.contracts.CommandWithParties
import net.corda.core.contracts.TypeOnlyCommandData
import net.corda.core.contracts.requireSingleCommand
import net.corda.core.contracts.select
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
@ -35,8 +40,8 @@ class RequireSingleCommandTests(private val testFunction: (Collection<CommandWit
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
fun data(): Collection<Array<Any>> = listOf( fun data(): Collection<Array<Any>> = listOf(
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>> -> commands.requireSingleCommand<TestCommands>() }, "Inline version"), arrayOf({ commands: Collection<CommandWithParties<CommandData>> -> commands.requireSingleCommand<TestCommands>() }, "Inline version"),
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>> -> commands.requireSingleCommand(TestCommands::class.java) }, "Interop version") arrayOf({ commands: Collection<CommandWithParties<CommandData>> -> commands.requireSingleCommand(TestCommands::class.java) }, "Interop version")
) )
} }
@ -47,16 +52,18 @@ class RequireSingleCommandTests(private val testFunction: (Collection<CommandWit
assertEquals(returnedCommand, validCommandOne, "they should be the same") assertEquals(returnedCommand, validCommandOne, "they should be the same")
} }
@Test(expected = IllegalArgumentException::class, timeout=300_000) @Test(timeout=300_000)
fun `check error is thrown if more than one valid command`() { fun `check error is thrown if more than one valid command`() {
val commands = listOf(validCommandOne, validCommandTwo) val commands = listOf(validCommandOne, validCommandTwo)
assertThatIllegalArgumentException().isThrownBy {
testFunction(commands) testFunction(commands)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `check error is thrown when command is of wrong type`() { fun `check error is thrown when command is of wrong type`() {
val commands = listOf(invalidCommand) val commands = listOf(invalidCommand)
Assertions.assertThatThrownBy { testFunction(commands) } assertThatThrownBy { testFunction(commands) }
.isInstanceOf(IllegalStateException::class.java) .isInstanceOf(IllegalStateException::class.java)
.hasMessage("Required net.corda.coretests.contracts.TestCommands command") .hasMessage("Required net.corda.coretests.contracts.TestCommands command")
} }
@ -69,8 +76,8 @@ class SelectWithSingleInputsTests(private val testFunction: (Collection<CommandW
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
fun data(): Collection<Array<Any>> = listOf( fun data(): Collection<Array<Any>> = listOf(
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>>, signer: PublicKey?, party: AbstractParty? -> commands.select<TestCommands>(signer, party) }, "Inline version"), arrayOf({ commands: Collection<CommandWithParties<CommandData>>, signer: PublicKey?, party: AbstractParty? -> commands.select<TestCommands>(signer, party) }, "Inline version"),
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>>, signer: PublicKey?, party: AbstractParty? -> commands.select(TestCommands::class.java, signer, party) }, "Interop version") arrayOf({ commands: Collection<CommandWithParties<CommandData>>, signer: PublicKey?, party: AbstractParty? -> commands.select(TestCommands::class.java, signer, party) }, "Interop version")
) )
} }
@ -118,8 +125,8 @@ class SelectWithMultipleInputsTests(private val testFunction: (Collection<Comman
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
fun data(): Collection<Array<Any>> = listOf( fun data(): Collection<Array<Any>> = listOf(
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>>, signers: Collection<PublicKey>?, party: Collection<Party>? -> commands.select<TestCommands>(signers, party) }, "Inline version"), arrayOf({ commands: Collection<CommandWithParties<CommandData>>, signers: Collection<PublicKey>?, party: Collection<Party>? -> commands.select<TestCommands>(signers, party) }, "Inline version"),
arrayOf<Any>({ commands: Collection<CommandWithParties<CommandData>>, signers: Collection<PublicKey>?, party: Collection<Party>? -> commands.select(TestCommands::class.java, signers, party) }, "Interop version") arrayOf({ commands: Collection<CommandWithParties<CommandData>>, signers: Collection<PublicKey>?, party: Collection<Party>? -> commands.select(TestCommands::class.java, signers, party) }, "Interop version")
) )
} }

View File

@ -1,11 +1,19 @@
package net.corda.coretests.crypto package net.corda.coretests.crypto
import org.mockito.kotlin.doReturn import net.corda.core.contracts.Command
import org.mockito.kotlin.mock import net.corda.core.contracts.PrivacySalt
import org.mockito.kotlin.whenever import net.corda.core.contracts.StateRef
import net.corda.core.contracts.* import net.corda.core.contracts.TimeWindow
import net.corda.core.crypto.* import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.MerkleTree
import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.PartialMerkleTree
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.internal.DigestAlgorithmFactory import net.corda.core.crypto.internal.DigestAlgorithmFactory
import net.corda.core.crypto.keys
import net.corda.core.crypto.randomHash
import net.corda.core.crypto.sha256
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.BLAKE2s256DigestAlgorithm import net.corda.core.internal.BLAKE2s256DigestAlgorithm
@ -16,9 +24,10 @@ import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.transactions.ReferenceStateRef import net.corda.core.transactions.ReferenceStateRef
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.`issued by`
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
@ -26,20 +35,29 @@ import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.LedgerDSL import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.testing.internal.createWireTransaction import net.corda.testing.internal.createWireTransaction
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.security.PublicKey import java.security.PublicKey
import java.util.function.Predicate import java.util.function.Predicate
import java.util.stream.IntStream import java.util.stream.IntStream
import kotlin.streams.toList import kotlin.streams.toList
import kotlin.test.* import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class PartialMerkleTreeTest(private var digestService: DigestService) { class PartialMerkleTreeTest(private var digestService: DigestService) {
@ -204,7 +222,7 @@ class PartialMerkleTreeTest(private var digestService: DigestService) {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `nothing filtered`() { fun `nothing filtered`() {
val ftxNothing = testTx.buildFilteredTransaction(Predicate { false }) val ftxNothing = testTx.buildFilteredTransaction { false }
assertTrue(ftxNothing.componentGroups.isEmpty()) assertTrue(ftxNothing.componentGroups.isEmpty())
assertTrue(ftxNothing.attachments.isEmpty()) assertTrue(ftxNothing.attachments.isEmpty())
assertTrue(ftxNothing.commands.isEmpty()) assertTrue(ftxNothing.commands.isEmpty())
@ -291,11 +309,13 @@ class PartialMerkleTreeTest(private var digestService: DigestService) {
assertFalse(pmt.verify(wrongRoot, inclHashes)) assertFalse(pmt.verify(wrongRoot, inclHashes))
} }
@Test(expected = Exception::class, timeout=300_000) @Test(timeout=300_000)
fun `hash map serialization not allowed`() { fun `hash map serialization not allowed`() {
val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4) val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4)
assertThatIllegalArgumentException().isThrownBy {
hm1.serialize() hm1.serialize()
} }
}
private fun makeSimpleCashWtx( private fun makeSimpleCashWtx(
notary: Party, notary: Party,
@ -322,11 +342,11 @@ class PartialMerkleTreeTest(private var digestService: DigestService) {
val merkleTree = MerkleTree.getMerkleTree(sampleLeaves, digestService) val merkleTree = MerkleTree.getMerkleTree(sampleLeaves, digestService)
// Provided hashes are not in the tree. // Provided hashes are not in the tree.
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("20"))) } assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, listOf(digestService.hash("20"))) }
// One of the provided hashes is not in the tree. // One of the provided hashes is not in the tree.
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("20"), digestService.hash("1"), digestService.hash("5"))) } assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, listOf(digestService.hash("20"), digestService.hash("1"), digestService.hash("5"))) }
val pmt = PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("1"), digestService.hash("5"), digestService.hash("0"), digestService.hash("19"))) val pmt = PartialMerkleTree.build(merkleTree, listOf(digestService.hash("1"), digestService.hash("5"), digestService.hash("0"), digestService.hash("19")))
// First leaf. // First leaf.
assertEquals(0, pmt.leafIndex(digestService.hash("0"))) assertEquals(0, pmt.leafIndex(digestService.hash("0")))
// Second leaf. // Second leaf.
@ -340,17 +360,17 @@ class PartialMerkleTreeTest(private var digestService: DigestService) {
// The provided hash is not in the tree (using a leaf that didn't exist in the original Merkle tree). // The provided hash is not in the tree (using a leaf that didn't exist in the original Merkle tree).
assertFailsWith<MerkleTreeException> { pmt.leafIndex(digestService.hash("30")) } assertFailsWith<MerkleTreeException> { pmt.leafIndex(digestService.hash("30")) }
val pmtFirstElementOnly = PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("0"))) val pmtFirstElementOnly = PartialMerkleTree.build(merkleTree, listOf(digestService.hash("0")))
assertEquals(0, pmtFirstElementOnly.leafIndex(digestService.hash("0"))) assertEquals(0, pmtFirstElementOnly.leafIndex(digestService.hash("0")))
// The provided hash is not in the tree. // The provided hash is not in the tree.
assertFailsWith<MerkleTreeException> { pmtFirstElementOnly.leafIndex(digestService.hash("10")) } assertFailsWith<MerkleTreeException> { pmtFirstElementOnly.leafIndex(digestService.hash("10")) }
val pmtLastElementOnly = PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("19"))) val pmtLastElementOnly = PartialMerkleTree.build(merkleTree, listOf(digestService.hash("19")))
assertEquals(19, pmtLastElementOnly.leafIndex(digestService.hash("19"))) assertEquals(19, pmtLastElementOnly.leafIndex(digestService.hash("19")))
// The provided hash is not in the tree. // The provided hash is not in the tree.
assertFailsWith<MerkleTreeException> { pmtLastElementOnly.leafIndex(digestService.hash("10")) } assertFailsWith<MerkleTreeException> { pmtLastElementOnly.leafIndex(digestService.hash("10")) }
val pmtOneElement = PartialMerkleTree.build(merkleTree, listOf<SecureHash>(digestService.hash("5"))) val pmtOneElement = PartialMerkleTree.build(merkleTree, listOf(digestService.hash("5")))
assertEquals(5, pmtOneElement.leafIndex(digestService.hash("5"))) assertEquals(5, pmtOneElement.leafIndex(digestService.hash("5")))
// The provided hash is not in the tree. // The provided hash is not in the tree.
assertFailsWith<MerkleTreeException> { pmtOneElement.leafIndex(digestService.hash("10")) } assertFailsWith<MerkleTreeException> { pmtOneElement.leafIndex(digestService.hash("10")) }

View File

@ -1,17 +1,14 @@
package net.corda.coretests.crypto package net.corda.coretests.crypto
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.PrivacySalt
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.TransactionState import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.MerkleTree import net.corda.core.crypto.MerkleTree
import net.corda.core.crypto.MerkleTreeException import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.PartialMerkleTree import net.corda.core.crypto.PartialMerkleTree
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SecureHash.Companion.SHA2_384 import net.corda.core.crypto.SecureHash.Companion.SHA2_384
import net.corda.core.crypto.SecureHash.Companion.hashAs import net.corda.core.crypto.SecureHash.Companion.hashAs
@ -26,9 +23,10 @@ import net.corda.core.serialization.serialize
import net.corda.core.transactions.ReferenceStateRef import net.corda.core.transactions.ReferenceStateRef
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.`issued by`
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
@ -36,10 +34,10 @@ import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.LedgerDSL import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.testing.internal.createWireTransaction import net.corda.testing.internal.createWireTransaction
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotNull
@ -49,6 +47,9 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.security.PublicKey import java.security.PublicKey
import java.util.function.Predicate import java.util.function.Predicate
import java.util.stream.IntStream import java.util.stream.IntStream
@ -209,7 +210,7 @@ class PartialMerkleTreeWithNamedHashMultiAlgTreeTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `nothing filtered`() { fun `nothing filtered`() {
val ftxNothing = testTx.buildFilteredTransaction(Predicate { false }) val ftxNothing = testTx.buildFilteredTransaction { false }
assertTrue(ftxNothing.componentGroups.isEmpty()) assertTrue(ftxNothing.componentGroups.isEmpty())
assertTrue(ftxNothing.attachments.isEmpty()) assertTrue(ftxNothing.attachments.isEmpty())
assertTrue(ftxNothing.commands.isEmpty()) assertTrue(ftxNothing.commands.isEmpty())
@ -296,11 +297,13 @@ class PartialMerkleTreeWithNamedHashMultiAlgTreeTest {
assertFalse(pmt.verify(wrongRoot, inclHashes)) assertFalse(pmt.verify(wrongRoot, inclHashes))
} }
@Test(expected = Exception::class, timeout=300_000) @Test(timeout=300_000)
fun `hash map serialization not allowed`() { fun `hash map serialization not allowed`() {
val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4) val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4)
assertThatIllegalArgumentException().isThrownBy {
hm1.serialize() hm1.serialize()
} }
}
private fun makeSimpleCashWtx( private fun makeSimpleCashWtx(
notary: Party, notary: Party,

View File

@ -1,17 +1,14 @@
package net.corda.coretests.crypto package net.corda.coretests.crypto
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.PrivacySalt
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.TransactionState import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.MerkleTree import net.corda.core.crypto.MerkleTree
import net.corda.core.crypto.MerkleTreeException import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.PartialMerkleTree import net.corda.core.crypto.PartialMerkleTree
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SecureHash.Companion.SHA2_384 import net.corda.core.crypto.SecureHash.Companion.SHA2_384
import net.corda.core.crypto.SecureHash.Companion.hashAs import net.corda.core.crypto.SecureHash.Companion.hashAs
@ -26,9 +23,10 @@ import net.corda.core.serialization.serialize
import net.corda.core.transactions.ReferenceStateRef import net.corda.core.transactions.ReferenceStateRef
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.`issued by`
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
@ -36,10 +34,10 @@ import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.LedgerDSL import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.testing.internal.createWireTransaction import net.corda.testing.internal.createWireTransaction
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotNull
@ -49,6 +47,9 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.security.PublicKey import java.security.PublicKey
import java.util.function.Predicate import java.util.function.Predicate
import java.util.stream.IntStream import java.util.stream.IntStream
@ -209,7 +210,7 @@ class PartialMerkleTreeWithNamedHashTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `nothing filtered`() { fun `nothing filtered`() {
val ftxNothing = testTx.buildFilteredTransaction(Predicate { false }) val ftxNothing = testTx.buildFilteredTransaction { false }
assertTrue(ftxNothing.componentGroups.isEmpty()) assertTrue(ftxNothing.componentGroups.isEmpty())
assertTrue(ftxNothing.attachments.isEmpty()) assertTrue(ftxNothing.attachments.isEmpty())
assertTrue(ftxNothing.commands.isEmpty()) assertTrue(ftxNothing.commands.isEmpty())
@ -296,11 +297,13 @@ class PartialMerkleTreeWithNamedHashTest {
assertFalse(pmt.verify(wrongRoot, inclHashes)) assertFalse(pmt.verify(wrongRoot, inclHashes))
} }
@Test(expected = Exception::class, timeout=300_000) @Test(timeout=300_000)
fun `hash map serialization not allowed`() { fun `hash map serialization not allowed`() {
val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4) val hm1 = hashMapOf("a" to 1, "b" to 2, "c" to 3, "e" to 4)
assertThatIllegalArgumentException().isThrownBy {
hm1.serialize() hm1.serialize()
} }
}
private fun makeSimpleCashWtx( private fun makeSimpleCashWtx(
notary: Party, notary: Party,

View File

@ -6,6 +6,7 @@ import net.corda.core.crypto.sign
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -35,12 +36,14 @@ class SignedDataTest {
assertEquals(data, unwrappedData) assertEquals(data, unwrappedData)
} }
@Test(expected = SignatureException::class, timeout=300_000) @Test(timeout=300_000)
fun `make sure incorrectly signed data raises an exception`() { fun `make sure incorrectly signed data raises an exception`() {
val keyPairA = generateKeyPair() val keyPairA = generateKeyPair()
val keyPairB = generateKeyPair() val keyPairB = generateKeyPair()
val sig = keyPairA.private.sign(serialized.bytes, keyPairB.public) val sig = keyPairA.private.sign(serialized.bytes, keyPairB.public)
val wrappedData = SignedData(serialized, sig) val wrappedData = SignedData(serialized, sig)
assertThatExceptionOfType(SignatureException::class.java).isThrownBy {
wrappedData.verified() wrappedData.verified()
} }
}
} }

View File

@ -1,7 +1,17 @@
package net.corda.coretests.crypto package net.corda.coretests.crypto
import net.corda.core.crypto.* import net.corda.core.crypto.Crypto
import net.corda.core.crypto.MerkleTree
import net.corda.core.crypto.MerkleTreeException
import net.corda.core.crypto.PartialMerkleTree
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SignableData
import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.TransactionSignature
import net.corda.core.crypto.sha256
import net.corda.core.crypto.sign
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.math.BigInteger import java.math.BigInteger
@ -39,13 +49,15 @@ class TransactionSignatureTest {
} }
/** Verification should fail; corrupted metadata - clearData (Merkle root) has changed. */ /** Verification should fail; corrupted metadata - clearData (Merkle root) has changed. */
@Test(expected = SignatureException::class,timeout=300_000) @Test(timeout=300_000)
fun `Signature metadata full failure clearData has changed`() { fun `Signature metadata full failure clearData has changed`() {
val keyPair = Crypto.generateKeyPair("ECDSA_SECP256K1_SHA256") val keyPair = Crypto.generateKeyPair("ECDSA_SECP256K1_SHA256")
val signableData = SignableData(testBytes.sha256(), SignatureMetadata(1, Crypto.findSignatureScheme(keyPair.public).schemeNumberID)) val signableData = SignableData(testBytes.sha256(), SignatureMetadata(1, Crypto.findSignatureScheme(keyPair.public).schemeNumberID))
val transactionSignature = keyPair.sign(signableData) val transactionSignature = keyPair.sign(signableData)
assertThatExceptionOfType(SignatureException::class.java).isThrownBy {
Crypto.doVerify((testBytes + testBytes).sha256(), transactionSignature) Crypto.doVerify((testBytes + testBytes).sha256(), transactionSignature)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `Verify multi-tx signature`() { fun `Verify multi-tx signature`() {

View File

@ -23,22 +23,22 @@ import net.corda.core.identity.groupAbstractPartyByWellKnownParty
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.coretesting.internal.matchers.flow.willReturn
import net.corda.coretesting.internal.matchers.flow.willThrow
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.coretesting.internal.matchers.flow.willReturn
import net.corda.coretesting.internal.matchers.flow.willThrow
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.TestStartedNode import net.corda.testing.node.internal.TestStartedNode
import net.corda.testing.node.internal.enclosedCordapp import net.corda.testing.node.internal.enclosedCordapp
import org.hamcrest.CoreMatchers.`is` import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.AfterClass import org.junit.AfterClass
import org.junit.Assert
import org.junit.Test import org.junit.Test
import java.security.PublicKey import java.security.PublicKey
@ -92,7 +92,7 @@ class CollectSignaturesFlowTests : WithContracts {
mockNet.runNetwork() mockNet.runNetwork()
val stx = future.get() val stx = future.get()
val missingSigners = stx.getMissingSigners() val missingSigners = stx.getMissingSigners()
Assert.assertThat(missingSigners, `is`(emptySet())) assertThat(missingSigners).isEmpty()
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -122,10 +122,10 @@ class CollectSignaturesFlowTests : WithContracts {
mockNet.runNetwork() mockNet.runNetwork()
val stx = future.get() val stx = future.get()
val missingSigners = stx.getMissingSigners() val missingSigners = stx.getMissingSigners()
Assert.assertThat(missingSigners, `is`(emptySet())) assertThat(missingSigners).isEmpty()
} }
@Test(expected = IllegalArgumentException::class, timeout=300_000) @Test(timeout=300_000)
fun `throws exception when extra sessions are initiated`() { fun `throws exception when extra sessions are initiated`() {
bobNode.registerInitiatedFlow(ExtraSessionsFlowResponder::class.java) bobNode.registerInitiatedFlow(ExtraSessionsFlowResponder::class.java)
charlieNode.registerInitiatedFlow(ExtraSessionsFlowResponder::class.java) charlieNode.registerInitiatedFlow(ExtraSessionsFlowResponder::class.java)
@ -137,8 +137,10 @@ class CollectSignaturesFlowTests : WithContracts {
listOf(bobNode.info.singleIdentity(), alice))) listOf(bobNode.info.singleIdentity(), alice)))
.resultFuture .resultFuture
mockNet.runNetwork() mockNet.runNetwork()
assertThatIllegalArgumentException().isThrownBy {
future.getOrThrow() future.getOrThrow()
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `it is possible to collect from multiple well known sessions`() { fun `it is possible to collect from multiple well known sessions`() {
@ -152,7 +154,7 @@ class CollectSignaturesFlowTests : WithContracts {
listOf(bobNode.info.singleIdentity(), alice))).resultFuture listOf(bobNode.info.singleIdentity(), alice))).resultFuture
mockNet.runNetwork() mockNet.runNetwork()
val signedTx = future.getOrThrow() val signedTx = future.getOrThrow()
Assert.assertThat(signedTx.getMissingSigners(), `is`(emptySet())) assertThat(signedTx.getMissingSigners()).isEmpty()
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -216,7 +218,7 @@ class CollectSignaturesFlowTests : WithContracts {
} }
} }
@InitiatedBy(TestFlow.Initiator::class) @InitiatedBy(Initiator::class)
class Responder(private val otherSideSession: FlowSession) : FlowLogic<Unit>() { class Responder(private val otherSideSession: FlowSession) : FlowLogic<Unit>() {
@Suspendable @Suspendable
override fun call() { override fun call() {
@ -251,7 +253,7 @@ class AnonymousSessionTestFlow(private val cis: List<PartyAndCertificate>) : Flo
} }
} }
val state = DummyContract.MultiOwnerState(owners = cis.map { AnonymousParty(it.owningKey) }) val state = DummyContract.MultiOwnerState(owners = cis.map { AnonymousParty(it.owningKey) })
val create = net.corda.testing.contracts.DummyContract.Commands.Create() val create = DummyContract.Commands.Create()
val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first()) val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first())
.addOutputState(state) .addOutputState(state)
.addCommand(create, cis.map { it.owningKey }) .addCommand(create, cis.map { it.owningKey })
@ -289,7 +291,7 @@ class MixAndMatchAnonymousSessionTestFlow(private val cis: List<PartyAndCertific
} }
} }
val state = DummyContract.MultiOwnerState(owners = cis.map { AnonymousParty(it.owningKey) }) val state = DummyContract.MultiOwnerState(owners = cis.map { AnonymousParty(it.owningKey) })
val create = net.corda.testing.contracts.DummyContract.Commands.Create() val create = DummyContract.Commands.Create()
val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first()) val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first())
.addOutputState(state) .addOutputState(state)
.addCommand(create, cis.map { it.owningKey }) .addCommand(create, cis.map { it.owningKey })
@ -324,7 +326,7 @@ class ExtraSessionsFlow(private val openFor: List<Party>, private val involve: L
val sessions = openFor.map { initiateFlow(it) } val sessions = openFor.map { initiateFlow(it) }
val state = DummyContract.MultiOwnerState(owners = involve.map { AnonymousParty(it.owningKey) }) val state = DummyContract.MultiOwnerState(owners = involve.map { AnonymousParty(it.owningKey) })
val create = net.corda.testing.contracts.DummyContract.Commands.Create() val create = DummyContract.Commands.Create()
val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first()) val txBuilder = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first())
.addOutputState(state) .addOutputState(state)
.addCommand(create, involve.map { it.owningKey }) .addCommand(create, involve.map { it.owningKey })

View File

@ -1,8 +1,5 @@
package net.corda.coretests.transactions package net.corda.coretests.transactions
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
import net.corda.core.contracts.ContractAttachment import net.corda.core.contracts.ContractAttachment
import net.corda.core.contracts.HashAttachmentConstraint import net.corda.core.contracts.HashAttachmentConstraint
@ -12,7 +9,7 @@ import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.TransactionState import net.corda.core.contracts.TransactionState
import net.corda.core.contracts.TransactionVerificationException import net.corda.core.contracts.TransactionVerificationException.UnsupportedHashTypeException
import net.corda.core.cordapp.CordappProvider import net.corda.core.cordapp.CordappProvider
import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.DigestService import net.corda.core.crypto.DigestService
@ -40,6 +37,7 @@ import net.corda.testing.core.DummyCommandData
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -47,6 +45,9 @@ import org.junit.Before
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.security.PublicKey import java.security.PublicKey
import java.time.Instant import java.time.Instant
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -270,7 +271,7 @@ class TransactionBuilderTest {
} }
@Ignore @Ignore
@Test(timeout=300_000, expected = TransactionVerificationException.UnsupportedHashTypeException::class) @Test(timeout=300_000)
fun `throws with non-default hash algorithm`() { fun `throws with non-default hash algorithm`() {
HashAgility.init() HashAgility.init()
try { try {
@ -286,13 +287,15 @@ class TransactionBuilderTest {
.addOutputState(outputState) .addOutputState(outputState)
.addCommand(DummyCommandData, notary.owningKey) .addCommand(DummyCommandData, notary.owningKey)
assertThatExceptionOfType(UnsupportedHashTypeException::class.java).isThrownBy {
builder.toWireTransaction(services) builder.toWireTransaction(services)
}
} finally { } finally {
HashAgility.init() HashAgility.init()
} }
} }
@Test(timeout=300_000, expected = Test.None::class) @Test(timeout=300_000)
fun `allows non-default hash algorithm`() { fun `allows non-default hash algorithm`() {
HashAgility.init(txHashAlgoName = DigestService.sha2_384.hashAlgorithm) HashAgility.init(txHashAlgoName = DigestService.sha2_384.hashAlgorithm)
assertThat(services.digestService).isEqualTo(DigestService.sha2_384) assertThat(services.digestService).isEqualTo(DigestService.sha2_384)

View File

@ -16,6 +16,7 @@ import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
@ -23,7 +24,6 @@ import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey
import org.bouncycastle.jce.ECNamedCurveTable import org.bouncycastle.jce.ECNamedCurveTable
import org.bouncycastle.jce.interfaces.ECKey import org.bouncycastle.jce.interfaces.ECKey
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
import org.bouncycastle.operator.ContentSigner
import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PrivateKey import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PrivateKey
import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PublicKey import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PublicKey
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
@ -33,8 +33,12 @@ import java.math.BigInteger
import java.security.KeyPairGenerator import java.security.KeyPairGenerator
import java.security.SecureRandom import java.security.SecureRandom
import java.security.Security import java.security.Security
import java.util.* import java.util.Random
import kotlin.test.* import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import kotlin.test.fail
/** /**
* Run tests for cryptographic algorithms. * Run tests for cryptographic algorithms.
@ -629,7 +633,7 @@ class CryptoUtilsTest {
val encodedPrivK1 = privK1.encoded val encodedPrivK1 = privK1.encoded
// fail on malformed key. // fail on malformed key.
for (i in 0 until encodedPrivK1.size) { for (i in encodedPrivK1.indices) {
val b = encodedPrivK1[i] val b = encodedPrivK1[i]
encodedPrivK1[i] = b.inc() encodedPrivK1[i] = b.inc()
try { try {
@ -665,7 +669,7 @@ class CryptoUtilsTest {
assertFalse(Crypto.publicKeyOnCurve(EDDSA_ED25519_SHA512, EdDSAPublicKey(pubKeySpec))) assertFalse(Crypto.publicKeyOnCurve(EDDSA_ED25519_SHA512, EdDSAPublicKey(pubKeySpec)))
} }
@Test(expected = IllegalArgumentException::class, timeout = 300_000) @Test(timeout = 300_000)
@Ignore("TODO JDK17: Fixme") @Ignore("TODO JDK17: Fixme")
fun `Unsupported EC public key type on curve`() { fun `Unsupported EC public key type on curve`() {
val keyGen = KeyPairGenerator.getInstance("EC") // sun.security.ec.ECPublicKeyImpl val keyGen = KeyPairGenerator.getInstance("EC") // sun.security.ec.ECPublicKeyImpl
@ -673,8 +677,10 @@ class CryptoUtilsTest {
val pairSun = keyGen.generateKeyPair() val pairSun = keyGen.generateKeyPair()
val pubSun = pairSun.public val pubSun = pairSun.public
// Should fail as pubSun is not a BCECPublicKey. // Should fail as pubSun is not a BCECPublicKey.
assertThatIllegalArgumentException().isThrownBy {
Crypto.publicKeyOnCurve(ECDSA_SECP256R1_SHA256, pubSun) Crypto.publicKeyOnCurve(ECDSA_SECP256R1_SHA256, pubSun)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `ECDSA secp256R1 deterministic key generation`() { fun `ECDSA secp256R1 deterministic key generation`() {
@ -929,11 +935,6 @@ class CryptoUtilsTest {
assertNotEquals(OpaqueBytes(signedData1stTime), OpaqueBytes(signedZeroArray1stTime)) assertNotEquals(OpaqueBytes(signedData1stTime), OpaqueBytes(signedZeroArray1stTime))
} }
fun ContentSigner.write(message: ByteArray) {
this.outputStream.write(message)
this.outputStream.close()
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test default SecureRandom uses platformSecureRandom`() { fun `test default SecureRandom uses platformSecureRandom`() {
// Note than in Corda, [CordaSecurityProvider] is registered as the first provider. // Note than in Corda, [CordaSecurityProvider] is registered as the first provider.

View File

@ -9,6 +9,7 @@ import net.corda.core.node.services.AttachmentId
import net.corda.core.serialization.internal.AttachmentURLStreamHandlerFactory import net.corda.core.serialization.internal.AttachmentURLStreamHandlerFactory
import net.corda.core.serialization.internal.AttachmentsClassLoader import net.corda.core.serialization.internal.AttachmentsClassLoader
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
@ -76,10 +77,12 @@ class ClassLoadingUtilsTest {
.doesNotContain(AbstractClass::class.java.name) .doesNotContain(AbstractClass::class.java.name)
} }
@Test(expected = IllegalArgumentException::class,timeout=300_000) @Test(timeout=300_000)
fun throwsExceptionWhenClassDoesNotContainProperConstructors() { fun throwsExceptionWhenClassDoesNotContainProperConstructors() {
assertThatIllegalArgumentException().isThrownBy {
createInstancesOfClassesImplementing(BaseInterface::class.java.classLoader, BaseInterface2::class.java) createInstancesOfClassesImplementing(BaseInterface::class.java.classLoader, BaseInterface2::class.java)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `thread context class loader is adjusted, during the function execution`() { fun `thread context class loader is adjusted, during the function execution`() {

View File

@ -31,6 +31,9 @@ import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServ
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import net.corda.testing.node.makeTestIdentityService import net.corda.testing.node.makeTestIdentityService
import net.corda.testing.node.transaction import net.corda.testing.node.transaction
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.assertj.core.api.Assertions.assertThatIllegalStateException
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
@ -300,7 +303,7 @@ class CashTests {
* Test that the issuance builder rejects building into a transaction with existing * Test that the issuance builder rejects building into a transaction with existing
* cash inputs. * cash inputs.
*/ */
@Test(expected = IllegalStateException::class, timeout=300_000) @Test(timeout=300_000)
fun `reject issuance with inputs`() { fun `reject issuance with inputs`() {
// Issue some cash // Issue some cash
var ptx = TransactionBuilder(dummyNotary.party) var ptx = TransactionBuilder(dummyNotary.party)
@ -311,8 +314,10 @@ class CashTests {
// Include the previously issued cash in a new issuance command // Include the previously issued cash in a new issuance command
ptx = TransactionBuilder(dummyNotary.party) ptx = TransactionBuilder(dummyNotary.party)
ptx.addInputState(tx.tx.outRef<Cash.State>(0)) ptx.addInputState(tx.tx.outRef<Cash.State>(0))
assertThatIllegalStateException().isThrownBy {
Cash().generateIssue(ptx, 100.DOLLARS `issued by` miniCorp.ref(12, 34), owner = miniCorp.party, notary = dummyNotary.party) Cash().generateIssue(ptx, 100.DOLLARS `issued by` miniCorp.ref(12, 34), owner = miniCorp.party, notary = dummyNotary.party)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun testMergeSplit() { fun testMergeSplit() {
@ -762,14 +767,16 @@ class CashTests {
assertEquals(6000.DOLLARS `issued by` defaultIssuer, states.sumCashBy(megaCorp.party)) assertEquals(6000.DOLLARS `issued by` defaultIssuer, states.sumCashBy(megaCorp.party))
} }
@Test(expected = UnsupportedOperationException::class, timeout=300_000) @Test(timeout=300_000)
fun `summing by owner throws`() { fun `summing by owner throws`() {
val states = listOf( val states = listOf(
Cash.State(2000.DOLLARS `issued by` defaultIssuer, megaCorp.party), Cash.State(2000.DOLLARS `issued by` defaultIssuer, megaCorp.party),
Cash.State(4000.DOLLARS `issued by` defaultIssuer, megaCorp.party) Cash.State(4000.DOLLARS `issued by` defaultIssuer, megaCorp.party)
) )
assertThatExceptionOfType(UnsupportedOperationException::class.java).isThrownBy {
states.sumCashBy(miniCorp.party) states.sumCashBy(miniCorp.party)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `summing no currencies`() { fun `summing no currencies`() {
@ -778,11 +785,13 @@ class CashTests {
assertNull(states.sumCashOrNull()) assertNull(states.sumCashOrNull())
} }
@Test(expected = UnsupportedOperationException::class, timeout=300_000) @Test(timeout=300_000)
fun `summing no currencies throws`() { fun `summing no currencies throws`() {
val states = emptyList<Cash.State>() val states = emptyList<Cash.State>()
assertThatExceptionOfType(UnsupportedOperationException::class.java).isThrownBy {
states.sumCash() states.sumCash()
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `summing a single currency`() { fun `summing a single currency`() {
@ -797,15 +806,17 @@ class CashTests {
assertEquals(expected, actual) assertEquals(expected, actual)
} }
@Test(expected = IllegalArgumentException::class, timeout=300_000) @Test(timeout=300_000)
fun `summing multiple currencies`() { fun `summing multiple currencies`() {
val states = listOf( val states = listOf(
Cash.State(1000.DOLLARS `issued by` defaultIssuer, megaCorp.party), Cash.State(1000.DOLLARS `issued by` defaultIssuer, megaCorp.party),
Cash.State(4000.POUNDS `issued by` defaultIssuer, megaCorp.party) Cash.State(4000.POUNDS `issued by` defaultIssuer, megaCorp.party)
) )
// Test that summing everything fails because we're mixing units // Test that summing everything fails because we're mixing units
assertThatIllegalArgumentException().isThrownBy {
states.sumCash() states.sumCash()
} }
}
// Double spend. // Double spend.
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -1,9 +1,14 @@
package net.corda.finance.contracts.asset package net.corda.finance.contracts.asset
import org.mockito.kotlin.doReturn import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import org.mockito.kotlin.mock import net.corda.core.contracts.Amount
import org.mockito.kotlin.whenever import net.corda.core.contracts.BelongsToContract
import net.corda.core.contracts.* import net.corda.core.contracts.ContractClassName
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.Issued
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.NullKeys.NULL_PARTY import net.corda.core.crypto.NullKeys.NULL_PARTY
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256 import net.corda.core.crypto.sha256
@ -16,25 +21,44 @@ import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.days import net.corda.core.utilities.days
import net.corda.core.utilities.hours import net.corda.core.utilities.hours
import net.corda.finance.* import net.corda.coretesting.internal.TEST_TX_TIME
import net.corda.finance.DOLLARS
import net.corda.finance.GBP
import net.corda.finance.POUNDS
import net.corda.finance.USD
import net.corda.finance.contracts.Commodity import net.corda.finance.contracts.Commodity
import net.corda.finance.contracts.NetType import net.corda.finance.contracts.NetType
import net.corda.finance.contracts.asset.Obligation.Lifecycle import net.corda.finance.contracts.asset.Obligation.Lifecycle
import net.corda.finance.`issued by`
import net.corda.finance.workflows.asset.ObligationUtils import net.corda.finance.workflows.asset.ObligationUtils
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.dsl.* import net.corda.testing.core.BOB_NAME
import net.corda.coretesting.internal.TEST_TX_TIME import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.DummyCommandData
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.EnforceVerifyOrFail
import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.dsl.TransactionDSL
import net.corda.testing.dsl.TransactionDSLInterpreter
import net.corda.testing.internal.fakeAttachment import net.corda.testing.internal.fakeAttachment
import net.corda.testing.internal.vault.CommodityState import net.corda.testing.internal.vault.CommodityState
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import net.corda.testing.node.transaction import net.corda.testing.node.transaction
import org.assertj.core.api.Assertions.assertThatIllegalStateException
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.time.Instant import java.time.Instant
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
import java.util.* import java.util.Currency
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
import kotlin.test.assertNotEquals import kotlin.test.assertNotEquals
@ -253,7 +277,7 @@ class ObligationTests {
* Test that the issuance builder rejects building into a transaction with existing * Test that the issuance builder rejects building into a transaction with existing
* cash inputs. * cash inputs.
*/ */
@Test(expected = IllegalStateException::class, timeout=300_000) @Test(timeout=300_000)
fun `reject issuance with inputs`() { fun `reject issuance with inputs`() {
// Issue some obligation // Issue some obligation
val tx = TransactionBuilder(DUMMY_NOTARY).apply { val tx = TransactionBuilder(DUMMY_NOTARY).apply {
@ -265,9 +289,11 @@ class ObligationTests {
// Include the previously issued obligation in a new issuance command // Include the previously issued obligation in a new issuance command
val ptx = TransactionBuilder(DUMMY_NOTARY) val ptx = TransactionBuilder(DUMMY_NOTARY)
ptx.addInputState(tx.outRef<Obligation.State<Currency>>(0)) ptx.addInputState(tx.outRef<Obligation.State<Currency>>(0))
assertThatIllegalStateException().isThrownBy {
ObligationUtils.generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, ObligationUtils.generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity,
beneficiary = MINI_CORP, notary = DUMMY_NOTARY) beneficiary = MINI_CORP, notary = DUMMY_NOTARY)
} }
}
/** Test generating a transaction to net two obligations of the same size, and therefore there are no outputs. */ /** Test generating a transaction to net two obligations of the same size, and therefore there are no outputs. */
@Test(timeout=300_000) @Test(timeout=300_000)
@ -576,7 +602,7 @@ class ObligationTests {
val defaultFcoj = Issued(defaultIssuer, Commodity.getInstance("FCOJ")!!) val defaultFcoj = Issued(defaultIssuer, Commodity.getInstance("FCOJ")!!)
val oneUnitFcoj = Amount(1, defaultFcoj) val oneUnitFcoj = Amount(1, defaultFcoj)
val obligationDef = Obligation.Terms(NonEmptySet.of(commodityContractBytes.sha256() as SecureHash), NonEmptySet.of(defaultFcoj), TEST_TX_TIME) val obligationDef = Obligation.Terms(NonEmptySet.of(commodityContractBytes.sha256() as SecureHash), NonEmptySet.of(defaultFcoj), TEST_TX_TIME)
val oneUnitFcojObligation = Obligation.State(Obligation.Lifecycle.NORMAL, ALICE, val oneUnitFcojObligation = Obligation.State(Lifecycle.NORMAL, ALICE,
obligationDef, oneUnitFcoj.quantity, NULL_PARTY) obligationDef, oneUnitFcoj.quantity, NULL_PARTY)
// Try settling a simple commodity obligation // Try settling a simple commodity obligation
ledgerServices.ledger(DUMMY_NOTARY) { ledgerServices.ledger(DUMMY_NOTARY) {
@ -853,10 +879,12 @@ class ObligationTests {
fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableIssuedProducts = miniCorpIssuer)).bilateralNetState) fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableIssuedProducts = miniCorpIssuer)).bilateralNetState)
} }
@Test(expected = IllegalStateException::class, timeout=300_000) @Test(timeout=300_000)
fun `states cannot be netted if not in the normal state`() { fun `states cannot be netted if not in the normal state`() {
assertThatIllegalStateException().isThrownBy {
inState.copy(lifecycle = Lifecycle.DEFAULTED).bilateralNetState inState.copy(lifecycle = Lifecycle.DEFAULTED).bilateralNetState
} }
}
/** /**
* Confirm that extraction of issuance definition works correctly. * Confirm that extraction of issuance definition works correctly.
@ -968,5 +996,5 @@ class ObligationTests {
private val Issued<Currency>.OBLIGATION_DEF: Obligation.Terms<Currency> private val Issued<Currency>.OBLIGATION_DEF: Obligation.Terms<Currency>
get() = Obligation.Terms(NonEmptySet.of(cashContractBytes.sha256() as SecureHash), NonEmptySet.of(this), TEST_TX_TIME) get() = Obligation.Terms(NonEmptySet.of(cashContractBytes.sha256() as SecureHash), NonEmptySet.of(this), TEST_TX_TIME)
private val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency> private val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency>
get() = Obligation.State(Obligation.Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER, token.OBLIGATION_DEF, quantity, NULL_PARTY) get() = Obligation.State(Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER, token.OBLIGATION_DEF, quantity, NULL_PARTY)
} }

View File

@ -1,16 +1,24 @@
package net.corda.nodeapi.internal.persistence package net.corda.nodeapi.internal.persistence
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import net.corda.core.cordapp.Cordapp import net.corda.core.cordapp.Cordapp
import net.corda.core.cordapp.CordappContext import net.corda.core.cordapp.CordappContext
import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runners.model.Statement
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.sql.Connection import java.sql.Connection
import java.sql.Savepoint import java.sql.Savepoint
class RestrictedConnectionTest { class RestrictedConnectionTest {
companion object {
private const val TEST_STRING: String = "test"
private const val TEST_INT: Int = 1
}
private val connection: Connection = mock() private val connection: Connection = mock()
private val savePoint: Savepoint = mock() private val savePoint: Savepoint = mock()
@ -21,212 +29,227 @@ class RestrictedConnectionTest {
} }
private val restrictedConnection: RestrictedConnection = RestrictedConnection(connection, serviceHub) private val restrictedConnection: RestrictedConnection = RestrictedConnection(connection, serviceHub)
companion object { @Rule
private const val TEST_STRING: String = "test" @JvmField
private const val TEST_INT: Int = 1 val assertUnsupportedExceptionBasedOnTestName = TestRule { base, description ->
object : Statement() {
override fun evaluate() {
val exception = try {
base.evaluate()
null
} catch (e: UnsupportedOperationException) {
e
}
if (description.methodName.endsWith(" throws unsupported exception")) {
assertThat(exception).isNotNull()
} else {
assertThat(exception).isNull()
}
}
}
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `abort with target platform version of current corda version throws unsupported exception`() { fun `abort with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.abort { println("I'm just an executor for this test...") } restrictedConnection.abort { println("I'm just an executor for this test...") }
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `clearWarnings with target platform version of current corda version throws unsupported exception`() { fun `clearWarnings with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.clearWarnings() restrictedConnection.clearWarnings()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `close with target platform version of current corda version throws unsupported exception`() { fun `close with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.close() restrictedConnection.close()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `commit with target platform version of current corda version throws unsupported exception`() { fun `commit with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.commit() restrictedConnection.commit()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSavepoint with target platform version of current corda version throws unsupported exception`() { fun `setSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setSavepoint() restrictedConnection.setSavepoint()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSavepoint with name with target platform version of current corda version throws unsupported exception`() { fun `setSavepoint with name with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setSavepoint(TEST_STRING) restrictedConnection.setSavepoint(TEST_STRING)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `releaseSavepoint with target platform version of current corda version throws unsupported exception`() { fun `releaseSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.releaseSavepoint(savePoint) restrictedConnection.releaseSavepoint(savePoint)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `rollback with target platform version of current corda version throws unsupported exception`() { fun `rollback with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.rollback() restrictedConnection.rollback()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `rollbackWithSavepoint with target platform version of current corda version throws unsupported exception`() { fun `rollbackWithSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.rollback(savePoint) restrictedConnection.rollback(savePoint)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setCatalog with target platform version of current corda version throws unsupported exception`() { fun `setCatalog with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.catalog = TEST_STRING restrictedConnection.catalog = TEST_STRING
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setTransactionIsolation with target platform version of current corda version throws unsupported exception`() { fun `setTransactionIsolation with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.transactionIsolation = TEST_INT restrictedConnection.transactionIsolation = TEST_INT
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setTypeMap with target platform version of current corda version throws unsupported exception`() { fun `setTypeMap with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
val map: MutableMap<String, Class<*>> = mutableMapOf() val map: MutableMap<String, Class<*>> = mutableMapOf()
restrictedConnection.typeMap = map restrictedConnection.typeMap = map
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setHoldability with target platform version of current corda version throws unsupported exception`() { fun `setHoldability with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.holdability = TEST_INT restrictedConnection.holdability = TEST_INT
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSchema with target platform version of current corda version throws unsupported exception`() { fun `setSchema with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.schema = TEST_STRING restrictedConnection.schema = TEST_STRING
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setNetworkTimeout with target platform version of current corda version throws unsupported exception`() { fun `setNetworkTimeout with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT) restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setAutoCommit with target platform version of current corda version throws unsupported exception`() { fun `setAutoCommit with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.autoCommit = true restrictedConnection.autoCommit = true
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setReadOnly with target platform version of current corda version throws unsupported exception`() { fun `setReadOnly with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.isReadOnly = true restrictedConnection.isReadOnly = true
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `abort with target platform version of 7 throws unsupported exception`() { fun `abort with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.abort { println("I'm just an executor for this test...") } restrictedConnection.abort { println("I'm just an executor for this test...") }
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `clearWarnings with target platform version of 7 throws unsupported exception`() { fun `clearWarnings with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.clearWarnings() restrictedConnection.clearWarnings()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `close with target platform version of 7 throws unsupported exception`() { fun `close with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.close() restrictedConnection.close()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `commit with target platform version of 7 throws unsupported exception`() { fun `commit with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.commit() restrictedConnection.commit()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSavepoint with target platform version of 7 throws unsupported exception`() { fun `setSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setSavepoint() restrictedConnection.setSavepoint()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSavepoint with name with target platform version of 7 throws unsupported exception`() { fun `setSavepoint with name with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setSavepoint(TEST_STRING) restrictedConnection.setSavepoint(TEST_STRING)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `releaseSavepoint with target platform version of 7 throws unsupported exception`() { fun `releaseSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.releaseSavepoint(savePoint) restrictedConnection.releaseSavepoint(savePoint)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `rollback with target platform version of 7 throws unsupported exception`() { fun `rollback with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.rollback() restrictedConnection.rollback()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `rollbackWithSavepoint with target platform version of 7 throws unsupported exception`() { fun `rollbackWithSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.rollback(savePoint) restrictedConnection.rollback(savePoint)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setCatalog with target platform version of 7 throws unsupported exception`() { fun `setCatalog with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.catalog = TEST_STRING restrictedConnection.catalog = TEST_STRING
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setTransactionIsolation with target platform version of 7 throws unsupported exception`() { fun `setTransactionIsolation with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.transactionIsolation = TEST_INT restrictedConnection.transactionIsolation = TEST_INT
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setTypeMap with target platform version of 7 throws unsupported exception`() { fun `setTypeMap with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
val map: MutableMap<String, Class<*>> = mutableMapOf() val map: MutableMap<String, Class<*>> = mutableMapOf()
restrictedConnection.typeMap = map restrictedConnection.typeMap = map
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setHoldability with target platform version of 7 throws unsupported exception`() { fun `setHoldability with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.holdability = TEST_INT restrictedConnection.holdability = TEST_INT
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setSchema with target platform version of current 7 unsupported exception`() { fun `setSchema with target platform version of current 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.schema = TEST_STRING restrictedConnection.schema = TEST_STRING
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setNetworkTimeout with target platform version of 7 throws unsupported exception`() { fun `setNetworkTimeout with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT) restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setAutoCommit with target platform version of 7 throws unsupported exception`() { fun `setAutoCommit with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.autoCommit = true restrictedConnection.autoCommit = true
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setReadOnly with target platform version of 7 throws unsupported exception`() { fun `setReadOnly with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.isReadOnly = true restrictedConnection.isReadOnly = true

View File

@ -1,13 +1,17 @@
package net.corda.nodeapi.internal.persistence package net.corda.nodeapi.internal.persistence
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import net.corda.core.cordapp.Cordapp import net.corda.core.cordapp.Cordapp
import net.corda.core.cordapp.CordappContext import net.corda.core.cordapp.CordappContext
import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runners.model.Statement
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import javax.persistence.EntityManager import javax.persistence.EntityManager
import javax.persistence.EntityTransaction import javax.persistence.EntityTransaction
import javax.persistence.LockModeType import javax.persistence.LockModeType
@ -23,19 +27,39 @@ class RestrictedEntityManagerTest {
} }
private val restrictedEntityManager = RestrictedEntityManager(entitymanager, serviceHub) private val restrictedEntityManager = RestrictedEntityManager(entitymanager, serviceHub)
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Rule
@JvmField
val assertUnsupportedExceptionBasedOnTestName = TestRule { base, description ->
object : Statement() {
override fun evaluate() {
val exception = try {
base.evaluate()
null
} catch (e: UnsupportedOperationException) {
e
}
if (description.methodName.endsWith(" throws unsupported exception")) {
assertThat(exception).isNotNull()
} else {
assertThat(exception).isNull()
}
}
}
}
@Test(timeout = 300_000)
fun `close with target platform version of current corda version throws unsupported exception`() { fun `close with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.close() restrictedEntityManager.close()
} }
@Test(timeout = 300_000) @Test(timeout = 300_000)
fun `clear with target platform version of current corda version throws unsupported exception`() { fun `clear with target platform version of current corda version`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.clear() restrictedEntityManager.clear()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `getMetaModel with target platform version of current corda version throws unsupported exception`() { fun `getMetaModel with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.metamodel restrictedEntityManager.metamodel
@ -48,32 +72,32 @@ class RestrictedEntityManagerTest {
assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction) assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `joinTransaction with target platform version of current corda version throws unsupported exception`() { fun `joinTransaction with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.joinTransaction() restrictedEntityManager.joinTransaction()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `lock with two parameters with target platform version of current corda version throws unsupported exception`() { fun `lock with two parameters with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC) restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `lock with three parameters with target platform version of current corda version throws unsupported exception`() { fun `lock with three parameters with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
val map: MutableMap<String, Any> = mutableMapOf() val map: MutableMap<String, Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map) restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setProperty with target platform version of current corda version throws unsupported exception`() { fun `setProperty with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.setProperty("number", 12) restrictedEntityManager.setProperty("number", 12)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `close with target platform version of 7 throws unsupported exception`() { fun `close with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.close() restrictedEntityManager.close()
@ -85,39 +109,39 @@ class RestrictedEntityManagerTest {
restrictedEntityManager.clear() restrictedEntityManager.clear()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `getMetaModel with target platform version of 7 throws unsupported exception`() { fun `getMetaModel with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.metamodel restrictedEntityManager.metamodel
} }
@Test(timeout = 300_000) @Test(timeout = 300_000)
fun `getTransaction with target platform version of 7 throws unsupported exception`() { fun `getTransaction with target platform version of 7`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
whenever(entitymanager.transaction).doReturn(transaction) whenever(entitymanager.transaction).doReturn(transaction)
assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction) assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `joinTransaction with target platform version of 7 throws unsupported exception`() { fun `joinTransaction with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.joinTransaction() restrictedEntityManager.joinTransaction()
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `lock with two parameters with target platform version of 7 throws unsupported exception`() { fun `lock with two parameters with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC) restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `lock with three parameters with target platform version of 7 throws unsupported exception`() { fun `lock with three parameters with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
val map: MutableMap<String, Any> = mutableMapOf() val map: MutableMap<String, Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map) restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map)
} }
@Test(expected = UnsupportedOperationException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `setProperty with target platform version of 7 throws unsupported exception`() { fun `setProperty with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7) whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.setProperty("number", 12) restrictedEntityManager.setProperty("number", 12)

View File

@ -6,14 +6,10 @@ import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.InitiatingFlow
import net.corda.node.services.config.FlowOverride import net.corda.node.services.config.FlowOverride
import net.corda.node.services.config.FlowOverrideConfig import net.corda.node.services.config.FlowOverrideConfig
import org.hamcrest.CoreMatchers.`is` import org.assertj.core.api.Assertions.assertThat
import org.hamcrest.CoreMatchers.instanceOf import org.assertj.core.api.Assertions.assertThatIllegalStateException
import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.mockito.Mockito import org.mockito.Mockito
import java.lang.IllegalStateException
private val marker = "This is a special marker"
class NodeFlowManagerTest { class NodeFlowManagerTest {
@ -57,13 +53,15 @@ class NodeFlowManagerTest {
} }
@Test(expected = IllegalStateException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `should fail to validate if more than one registration with equal weight`() { fun `should fail to validate if more than one registration with equal weight`() {
val nodeFlowManager = NodeFlowManager() val nodeFlowManager = NodeFlowManager()
nodeFlowManager.registerInitiatedFlow(Init::class.java, Resp::class.java) nodeFlowManager.registerInitiatedFlow(Init::class.java, Resp::class.java)
nodeFlowManager.registerInitiatedFlow(Init::class.java, Resp2::class.java) nodeFlowManager.registerInitiatedFlow(Init::class.java, Resp2::class.java)
assertThatIllegalStateException().isThrownBy {
nodeFlowManager.validateRegistrations() nodeFlowManager.validateRegistrations()
} }
}
@Test(timeout = 300_000) @Test(timeout = 300_000)
fun `should allow registration of flows with different weights`() { fun `should allow registration of flows with different weights`() {
@ -73,7 +71,7 @@ class NodeFlowManagerTest {
nodeFlowManager.validateRegistrations() nodeFlowManager.validateRegistrations()
val factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!! val factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!!
val flow = factory.createFlow(Mockito.mock(FlowSession::class.java)) val flow = factory.createFlow(Mockito.mock(FlowSession::class.java))
Assert.assertThat(flow, `is`(instanceOf(RespSub::class.java))) assertThat(flow).isInstanceOf(RespSub::class.java)
} }
@Test(timeout = 300_000) @Test(timeout = 300_000)
@ -84,14 +82,14 @@ class NodeFlowManagerTest {
nodeFlowManager.validateRegistrations() nodeFlowManager.validateRegistrations()
var factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!! var factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!!
var flow = factory.createFlow(Mockito.mock(FlowSession::class.java)) var flow = factory.createFlow(Mockito.mock(FlowSession::class.java))
Assert.assertThat(flow, `is`(instanceOf(RespSub::class.java))) assertThat(flow).isInstanceOf(RespSub::class.java)
// update // update
nodeFlowManager.registerInitiatedFlow(Init::class.java, RespSubSub::class.java) nodeFlowManager.registerInitiatedFlow(Init::class.java, RespSubSub::class.java)
nodeFlowManager.validateRegistrations() nodeFlowManager.validateRegistrations()
factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!! factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!!
flow = factory.createFlow(Mockito.mock(FlowSession::class.java)) flow = factory.createFlow(Mockito.mock(FlowSession::class.java))
Assert.assertThat(flow, `is`(instanceOf(RespSubSub::class.java))) assertThat(flow).isInstanceOf(RespSubSub::class.java)
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -105,6 +103,6 @@ class NodeFlowManagerTest {
val factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!! val factory = nodeFlowManager.getFlowFactoryForInitiatingFlow(Init::class.java)!!
val flow = factory.createFlow(Mockito.mock(FlowSession::class.java)) val flow = factory.createFlow(Mockito.mock(FlowSession::class.java))
Assert.assertThat(flow, `is`(instanceOf(Resp::class.java))) assertThat(flow).isInstanceOf(Resp::class.java)
} }
} }

View File

@ -7,6 +7,7 @@ import com.typesafe.config.ConfigRenderOptions
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.writeText import net.corda.core.internal.writeText
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test import org.junit.Test
import java.nio.file.Paths import java.nio.file.Paths
@ -45,11 +46,13 @@ class CordappConfigFileProviderTests {
assertThat(provider.getConfigByName(cordappName)).isEqualTo(alternateValidConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(alternateValidConfig)
} }
@Test(expected = ConfigException.Parse::class, timeout=300_000) @Test(timeout=300_000)
fun `an invalid config throws an exception`() { fun `an invalid config throws an exception`() {
cordappConfFile.writeText(invalidConfig) cordappConfFile.writeText(invalidConfig)
assertThatExceptionOfType(ConfigException::class.java).isThrownBy {
provider.getConfigByName(cordappName) provider.getConfigByName(cordappName)
} }
}
/** /**
* Writes the config to the path provided - will (and must) overwrite any existing config * Writes the config to the path provided - will (and must) overwrite any existing config

View File

@ -1,14 +1,20 @@
package net.corda.node.internal.cordapp package net.corda.node.internal.cordapp
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.flows.* import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.SchedulableFlow
import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.packageName_
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
import net.corda.nodeapi.internal.DEV_PUB_KEY_HASHES import net.corda.nodeapi.internal.DEV_PUB_KEY_HASHES
import net.corda.testing.node.internal.cordappWithPackages import net.corda.testing.node.internal.cordappWithPackages
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test import org.junit.Test
import java.nio.file.Paths import java.nio.file.Paths
import net.corda.core.internal.packageName_
@InitiatingFlow @InitiatingFlow
class DummyFlow : FlowLogic<Unit>() { class DummyFlow : FlowLogic<Unit>() {
@ -49,7 +55,7 @@ class JarScanningCordappLoaderTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `isolated JAR contains a CorDapp with a contract and plugin`() { fun `isolated JAR contains a CorDapp with a contract and plugin`() {
val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar") val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar")!!
val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR)) val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR))
assertThat(loader.cordapps).hasSize(1) assertThat(loader.cordapps).hasSize(1)
@ -67,7 +73,7 @@ class JarScanningCordappLoaderTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `constructed CordappImpl contains the right cordapp classes`() { fun `constructed CordappImpl contains the right cordapp classes`() {
val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar") val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar")!!
val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR)) val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR))
val actualCordapp = loader.cordapps.single() val actualCordapp = loader.cordapps.single()
@ -85,7 +91,7 @@ class JarScanningCordappLoaderTest {
// One cordapp from this source tree. In gradle it will also pick up the node jar. // One cordapp from this source tree. In gradle it will also pick up the node jar.
assertThat(loader.cordapps).isNotEmpty assertThat(loader.cordapps).isNotEmpty
val actualCordapp = loader.cordapps.single { !it.initiatedFlows.isEmpty() } val actualCordapp = loader.cordapps.single { it.initiatedFlows.isNotEmpty() }
assertThat(actualCordapp.initiatedFlows.first()).hasSameClassAs(DummyFlow::class.java) assertThat(actualCordapp.initiatedFlows.first()).hasSameClassAs(DummyFlow::class.java)
assertThat(actualCordapp.rpcFlows).first().hasSameClassAs(DummyRPCFlow::class.java) assertThat(actualCordapp.rpcFlows).first().hasSameClassAs(DummyRPCFlow::class.java)
assertThat(actualCordapp.schedulableFlows).first().hasSameClassAs(DummySchedulableFlow::class.java) assertThat(actualCordapp.schedulableFlows).first().hasSameClassAs(DummySchedulableFlow::class.java)
@ -95,7 +101,7 @@ class JarScanningCordappLoaderTest {
// being used internally. Later iterations will use a classloader per cordapp and this test can be retired. // being used internally. Later iterations will use a classloader per cordapp and this test can be retired.
@Test(timeout=300_000) @Test(timeout=300_000)
fun `cordapp classloader can load cordapp classes`() { fun `cordapp classloader can load cordapp classes`() {
val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar") val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("/isolated.jar")!!
val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR), VersionInfo.UNKNOWN) val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR), VersionInfo.UNKNOWN)
loader.appClassLoader.loadClass(isolatedContractId) loader.appClassLoader.loadClass(isolatedContractId)
@ -134,10 +140,13 @@ class JarScanningCordappLoaderTest {
assertThat(cordapp.minimumPlatformVersion).isEqualTo(2) assertThat(cordapp.minimumPlatformVersion).isEqualTo(2)
} }
@Test(expected = InvalidCordappException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `cordapp classloader does not load apps when their min platform version is greater than the node platform version`() { fun `cordapp classloader does not load apps when their min platform version is greater than the node platform version`() {
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-no-target.jar")!! val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-no-target.jar")!!
JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN.copy(platformVersion = 1)).cordapps val cordappLoader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN.copy(platformVersion = 1))
assertThatExceptionOfType(InvalidCordappException::class.java).isThrownBy {
cordappLoader.cordapps
}
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -161,10 +170,13 @@ class JarScanningCordappLoaderTest {
assertThat(loader.cordapps).hasSize(1) assertThat(loader.cordapps).hasSize(1)
} }
@Test(expected = InvalidCordappException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `cordapp classloader does not load app signed by blacklisted certificate`() { fun `cordapp classloader does not load app signed by blacklisted certificate`() {
val jar = JarScanningCordappLoaderTest::class.java.getResource("signed/signed-by-dev-key.jar")!! val jar = JarScanningCordappLoaderTest::class.java.getResource("signed/signed-by-dev-key.jar")!!
JarScanningCordappLoader.fromJarUrls(listOf(jar), cordappsSignerKeyFingerprintBlacklist = DEV_PUB_KEY_HASHES).cordapps val cordappLoader = JarScanningCordappLoader.fromJarUrls(listOf(jar), cordappsSignerKeyFingerprintBlacklist = DEV_PUB_KEY_HASHES)
assertThatExceptionOfType(InvalidCordappException::class.java).isThrownBy {
cordappLoader.cordapps
}
} }
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -4,6 +4,7 @@ import com.typesafe.config.ConfigFactory
import net.corda.core.cordapp.CordappConfigException import net.corda.core.cordapp.CordappConfigException
import org.junit.Test import org.junit.Test
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
class TypesafeCordappConfigTests { class TypesafeCordappConfigTests {
@Test(timeout=300_000) @Test(timeout=300_000)
@ -37,11 +38,12 @@ class TypesafeCordappConfigTests {
assertThat(cordappConf.exists("notexists")).isFalse() assertThat(cordappConf.exists("notexists")).isFalse()
} }
@Test(expected = CordappConfigException::class, timeout=300_000) @Test(timeout=300_000)
fun `test that an exception is thrown when trying to access a non-extant field`() { fun `test that an exception is thrown when trying to access a non-extant field`() {
val config = ConfigFactory.empty() val config = ConfigFactory.empty()
val cordappConf = TypesafeCordappConfig(config) val cordappConf = TypesafeCordappConfig(config)
assertThatExceptionOfType(CordappConfigException::class.java).isThrownBy {
cordappConf.get("anything") cordappConf.get("anything")
} }
}
} }

View File

@ -26,6 +26,7 @@ import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.concurrent.flatMap
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
import net.corda.core.internal.rootCause import net.corda.core.internal.rootCause
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
@ -77,6 +78,7 @@ import net.corda.testing.node.internal.TestStartedNode
import net.corda.testing.node.internal.startFlow import net.corda.testing.node.internal.startFlow
import net.corda.testing.node.ledger import net.corda.testing.node.ledger
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@ -84,7 +86,6 @@ import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import rx.Observable import rx.Observable
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.util.ArrayList
import java.util.Collections import java.util.Collections
import java.util.Currency import java.util.Currency
import java.util.Random import java.util.Random
@ -186,7 +187,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
} }
} }
@Test(expected = InsufficientBalanceException::class, timeout=300_000) @Test(timeout=300_000)
fun `trade cash for commercial paper fails using soft locking`() { fun `trade cash for commercial paper fails using soft locking`() {
mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP), threadPerNode = true) mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP), threadPerNode = true)
val notaryNode = mockNet.defaultNotaryNode val notaryNode = mockNet.defaultNotaryNode
@ -226,7 +227,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode, val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
"alice's paper".outputStateAndRef()) "alice's paper".outputStateAndRef())
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow()) assertThatExceptionOfType(InsufficientBalanceException::class.java).isThrownBy {
bobStateMachine.flatMap { it.resultFuture }.getOrThrow()
}
assertThatExceptionOfType(InsufficientBalanceException::class.java).isThrownBy {
aliceResult.getOrThrow()
}
aliceNode.dispose() aliceNode.dispose()
bobNode.dispose() bobNode.dispose()
@ -734,7 +741,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
} }
val eb3Txns = insertFakeTransactions(listOf(bc2), node, identity, notaryNode, *extraSigningNodes) val eb3Txns = insertFakeTransactions(listOf(bc2), node, identity, notaryNode, *extraSigningNodes)
val vault = Vault<ContractState>(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef())) val vault = Vault(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef()))
return Triple(vault, listOf(eb1, bc1, bc2), eb1Txns + eb2Txns + eb3Txns) return Triple(vault, listOf(eb1, bc1, bc2), eb1Txns + eb2Txns + eb3Txns)
} }
@ -747,10 +754,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> { notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) { val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary, output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary,
contractState = CommercialPaper.State(issuer, owner, amount, net.corda.coretesting.internal.TEST_TX_TIME + 7.days)) contractState = CommercialPaper.State(issuer, owner, amount, TEST_TX_TIME + 7.days))
command(issuer.party.owningKey, CommercialPaper.Commands.Issue()) command(issuer.party.owningKey, CommercialPaper.Commands.Issue())
if (!withError) if (!withError)
timeWindow(time = net.corda.coretesting.internal.TEST_TX_TIME) timeWindow(time = TEST_TX_TIME)
if (attachmentID != null) if (attachmentID != null)
attachment(attachmentID) attachment(attachmentID)
if (withError) { if (withError) {
@ -760,7 +767,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
} }
} }
val vault = Vault<ContractState>(listOf("alice's paper".outputStateAndRef())) val vault = Vault(listOf("alice's paper".outputStateAndRef()))
return Pair(vault, listOf(ap)) return Pair(vault, listOf(ap))
} }
@ -786,7 +793,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
} }
} }
val records: MutableList<TxRecord> = Collections.synchronizedList(ArrayList<TxRecord>()) val records: MutableList<TxRecord> = Collections.synchronizedList(ArrayList())
override val updates: Observable<SignedTransaction> override val updates: Observable<SignedTransaction>
get() = delegate.updates get() = delegate.updates

View File

@ -2,8 +2,18 @@ package net.corda.node.migration
import liquibase.database.Database import liquibase.database.Database
import liquibase.database.jvm.JdbcConnection import liquibase.database.jvm.JdbcConnection
import net.corda.core.contracts.* import net.corda.core.contracts.Amount
import net.corda.core.crypto.* import net.corda.core.contracts.ContractState
import net.corda.core.contracts.Issued
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SignableData
import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
@ -36,7 +46,14 @@ import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.contextTransactionOrNull import net.corda.nodeapi.internal.persistence.contextTransactionOrNull
import net.corda.nodeapi.internal.persistence.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.testing.core.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.BOC_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.dummyCommand
import net.corda.testing.internal.configureDatabase import net.corda.testing.internal.configureDatabase
import net.corda.testing.internal.vault.CommodityState import net.corda.testing.internal.vault.CommodityState
import net.corda.testing.internal.vault.DUMMY_LINEAR_CONTRACT_PROGRAM_ID import net.corda.testing.internal.vault.DUMMY_LINEAR_CONTRACT_PROGRAM_ID
@ -46,13 +63,30 @@ 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.TestClock import net.corda.testing.node.TestClock
import net.corda.testing.node.makeTestIdentityService import net.corda.testing.node.makeTestIdentityService
import org.junit.* import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After
import org.junit.Before
import org.junit.ClassRule
import org.junit.Ignore
import org.junit.Test
import org.mockito.Mockito import org.mockito.Mockito
import java.security.KeyPair import java.security.KeyPair
import java.time.Clock import java.time.Clock
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
import java.util.* import java.util.Currency
import java.util.Properties
import kotlin.collections.List
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.first
import kotlin.collections.forEach
import kotlin.collections.forEachIndexed
import kotlin.collections.groupBy
import kotlin.collections.listOf
import kotlin.collections.map
import kotlin.collections.mapOf
import kotlin.collections.plus
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
import kotlin.test.assertFalse import kotlin.test.assertFalse
@ -464,12 +498,14 @@ class VaultStateMigrationTest {
assertEquals(10, getVaultStateCount(Vault.RelevancyStatus.RELEVANT)) assertEquals(10, getVaultStateCount(Vault.RelevancyStatus.RELEVANT))
} }
@Test(expected = VaultStateMigrationException::class) @Test(timeout = 300_000)
fun `Null database causes migration to fail`() { fun `Null database causes migration to fail`() {
val migration = VaultStateMigration() val migration = VaultStateMigration()
// Just check this does not throw an exception // Just check this does not throw an exception
assertThatExceptionOfType(VaultStateMigrationException::class.java).isThrownBy {
migration.execute(null) migration.execute(null)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `State with non-owning key for our name marked as relevant`() { fun `State with non-owning key for our name marked as relevant`() {

View File

@ -1,18 +1,19 @@
package net.corda.node.services.config package net.corda.node.services.config
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import com.typesafe.config.Config import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import net.corda.core.internal.delete import net.corda.core.internal.delete
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.node.internal.Node import net.corda.node.internal.Node
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After import org.junit.After
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentMatchers.contains import org.mockito.ArgumentMatchers.contains
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.slf4j.Logger import org.slf4j.Logger
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
@ -60,12 +61,14 @@ class ConfigHelperTests {
Assert.assertEquals(sshPort, config?.getLong("sshd.port")) Assert.assertEquals(sshPort, config?.getLong("sshd.port"))
} }
@Test(timeout = 300_000, expected = ShadowingException::class) @Test(timeout = 300_000)
fun `shadowing is forbidden`() { fun `shadowing is forbidden`() {
val sshPort: Long = 12000 val sshPort: Long = 12000
assertThatExceptionOfType(ShadowingException::class.java).isThrownBy {
loadConfig("CORDA_sshd_port" to sshPort.toString(), loadConfig("CORDA_sshd_port" to sshPort.toString(),
"corda.sshd.port" to sshPort.toString()) "corda.sshd.port" to sshPort.toString())
} }
}
@Test(timeout = 300_000) @Test(timeout = 300_000)
@Ignore("TODO JDK17: Modifiers no longer supported") @Ignore("TODO JDK17: Modifiers no longer supported")

View File

@ -3,6 +3,7 @@ package net.corda.node.services.statemachine
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.IllegalFlowLogicException import net.corda.core.flows.IllegalFlowLogicException
import net.corda.core.flows.SchedulableFlow import net.corda.core.flows.SchedulableFlow
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test import org.junit.Test
import java.time.Duration import java.time.Duration
import kotlin.reflect.jvm.jvmName import kotlin.reflect.jvm.jvmName
@ -77,8 +78,10 @@ class FlowLogicRefFactoryImplTest {
flowLogicRefFactory.createKotlin(KotlinFlowLogic::class.java, args) flowLogicRefFactory.createKotlin(KotlinFlowLogic::class.java, args)
} }
@Test(expected = IllegalFlowLogicException::class, timeout=300_000) @Test(timeout=300_000)
fun `create for non-schedulable flow logic`() { fun `create for non-schedulable flow logic`() {
assertThatExceptionOfType(IllegalFlowLogicException::class.java).isThrownBy {
flowLogicRefFactory.create(NonSchedulableFlow::class.jvmName) flowLogicRefFactory.create(NonSchedulableFlow::class.jvmName)
} }
}
} }

View File

@ -1,35 +1,40 @@
package net.corda.serialization.internal package net.corda.serialization.internal
import com.esotericsoftware.kryo.* import com.esotericsoftware.kryo.DefaultSerializer
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.KryoSerializable
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.util.DefaultClassResolver import com.esotericsoftware.kryo.util.DefaultClassResolver
import com.esotericsoftware.kryo.util.MapReferenceResolver import com.esotericsoftware.kryo.util.MapReferenceResolver
import org.mockito.kotlin.any import net.corda.core.contracts.TransactionVerificationException.UntrustedAttachmentsException
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import net.corda.core.contracts.TransactionVerificationException
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
import net.corda.core.node.services.AttachmentStorage import net.corda.core.node.services.AttachmentStorage
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.internal.AttachmentsClassLoader import net.corda.core.serialization.internal.AttachmentsClassLoader
import net.corda.core.serialization.internal.CheckpointSerializationContext import net.corda.core.serialization.internal.CheckpointSerializationContext
import net.corda.coretesting.internal.rigorousMock
import net.corda.node.services.attachments.NodeAttachmentTrustCalculator
import net.corda.nodeapi.internal.serialization.kryo.CordaClassResolver import net.corda.nodeapi.internal.serialization.kryo.CordaClassResolver
import net.corda.nodeapi.internal.serialization.kryo.CordaKryo import net.corda.nodeapi.internal.serialization.kryo.CordaKryo
import net.corda.node.services.attachments.NodeAttachmentTrustCalculator
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.internal.TestingNamedCacheFactory import net.corda.testing.internal.TestingNamedCacheFactory
import net.corda.coretesting.internal.rigorousMock
import net.corda.testing.internal.services.InternalMockAttachmentStorage import net.corda.testing.internal.services.InternalMockAttachmentStorage
import net.corda.testing.services.MockAttachmentStorage import net.corda.testing.services.MockAttachmentStorage
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.ExpectedException import org.junit.rules.ExpectedException
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import java.net.URL import java.net.URL
import java.sql.Connection import java.sql.Connection
import java.util.* import java.util.Collections
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
import kotlin.test.assertNull import kotlin.test.assertNull
@ -114,7 +119,7 @@ class CordaClassResolverTests {
val emptyListClass = listOf<Any>().javaClass val emptyListClass = listOf<Any>().javaClass
val emptySetClass = setOf<Any>().javaClass val emptySetClass = setOf<Any>().javaClass
val emptyMapClass = mapOf<Any, Any>().javaClass val emptyMapClass = mapOf<Any, Any>().javaClass
val ISOLATED_CONTRACTS_JAR_PATH: URL = CordaClassResolverTests::class.java.getResource("/isolated.jar") val ISOLATED_CONTRACTS_JAR_PATH: URL = CordaClassResolverTests::class.java.getResource("/isolated.jar")!!
} }
private val emptyWhitelistContext: CheckpointSerializationContext = CheckpointSerializationContextImpl(this.javaClass.classLoader, EmptyWhitelist, emptyMap(), true, null) private val emptyWhitelistContext: CheckpointSerializationContext = CheckpointSerializationContextImpl(this.javaClass.classLoader, EmptyWhitelist, emptyMap(), true, null)
@ -125,20 +130,24 @@ class CordaClassResolverTests {
CordaClassResolver(emptyWhitelistContext).getRegistration(Foo.Bar::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(Foo.Bar::class.java)
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Unannotated specialised enum does not work`() { fun `Unannotated specialised enum does not work`() {
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(BadFood.Mud::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(BadFood.Mud::class.java)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `Annotation on simple enum works`() { fun `Annotation on simple enum works`() {
CordaClassResolver(emptyWhitelistContext).getRegistration(Simple.Easy::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(Simple.Easy::class.java)
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Unannotated simple enum does not work`() { fun `Unannotated simple enum does not work`() {
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(BadSimple.Nasty::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(BadSimple.Nasty::class.java)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `Annotation on array element works`() { fun `Annotation on array element works`() {
@ -146,11 +155,13 @@ class CordaClassResolverTests {
CordaClassResolver(emptyWhitelistContext).getRegistration(values.javaClass) CordaClassResolver(emptyWhitelistContext).getRegistration(values.javaClass)
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Unannotated array elements do not work`() { fun `Unannotated array elements do not work`() {
val values = arrayOf(NotSerializable()) val values = arrayOf(NotSerializable())
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(values.javaClass) CordaClassResolver(emptyWhitelistContext).getRegistration(values.javaClass)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `Annotation not needed on abstract class`() { fun `Annotation not needed on abstract class`() {
@ -168,16 +179,20 @@ class CordaClassResolverTests {
kryo.register(NotSerializable::class.java) kryo.register(NotSerializable::class.java)
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Calling register method on unmodified Kryo does consult the whitelist`() { fun `Calling register method on unmodified Kryo does consult the whitelist`() {
val kryo = Kryo(CordaClassResolver(emptyWhitelistContext), MapReferenceResolver()) val kryo = Kryo(CordaClassResolver(emptyWhitelistContext), MapReferenceResolver())
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
kryo.register(NotSerializable::class.java) kryo.register(NotSerializable::class.java)
} }
}
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Annotation is needed without whitelisting`() { fun `Annotation is needed without whitelisting`() {
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(NotSerializable::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(NotSerializable::class.java)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `Annotation is not needed with whitelisting`() { fun `Annotation is not needed with whitelisting`() {
@ -195,36 +210,47 @@ class CordaClassResolverTests {
CordaClassResolver(emptyWhitelistContext).getRegistration(Integer.TYPE) CordaClassResolver(emptyWhitelistContext).getRegistration(Integer.TYPE)
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Annotation does not work for custom serializable`() { fun `Annotation does not work for custom serializable`() {
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(CustomSerializable::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(CustomSerializable::class.java)
} }
}
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Annotation does not work in conjunction with Kryo annotation`() { fun `Annotation does not work in conjunction with Kryo annotation`() {
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(DefaultSerializable::class.java) CordaClassResolver(emptyWhitelistContext).getRegistration(DefaultSerializable::class.java)
} }
}
private fun importJar(storage: AttachmentStorage, uploader: String = DEPLOYED_CORDAPP_UPLOADER) = ISOLATED_CONTRACTS_JAR_PATH.openStream().use { storage.importAttachment(it, uploader, "") } private fun importJar(storage: AttachmentStorage, uploader: String = DEPLOYED_CORDAPP_UPLOADER) = ISOLATED_CONTRACTS_JAR_PATH.openStream().use { storage.importAttachment(it, uploader, "") }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `Annotation does not work in conjunction with AttachmentClassLoader annotation`() { fun `Annotation does not work in conjunction with AttachmentClassLoader annotation`() {
val storage = InternalMockAttachmentStorage(MockAttachmentStorage()) val storage = InternalMockAttachmentStorage(MockAttachmentStorage())
val attachmentTrustCalculator = NodeAttachmentTrustCalculator(storage, TestingNamedCacheFactory()) val attachmentTrustCalculator = NodeAttachmentTrustCalculator(storage, TestingNamedCacheFactory())
val attachmentHash = importJar(storage) val attachmentHash = importJar(storage)
val classLoader = AttachmentsClassLoader(arrayOf(attachmentHash).map { storage.openAttachment(it)!! }, testNetworkParameters(), SecureHash.zeroHash, { attachmentTrustCalculator.calculate(it) }) val classLoader = AttachmentsClassLoader(arrayOf(attachmentHash).map { storage.openAttachment(it)!! }, testNetworkParameters(), SecureHash.zeroHash, { attachmentTrustCalculator.calculate(it) })
val attachedClass = Class.forName("net.corda.isolated.contracts.AnotherDummyContract", true, classLoader) val attachedClass = Class.forName("net.corda.isolated.contracts.AnotherDummyContract", true, classLoader)
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
CordaClassResolver(emptyWhitelistContext).getRegistration(attachedClass) CordaClassResolver(emptyWhitelistContext).getRegistration(attachedClass)
} }
}
@Test(expected = TransactionVerificationException.UntrustedAttachmentsException::class, timeout=300_000) @Test(timeout=300_000)
fun `Attempt to load contract attachment with untrusted uploader should fail with UntrustedAttachmentsException`() { fun `Attempt to load contract attachment with untrusted uploader should fail with UntrustedAttachmentsException`() {
val storage = InternalMockAttachmentStorage(MockAttachmentStorage()) val storage = InternalMockAttachmentStorage(MockAttachmentStorage())
val attachmentTrustCalculator = NodeAttachmentTrustCalculator(storage, TestingNamedCacheFactory()) val attachmentTrustCalculator = NodeAttachmentTrustCalculator(storage, TestingNamedCacheFactory())
val attachmentHash = importJar(storage, "some_uploader") val attachmentHash = importJar(storage, "some_uploader")
val classLoader = AttachmentsClassLoader(arrayOf(attachmentHash).map { storage.openAttachment(it)!! }, testNetworkParameters(), SecureHash.zeroHash, { attachmentTrustCalculator.calculate(it) }) assertThatExceptionOfType(UntrustedAttachmentsException::class.java).isThrownBy {
val attachedClass = Class.forName("net.corda.isolated.contracts.AnotherDummyContract", true, classLoader) AttachmentsClassLoader(
CordaClassResolver(emptyWhitelistContext).getRegistration(attachedClass) arrayOf(attachmentHash).map { storage.openAttachment(it)!! },
testNetworkParameters(),
SecureHash.zeroHash,
{ attachmentTrustCalculator.calculate(it) }
)
}
} }
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -3,18 +3,24 @@ package net.corda.serialization.internal
import com.esotericsoftware.kryo.Kryo import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.io.Output import com.esotericsoftware.kryo.io.Output
import net.corda.core.serialization.* import net.corda.core.serialization.SerializationToken
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SerializeAsTokenContext
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.SingletonSerializationToken
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.internal.CheckpointSerializationContext import net.corda.core.serialization.internal.CheckpointSerializationContext
import net.corda.core.serialization.internal.checkpointDeserialize import net.corda.core.serialization.internal.checkpointDeserialize
import net.corda.core.serialization.internal.checkpointSerialize import net.corda.core.serialization.internal.checkpointSerialize
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.coretesting.internal.rigorousMock
import net.corda.nodeapi.internal.serialization.kryo.CordaClassResolver import net.corda.nodeapi.internal.serialization.kryo.CordaClassResolver
import net.corda.nodeapi.internal.serialization.kryo.CordaKryo import net.corda.nodeapi.internal.serialization.kryo.CordaKryo
import net.corda.nodeapi.internal.serialization.kryo.DefaultKryoCustomizer import net.corda.nodeapi.internal.serialization.kryo.DefaultKryoCustomizer
import net.corda.nodeapi.internal.serialization.kryo.kryoMagic import net.corda.nodeapi.internal.serialization.kryo.kryoMagic
import net.corda.coretesting.internal.rigorousMock
import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -70,30 +76,35 @@ class SerializationTokenTest {
assertThat(tokenizableAfter).isSameAs(tokenizableBefore) assertThat(tokenizableAfter).isSameAs(tokenizableBefore)
} }
@Test(expected = UnsupportedOperationException::class, timeout=300_000) @Test(timeout=300_000)
fun `new token encountered after context init`() { fun `new token encountered after context init`() {
val tokenizableBefore = UnitSerializeAsToken() val tokenizableBefore = UnitSerializeAsToken()
val context = serializeAsTokenContext(emptyList<Any>()) val context = serializeAsTokenContext(emptyList<Any>())
val testContext = this.context.withTokenContext(context) val testContext = this.context.withTokenContext(context)
assertThatExceptionOfType(UnsupportedOperationException::class.java).isThrownBy {
tokenizableBefore.checkpointSerialize(testContext) tokenizableBefore.checkpointSerialize(testContext)
} }
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000) @Test(timeout=300_000)
fun `deserialize unregistered token`() { fun `deserialize unregistered token`() {
val tokenizableBefore = UnitSerializeAsToken() val tokenizableBefore = UnitSerializeAsToken()
val context = serializeAsTokenContext(emptyList<Any>()) val context = serializeAsTokenContext(emptyList<Any>())
val testContext = this.context.withTokenContext(context) val testContext = this.context.withTokenContext(context)
val serializedBytes = tokenizableBefore.toToken(serializeAsTokenContext(emptyList<Any>())).checkpointSerialize(testContext) assertThatExceptionOfType(UnsupportedOperationException::class.java).isThrownBy {
serializedBytes.checkpointDeserialize(testContext) tokenizableBefore.toToken(serializeAsTokenContext(emptyList<Any>())).checkpointSerialize(testContext)
}
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `no context set`() { fun `no context set`() {
val tokenizableBefore = UnitSerializeAsToken() val tokenizableBefore = UnitSerializeAsToken()
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
tokenizableBefore.checkpointSerialize(context) tokenizableBefore.checkpointSerialize(context)
} }
}
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `deserialize non-token`() { fun `deserialize non-token`() {
val tokenizableBefore = UnitSerializeAsToken() val tokenizableBefore = UnitSerializeAsToken()
val context = serializeAsTokenContext(tokenizableBefore) val context = serializeAsTokenContext(tokenizableBefore)
@ -108,8 +119,10 @@ class SerializationTokenTest {
kryo.writeObject(it, emptyList<Any>()) kryo.writeObject(it, emptyList<Any>())
} }
val serializedBytes = SerializedBytes<Any>(stream.toByteArray()) val serializedBytes = SerializedBytes<Any>(stream.toByteArray())
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
serializedBytes.checkpointDeserialize(testContext) serializedBytes.checkpointDeserialize(testContext)
} }
}
private class WrongTypeSerializeAsToken : SerializeAsToken { private class WrongTypeSerializeAsToken : SerializeAsToken {
object UnitSerializationToken : SerializationToken { object UnitSerializationToken : SerializationToken {
@ -119,12 +132,14 @@ class SerializationTokenTest {
override fun toToken(context: SerializeAsTokenContext): SerializationToken = UnitSerializationToken override fun toToken(context: SerializeAsTokenContext): SerializationToken = UnitSerializationToken
} }
@Test(expected = KryoException::class, timeout=300_000) @Test(timeout=300_000)
fun `token returns unexpected type`() { fun `token returns unexpected type`() {
val tokenizableBefore = WrongTypeSerializeAsToken() val tokenizableBefore = WrongTypeSerializeAsToken()
val context = serializeAsTokenContext(tokenizableBefore) val context = serializeAsTokenContext(tokenizableBefore)
val testContext = this.context.withTokenContext(context) val testContext = this.context.withTokenContext(context)
val serializedBytes = tokenizableBefore.checkpointSerialize(testContext) val serializedBytes = tokenizableBefore.checkpointSerialize(testContext)
assertThatExceptionOfType(KryoException::class.java).isThrownBy {
serializedBytes.checkpointDeserialize(testContext) serializedBytes.checkpointDeserialize(testContext)
} }
}
} }

View File

@ -2,8 +2,6 @@
package net.corda.serialization.internal.amqp package net.corda.serialization.internal.amqp
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.whenever
import net.corda.client.rpc.RPCException import net.corda.client.rpc.RPCException
import net.corda.core.CordaException import net.corda.core.CordaException
import net.corda.core.CordaRuntimeException import net.corda.core.CordaRuntimeException
@ -56,19 +54,24 @@ import org.apache.qpid.proton.codec.DecoderImpl
import org.apache.qpid.proton.codec.EncoderImpl import org.apache.qpid.proton.codec.EncoderImpl
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.api.Assertions.catchThrowable import org.assertj.core.api.Assertions.catchThrowable
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.cert.X509v2CRLBuilder import org.bouncycastle.cert.X509v2CRLBuilder
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.Assert.* import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertNotSame
import org.junit.Assert.assertSame
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters import org.junit.runners.Parameterized.Parameters
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.whenever
import java.io.IOException import java.io.IOException
import java.io.NotSerializableException import java.io.NotSerializableException
import java.math.BigDecimal import java.math.BigDecimal
@ -89,14 +92,11 @@ import java.time.Year
import java.time.YearMonth import java.time.YearMonth
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
import java.util.ArrayList
import java.util.Arrays
import java.util.BitSet import java.util.BitSet
import java.util.Currency import java.util.Currency
import java.util.Date import java.util.Date
import java.util.EnumMap import java.util.EnumMap
import java.util.EnumSet import java.util.EnumSet
import java.util.HashMap
import java.util.NavigableMap import java.util.NavigableMap
import java.util.Objects import java.util.Objects
import java.util.Random import java.util.Random
@ -294,14 +294,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
} }
val des = DeserializationInput(freshDeserializationFactory) val des = DeserializationInput(freshDeserializationFactory)
val desObj = des.deserialize(bytes, testSerializationContext.withEncodingWhitelist(encodingWhitelist)) val desObj = des.deserialize(bytes, testSerializationContext.withEncodingWhitelist(encodingWhitelist))
assertTrue(deepEquals(obj, desObj) == expectedEqual) assertEquals(deepEquals(obj, desObj), expectedEqual)
// Now repeat with a re-used factory // Now repeat with a re-used factory
val ser2 = SerializationOutput(factory) val ser2 = SerializationOutput(factory)
val des2 = DeserializationInput(factory) val des2 = DeserializationInput(factory)
val desObj2 = des2.deserialize(ser2.serialize(obj, compression), testSerializationContext.withEncodingWhitelist(encodingWhitelist)) val desObj2 = des2.deserialize(ser2.serialize(obj, compression), testSerializationContext.withEncodingWhitelist(encodingWhitelist))
assertTrue(deepEquals(obj, desObj2) == expectedEqual) assertEquals(deepEquals(obj, desObj2), expectedEqual)
assertTrue(deepEquals(desObj, desObj2) == expectDeserializedEqual) assertEquals(deepEquals(desObj, desObj2), expectDeserializedEqual)
// TODO: add some schema assertions to check correctly formed. // TODO: add some schema assertions to check correctly formed.
return desObj return desObj
@ -374,11 +374,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
serdes(obj) serdes(obj)
} }
@Test(expected = IllegalArgumentException::class, timeout=300_000) @Test(timeout=300_000)
fun `test dislike of HashMap`() { fun `test dislike of HashMap`() {
val obj = WrapHashMap(HashMap()) val obj = WrapHashMap(HashMap())
assertThatIllegalArgumentException().isThrownBy {
serdes(obj) serdes(obj)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test string array`() { fun `test string array`() {
@ -416,13 +418,15 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
serdes(obj) serdes(obj)
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun `test whitelist`() { fun `test whitelist`() {
val obj = Woo2(4) val obj = Woo2(4)
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
)) ))
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test annotation whitelisting`() { fun `test annotation whitelisting`() {
@ -432,11 +436,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
)) ))
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun `test generic list subclass is not supported`() { fun `test generic list subclass is not supported`() {
val obj = FooList() val obj = FooList()
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
serdes(obj) serdes(obj)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test generic foo`() { fun `test generic foo`() {
@ -498,29 +504,33 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test NavigableMap property`() { fun `test NavigableMap property`() {
val obj = NavigableMapWrapper(TreeMap<Int, Foo>()) val obj = NavigableMapWrapper(TreeMap())
obj.tree[456] = Foo("Fred", 123) obj.tree[456] = Foo("Fred", 123)
serdes(obj) serdes(obj)
} }
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test SortedSet property`() { fun `test SortedSet property`() {
val obj = SortedSetWrapper(TreeSet<Int>()) val obj = SortedSetWrapper(TreeSet())
obj.set += 456 obj.set += 456
serdes(obj) serdes(obj)
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun `test mismatched property and constructor naming`() { fun `test mismatched property and constructor naming`() {
val obj = Mismatch(456) val obj = Mismatch(456)
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
serdes(obj) serdes(obj)
} }
}
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun `test mismatched property and constructor type`() { fun `test mismatched property and constructor type`() {
val obj = MismatchType(456) val obj = MismatchType(456)
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
serdes(obj) serdes(obj)
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `class constructor is invoked on deserialisation`() { fun `class constructor is invoked on deserialisation`() {
@ -575,7 +585,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Test(timeout=300_000) @Test(timeout=300_000)
fun `generics from java are supported`() { fun `generics from java are supported`() {
val obj = DummyOptional<String>("YES") val obj = DummyOptional("YES")
serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist,
ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader())
)) ))
@ -630,13 +640,11 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
private fun assertSerializedThrowableEquivalent(t: Throwable, desThrowable: Throwable) { private fun assertSerializedThrowableEquivalent(t: Throwable, desThrowable: Throwable) {
assertTrue(desThrowable is CordaRuntimeException) // Since we don't handle the other case(s) yet assertTrue(desThrowable is CordaRuntimeException) // Since we don't handle the other case(s) yet
if (desThrowable is CordaRuntimeException) {
assertEquals("${t.javaClass.name}: ${t.message}", desThrowable.message) assertEquals("${t.javaClass.name}: ${t.message}", desThrowable.message)
assertTrue(Objects.deepEquals(t.stackTrace.toStackTraceBasic, desThrowable.stackTrace.toStackTraceBasic)) assertTrue(Objects.deepEquals(t.stackTrace.toStackTraceBasic, desThrowable.stackTrace.toStackTraceBasic))
assertEquals(t.suppressed.size, desThrowable.suppressed.size) assertEquals(t.suppressed.size, desThrowable.suppressed.size)
t.suppressed.zip(desThrowable.suppressed).forEach { (before, after) -> assertSerializedThrowableEquivalent(before, after) } t.suppressed.zip(desThrowable.suppressed).forEach { (before, after) -> assertSerializedThrowableEquivalent(before, after) }
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test suppressed throwables serialize`() { fun `test suppressed throwables serialize`() {
@ -762,8 +770,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false) val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false)
assertTrue((desState as TransactionState<*>).data is FooState) assertTrue((desState as TransactionState<*>).data is FooState)
assertTrue(desState.notary == state.notary) assertEquals(desState.notary, state.notary)
assertTrue(desState.encumbrance == state.encumbrance) assertEquals(desState.encumbrance, state.encumbrance)
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -1091,7 +1099,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
@Ignore("Ignored due to cyclic graphs not currently supported by AMQP serialization") @Ignore("Ignored due to cyclic graphs not currently supported by AMQP serialization")
fun `test serialization of cyclic graph`() { fun `test serialization of cyclic graph`() {
val nodeA = TestNode("A") val nodeA = TestNode("A")
val nodeB = TestNode("B", ArrayList(Arrays.asList(nodeA))) val nodeB = TestNode("B", ArrayList(listOf(nodeA)))
nodeA.children.add(nodeB) nodeA.children.add(nodeB)
// Also blows with StackOverflow error // Also blows with StackOverflow error
@ -1330,7 +1338,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
) )
factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2)) factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2))
val obj = BitSet.valueOf(kotlin.ByteArray(16) { it.toByte() }).get(0, 123) val obj = BitSet.valueOf(ByteArray(16) { it.toByte() }).get(0, 123)
serdes(obj, factory, factory2) serdes(obj, factory, factory2)
} }

View File

@ -1,16 +1,18 @@
package net.corda.serialization.internal.amqp package net.corda.serialization.internal.amqp
import com.google.common.reflect.TypeToken import com.google.common.reflect.TypeToken
import net.corda.serialization.internal.MAX_TYPE_PARAM_DEPTH
import net.corda.serialization.internal.model.TypeIdentifier import net.corda.serialization.internal.model.TypeIdentifier
import org.apache.qpid.proton.amqp.UnsignedShort import org.apache.qpid.proton.amqp.UnsignedShort
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test import org.junit.Test
import java.io.NotSerializableException import java.io.NotSerializableException
import java.lang.reflect.Type import java.lang.reflect.Type
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.* import java.util.Date
import java.util.UUID
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
import net.corda.serialization.internal.MAX_TYPE_PARAM_DEPTH
class AMQPTypeIdentifierParserTests { class AMQPTypeIdentifierParserTests {
@ -100,49 +102,49 @@ class AMQPTypeIdentifierParserTests {
verify("java.util.List<net.corda.core.contracts.Command<net.corda.core.contracts.Command<net.corda.core.contracts.CommandData>>>") verify("java.util.List<net.corda.core.contracts.Command<net.corda.core.contracts.Command<net.corda.core.contracts.CommandData>>>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test trailing text`() { fun `test trailing text`() {
verify("java.util.Map<java.lang.String, java.lang.Integer>foo") verifyInvalid("java.util.Map<java.lang.String, java.lang.Integer>foo")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test trailing comma`() { fun `test trailing comma`() {
verify("java.util.Map<java.lang.String, java.lang.Integer,>") verifyInvalid("java.util.Map<java.lang.String, java.lang.Integer,>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test leading comma`() { fun `test leading comma`() {
verify("java.util.Map<,java.lang.String, java.lang.Integer>") verifyInvalid("java.util.Map<,java.lang.String, java.lang.Integer>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test middle comma`() { fun `test middle comma`() {
verify("java.util.Map<,java.lang.String,, java.lang.Integer>") verifyInvalid("java.util.Map<,java.lang.String,, java.lang.Integer>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test trailing close`() { fun `test trailing close`() {
verify("java.util.Map<java.lang.String, java.lang.Integer>>") verifyInvalid("java.util.Map<java.lang.String, java.lang.Integer>>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test empty params`() { fun `test empty params`() {
verify("java.util.Map<>") verifyInvalid("java.util.Map<>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test mid whitespace`() { fun `test mid whitespace`() {
verify("java.u til.List<java.lang.String>") verifyInvalid("java.u til.List<java.lang.String>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test mid whitespace2`() { fun `test mid whitespace2`() {
verify("java.util.List<java.l ng.String>") verifyInvalid("java.util.List<java.l ng.String>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test wrong number of parameters`() { fun `test wrong number of parameters`() {
verify("java.util.List<java.lang.String, java.lang.Integer>") verifyInvalid("java.util.List<java.lang.String, java.lang.Integer>")
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -150,18 +152,18 @@ class AMQPTypeIdentifierParserTests {
verify("java.lang.String") verify("java.lang.String")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test parameters on non-generic type`() { fun `test parameters on non-generic type`() {
verify("java.lang.String<java.lang.Integer>") verifyInvalid("java.lang.String<java.lang.Integer>")
} }
@Test(expected = NotSerializableException::class, timeout = 300_000) @Test(timeout = 300_000)
fun `test excessive nesting`() { fun `test excessive nesting`() {
var nested = "java.lang.Integer" var nested = "java.lang.Integer"
for (i in 1..MAX_TYPE_PARAM_DEPTH) { for (i in 1..MAX_TYPE_PARAM_DEPTH) {
nested = "java.util.List<$nested>" nested = "java.util.List<$nested>"
} }
verify(nested) verifyInvalid(nested)
} }
private inline fun <reified T> assertParseResult(typeString: String) { private inline fun <reified T> assertParseResult(typeString: String) {
@ -195,4 +197,10 @@ class AMQPTypeIdentifierParserTests {
val type = AMQPTypeIdentifierParser.parse(typeName).getLocalType() val type = AMQPTypeIdentifierParser.parse(typeName).getLocalType()
assertEquals(normalise(typeName), normalise(type.typeName)) assertEquals(normalise(typeName), normalise(type.typeName))
} }
private fun verifyInvalid(typeName: String) {
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
AMQPTypeIdentifierParser.parse(typeName).getLocalType()
}
}
} }

View File

@ -4,8 +4,16 @@ import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test import org.junit.Test
import java.util.* import java.io.NotSerializableException
import java.util.AbstractMap
import java.util.Dictionary
import java.util.Hashtable
import java.util.NavigableMap
import java.util.SortedMap
import java.util.TreeMap
import java.util.WeakHashMap
class DeserializeMapTests { class DeserializeMapTests {
companion object { companion object {
@ -27,24 +35,26 @@ class DeserializeMapTests {
DeserializationInput(sf).deserialize(serialisedBytes) DeserializationInput(sf).deserialize(serialisedBytes)
} }
@Test(expected = java.io.NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun abstractMapFromMapOf() { fun abstractMapFromMapOf() {
data class C(val c: AbstractMap<String, Int>) data class C(val c: AbstractMap<String, Int>)
val c = C(mapOf("A" to 1, "B" to 2) as AbstractMap) val c = C(mapOf("A" to 1, "B" to 2) as AbstractMap)
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf).deserialize(serialisedBytes) TestSerializationOutput(VERBOSE, sf).serialize(c)
}
} }
@Test(expected = java.io.NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun abstractMapFromTreeMap() { fun abstractMapFromTreeMap() {
data class C(val c: AbstractMap<String, Int>) data class C(val c: AbstractMap<String, Int>)
val c = C(TreeMap(mapOf("A" to 1, "B" to 2))) val c = C(TreeMap(mapOf("A" to 1, "B" to 2)))
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf).deserialize(serialisedBytes) TestSerializationOutput(VERBOSE, sf).serialize(c)
}
} }
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -12,6 +12,7 @@ import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolu
import net.corda.serialization.internal.amqp.testutils.testName import net.corda.serialization.internal.amqp.testutils.testName
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Assert.assertNotSame import org.junit.Assert.assertNotSame
import org.junit.Test import org.junit.Test
import java.io.NotSerializableException import java.io.NotSerializableException
@ -157,7 +158,7 @@ class EnumTests {
assertEquals(c.c, obj.c) assertEquals(c.c, obj.c)
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun changedEnum1() { fun changedEnum1() {
val url = EnumTests::class.java.getResource("EnumTests.changedEnum1") val url = EnumTests::class.java.getResource("EnumTests.changedEnum1")
@ -173,10 +174,12 @@ class EnumTests {
val sc2 = url.readBytes() val sc2 = url.readBytes()
// we expect this to throw // we expect this to throw
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2)) DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2))
} }
}
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun changedEnum2() { fun changedEnum2() {
val url = EnumTests::class.java.getResource("EnumTests.changedEnum2") val url = EnumTests::class.java.getResource("EnumTests.changedEnum2")
@ -195,8 +198,10 @@ class EnumTests {
val sc2 = url.readBytes() val sc2 = url.readBytes()
// we expect this to throw // we expect this to throw
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2)) DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2))
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun enumNotWhitelistedFails() { fun enumNotWhitelistedFails() {

View File

@ -15,6 +15,7 @@ import net.corda.core.serialization.DeprecatedConstructorForDeserialization
import net.corda.core.serialization.SerializableCalculatedProperty import net.corda.core.serialization.SerializableCalculatedProperty
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.amqp.custom.InstantSerializer import net.corda.serialization.internal.amqp.custom.InstantSerializer
import net.corda.serialization.internal.amqp.custom.PublicKeySerializer
import net.corda.serialization.internal.amqp.testutils.ProjectStructure.projectRootDir import net.corda.serialization.internal.amqp.testutils.ProjectStructure.projectRootDir
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
@ -23,6 +24,7 @@ import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.amqp.testutils.testName import net.corda.serialization.internal.amqp.testutils.testName
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
import org.junit.jupiter.api.Assertions.assertNotSame import org.junit.jupiter.api.Assertions.assertNotSame
@ -68,7 +70,7 @@ class EvolvabilityTests {
// new version of the class, in this case the order of the parameters has been swapped // new version of the class, in this case the order of the parameters has been swapped
data class C(val b: Int, val a: Int) data class C(val b: Int, val a: Int)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
@ -90,7 +92,7 @@ class EvolvabilityTests {
// new version of the class, in this case the order of the parameters has been swapped // new version of the class, in this case the order of the parameters has been swapped
data class C(val b: String, val a: Int) data class C(val b: String, val a: Int)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
@ -110,7 +112,7 @@ class EvolvabilityTests {
data class C(val a: Int, val b: Int?) data class C(val a: Int, val b: Int?)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
@ -118,10 +120,10 @@ class EvolvabilityTests {
assertEquals(null, deserializedC.b) assertEquals(null, deserializedC.b)
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
fun addAdditionalParam() { fun addAdditionalParam() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam") val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam")!!
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val A = 1 val A = 1
@ -140,8 +142,10 @@ class EvolvabilityTests {
// Expected to throw as we can't construct the new type as it contains a newly // Expected to throw as we can't construct the new type as it contains a newly
// added parameter that isn't optional, i.e. not nullable and there isn't // added parameter that isn't optional, i.e. not nullable and there isn't
// a constructor that takes the old parameters // a constructor that takes the old parameters
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
} }
}
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
@Test(timeout=300_000) @Test(timeout=300_000)
@ -159,7 +163,7 @@ class EvolvabilityTests {
data class CC(val b: String, val d: Int) data class CC(val b: String, val d: Int)
val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters") val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters")!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -167,7 +171,6 @@ class EvolvabilityTests {
assertEquals(D, deserializedCC.d) assertEquals(D, deserializedCC.d)
} }
@Suppress("UNUSED_VARIABLE")
@Test(timeout=300_000) @Test(timeout=300_000)
fun removeParameterWithCalculatedParameter() { fun removeParameterWithCalculatedParameter() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
@ -186,7 +189,7 @@ class EvolvabilityTests {
val e: String get() = "$b sailor" val e: String get() = "$b sailor"
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -213,7 +216,7 @@ class EvolvabilityTests {
data class CC(val a: Int, val e: Boolean?, val d: Int) data class CC(val a: Int, val e: Boolean?, val d: Int)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -238,7 +241,7 @@ class EvolvabilityTests {
constructor (a: Int) : this(a, "hello") constructor (a: Int) : this(a, "hello")
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -263,7 +266,7 @@ class EvolvabilityTests {
constructor (z: Int, y: Int) : this(z, y, "10") constructor (z: Int, y: Int) : this(z, y, "10")
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes())) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes()))
assertEquals("10", deserializedCC.a) assertEquals("10", deserializedCC.a)
@ -322,16 +325,16 @@ class EvolvabilityTests {
// 9, // 9,
// mapOf("A" to listOf(1, 2, 3), "B" to listOf (4, 5, 6)))).bytes) // mapOf("A" to listOf(1, 2, 3), "B" to listOf (4, 5, 6)))).bytes)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
DeserializationInput(factory).deserialize(SerializedBytes<NetworkParametersExample>(url.readBytes())) DeserializationInput(factory).deserialize(SerializedBytes<NetworkParametersExample>(url.readBytes()))
} }
@Test(expected = NotSerializableException::class, timeout=300_000) @Test(timeout=300_000)
@Suppress("UNUSED") @Suppress("UNUSED")
fun addMandatoryFieldWithAltConstructorUnAnnotated() { fun addMandatoryFieldWithAltConstructorUnAnnotated() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
val url = EvolvabilityTests::class.java.getResource( val url = EvolvabilityTests::class.java.getResource(
"EvolvabilityTests.addMandatoryFieldWithAltConstructorUnAnnotated") "EvolvabilityTests.addMandatoryFieldWithAltConstructorUnAnnotated")!!
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val A = 1 val A = 1
@ -349,8 +352,10 @@ class EvolvabilityTests {
// we expect this to throw as we should not find any constructors // we expect this to throw as we should not find any constructors
// capable of dealing with this // capable of dealing with this
assertThatExceptionOfType(NotSerializableException::class.java).isThrownBy {
DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes())) DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes()))
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun addMandatoryFieldWithAltReorderedConstructor() { fun addMandatoryFieldWithAltReorderedConstructor() {
@ -372,7 +377,7 @@ class EvolvabilityTests {
constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble") constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble")
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -404,7 +409,7 @@ class EvolvabilityTests {
constructor (c: String, a: Int) : this(a, c, "wibble") constructor (c: String, a: Int) : this(a, c, "wibble")
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
@ -451,9 +456,9 @@ class EvolvabilityTests {
constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d) constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d)
} }
val url1 = EvolvabilityTests::class.java.getResource(resource1) val url1 = EvolvabilityTests::class.java.getResource(resource1)!!
val url2 = EvolvabilityTests::class.java.getResource(resource2) val url2 = EvolvabilityTests::class.java.getResource(resource2)!!
val url3 = EvolvabilityTests::class.java.getResource(resource3) val url3 = EvolvabilityTests::class.java.getResource(resource3)!!
val sb1 = url1.readBytes() val sb1 = url1.readBytes()
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1)) val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
@ -500,7 +505,7 @@ class EvolvabilityTests {
data class Outer(val a: Int, val b: Inner) data class Outer(val a: Int, val b: Inner)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2)) val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2))
@ -565,9 +570,9 @@ class EvolvabilityTests {
constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1) constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1)
} }
val url1 = EvolvabilityTests::class.java.getResource(resource1) val url1 = EvolvabilityTests::class.java.getResource(resource1)!!
val url2 = EvolvabilityTests::class.java.getResource(resource2) val url2 = EvolvabilityTests::class.java.getResource(resource2)!!
val url3 = EvolvabilityTests::class.java.getResource(resource3) val url3 = EvolvabilityTests::class.java.getResource(resource3)!!
val sb1 = url1.readBytes() val sb1 = url1.readBytes()
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1)) val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
@ -616,8 +621,8 @@ class EvolvabilityTests {
@Ignore("Test fails after moving NetworkParameters and NotaryInfo into core from node-api") @Ignore("Test fails after moving NetworkParameters and NotaryInfo into core from node-api")
fun readBrokenNetworkParameters() { fun readBrokenNetworkParameters() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
sf.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(sf)) sf.register(InstantSerializer(sf))
sf.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) sf.register(PublicKeySerializer)
// //
// filename breakdown // filename breakdown
@ -627,7 +632,7 @@ class EvolvabilityTests {
// //
val resource = "networkParams.r3corda.6a6b6f256" val resource = "networkParams.r3corda.6a6b6f256"
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2))
val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw) val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw)
@ -654,8 +659,8 @@ class EvolvabilityTests {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `read corda 4-11 network parameters`() { fun `read corda 4-11 network parameters`() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
sf.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(sf)) sf.register(InstantSerializer(sf))
sf.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) sf.register(PublicKeySerializer)
sf.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(sf)) sf.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(sf))
// //
@ -666,7 +671,7 @@ class EvolvabilityTests {
// //
val resource = "networkParams.4.11.58ecce1" val resource = "networkParams.4.11.58ecce1"
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2))
val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw) val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw)
@ -691,8 +696,8 @@ class EvolvabilityTests {
3, listOf(NotaryInfo(DUMMY_NOTARY_PARTY, false)), 1000, 1000, Instant.EPOCH, 1, emptyMap()) 3, listOf(NotaryInfo(DUMMY_NOTARY_PARTY, false)), 1000, 1000, Instant.EPOCH, 1, emptyMap())
val sf = testDefaultFactory() val sf = testDefaultFactory()
sf.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(sf)) sf.register(InstantSerializer(sf))
sf.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) sf.register(PublicKeySerializer)
val testOutput = TestSerializationOutput(true, sf) val testOutput = TestSerializationOutput(true, sf)
val serialized = testOutput.serialize(networkParameters) val serialized = testOutput.serialize(networkParameters)
@ -704,7 +709,6 @@ class EvolvabilityTests {
File(URI("$localPath/$resource")).writeBytes(signedAndSerialized.bytes) File(URI("$localPath/$resource")).writeBytes(signedAndSerialized.bytes)
} }
@Suppress("UNCHECKED_CAST")
@Test(timeout=300_000) @Test(timeout=300_000)
fun getterSetterEvolver1() { fun getterSetterEvolver1() {
val resource = "EvolvabilityTests.getterSetterEvolver1" val resource = "EvolvabilityTests.getterSetterEvolver1"
@ -734,7 +738,7 @@ class EvolvabilityTests {
constructor() : this(0, 0, 0, 0) constructor() : this(0, 0, 0, 0)
} }
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
@ -759,7 +763,7 @@ class EvolvabilityTests {
// Uncomment to recreate // Uncomment to recreate
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(Evolved("dronf", NewEnum.BUCKLE_MY_SHOE)).bytes) // File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(Evolved("dronf", NewEnum.BUCKLE_MY_SHOE)).bytes)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserialized = DeserializationInput(sf).deserialize(SerializedBytes<Evolved>(sc2)) val deserialized = DeserializationInput(sf).deserialize(SerializedBytes<Evolved>(sc2))
@ -786,7 +790,7 @@ class EvolvabilityTests {
// Uncomment to recreate // Uncomment to recreate
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(ParameterizedContainer(Parameterized(10, setOf(20)))).bytes) // File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(ParameterizedContainer(Parameterized(10, setOf(20)))).bytes)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserialized = DeserializationInput(sf).deserialize(SerializedBytes<ParameterizedContainer>(sc2)) val deserialized = DeserializationInput(sf).deserialize(SerializedBytes<ParameterizedContainer>(sc2))
@ -900,7 +904,7 @@ class EvolvabilityTests {
File(URI("$localPath/$resource")).writeBytes(currentForm.bytes) File(URI("$localPath/$resource")).writeBytes(currentForm.bytes)
*/ */
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val previousForm = SerializedBytes<NotarisationRequest>(sc2) val previousForm = SerializedBytes<NotarisationRequest>(sc2)
val deserialized = DeserializationInput(sf).deserialize(previousForm) val deserialized = DeserializationInput(sf).deserialize(previousForm)
@ -932,7 +936,7 @@ class EvolvabilityTests {
//val A = MaybeSerializedSignedTransaction(SecureHash.randomSHA256(), null, null) //val A = MaybeSerializedSignedTransaction(SecureHash.randomSHA256(), null, null)
//File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(A).bytes) //File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(A).bytes)
val url = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)!!
val sc2 = url.readBytes() val sc2 = url.readBytes()
val deserializedA = DeserializationInput(sf).deserialize(SerializedBytes<MaybeSerializedSignedTransaction>(sc2)) val deserializedA = DeserializationInput(sf).deserialize(SerializedBytes<MaybeSerializedSignedTransaction>(sc2))

View File

@ -5,6 +5,7 @@ import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
@ -40,10 +41,12 @@ class C2(var b: Int) {
} }
class StaticInitialisationOfSerializedObjectTest { class StaticInitialisationOfSerializedObjectTest {
@Test(expected = java.lang.ExceptionInInitializerError::class, timeout=300_000) @Test(timeout=300_000)
fun itBlowsUp() { fun itBlowsUp() {
assertThatExceptionOfType(ExceptionInInitializerError::class.java).isThrownBy {
C() C()
} }
}
@Ignore("Suppressing this, as it depends on obtaining internal access to serialiser cache") @Ignore("Suppressing this, as it depends on obtaining internal access to serialiser cache")
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -3,9 +3,11 @@ package net.corda.serialization.internal.carpenter
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.AllWhitelist
import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.Test import org.junit.Test
import java.beans.Introspector import java.beans.Introspector
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method import java.lang.reflect.Method
import javax.annotation.Nonnull import javax.annotation.Nonnull
import javax.annotation.Nullable import javax.annotation.Nullable
@ -95,11 +97,13 @@ class ClassCarpenterTest {
assertEquals("Person{age=32, name=Mike}", i.toString()) assertEquals("Person{age=32, name=Mike}", i.toString())
} }
@Test(expected = DuplicateNameException::class, timeout=300_000) @Test(timeout=300_000)
fun duplicates() { fun duplicates() {
cc.build(ClassSchema("gen.EmptyClass", emptyMap())) cc.build(ClassSchema("gen.EmptyClass", emptyMap()))
assertThatExceptionOfType(DuplicateNameException::class.java).isThrownBy {
cc.build(ClassSchema("gen.EmptyClass", emptyMap())) cc.build(ClassSchema("gen.EmptyClass", emptyMap()))
} }
}
@Test(timeout=300_000) @Test(timeout=300_000)
fun `can refer to each other`() { fun `can refer to each other`() {
@ -301,7 +305,7 @@ class ClassCarpenterTest {
assertEquals(testD, i["d"]) assertEquals(testD, i["d"])
} }
@Test(expected = java.lang.IllegalArgumentException::class, timeout=300_000) @Test(timeout=300_000)
fun `null parameter small int`() { fun `null parameter small int`() {
val className = "iEnjoySwede" val className = "iEnjoySwede"
val schema = ClassSchema( val schema = ClassSchema(
@ -310,17 +314,16 @@ class ClassCarpenterTest {
val clazz = cc.build(schema) val clazz = cc.build(schema)
val a: Int? = null val a: Int? = null
assertThatIllegalArgumentException().isThrownBy {
clazz.constructors[0].newInstance(a) clazz.constructors[0].newInstance(a)
} }
}
@Test(expected = NullablePrimitiveException::class, timeout=300_000) @Test(timeout=300_000)
fun `nullable parameter small int`() { fun `nullable parameter small int`() {
val className = "iEnjoySwede" assertThatExceptionOfType(NullablePrimitiveException::class.java).isThrownBy {
val schema = ClassSchema( NullableField(Int::class.java)
"gen.$className", }
mapOf("a" to NullableField(Int::class.java)))
cc.build(schema)
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -351,7 +354,7 @@ class ClassCarpenterTest {
clazz.constructors[0].newInstance(a) clazz.constructors[0].newInstance(a)
} }
@Test(expected = java.lang.reflect.InvocationTargetException::class, timeout=300_000) @Test(timeout=300_000)
fun `non nullable parameter integer with null`() { fun `non nullable parameter integer with null`() {
val className = "iEnjoyWibble" val className = "iEnjoyWibble"
val schema = ClassSchema( val schema = ClassSchema(
@ -361,7 +364,9 @@ class ClassCarpenterTest {
val clazz = cc.build(schema) val clazz = cc.build(schema)
val a: Int? = null val a: Int? = null
assertThatExceptionOfType(InvocationTargetException::class.java).isThrownBy {
clazz.constructors[0].newInstance(a) clazz.constructors[0].newInstance(a)
}.withCauseInstanceOf(NullPointerException::class.java)
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -383,7 +388,7 @@ class ClassCarpenterTest {
assertEquals("$className{a=[1, 2, 3]}", i.toString()) assertEquals("$className{a=[1, 2, 3]}", i.toString())
} }
@Test(expected = java.lang.reflect.InvocationTargetException::class, timeout=300_000) @Test(timeout=300_000)
fun `nullable int array throws`() { fun `nullable int array throws`() {
val className = "iEnjoySwede" val className = "iEnjoySwede"
val schema = ClassSchema( val schema = ClassSchema(
@ -393,7 +398,9 @@ class ClassCarpenterTest {
val clazz = cc.build(schema) val clazz = cc.build(schema)
val a: IntArray? = null val a: IntArray? = null
assertThatExceptionOfType(InvocationTargetException::class.java).isThrownBy {
clazz.constructors[0].newInstance(a) clazz.constructors[0].newInstance(a)
}.withCauseInstanceOf(NullPointerException::class.java)
} }
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -14,11 +14,12 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.enclosedCordapp import net.corda.testing.node.internal.enclosedCordapp
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.security.PublicKey import java.security.PublicKey
import java.util.* import java.util.Random
class CustomNotaryTest { class CustomNotaryTest {
private lateinit var mockNet: MockNetwork private lateinit var mockNet: MockNetwork
@ -50,14 +51,16 @@ class CustomNotaryTest {
mockNet.stopNodes() mockNet.stopNodes()
} }
@Test(expected = CustomNotaryException::class, timeout=300_000) @Test(timeout=300_000)
fun `custom notary service is active`() { fun `custom notary service is active`() {
val tx = DummyContract.generateInitial(Random().nextInt(), notary, alice.ref(0)) val tx = DummyContract.generateInitial(Random().nextInt(), notary, alice.ref(0))
val stx = aliceNode.services.signInitialTransaction(tx) val stx = aliceNode.services.signInitialTransaction(tx)
val future = aliceNode.startFlow(NotaryFlow.Client(stx)) val future = aliceNode.startFlow(NotaryFlow.Client(stx))
mockNet.runNetwork() mockNet.runNetwork()
assertThatExceptionOfType(CustomNotaryException::class.java).isThrownBy {
future.getOrThrow() future.getOrThrow()
} }
}
class CustomNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : NotaryService() { class CustomNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : NotaryService() {

View File

@ -8,15 +8,16 @@ dependencies {
implementation "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version" implementation "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
testImplementation "junit:junit:$junit_version" testImplementation "junit:junit:$junit_version"
testImplementation "org.assertj:assertj-core:$assertj_version"
} }
jar { jar {
enabled = false enabled = false
classifier = 'ignore' archiveClassifier = 'ignore'
} }
shadowJar { shadowJar {
baseName = "corda-tools-error-utils" archiveBaseName = "corda-tools-error-utils"
manifest { manifest {
attributes( attributes(
'Main-Class': "net.corda.errorUtilities.ErrorToolKt" 'Main-Class': "net.corda.errorUtilities.ErrorToolKt"

View File

@ -1,10 +1,10 @@
package net.corda.errorUtilities.docsTable package net.corda.errorUtilities.docsTable
import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertEquals
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import org.junit.Test import org.junit.Test
import java.lang.IllegalArgumentException
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.Locale
class DocsTableGeneratorTest { class DocsTableGeneratorTest {
@ -37,9 +37,11 @@ class DocsTableGeneratorTest {
assertEquals(irishTable.split("\n").joinToString(System.lineSeparator()), table) assertEquals(irishTable.split("\n").joinToString(System.lineSeparator()), table)
} }
@Test(expected = IllegalArgumentException::class, timeout = 1000) @Test(timeout = 1000)
fun `error thrown if unknown directory passed to generator`() { fun `error thrown if unknown directory passed to generator`() {
val generator = DocsTableGenerator(Paths.get("not/a/directory"), Locale.getDefault()) val generator = DocsTableGenerator(Paths.get("not/a/directory"), Locale.getDefault())
assertThatIllegalArgumentException().isThrownBy {
generator.generateMarkdown() generator.generateMarkdown()
} }
}
} }