Newer
Older
GitBucket / src / test / scala / gitbucket / core / GitBucketCoreModuleSpec.scala
package gitbucket.core

import java.sql.DriverManager
import java.time.Duration
import java.time.temporal.ChronoUnit.SECONDS

import com.dimafeng.testcontainers.GenericContainer
import io.github.gitbucket.solidbase.Solidbase
import io.github.gitbucket.solidbase.model.Module
import liquibase.database.core.{H2Database, MySQLDatabase, PostgresDatabase}
import org.junit.runner.Description
import org.scalatest.{FunSuite, Tag}
import org.testcontainers.containers.ContainerLaunchException
import org.testcontainers.containers.wait.strategy.{HostPortWaitStrategy, Wait}

object ExternalDBTest extends Tag("ExternalDBTest")

class GitBucketCoreModuleSpec extends FunSuite {

  test("Migration H2") {
    new Solidbase().migrate(
      DriverManager.getConnection("jdbc:h2:mem:test", "sa", "sa"),
      Thread.currentThread().getContextClassLoader(),
      new H2Database(),
      new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
    )
  }

  implicit private val suiteDescription = Description.createSuiteDescription(getClass)

  test("Migration MySQL 5.7", ExternalDBTest) {
    val container = GenericContainer(
      "mysql:5.7",
      env = Map("MYSQL_ROOT_PASSWORD" -> "my-secret-pw", "MYSQL_DATABASE" -> "gitbucket"),
      waitStrategy = new HostPortWaitStrategy {
        override def waitUntilReady(): Unit = {
          super.waitUntilReady()

          def readyForConnections(retry: Int = 0): Boolean = {
            var con: java.sql.Connection = null
            try {
              con = DriverManager.getConnection(
                s"jdbc:mysql://${waitStrategyTarget.getContainerIpAddress}:${waitStrategyTarget.getMappedPort(3306)}/gitbucket?useSSL=false",
                "root",
                "my-secret-pw"
              )
              con.createStatement().execute("SELECT 1")
            } catch {
              case _: Exception if retry < 3 =>
                Thread.sleep(10000)
                readyForConnections(retry + 1)
              case _: Exception => false
            } finally {
              Option(con).foreach(_.close())
            }
          }

          if (!readyForConnections()) throw new ContainerLaunchException("Timed out")
        }
      }
    )

    container.starting()
    try {
      new Solidbase().migrate(
        DriverManager.getConnection(
          s"jdbc:mysql://${container.containerIpAddress}:${container.mappedPort(3306)}/gitbucket?useSSL=false",
          "root",
          "my-secret-pw"
        ),
        Thread.currentThread().getContextClassLoader(),
        new MySQLDatabase(),
        new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
      )
    } finally {
      container.finished()
    }
  }

  test("Migration PostgreSQL 11", ExternalDBTest) {
    val container = GenericContainer(
      "postgres:11",
      env = Map("POSTGRES_PASSWORD" -> "mysecretpassword", "POSTGRES_DB" -> "gitbucket"),
      waitStrategy = Wait
        .forLogMessage(".*database system is ready to accept connections.*\\s", 2)
        .withStartupTimeout(Duration.of(60, SECONDS))
    )

    container.starting()
    try {
      new Solidbase().migrate(
        DriverManager.getConnection(
          s"jdbc:postgresql://${container.containerIpAddress}:${container.mappedPort(5432)}/gitbucket",
          "postgres",
          "mysecretpassword"
        ),
        Thread.currentThread().getContextClassLoader(),
        new PostgresDatabase(),
        new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
      )
    } finally {
      container.finished()
    }
  }

  test("Migration PostgreSQL 10", ExternalDBTest) {
    val container = GenericContainer(
      "postgres:10",
      env = Map("POSTGRES_PASSWORD" -> "mysecretpassword", "POSTGRES_DB" -> "gitbucket"),
      waitStrategy = Wait
        .forLogMessage(".*database system is ready to accept connections.*\\s", 2)
        .withStartupTimeout(Duration.of(60, SECONDS))
    )

    container.starting()
    try {
      new Solidbase().migrate(
        DriverManager.getConnection(
          s"jdbc:postgresql://${container.containerIpAddress}:${container.mappedPort(5432)}/gitbucket",
          "postgres",
          "mysecretpassword"
        ),
        Thread.currentThread().getContextClassLoader(),
        new PostgresDatabase(),
        new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
      )
    } finally {
      container.finished()
    }
  }

}