5

I made some unit-tests using fest, now I need to run mvn my test using maven on a headless system. I would like to run test using Xvfb but I need help to configure maven to start Xvfb before testing and stop it when all is done.

Alepac
  • 1,833
  • 13
  • 24

3 Answers3

3

With the exec-maven-plugin:

You'll have to define two executions, one for starting your server and one for stopping it. You'll have to tie those execution configurations with the appropriate maven phase -- start the Xvfb before your test phase, and stop Xvfb after your test phase.

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>

            <executions>
                <execution>
                    <id>exec-at-test-compile</id>
                    <phase>test-compile</phase> <!-- runs right before 'test' -->
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>/home/anew/bin/manage-xvfb.sh</executable>
                        <arguments>
                            <argument>start</argument>
                        </arguments>
                    </configuration>
                </execution>
                <execution>
                    <id>exec-at-prepare-package</id>
                    <phase>prepare-package</phase> <!-- runs right after 'test' -->
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>/home/anew/bin/manage-xvfb.sh</executable>
                        <arguments>
                            <argument>stop</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Here is the content of the manage-xvfb.sh script:

#!/bin/bash

XVFB_CMD="sudo /usr/bin/Xvfb :15 -ac -screen 0 1024x768x8"

function stop_xvfb {
  XVFB_PID=`ps ax | pgrep "Xvfb"`
  if [ "${XVFB_PID}" != "" ]; then
    sudo kill ${XVFB_PID}
  fi
}

if [ "${1}" == "start" ]; then
  stop_xvfb
  ${XVFB_CMD} &
elif [ "${1}" == "stop" ]; then
  stop_xvfb
fi 

Note that you'll need to have NOPASSWD set in your sudoers file.

Anew
  • 5,175
  • 1
  • 24
  • 36
  • I have 2 problems here: 1st) executing Xvfb maven waits for process termination (we need a way to run it in background, probably running a shell script that call Xvfb :1 &); 2nd) the prepare-package phase isn't executed if some test fails so Xvfb keeps running. – Alepac Feb 05 '13 at 06:29
  • 1) Create a shell script that a) checks if Xvfb is still running from a prior test run -- if it is, kill it. You'll need to do something like `kill \`ps axuf | pgrep Xvfb\`` to kill it. And b) Starts Xvfb if it isn't running with the `&` operator at the end of the line so that your shell script can exit but will leave Xvfb running asynchronously, like this: `/usr/X11R6/bin/Xvfb :15 -ac -screen 0 1024x768x8 &` – Anew Feb 05 '13 at 10:22
  • I've updated my example to show you what I mean. Hope it helps. – Anew Feb 05 '13 at 16:11
1

Actually I use this plugin configuration:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>start-xvfb</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo message="Starting xvfb ..." />
                    <exec executable="Xvfb" spawn="true">
                        <arg value=":1" />
                    </exec>
                </tasks>
            </configuration>
        </execution>
        <execution>
            <id>shutdown-xvfb</id>
            <phase>test</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo message="Ending xvfb ..." />
                    <exec executable="killall">
                            <arg value="Xvfb" />
                    </exec>
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>

The good is that you get a background process (with spawn = "true") and you can kill the Xvfb process (with killall) without having to write any script. Moreover in my Ubuntu distro I don't hav to set any special setting in my sudoers file to let this works.

The shutdown-xvfb execution is executed at the end of the test phase but (here is the problem) is not executed if the test fail. This is not a problem if you want to restart another test (the old Xvfb is still running and the new one can't run, but this is not a problem) but the problem is that the resources are still busy by Xvfb. A workaround for this could be to add testFailureIgnore = "true" to the configuration of maven-surefire-plugin but this way I can't easily see if some test fail.

Alepac
  • 1,833
  • 13
  • 24
  • That works too. Curious, why don't you just add `` before starting `Xvfb` in your `start-xvfb` execution? Or are you mostly concerned about *not* leaving Xvfb running for another (boy-scout-campsite) reason? Alternatively using a CI environment like [Jenkins](http://jenkins-ci.org/) it's trivial to trigger other builds on failures (ie. a "Stop Xvfb" build). – Anew Feb 07 '13 at 05:15
  • @Anew I simply don't add the killall before starting because in my environment I don't have any errors (if there was another instance yet the second is simply not started) but I would like to stop it at the end to have always a clean environment (I use this pc even for other tasks). Thanks for the suggestion using [Jenkins](http://jenkins-ci.org/) / [Hudson](http://hudson-ci.org/) or other CI environment, I've programmed to setup such a thing as soon as I have time to learn how to do that. – Alepac Feb 07 '13 at 08:29
0

This job can easily be done via the selenium-maven-plugin:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>selenium-maven-plugin</artifactId>

  <executions>
    <execution>
      <id>setup-xvfb</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>xvfb</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Unfortunately, this plugin seems quite unmaintained. It was part of the mojohaus project which recently migrated from codehaus.org to github.com. It seems no one has yet ported the selenium-maven-plugin to github and thus sources and documentation is currently not available on mojohaus' github page.

However, the JARs are available on Maven Central and the plugin can still be used. There is a fork of the sources and site available on github here, if you need to lookup some more configuration parameters.

Martin Höller
  • 2,714
  • 26
  • 44