diff --git a/.ci/dev/nightly-regression/Jenkinsfile b/.ci/dev/nightly-regression/Jenkinsfile index a122ea0fd3..a7f5d5ba17 100644 --- a/.ci/dev/nightly-regression/Jenkinsfile +++ b/.ci/dev/nightly-regression/Jenkinsfile @@ -23,51 +23,57 @@ pipeline { } stages { - stage('Corda Pull Request - Generate Build Image') { - steps { - 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}\" " + - "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + - " clean jar deployNodes install pushBuildImage --stacktrace" - } - sh "kubectl auth can-i get pods" - } + stage('Deploy Nodes') { + steps { + sh "./gradlew --no-daemon jar deployNodes" } + } - stage('Testing phase') { - parallel { - stage('Regression Test') { - steps { - sh "./gradlew " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + - " parallelRegressionTest --stacktrace" - } + stage('Generate Build Image') { + steps { + 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}\" " + + "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + + " clean pushBuildImage --stacktrace" + } + sh "kubectl auth can-i get pods" + } + } + + stage('Testing phase') { + parallel { + stage('Regression Test') { + steps { + sh "./gradlew " + + "-DbuildId=\"\${BUILD_ID}\" " + + "-Dkubenetize=true " + + "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + + "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + + "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + + "-Dgit.branch=\"\${GIT_BRANCH}\" " + + "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + + " parallelRegressionTest --stacktrace" } - stage('Slow Integration Test') { - steps { - sh "./gradlew " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + - " allParallelSlowIntegrationTest --stacktrace" - } + } + stage('Slow Integration Test') { + steps { + sh "./gradlew " + + "-DbuildId=\"\${BUILD_ID}\" " + + "-Dkubenetize=true " + + "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + + "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + + "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + + "-Dgit.branch=\"\${GIT_BRANCH}\" " + + "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + + " allParallelSlowIntegrationTest --stacktrace" } } } } + } post { diff --git a/.ci/dev/pr-code-checks/Jenkinsfile b/.ci/dev/pr-code-checks/Jenkinsfile index 0fdd5b0055..c74639b4f6 100644 --- a/.ci/dev/pr-code-checks/Jenkinsfile +++ b/.ci/dev/pr-code-checks/Jenkinsfile @@ -40,6 +40,12 @@ pipeline { sh ".ci/check-api-changes.sh" } } + + stage('Deploy Nodes') { + steps { + sh "./gradlew --no-daemon jar deployNodes" + } + } } post { diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index f5bc830757..995fd50f76 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -15,7 +15,7 @@ pipeline { } stages { - stage('Corda Pull Request - Generate Build Image') { + stage('Generate Build Image') { steps { withCredentials([string(credentialsId: 'container_reg_passwd', variable: 'DOCKER_PUSH_PWD')]) { sh "./gradlew " + @@ -23,7 +23,7 @@ pipeline { "-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " + "-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " + "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + - " clean jar deployNodes install pushBuildImage --stacktrace" + " clean preAllocateForParallelRegressionTest preAllocateForAllSlowIntegrationTest pushBuildImage --stacktrace" } sh "kubectl auth can-i get pods" } diff --git a/Jenkinsfile b/Jenkinsfile index 604235e193..ec5f32ee1d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { "-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " + "-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " + "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + - " clean jar deployNodes pushBuildImage preAllocateForAllParallelIntegrationTest preAllocateForAllParallelIntegrationTest --stacktrace" + " clean preAllocateForAllParallelUnitTest preAllocateForAllParallelIntegrationTest pushBuildImage --stacktrace" } sh "kubectl auth can-i get pods" } diff --git a/common/logging/src/main/kotlin/net/corda/common/logging/ExceptionsErrorCodeFunctions.kt b/common/logging/src/main/kotlin/net/corda/common/logging/ExceptionsErrorCodeFunctions.kt index a34e436bb8..3064fce1cc 100644 --- a/common/logging/src/main/kotlin/net/corda/common/logging/ExceptionsErrorCodeFunctions.kt +++ b/common/logging/src/main/kotlin/net/corda/common/logging/ExceptionsErrorCodeFunctions.kt @@ -32,8 +32,9 @@ fun Message.withErrorCodeFor(error: Throwable?, level: Level): Message { return when { error != null && level.isInRange(Level.FATAL, Level.WARN) -> { + val logMessage = this.formattedMessage val message = error.walkExceptionCausedByList().asSequence().mapNotNull(Throwable::message).joinToString(" - ") - CompositeMessage("$message [errorCode=${error.errorCode()}, moreInformationAt=${error.errorCodeLocationUrl()}]", format, parameters, throwable) + CompositeMessage("$logMessage - $message [errorCode=${error.errorCode()}, moreInformationAt=${error.errorCodeLocationUrl()}]", format, parameters, throwable) } else -> this } diff --git a/common/logging/src/test/kotlin/net/corda/commmon/logging/ExceptionsErrorCodeFunctionsTest.kt b/common/logging/src/test/kotlin/net/corda/commmon/logging/ExceptionsErrorCodeFunctionsTest.kt new file mode 100644 index 0000000000..45b44abedb --- /dev/null +++ b/common/logging/src/test/kotlin/net/corda/commmon/logging/ExceptionsErrorCodeFunctionsTest.kt @@ -0,0 +1,34 @@ +package net.corda.commmon.logging + +import com.natpryce.hamkrest.assertion.assertThat +import com.natpryce.hamkrest.contains +import net.corda.common.logging.withErrorCodeFor +import org.apache.logging.log4j.Level +import org.apache.logging.log4j.message.SimpleMessage +import org.junit.Test +import kotlin.test.assertEquals + +class ExceptionsErrorCodeFunctionsTest { + + @Test(timeout=3_000) + fun `error code for message prints out message and full stack trace`() { + val originalMessage = SimpleMessage("This is a test message") + var previous: Exception? = null + val throwables = (0..10).map { + val current = TestThrowable(it, previous) + previous = current + current + } + val exception = throwables.last() + val message = originalMessage.withErrorCodeFor(exception, Level.ERROR) + assertThat(message.formattedMessage, contains("This is a test message".toRegex())) + for (i in (0..10)) { + assertThat(message.formattedMessage, contains("This is exception $i".toRegex())) + } + assertEquals(message.format, originalMessage.format) + assertEquals(message.parameters, originalMessage.parameters) + assertEquals(message.throwable, originalMessage.throwable) + } + + private class TestThrowable(index: Int, cause: Exception?) : Exception("This is exception $index", cause) +} \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleEventsDistributor.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleEventsDistributor.kt index 7c2454c857..ee4d6f7be3 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleEventsDistributor.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleEventsDistributor.kt @@ -7,6 +7,8 @@ import net.corda.core.internal.concurrent.openFuture import net.corda.core.node.services.CordaServiceCriticalFailureException import net.corda.core.utilities.Try import net.corda.core.utilities.contextLogger +import net.corda.nodeapi.internal.persistence.contextDatabase +import net.corda.nodeapi.internal.persistence.contextDatabaseOrNull import java.io.Closeable import java.util.Collections.singleton import java.util.LinkedList @@ -93,7 +95,14 @@ class NodeLifecycleEventsDistributor : Closeable { log.warn("Not distributing $event as executor been already shutdown. Double close() case?") result.set(null) } else { + + val passTheDbToTheThread = contextDatabaseOrNull + executor.execute { + + if (passTheDbToTheThread != null) + contextDatabase = passTheDbToTheThread + val orderedSnapshot = if (event.reversedPriority) snapshot.reversed() else snapshot orderedSnapshot.forEach { log.debug("Distributing event $event to: $it")