mirror of
https://github.com/corda/corda.git
synced 2025-04-16 07:27:17 +00:00
Merge pull request #6279 from corda/christians/update-fb-from-4.6
Update db changes feature branch with latest from 4.6
This commit is contained in:
commit
8a0916b2a2
@ -12,7 +12,7 @@ pipeline {
|
||||
}
|
||||
|
||||
environment {
|
||||
DOCKER_TAG_TO_USE = "${env.GIT_COMMIT.subSequence(0, 8)}"
|
||||
DOCKER_TAG_TO_USE = "${env.GIT_COMMIT.subSequence(0, 8)}JDK11"
|
||||
EXECUTOR_NUMBER = "${env.EXECUTOR_NUMBER}"
|
||||
BUILD_ID = "${env.BUILD_ID}-${env.JOB_NAME}"
|
||||
ARTIFACTORY_CREDENTIALS = credentials('artifactory-credentials')
|
||||
|
101
.ci/dev/smoke/Jenkinsfile
vendored
101
.ci/dev/smoke/Jenkinsfile
vendored
@ -1,101 +0,0 @@
|
||||
@Library('corda-shared-build-pipeline-steps')
|
||||
import static com.r3.build.BuildControl.killAllExistingBuildsForJob
|
||||
|
||||
killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger())
|
||||
|
||||
pipeline {
|
||||
agent { label 'k8s' }
|
||||
options {
|
||||
timestamps()
|
||||
overrideIndexTriggers(false)
|
||||
timeout(time: 3, unit: 'HOURS')
|
||||
}
|
||||
|
||||
triggers {
|
||||
issueCommentTrigger('.*smoke tests.*')
|
||||
}
|
||||
|
||||
environment {
|
||||
EXECUTOR_NUMBER = "${env.EXECUTOR_NUMBER}"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Corda Smoke Tests') {
|
||||
steps {
|
||||
script {
|
||||
if (currentBuildTriggeredByComment()) {
|
||||
stage('Run Smoke Tests') {
|
||||
script {
|
||||
pullRequest.createStatus(status: 'pending',
|
||||
context: 'continuous-integration/jenkins/pr-merge/smokeTest',
|
||||
description: 'Smoke Tests Running',
|
||||
targetUrl: "${env.JOB_URL}")
|
||||
}
|
||||
|
||||
withCredentials([string(credentialsId: 'container_reg_passwd', variable: 'DOCKER_PUSH_PWD')]) {
|
||||
sh "./gradlew " +
|
||||
"-Dkubenetize=true " +
|
||||
"-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " +
|
||||
"-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " +
|
||||
" clean allParallelSmokeTest --stacktrace"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
if (currentBuildTriggeredByComment()) {
|
||||
archiveArtifacts artifacts: '**/pod-logs/**/*.log', fingerprint: false
|
||||
junit '**/build/test-results-xml/**/*.xml'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
success {
|
||||
script {
|
||||
if (currentBuildTriggeredByComment()) {
|
||||
pullRequest.createStatus(status: 'success',
|
||||
context: 'continuous-integration/jenkins/pr-merge/smokeTest',
|
||||
description: 'Smoke Tests Passed',
|
||||
targetUrl: "${env.BUILD_URL}testResults")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
failure {
|
||||
script {
|
||||
if (currentBuildTriggeredByComment()) {
|
||||
pullRequest.createStatus(status: 'failure',
|
||||
context: 'continuous-integration/jenkins/pr-merge/smokeTest',
|
||||
description: 'Smoke Tests Failed',
|
||||
targetUrl: "${env.BUILD_URL}testResults")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup {
|
||||
deleteDir() /* clean up our workspace */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
def currentBuildTriggeredByComment() {
|
||||
def triggerCause = currentBuild.rawBuild.getCause(org.jenkinsci.plugins.pipeline.github.trigger.IssueCommentCause)
|
||||
if (triggerCause) {
|
||||
echo("Build was started by ${triggerCause.userLogin}, who wrote: " +
|
||||
"\"${triggerCause.comment}\", which matches the " +
|
||||
"\"${triggerCause.triggerPattern}\" trigger pattern.")
|
||||
} else {
|
||||
echo('Build was not started by a trigger')
|
||||
}
|
||||
|
||||
return triggerCause != null
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
errorTemplate = Version identifier ({0}) for attribute {1} must be a whole number starting from 1.
|
||||
shortDescription = A version attribute with an invalid value was specified in the manifest of the CorDapp JAR. The version attribute value must be a whole number that is greater than or equal to 1.
|
||||
actionsToFix = Investigate the logs to find the invalid version attribute, and change its value to a valid one (a whole number greater than or equal to 1).
|
||||
aliases =
|
||||
aliases = 1nskd37
|
@ -1,4 +1,3 @@
|
||||
errorTemplate = Version identifier ({0}) for attribute {1} must be a whole number starting from 1.
|
||||
shortDescription = A version attribute with an invalid value was specified in the manifest of the CorDapp JAR. The version attribute value must be a whole number that is greater than or equal to 1.
|
||||
actionsToFix = Investigate the logs to find the invalid version attribute, and change its value to a valid one (a whole number greater than or equal to 1).
|
||||
aliases =
|
||||
actionsToFix = Investigate the logs to find the invalid version attribute, and change its value to a valid one (a whole number greater than or equal to 1).
|
@ -1,4 +1,4 @@
|
||||
errorTemplate = Target versionId attribute {0} not specified. Please specify a whole number starting from 1.
|
||||
shortDescription = A required version attribute was not specified in the manifest of the CorDapp JAR.
|
||||
actionsToFix = Investigate the logs to find out which version attribute was not specified, and add that version attribute to the CorDapp manifest.
|
||||
aliases =
|
||||
aliases = 1nskd37
|
@ -1,4 +1,3 @@
|
||||
errorTemplate = Target versionId attribute {0} not specified. Please specify a whole number starting from 1.
|
||||
shortDescription = A required version attribute was not specified in the manifest of the CorDapp JAR.
|
||||
actionsToFix = Investigate the logs to find out which version attribute was not specified, and add that version attribute to the CorDapp manifest.
|
||||
aliases =
|
||||
actionsToFix = Investigate the logs to find out which version attribute was not specified, and add that version attribute to the CorDapp manifest.
|
@ -20,10 +20,7 @@ import net.corda.testing.core.CHARLIE_NAME
|
||||
import net.corda.testing.core.singleIdentity
|
||||
import net.corda.testing.driver.DriverParameters
|
||||
import net.corda.testing.driver.driver
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.core.config.Configurator
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.Semaphore
|
||||
import kotlin.test.assertEquals
|
||||
@ -36,11 +33,6 @@ class FlowIsKilledTest {
|
||||
const val EXCEPTION_MESSAGE = "Goodbye, cruel world!"
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
Configurator.setLevel("net.corda.node.services.statemachine", Level.DEBUG)
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `manually handle the isKilled check`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) {
|
||||
@ -111,7 +103,6 @@ class FlowIsKilledTest {
|
||||
assertFailsWith<UnexpectedFlowEndException> {
|
||||
handle.returnValue.getOrThrow(1.minutes)
|
||||
}
|
||||
assertTrue(AFlowThatGetsMurderedByItsFriend.receivedKilledException)
|
||||
assertEquals(11, AFlowThatGetsMurderedByItsFriendResponder.position)
|
||||
val aliceCheckpoints = alice.rpc.startFlow(::GetNumberOfCheckpointsFlow).returnValue.getOrThrow(20.seconds)
|
||||
assertEquals(1, aliceCheckpoints)
|
||||
@ -121,7 +112,7 @@ class FlowIsKilledTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `manually handle killed flows using checkForIsNotKilled`() {
|
||||
fun `manually handle killed flows using checkFlowIsNotKilled`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) {
|
||||
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
|
||||
alice.rpc.let { rpc ->
|
||||
@ -140,7 +131,7 @@ class FlowIsKilledTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `manually handle killed flows using checkForIsNotKilled with lazy message`() {
|
||||
fun `manually handle killed flows using checkFlowIsNotKilled with lazy message`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) {
|
||||
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
|
||||
alice.rpc.let { rpc ->
|
||||
@ -192,6 +183,7 @@ class FlowIsKilledTest {
|
||||
companion object {
|
||||
val lockA = Semaphore(0)
|
||||
val lockB = Semaphore(0)
|
||||
var isKilled = false
|
||||
var position = 0
|
||||
}
|
||||
|
||||
@ -208,6 +200,7 @@ class FlowIsKilledTest {
|
||||
position = i
|
||||
logger.info("i = $i")
|
||||
if (isKilled) {
|
||||
AFlowThatWantsToDieAndKillsItsFriends.isKilled = true
|
||||
throw KilledFlowException(runId, EXCEPTION_MESSAGE)
|
||||
}
|
||||
|
||||
@ -244,6 +237,9 @@ class FlowIsKilledTest {
|
||||
} catch (e: UnexpectedFlowEndException) {
|
||||
receivedKilledExceptions[ourIdentity.name] = true
|
||||
locks[ourIdentity.name]!!.release()
|
||||
require(AFlowThatWantsToDieAndKillsItsFriends.isKilled) {
|
||||
"The initiator must be killed when this exception is received"
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@ -253,19 +249,16 @@ class FlowIsKilledTest {
|
||||
@InitiatingFlow
|
||||
class AFlowThatGetsMurderedByItsFriend(private val party: Party) : FlowLogic<Unit>() {
|
||||
|
||||
companion object {
|
||||
var receivedKilledException = false
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
override fun call() {
|
||||
val sessionOne = initiateFlow(party)
|
||||
// trigger sessions with 2 counter parties
|
||||
sessionOne.sendAndReceive<String>("what is up")
|
||||
try {
|
||||
sessionOne.sendAndReceive<String>("what is up")
|
||||
sessionOne.receive<String>()
|
||||
} catch (e: UnexpectedFlowEndException) {
|
||||
receivedKilledException = true
|
||||
require(AFlowThatGetsMurderedByItsFriendResponder.isKilled) {
|
||||
"The responder must be killed when this exception is received"
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@ -277,6 +270,7 @@ class FlowIsKilledTest {
|
||||
companion object {
|
||||
val lockA = Semaphore(0)
|
||||
val lockB = Semaphore(0)
|
||||
var isKilled = false
|
||||
var flowId: StateMachineRunId? = null
|
||||
var position = 0
|
||||
}
|
||||
@ -289,6 +283,7 @@ class FlowIsKilledTest {
|
||||
for (i in 0..100) {
|
||||
position = i
|
||||
if (isKilled) {
|
||||
AFlowThatGetsMurderedByItsFriendResponder.isKilled = true
|
||||
throw KilledFlowException(runId, EXCEPTION_MESSAGE)
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,6 @@ import net.corda.testing.core.BOB_NAME
|
||||
import net.corda.testing.core.singleIdentity
|
||||
import net.corda.testing.driver.DriverParameters
|
||||
import net.corda.testing.driver.driver
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.core.config.Configurator
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
@ -27,11 +24,6 @@ import kotlin.test.assertTrue
|
||||
|
||||
class FlowSleepTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
Configurator.setLevel("net.corda.node.services.statemachine", Level.DEBUG)
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `flow can sleep`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) {
|
||||
|
@ -113,7 +113,7 @@ class AMQPClient(val targets: List<NetworkHostAndPort>,
|
||||
override fun operationComplete(future: ChannelFuture) {
|
||||
amqpActive = false
|
||||
if (!future.isSuccess) {
|
||||
log.info("Failed to connect to $currentTarget")
|
||||
log.info("Failed to connect to $currentTarget", future.cause())
|
||||
|
||||
if (started) {
|
||||
workerGroup?.schedule({
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.toFuture
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.services.config.configureWithDevSSLCertificate
|
||||
import net.corda.node.services.messaging.ArtemisMessagingServer
|
||||
@ -51,7 +52,11 @@ class ProtonWrapperTests {
|
||||
@JvmField
|
||||
val temporaryFolder = TemporaryFolder()
|
||||
|
||||
private val portAllocation = incrementalPortAllocation() // use 15000 to move us out of harms way
|
||||
companion object {
|
||||
private val log = contextLogger()
|
||||
}
|
||||
|
||||
private val portAllocation = incrementalPortAllocation()
|
||||
private val serverPort = portAllocation.nextPort()
|
||||
private val serverPort2 = portAllocation.nextPort()
|
||||
private val artemisPort = portAllocation.nextPort()
|
||||
@ -350,7 +355,8 @@ class ProtonWrapperTests {
|
||||
val connection2ID = CordaX500Name.build(connection2.remoteCert!!.subjectX500Principal)
|
||||
assertEquals("client 1", connection2ID.organisationUnit)
|
||||
val source2 = connection2.remoteAddress
|
||||
// Stopping one shouldn't disconnect the other
|
||||
|
||||
log.info("Stopping one shouldn't disconnect the other")
|
||||
amqpClient1.stop()
|
||||
val connection3 = connectionEvents.next()
|
||||
assertEquals(false, connection3.connected)
|
||||
@ -358,14 +364,16 @@ class ProtonWrapperTests {
|
||||
assertEquals(false, amqpClient1.connected)
|
||||
client2Connected.get(60, TimeUnit.SECONDS)
|
||||
assertEquals(true, amqpClient2.connected)
|
||||
// Now shutdown both
|
||||
|
||||
log.info("Now shutdown both")
|
||||
amqpClient2.stop()
|
||||
val connection4 = connectionEvents.next()
|
||||
assertEquals(false, connection4.connected)
|
||||
assertEquals(source2, connection4.remoteAddress)
|
||||
assertEquals(false, amqpClient1.connected)
|
||||
assertEquals(false, amqpClient2.connected)
|
||||
// Now restarting one should work
|
||||
|
||||
log.info("Now restarting one should work")
|
||||
val client1Connected = amqpClient1.onConnection.toFuture()
|
||||
amqpClient1.start()
|
||||
val connection5 = connectionEvents.next()
|
||||
@ -375,7 +383,8 @@ class ProtonWrapperTests {
|
||||
client1Connected.get(60, TimeUnit.SECONDS)
|
||||
assertEquals(true, amqpClient1.connected)
|
||||
assertEquals(false, amqpClient2.connected)
|
||||
// Cleanup
|
||||
|
||||
log.info("Cleanup")
|
||||
amqpClient1.stop()
|
||||
sharedThreads.shutdownGracefully()
|
||||
sharedThreads.terminationFuture().sync()
|
||||
|
@ -34,10 +34,7 @@ import net.corda.testing.driver.NodeParameters
|
||||
import net.corda.testing.driver.OutOfProcess
|
||||
import net.corda.testing.driver.driver
|
||||
import net.corda.testing.node.internal.FINANCE_CORDAPPS
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.core.config.Configurator
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.Semaphore
|
||||
@ -50,11 +47,6 @@ import kotlin.test.assertTrue
|
||||
|
||||
class KillFlowTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
Configurator.setLevel("net.corda.node.services.statemachine", Level.DEBUG)
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `a killed flow will end when it reaches the next suspension point`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) {
|
||||
|
@ -761,8 +761,14 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
val existingParticipants = ((((commonPredicates[predicateID]) as CompoundPredicate).expressions[0]) as InPredicate<*>)
|
||||
.values.map { participant -> (participant as LiteralExpression<*>).literal }
|
||||
log.warn("Adding new participants: $participants to existing participants: $existingParticipants")
|
||||
commonPredicates.replace(predicateID, criteriaBuilder.and(
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("x500Name").`in`(existingParticipants + participants)))
|
||||
commonPredicates.replace(
|
||||
predicateID,
|
||||
checkIfListIsEmpty(
|
||||
args = existingParticipants + participants,
|
||||
criteriaBuilder = criteriaBuilder,
|
||||
predicate = criteriaBuilder.and(getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("x500Name").`in`(existingParticipants + participants))
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
// Get the persistent party entity.
|
||||
@ -791,12 +797,18 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
val subQueryNotExists = criteriaQuery.subquery(Tuple::class.java)
|
||||
val subRoot = subQueryNotExists.from(VaultSchemaV1.PersistentParty::class.java)
|
||||
subQueryNotExists.select(subRoot.get("x500Name"))
|
||||
subQueryNotExists.where(criteriaBuilder.and(
|
||||
criteriaBuilder.equal(vaultStates.get<VaultSchemaV1.VaultStates>("stateRef"),
|
||||
subRoot.get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef"))),
|
||||
criteriaBuilder.not(subRoot.get<VaultSchemaV1.PersistentParty>("x500Name").`in`(exactParticipants)))
|
||||
val subQueryNotExistsPredicate = criteriaBuilder.and(criteriaBuilder.not(criteriaBuilder.exists(subQueryNotExists)))
|
||||
constraintPredicates.add(subQueryNotExistsPredicate)
|
||||
|
||||
//if the list of exact participants is empty, we return nothing with 1=0
|
||||
if (exactParticipants.isEmpty()) {
|
||||
constraintPredicates.add(criteriaBuilder.and(criteriaBuilder.equal(criteriaBuilder.literal(1), 0)))
|
||||
} else {
|
||||
subQueryNotExists.where(criteriaBuilder.and(
|
||||
criteriaBuilder.equal(vaultStates.get<VaultSchemaV1.VaultStates>("stateRef"),
|
||||
subRoot.get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef"))),
|
||||
criteriaBuilder.not(subRoot.get<VaultSchemaV1.PersistentParty>("x500Name").`in`(exactParticipants)))
|
||||
val subQueryNotExistsPredicate = criteriaBuilder.and(criteriaBuilder.not(criteriaBuilder.exists(subQueryNotExists)))
|
||||
constraintPredicates.add(subQueryNotExistsPredicate)
|
||||
}
|
||||
|
||||
// join with transactions for each matching participant (only required where more than one)
|
||||
if (exactParticipants.size > 1)
|
||||
|
@ -249,6 +249,27 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `returns zero states when exact participants list is empty`() {
|
||||
database.transaction {
|
||||
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP))
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP, BIG_CORP))
|
||||
|
||||
val criteria = VaultQueryCriteria(exactParticipants = emptyList())
|
||||
val results = vaultService.queryBy<ContractState>(criteria)
|
||||
assertThat(results.states).hasSize(0)
|
||||
|
||||
val criteriaWithOneExactParticipant = VaultQueryCriteria(exactParticipants = listOf(MEGA_CORP))
|
||||
val resultsWithOneExactParticipant = vaultService.queryBy<ContractState>(criteriaWithOneExactParticipant)
|
||||
assertThat(resultsWithOneExactParticipant.states).hasSize(1)
|
||||
|
||||
val criteriaWithMoreExactParticipants = VaultQueryCriteria(exactParticipants = listOf(MEGA_CORP, BIG_CORP))
|
||||
val resultsWithMoreExactParticipants = vaultService.queryBy<ContractState>(criteriaWithMoreExactParticipants)
|
||||
assertThat(resultsWithMoreExactParticipants.states).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `unconsumed base contract states for two participants`() {
|
||||
database.transaction {
|
||||
|
Loading…
x
Reference in New Issue
Block a user