Fork me on GitHub

Integration tests

The aim here is to combine the usage of the cassandra-maven-plugin with the maven-failsafe-plugin to allow the integration tests to be run against a test instance of Apache Cassandra. The developer does not have to manually install Cassandra.

First we need to modify the pom.xml to reference both cassandra-maven-plugin and the maven-failsafe-plugin

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>2.7.1</version>
        <executions>
          <execution>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>cassandra-maven-plugin</artifactId>
        <version>4.0.0</version>
        <executions>
          <execution>
            <goals>
              <goal>start</goal>
              <goal>stop</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

This will result in the following mojos being executed during the lifecycle as follows:

Phase Goal(s)
pre-integration-test cassandra:start
integration-test failsafe:integration-test
post-integration-test cassandra:stop
verify failsafe:verify

If you want the tests to be more independent, you can leverage the build-helper-maven-plugin to allocate random ports to your tests, thereby ensuring that the tests don't fail if a port is in use, and allowing, e.g. parallel builds on a build server.

For example (Note this example assumes you use resource filtering to pass the cassandra ports through to the tests, you could also pass them through as system properties by configuring maven-failsafe-plugin):

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.5</version>
        <executions>
          <execution>
            <id>reserve-network-port</id>
            <goals>
              <goal>reserve-network-port</goal>
            </goals>
            <phase>process-test-resources</phase>
            <configuration>
              <portNames>
                <portName>cassandra.nativeTransportPort</portName>
                <portName>cassandra.jmxPort</portName>
                <portName>cassandra.storagePort</portName>
              </portNames>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>2.7.1</version>
        <executions>
          <execution>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>cassandra-maven-plugin</artifactId>
        <version>4.0.0</version>
        <executions>
          <execution>
            <goals>
              <goal>start</goal>
              <goal>stop</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

Local clusters

To use a local cluster, you just change the start and stop goals to start-cluster and stop-cluster respectively.

Note: On OS-X you will need to enable the local loop back aliases before you can run a cluster. One way to do this is to use the command

ifconfig lo0 alias 127.0.0.2

These aliases are not persisted across reboots.

Port usage

As well as the standard Cassandra ports, the Maven plugin also opens a stop port (defaults to 8081) in order to allow the Cassandra service(s) to be shut down cleanly. If the default stop port is used by your tests, or is already in use on your system then you might need to change that default.

The best designed builds will use something like build-helper:reserve-network-port to allocate ports.

Multi JVM use

To use JDK8 with Cassandra Server 3.x in combination with Failsafe integration tests you need to use Toolchains. First we need to configure some Toolchains with Maven. Making the more recent the default for your project. See the Toolchains Plugin for instructions.

Additionally add another execution to Toolchains. To set JDK8 during the maven-failsafe-plugin pre-integration-test phase

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-toolchains-plugin</artifactId>
 <version>3.0.0</version>
 <executions>
   <execution>
     <id>default-pre-integration-test</id>
     <phase>pre-integration-test</phase>
     <goals>
       <goal>toolchain</goal>
     </goals>
     <configuration>
       <toolchains>
         <jdk>
           <version>1.8</version>
           <vendor>OpenJDK</vendor>
         </jdk>
       </toolchains>
     </configuration>
   </execution>
 </executions>
</plugin>

Finally override the toolchain assigned during pre-integration-test phase. So that the integration-test phase executes with the intended more recent JDK.

<plugin>
 <artifactId>maven-failsafe-plugin</artifactId>
 <configuration>
   <jvm>/usr/lib/jvm/java-11-openjdk/bin/java</jvm>
 </configuration>
</plugin>

This will result in the following during the lifecycle

Phase Goal(s) JDK
pre-integration-test cassandra:start 8
integration-test failsafe:integration-test 11
post-integration-test cassandra:stop 8
verify failsafe:verify 11

Trademarks

Apache, Apache Maven, Apache Cassandra, Maven, Cassandra and the Apache feather logo are trademarks of The Apache Software Foundation.