mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
ENT-5759 check for app schema migration (#6701)
* Fix behaviour for missing schema outside devMode plus test
This commit is contained in:
parent
7ec59da318
commit
ea423215c2
@ -242,6 +242,8 @@ dependencies {
|
||||
slowIntegrationTestRuntime configurations.runtime
|
||||
slowIntegrationTestRuntime configurations.testRuntime
|
||||
|
||||
integrationTestCompile(project(":testing:cordapps:missingmigration"))
|
||||
|
||||
testCompile project(':testing:cordapps:dbfailure:dbfworkflows')
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
@ -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. */
|
||||
|
@ -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'
|
||||
|
16
testing/cordapps/missingmigration/build.gradle
Normal file
16
testing/cordapps/missingmigration/build.gradle
Normal 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)
|
||||
}
|
||||
}
|
@ -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("")
|
||||
}
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user