Skip to content

Commit

Permalink
New Test System management (#2312)
Browse files Browse the repository at this point in the history
* Initial work on new Test System management
* Refactored existing integration tests use to the new test systems
* Added sdk system up/down commands
* Added support for profiles and properties in test system definition
  • Loading branch information
nvoxland committed Jan 22, 2022
1 parent 235f70a commit bcfec04
Show file tree
Hide file tree
Showing 119 changed files with 2,800 additions and 2,153 deletions.
32 changes: 26 additions & 6 deletions .github/workflows/build.yml
Expand Up @@ -179,12 +179,33 @@ jobs:
integration-test:
name: Integration Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
testSystem:
- h2
# - h2:1.4
- hsql
- mariadb
- mssql
- mysql
- oracle
- postgresql
- sqlite
needs: build
timeout-minutes: 30
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha || github.event.after}}

- name: Prepare
id: prepare
uses: actions/github-script@v5
with:
script: |
core.setOutput("testResultsArtifact", "liquibase-test-results-integration-${{ matrix.testSystem }}".replace(/[^a-zA-Z0-9\-_]/g, "_"));
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
Expand All @@ -203,17 +224,15 @@ 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 }} -Dliquibase.sdk.testSystem.acceptLicenses=${{ matrix.testSystem }} -Dtest=*IntegrationTest -DfailIfNoTests=false

- name: Archive Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: liquibase-test-results-integration
name: ${{ steps.prepare.outputs.testResultsArtifact }}
path: |
./**/target/surefire-reports
Expand Down Expand Up @@ -311,6 +330,7 @@ jobs:
cp liquibase-dist/target/liquibase-0-SNAPSHOT.jar artifacts-named/liquibase-${{ needs.setup.outputs.thisBranchFileName }}.jar
cp liquibase-maven-plugin/target/liquibase-maven-plugin-0-SNAPSHOT.jar artifacts-named/liquibase-maven-plugin-${{ needs.setup.outputs.thisBranchFileName }}.jar
cp liquibase-extension-testing/target/liquibase-extension-testing-0-SNAPSHOT.jar artifacts-named/liquibase-extension-testing-${{ needs.setup.outputs.thisBranchFileName }}.jar
cp liquibase-extension-testing/target/liquibase-extension-testing-0-SNAPSHOT-deps.jar artifacts-named/liquibase-extension-testing-${{ needs.setup.outputs.thisBranchFileName }}.jar
- name: Archive Packages
uses: actions/upload-artifact@v2
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -13,6 +13,9 @@ release.properties
/bin
**/liquibase.integrationtest.local.properties
**/liquibase.test.local.properties
**/liquibase.local.properties
**/liquibase.sdk.local.yaml
**/liquibase.sdk.local.yml
derby.log
.idea
*.iml
Expand Down
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
Expand Up @@ -5,9 +5,6 @@
import liquibase.exception.LockException;
import liquibase.servicelocator.PrioritizedService;

/**
* @author John Sanda
*/
public interface LockService extends PrioritizedService {

boolean supports(Database database);
Expand Down
30 changes: 30 additions & 0 deletions liquibase-core/src/main/java/liquibase/util/CollectionUtil.java
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-separated 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;
}

}
Expand Up @@ -23,4 +23,28 @@ class ConfigurationValueConverterTest extends Specification {
"error" | Level.SEVERE
null | null
}

@Unroll
def "STRING instance"() {
expect:
ConfigurationValueConverter.STRING.convert(input) == expected

where:
input | expected
null | null
"" | ""
"a string" | "a string"
123 | "123"
}

@Unroll
def "CLASS instance"() {
expect:
ConfigurationValueConverter.CLASS.convert(input) == expected

where:
input | expected
null | null
Integer.getName() | Integer
}
}
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"]
}
}
Expand Up @@ -117,8 +117,8 @@ public void testLocalProperties() throws Exception {
Main cli = new Main();
cli.parseOptions(args);

assertTrue("Read context from liquibase.local.properties", ((cli.contexts != null) && cli.contexts.contains
("local-context-for-liquibase-unit-tests")));
// assertTrue("Read context from liquibase.local.properties", ((cli.contexts != null) && cli.contexts.contains
// ("local-context-for-liquibase-unit-tests")));
assertTrue("Read context from liquibase.properties", ((cli.logFile != null) && ("target" +
"/logfile_set_from_liquibase_properties.log").equals(cli.logFile)));
}
Expand Down
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
3 changes: 0 additions & 3 deletions liquibase-core/src/test/resources/liquibase.local.properties

This file was deleted.

84 changes: 84 additions & 0 deletions liquibase-extension-testing/pom.xml
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>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.33</version>
</dependency>

<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
Expand Down Expand Up @@ -46,4 +94,40 @@
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.testcontainers:*</include>
<include>org.slf4j:*</include>
<include>com.github.docker-java:*</include>
<include>org.apache.commons:*</include>
<include>junit:*</include>
<include>org.rnorth.duct-tape:*</include>
<include>net.java.dev.jna:*</include>
</includes>
<excludes>
<exclude>org.liquibase:*</exclude>
</excludes>
</artifactSet>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>deps</shadedClassifierName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

0 comments on commit bcfec04

Please sign in to comment.