Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration Test System Management #2310

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 18 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,22 @@ jobs:
integration-test:
name: Integration Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
testSystem:
- cockroachdb
- db2
- h2
- hsql
- mariadb
- mssql
- mysql
- oracle
- postgresql
- sqlite
needs: build
timeout-minutes: 30
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -177,17 +192,14 @@ jobs:
registry: docker-dev.artifactory.datical.net
username: ${{ secrets.ARTIFACTORY_USER }}
password: ${{ secrets.ARTIFACTORY_TOKEN }}
- name: Start Docker Databases
run: docker-compose -f ./liquibase-integration-tests/docker/docker-compose.yml up -d

- name: Run Tests
run: mvn -B jar:jar jar:test-jar surefire:test -DtrimStackTrace=false
- name: Stop Docker Databases
run: docker-compose -f ./liquibase-integration-tests/docker/docker-compose.yml down
run: mvn -B jar:jar jar:test-jar surefire:test -DtrimStackTrace=false -Dliquibase.sdk.testSystem.test=hub,${{ matrix.testSystem }}
- name: Archive Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: liquibase-test-results-integration
name: liquibase-test-results-integration-${{ matrix.testSystem }}
path: |
./**/target/surefire-reports

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ public interface ConfigurationValueConverter<DataType> {
}
};

ConfigurationValueConverter<String> STRING = value -> {
if (value == null) {
return null;
}

return String.valueOf(value);
};

ConfigurationValueConverter<Class> CLASS = value -> {
if (value == null) {
return null;
}

try {
return Class.forName(String.valueOf(value));
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Cannot instantiate "+value+": "+e.getMessage(), e);
}
};

/**
* Converts an arbitrary object into the correct type.
* Implementations should be able to handle <b>any</b> type passed them, often types by calling toString() on the incoming value and parsing the string.
Expand Down
30 changes: 30 additions & 0 deletions liquibase-core/src/main/java/liquibase/util/CollectionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,34 @@ public static <T> Set<T> createIfNull(Set<T> currentValue) {
}
}

/**
* Converts a set of nested maps (like from yaml/json) into a flat map with dot-seprated properties
*/
public static Map<String, Object> flatten(Map<String, Object> map) {
if (map == null) {
return null;
}

return flatten(null, map);

}

private static Map<String, Object> flatten(String prefix, Map<String, Object> map) {
Map<String, Object> outMap = new HashMap<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String propertyName = entry.getKey();
if (prefix != null) {
propertyName = prefix + "." + propertyName;
}

if (entry.getValue() instanceof Map) {
outMap.putAll(flatten(propertyName, (Map<String, Object>) entry.getValue()));
} else {
outMap.put(propertyName, entry.getValue());
}
}

return outMap;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,18 @@ class CollectionUtilTest extends Specification {
["a": 1, "b": 5, "c": 9], ["a": 2, "b": 5, "c": 9], ["a": 3, "b": 5, "c": 9],
["a": 1, "b": 6, "c": 9], ["a": 2, "b": 6, "c": 9], ["a": 3, "b": 6, "c": 9]]
}

@Unroll
def "flatten"() {
expect:
CollectionUtil.flatten(input as Map) == expected

where:
input | expected
null | null
[:] | [:]
[a: "a1", b: "b1"] | [a: "a1", b: "b1"]
[a: [a1: "a1a", "a2": "a2a"], b: "b1"] | ["a.a1": "a1a", "a.a2": "a2a", b: "b1"]
[a: [a1: "a1a", "a2": ["a2a": "a2a1", "a2b": "a2b1"]], b: "b1"] | ["a.a1": "a1a", "a.a2.a2a": "a2a1", "a.a2.a2b": "a2b1", b: "b1"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public File findCoreProjectRoot() throws URISyntaxException {
File thisClassFile = new File(uri);
return new File(thisClassFile.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile().getParentFile(), "liquibase-core");
}
uri = new URI(this.getClass().getClassLoader().getResource("liquibase/test/DatabaseTest.class").toExternalForm());
uri = new URI(this.getClass().getClassLoader().getResource("liquibase/dbtest/AbstractIntegrationTest.class").toExternalForm());
if(!uri.isOpaque()) {
File thisClassFile = new File(uri);
return new File(thisClassFile.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile().getParentFile(), "liquibase-core");
Expand Down
48 changes: 48 additions & 0 deletions liquibase-extension-testing/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,61 @@

<artifactId>liquibase-extension-testing</artifactId>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>1.16.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${project.version}</version>
</dependency>


<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mariadb</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mssqlserver</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>oracle-xe</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>cockroachdb</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>db2</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.5</version>
</dependency>

<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import liquibase.configuration.LiquibaseConfiguration
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.TestDatabaseConnections
import liquibase.extension.testing.TestFilter
import liquibase.extension.testing.setup.*
import liquibase.extension.testing.testsystem.DatabaseTestSystem
import liquibase.extension.testing.testsystem.TestSystemFactory
import liquibase.hub.HubService
import liquibase.hub.core.MockHubService
import liquibase.integration.commandline.LiquibaseCommandLineConfiguration
Expand Down Expand Up @@ -182,11 +183,11 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}
def "run"() {
setup:
Main.runningFromNewCli = true
Assume.assumeTrue("Skipping test: " + permutation.connectionStatus.errorMessage, permutation.connectionStatus.connection != null)
Assume.assumeTrue("Skipping test: " + permutation.testSetupEnvironment.errorMessage, permutation.testSetupEnvironment.connection != null)

def testDef = permutation.definition

Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(permutation.connectionStatus.connection))
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(permutation.testSetupEnvironment.connection))

//clean regular database
String defaultSchemaName = database.getDefaultSchemaName()
Expand All @@ -196,8 +197,8 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}

//clean alt database
Database altDatabase = null
if (permutation.connectionStatus.altConnection != null) {
altDatabase = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(permutation.connectionStatus.altConnection))
if (permutation.testSetupEnvironment.altConnection != null) {
altDatabase = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(permutation.testSetupEnvironment.altConnection))
String altDefaultSchemaName = altDatabase.getDefaultSchemaName()
CatalogAndSchema[] altCatalogAndSchemas = new CatalogAndSchema[1]
altCatalogAndSchemas[0] = new CatalogAndSchema(null, altDefaultSchemaName)
Expand All @@ -219,14 +220,14 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}

def runScope = new RunSettings(
database: database,
url: permutation.connectionStatus.url,
username: permutation.connectionStatus.username,
password: permutation.connectionStatus.password,
url: permutation.testSetupEnvironment.url,
username: permutation.testSetupEnvironment.username,
password: permutation.testSetupEnvironment.password,

altDatabase: altDatabase,
altUrl: permutation.connectionStatus.altUrl,
altUsername: permutation.connectionStatus.altUsername,
altPassword: permutation.connectionStatus.altPassword,
altUrl: permutation.testSetupEnvironment.altUrl,
altUsername: permutation.testSetupEnvironment.altUsername,
altPassword: permutation.testSetupEnvironment.altPassword,
)

def uiOutputWriter = new StringWriter()
Expand All @@ -242,7 +243,7 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}

if (testDef.setup != null) {
for (def setup : testDef.setup) {
setup.setup(permutation.connectionStatus)
setup.setup(permutation.testSetupEnvironment)
}
}

Expand Down Expand Up @@ -513,8 +514,13 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}
continue
}

permutation.connectionStatus = TestDatabaseConnections.getInstance().getConnection(database.shortName)
returnList.add(permutation)

def system = (DatabaseTestSystem) Scope.getCurrentScope().getSingleton(TestSystemFactory.class).getTestSystem(database.shortName)
if (system.shouldTest()) {
system.start(false)
permutation.testSetupEnvironment = new TestSetupEnvironment(system, null)
returnList.add(permutation)
}
}
}
}
Expand Down Expand Up @@ -768,7 +774,7 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"}
private static class RunTestPermutation {
RunTestDefinition definition
String databaseName
TestDatabaseConnections.ConnectionStatus connectionStatus
TestSetupEnvironment testSetupEnvironment

boolean shouldRun() {
def filter = TestFilter.getInstance()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@ import liquibase.change.Change
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.TestDatabaseConnections

import java.util.List

class SetupAltDatabaseStructure extends SetupDatabaseStructure {

SetupAltDatabaseStructure(List<Change> changes) {
super(changes)
}

protected Database getDatabase(TestDatabaseConnections.ConnectionStatus connectionStatus) {
if (connectionStatus.altConnection == null) {
@Override
protected Database getDatabase(TestSetupEnvironment testSetupEnvironment) {
if (testSetupEnvironment.altConnection == null) {
throw new RuntimeException("No alt database configured")
}
return DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connectionStatus.altConnection))
return DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(testSetupEnvironment.altConnection))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import liquibase.changelog.ChangeLogHistoryServiceFactory
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.TestDatabaseConnections
import liquibase.integration.commandline.CommandLineResourceAccessor
import liquibase.resource.CompositeResourceAccessor
import liquibase.resource.FileSystemResourceAccessor
Expand All @@ -22,8 +21,8 @@ class SetupChangeLogSync extends TestSetup {
}

@Override
void setup(TestDatabaseConnections.ConnectionStatus connectionStatus) throws Exception {
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connectionStatus.connection))
void setup(TestSetupEnvironment testSetupEnvironment) throws Exception {
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(testSetupEnvironment.connection))

final ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database)
changeLogService.init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import liquibase.changelog.RanChangeSet
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.TestDatabaseConnections

class SetupChangelogHistory extends TestSetup {

Expand All @@ -18,8 +17,8 @@ class SetupChangelogHistory extends TestSetup {
}

@Override
void setup(TestDatabaseConnections.ConnectionStatus connectionStatus) throws Exception {
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connectionStatus.connection))
void setup(TestSetupEnvironment testSetupEnvironment) throws Exception {
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(testSetupEnvironment.connection))

final ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database)
changeLogService.init()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
package liquibase.extension.testing.setup

import liquibase.Contexts
import liquibase.LabelExpression
import liquibase.Liquibase
import liquibase.changelog.ChangeLogHistoryService
import liquibase.changelog.ChangeLogHistoryServiceFactory
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.TestDatabaseConnections
import liquibase.integration.commandline.CommandLineResourceAccessor
import liquibase.resource.CompositeResourceAccessor
import liquibase.resource.FileSystemResourceAccessor

import java.nio.file.Paths

class SetupCleanResources extends TestSetup {

private final List<String> resourcesToDelete = new ArrayList<>()
Expand All @@ -24,7 +9,7 @@ class SetupCleanResources extends TestSetup {
}

@Override
void setup(TestDatabaseConnections.ConnectionStatus connectionStatus) throws Exception {
void setup(TestSetupEnvironment testSetupEnvironment) throws Exception {
for (String fileToDelete : resourcesToDelete) {
URL url = Thread.currentThread().getContextClassLoader().getResource(fileToDelete)
if (url == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package liquibase.extension.testing.setup

import liquibase.extension.testing.TestDatabaseConnections

import liquibase.util.FileUtil

class SetupCreateTempResources extends TestSetup {
Expand All @@ -14,7 +14,7 @@ class SetupCreateTempResources extends TestSetup {
}

@Override
void setup(TestDatabaseConnections.ConnectionStatus connectionStatus) throws Exception {
void setup(TestSetupEnvironment testSetupEnvironment) throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource(originalFile)
File f = new File(url.toURI())
String contents = FileUtil.getContents(f)
Expand Down