What is this plugin ?

This plugin was developed to make a smoother integration testing which requires deployment on a virtual machine hosted by VMWare Server 1 or 2. For example, it could be used in a continuous integration that uses maven to compile, test and deploy. Since we were using Maven within Hudson, we had to make a plugin which helped us for complex testing.

This plugin is based on an Java API developed by Agaetis to manage a VMWare Server VM's. If you're interested in using it or participating in this project go to http://www.agaetis.fr/public/vmware-console . You can also send me an email to fmarchand [at] agaetis.fr.

How to use it ?

To use this plugin follow the next steps:

  • 1. Install the VIX API
  • First, you need to install the vix api on the computer which will process integration tests. The sub-project vmware-console needs the api to be installed to work. To download it please go to http://www.vmware.com/support/developer/vix-api/. When you'll install it you will probably need to add the location of some shared libraries in tour PATH. If you don't do it, you will obtain error messages such "cannot open shared library xxxxxx.so". In this case localize the library and modify your PATH. More details available in the introduction to use the Agaetis VMWare API. I strongly recommend you to read it to have a better understanding of how the maven plugin connect to the virtual machine.

  • 2. Add Agaetis public repository in your settings.xml:
  • Add those lines in your settings file (more frequently ~/.m2/settings.xml):
    <settings>
      ...  <repositories>
        ...    <repository>
            <id>agaetis.public</id>
            <name>Public Repository Agaetis</name>
            <url>http://www.agaetis.fr/nexus/content/repositories/releases/</url>
            <releases>
              <enabled>true</enabled>
            </releases>
            <snapshots>
              <enabled>true</enabled>
            </snapshots>
        </repository>
        ...  </repositories>
      ...  <pluginRepositories>
        ...    <pluginRepository>
            <id>agaetis.public</id>
            <name>Public Repository Agaetis</name>
            <url>http://www.agaetis.fr/nexus/content/repositories/releases/</url>
            <releases>
              <enabled>true</enabled>
            </releases>
            <snapshots>
              <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        ...  </pluginRepositories>
      ...</settings>
    and
    <pluginGroups>
       <pluginGroup>agaetis.public.maven-plugins</pluginGroup>
    </pluginGroups>

  • 3. Add dependency in your pom.xml (Optional):
  • Open your pom.xml and add those lines in the plugins section (in here, you will later add the parameters for the configuration):
    <plugins>
      ...    <plugin>
          <groupId>agaetis.public.maven-plugins</groupId>
          <artifactId>maven-vmware-plugin</artifactId>
          <version>X.X</version>
          <type>maven-plugin</type>
        </plugin>
      ...<plugins>
    Placing this in your pom.xml allows you to choose the version of the plugin you want to use; this can be useful if you want to avoid the possible bugs in a newer version.

Get down to business !

Once you've completed the steps above and finished your project, if you want to add a unit testing phase you would need to have a machine constantly on to deploy and undeploy your project during the test phase. But these involves some problems:

  • The application container maybe will crash with your application or something unexpected on the server machine could happen.
  • Also, the memory state could be altered and maybe it will affect the test execution, giving you inaccurate results.

The virtualization of machines can bring you an efficient and reliable alternative to unit testing on a physical machine.

So what is the plugin's main goal? Let's say you have a Linux virtual machine hosted by VMWare Server (a snapshot of this vm is available on the server) and you want to compile your project, as well as test locally some methods and services you developed, but you also need to test a webservice in the context of your Linux virtual machine. The solution will be to:

  • Revert the vm to the snapshot to be sure that everything was initialized correctly.
  • Wait for a signal that confirms you can communicate with the vm and all the required software for the test has started.
  • Proceed with testing
  • When tests are finished, shutdown the vm

This plugin offers goals that can be used for this kind of job.

For example to power on a virtual machine you can run :
mvn vmware:powerOn -DvixLibPath=./src/main/resources/libs 
                -DvmxFilepath=/remote/path/to/the/vmx/file -Dhost=192.168.x.x
                -Dusername=vmware_username -Dpassword=vmware_password -DwaitForTools=true
                -Dport=0 -DserviceProvider=10

In this example the parameters are :
  • vixLibPath: path where is located the VIX shared library (frequently called 'libvixAllProducts.so').
  • vmxFilepath: for VMWare Server 1.x : path on the remote vmware server of the vmx file for the virtual machine. If you are using VMWare Server 2, ESX or Workstation, this path needs to comply with a storage path format. ie: [standard] /Ubuntu/ubuntu.vmx where [standard] is the storage name for vm's, and /Ubuntu/ubuntu.vmx is the relative path to the target vm. If you have access to the web interface for VMWare Server 2.x, you can find this parameter clicking on the VM you want to know more about, and clicking on "Configure VM" on the right side. Then on the first tab "General" you'll find "Virtual Machine Configuration File". Just under this label, you have the complete name for your vm configuration file location to use here.
  • host : ip address or hostname where the vm is hosted. If the VMWare Server where is located the virtual machine you want to run is a version 2 then you need to provide here an URL with a specific structure. it has to be something like https://localhost:8333/sdk. Don't forget the "sdk" in the end of the URL. You can either use "http" or "https" for the protocol. It's up to you. check the Agaetis VMWare API to know more about that.
  • username : user that has sufficient credentials on the vm.
  • password : password for the user.
  • waitForTools : wait until the vmware tools have started.
  • port : port to use to communicate with the server. If it has to connect to a vmware server 2.x then you need to put this value to 0 like in the example. Otherwise it could be set to 902 for instance (default port for vmware server 1.X).
  • serviceProvider : remote server type. Informs the plugin with which kind of vmware server it has to talk to. Here are the values to use :
    • 2 : VMWare Server 1.x
    • 3 : VMWare Workstation (not tested yet)
    • 10 : VMWare Server 2.x
    In the previous example we informs the plugin that it will communicate with a VMWare Server 2.x (the value 10).
This was a simple example but when you want to do IT (Integration Test), the trick is to attach a goal to a phase of Maven. There are three important phases for this kind of test in Maven life cycle:
  • pre-integration-test : this is the phase where you will ask to a vm to start and to revert to snapshot.
  • integration-test : conduct your testing
  • post-integration-test : shutdown the vm, undeploy a project on the vm machine or power it off.
Therefore, you can expect positive results if you attach your tests to the integration-test, the preparation to pre-integration-test and the closing part to the post-integration-test.

Below you will find an example of execution attached to a phase:
<plugins>
 ... <plugin>
  <groupId>agaetis.public.maven-plugins</groupId>
  <artifactId>maven-vmware-plugin</artifactId>
  <version>1.0-SNAPSHOT</version>
  <executions>
   <execution>
     <id>pre-integration-test.revert</id>
     <phase>pre-integration-test</phase>
     <goals>
        <goal>revertToSnapshot</goal>
     </goals>
     <configuration>
        <vixLibPath>./src/main/resources/libs</vixLibPath>
        <username>vm_username</username>
        <password>vm_password</password>
        <host>192.168.x.x</host>
        <vmxFilepath>/path/to/vmx/file</vmxFilepath>
     </configuration>
   </execution>
  </executions>
 </plugin>
 ...</plugins>

Some tricks to configure IT with Maven 2

If you want to do Integration Test using JUnit, you need to move the test phase to the integration-test phase. Below are the lines you need to put in your pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <skip>true</skip>
  </configuration>
  <executions>
    <execution>
	 <id>surefire-it</id>
	 <phase>integration-test</phase>
	 <goals>
	   <goal>test</goal>
	 </goals>
	 <configuration>
	   <skip>false</skip>
	 </configuration>
    </execution>
  </executions>
</plugin>

You will also need to specify where are the JUnit java test files: put in the build section of your pom.xml these lines:

<testSourceDirectory>src/it/java</testSourceDirectory>
<testResources>
  <testResource>
    <filtering>false</filtering>
    <directory>src/it/resources</directory>
  </testResource>
</testResources>

NB : This is an example. So don't forget to put your test files in the same folder as specified above.

That's all folks !

If you need more explanations or have any suggestion on how to use this plugin, write me to fmarchand [at] agaetis.fr, or use the Team page to get my email.