2

I'm trying to come up with a parallel maven test execution for integration tests.

Using sql-maven-plugin to create a test database before test execution starts, in conjunction with maven surefire plugin parameters and parallel execution, seems like a good approach to start with.

What I'm failing to understand is how to use the system properties that the surefire plugin sets, with sql-maven-plugin (or any other plugins for that matter). I have a setup that fails on this.

surefire plugin configuration:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <forkCount>2</forkCount>
        <reuseForks>true</reuseForks>
        <argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
        <systemPropertyVariables>
            <databaseSchema>test_schema_${surefire.forkNumber}</databaseSchema>
        </systemPropertyVariables>
    </configuration>
</plugin>

sql-maven-plugin configuration:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>sql-maven-plugin</artifactId>
    <version>1.5</version>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector-java.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <driver>com.mysql.jdbc.Driver</driver>
        <username>user_with_create_privs</username>
        <password>password</password>
        <url>jdbc:mysql://localhost/dummy_schema</url>
    </configuration>
    <executions>
        <execution>
            <id>create-db</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <url>jdbc:mysql://localhost/dummy_schema</url>
                <autocommit>true</autocommit>
                <sqlCommand>create database ${databaseSchema}</sqlCommand>
            </configuration>
        </execution>
    </executions>
</plugin>

shell execution:

mvn test

result output:

[DEBUG] SQL:  drop database ${databaseSchema}
[ERROR] Failed to execute:  drop database ${databaseSchema}
[ERROR] Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute
(create-db) on project billing-core: You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for the right
syntax to use near '{databaseSchema}' at line 1 -> [Help 1]

So, looks like ${databaseSchema} is not populated, or a syntax problem. I've fiddled, but cannot get this working although it looks like it's easy and should.

Wrench
  • 4,070
  • 4
  • 34
  • 46
  • For integration tests, you should have a look at the Maven failsafe plugin. – J Fabian Meier Mar 07 '17 at 14:15
  • 1
    Surefire's `systemPropertyVariables` will set a system property when creating the JVM executing the tests. Obviously, when Maven tries to execute the sql-maven-plugin, that property is not a property set for the Maven project. – Tome Mar 07 '17 at 14:22
  • @Tome So basically sql-maven-plugin and surefire plugin are not compatible in the way I want them to be? – Wrench Mar 07 '17 at 14:27
  • 1
    Indeed, in your use case, surefire plugin would set that property after the sql-maven-plugin needs it. And moreover, it would set it for another JVM. A Java-centric solution would be to execute the statements in your tests code, in a @BeforeClass method (or something similar), that would retrieve the system property to create the appropriate statement. – Tome Mar 07 '17 at 15:49
  • @Tome Thanks for the elaboration. I have now implemented an abstract class for db-dependent tests to extend, that handles hibernate bootstrapping and using, if available, the system property set by surefire to create unique schema names for each fork. Extends RunListener class from JUnit to trigger bootstrapping and dropping on JUnit events before and after tests. Almost there, will test, then update. – Wrench Mar 07 '17 at 23:58

1 Answers1

2

You may be confusing Maven's properties, Java system properties, and environment variables. The variables that you appear to wish to use look like Maven properties.

You can define properties in your POM within a properties element. In addition, you can reference environment variables using the ${env.PropertyName} form, and Java system properties using the ${java.PropertyName} form.

You can refer to this for more info: https://maven.apache.org/pom.html#Properties

Michael Peacock
  • 2,011
  • 1
  • 11
  • 14
  • You are correct, I was. As mentioned in a comment to my question, I've started another approach which gives more implementation work, but should atleast work in theory, compared to that in my question. Thanks for your answer. – Wrench Mar 08 '17 at 00:00