adding a simple test to hedge against existing sql migration files (#943)

* simple test to hedge against existing sql migration files

* copyright

* adding better failure message

* adding intructions on generating the digest file
This commit is contained in:
Gabor Aranyossy 2019-05-06 17:34:56 +02:00 committed by GitHub
parent d77384bcb6
commit dd1ac5067b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 1 deletions

View File

@ -0,0 +1 @@
151c783c3f472552b64eeacee929c21d9fc16b27ca591a1a07020337f993178b

View File

@ -10,12 +10,13 @@ import org.slf4j.LoggerFactory
import scala.util.control.NonFatal
class FlywayMigrations(ds: DataSource) {
import FlywayMigrations._
private val logger = LoggerFactory.getLogger(getClass)
def migrate(): Unit = {
try {
val flyway = Flyway.configure().dataSource(ds).load()
val flyway = configurationBase.dataSource(ds).load()
logger.info(s"running Flyway migration..")
val stepsTaken = flyway.migrate()
logger.info(s"Flyway schema migration finished successfully applying ${stepsTaken} steps.")
@ -31,5 +32,8 @@ class FlywayMigrations(ds: DataSource) {
}
object FlywayMigrations {
val configurationBase = Flyway.configure()
def apply(ds: DataSource): FlywayMigrations = new FlywayMigrations(ds)
}

View File

@ -0,0 +1,58 @@
// Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.digitalasset.platform.sandbox.stores.ledger.sql.migration
import java.math.BigInteger
import java.security.MessageDigest
import com.digitalasset.platform.sandbox.stores.ledger.sql.migration.FlywayMigrations.configurationBase
import org.flywaydb.core.internal.resource.LoadableResource
import org.flywaydb.core.internal.scanner.Scanner
import org.scalatest.{Matchers, WordSpec}
import scala.collection.JavaConverters._
// SQL MIGRATION AND THEIR DIGEST FILES SHOULD BE CREATED ONLY ONCE AND NEVER CHANGED AGAIN,
// OTHERWISE MIGRATIONS BREAK ON EXISTING DEPLOYMENTS!
@SuppressWarnings(Array("org.wartremover.warts.Any", "org.wartremover.warts.StringPlusAny"))
class FlywayMigrationsSpec extends WordSpec with Matchers {
private val digester = MessageDigest.getInstance("SHA-256")
private val resourceScanner = new Scanner(
configurationBase.getLocations.toList.asJava,
getClass.getClassLoader,
configurationBase.getEncoding
)
"Flyway migration files" should {
"always have a valid SHA-256 digest file accompanied" in {
resourceScanner
.getResources("", ".sql")
.asScala
.map { res =>
val fileName = res.getFilename
val expectedDigest = getExpectedDigest(fileName, fileName.dropRight(4) + ".sha256")
val currentDigest = getCurrentDigest(res)
assert(
currentDigest == expectedDigest,
s"Digest of migration file $fileName has changed! It is NOT allowed to change neither existing sql migrations files nor their digests!"
)
}
}
}
private def getExpectedDigest(sourceFile: String, digestFile: String) =
new String(Option(resourceScanner.getResource(digestFile))
.getOrElse(sys.error(
s"Missing sha-256 file $digestFile! Are you introducing a new Flyway migration step? You need to create a sha-256 digest file by running this under the db/migration folder: shasum -a 256 $sourceFile | awk '{print $$1}' > $digestFile"))
.loadAsBytes())
private def getCurrentDigest(res: LoadableResource) = {
val digest = digester.digest(res.loadAsBytes())
val bi = new BigInteger(1, digest)
(String.format("%0" + (digest.length << 1) + "X", bi) + "\n").toLowerCase
}
}