ENT-5759 check for app schema migration (#6701)

* Fix behaviour for missing schema outside devMode plus test
This commit is contained in:
Christian Sailer 2020-09-14 11:25:18 +01:00 committed by GitHub
parent 7ec59da318
commit ea423215c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 3 deletions

View File

@ -242,6 +242,8 @@ dependencies {
slowIntegrationTestRuntime configurations.runtime
slowIntegrationTestRuntime configurations.testRuntime
integrationTestCompile(project(":testing:cordapps:missingmigration"))
testCompile project(':testing:cordapps:dbfailure:dbfworkflows')
}

View File

@ -3,10 +3,16 @@ package net.corda.node.persistence
import net.corda.core.utilities.getOrThrow
import net.corda.node.flows.isQuasarAgentSpecified
import net.corda.node.internal.ConfigurationException
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import net.corda.nodeapi.internal.persistence.HibernateSchemaChangeException
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.NodeParameters
import net.corda.testing.driver.driver
import net.corda.testing.node.TestCordapp
import org.junit.Test
import net.corda.testing.node.internal.startNode
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import kotlin.test.assertFailsWith
class DbSchemaInitialisationTest {
@ -19,4 +25,27 @@ class DbSchemaInitialisationTest {
}
}
@Test(timeout = 300_000)
fun `app migration resource is only mandatory when not in dev mode`() {
driver(DriverParameters(startNodesInProcess = true,
cordappsForAllNodes = emptyList(),
allowHibernateToManageAppSchema = false)) {
// in dev mode, it fails because the schema of our test CorDapp is missing
assertThatExceptionOfType(HibernateSchemaChangeException::class.java)
.isThrownBy {
startNode(NodeParameters(additionalCordapps = listOf(TestCordapp.findCordapp("net.corda.testing.missingmigrationcordapp")))).getOrThrow()
}
.withMessage("Incompatible schema change detected. Please run schema migration scripts (node with sub-command run-migration-scripts). Reason: Schema-validation: missing table [test_table]")
// without devMode, it doesn't even get this far as it complains about the schema migration missing.
assertThatExceptionOfType(CouldNotCreateDataSourceException::class.java)
.isThrownBy {
startNode(
ALICE_NAME,
false,
NodeParameters(additionalCordapps = listOf(TestCordapp.findCordapp("net.corda.testing.missingmigrationcordapp")))).getOrThrow()
}
.withMessage("Could not create the DataSource: No migration defined for schema: net.corda.testing.missingmigrationcordapp.MissingMigrationSchema v1")
}
}
}

View File

@ -469,9 +469,9 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
pendingCoreChanges = schemaMigration.getPendingChangesCount(schemaService.internalSchemas, true)
}
if(updateAppSchemas) {
schemaMigration.runMigration(!updateAppSchemasWithCheckpoints && haveCheckpoints, schemaService.appSchemas, false)
schemaMigration.runMigration(!updateAppSchemasWithCheckpoints && haveCheckpoints, schemaService.appSchemas, !configuration.devMode)
} else {
pendingAppChanges = schemaMigration.getPendingChangesCount(schemaService.appSchemas, false)
pendingAppChanges = schemaMigration.getPendingChangesCount(schemaService.appSchemas, !configuration.devMode)
}
}
// Now log the vendor string as this will also cause a connection to be tested eagerly.
@ -1023,7 +1023,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
database.startHikariPool(configuration.dataSourceProperties, metricRegistry) { dataSource, haveCheckpoints ->
SchemaMigration(dataSource, cordappLoader, configuration.baseDirectory, configuration.myLegalName)
.checkOrUpdate(schemaService.internalSchemas, runMigrationScripts, haveCheckpoints, true)
.checkOrUpdate(schemaService.appSchemas, runMigrationScripts, haveCheckpoints && !allowAppSchemaUpgradeWithCheckpoints, false)
.checkOrUpdate(schemaService.appSchemas, runMigrationScripts, haveCheckpoints && !allowAppSchemaUpgradeWithCheckpoints, !configuration.devMode)
}
/** Loads and starts a notary service if it is configured. */

View File

@ -101,6 +101,7 @@ include 'serialization-djvm:deserializers'
include 'serialization-tests'
include 'testing:cordapps:dbfailure:dbfcontracts'
include 'testing:cordapps:dbfailure:dbfworkflows'
include 'testing:cordapps:missingmigration'
// Common libraries - start
include 'common-validation'

View File

@ -0,0 +1,16 @@
apply plugin: 'kotlin'
//apply plugin: 'net.corda.plugins.cordapp'
//apply plugin: 'net.corda.plugins.quasar-utils'
dependencies {
compile project(":core")
}
jar {
baseName "testing-missingmigration-cordapp"
manifest {
// This JAR is part of Corda's testing framework.
// Driver will not include it as part of an out-of-process node.
attributes('Corda-Testing': true)
}
}

View File

@ -0,0 +1,24 @@
package net.corda.testing.missingmigrationcordapp
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table
object MissingMigrationSchema
object MissingMigrationSchemaV1 : MappedSchema(
schemaFamily = MissingMigrationSchema.javaClass,
version = 1,
mappedTypes = listOf(MissingMigrationSchemaV1.TestEntity::class.java)) {
@Entity
@Table(name = "test_table")
class TestEntity(
@Column(name = "random_value")
var randomValue: String
) : PersistentState() {
constructor() : this("")
}
}

View File

@ -0,0 +1,13 @@
package net.corda.testing.missingmigrationcordapp
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StartableByRPC
@StartableByRPC
@InitiatingFlow
class SimpleFlow : FlowLogic<Unit>() {
override fun call() {
logger.info("Running simple flow doing nothing")
}
}

View File

@ -0,0 +1,16 @@
package net.corda.testing.missingmigrationcordapp
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
class TestEntity(val randomValue: String, override val participants: List<AbstractParty>) : QueryableState {
override fun supportedSchemas(): Iterable<MappedSchema> {
return listOf(MissingMigrationSchemaV1)
}
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return MissingMigrationSchemaV1.TestEntity(randomValue)
}
}