Skip navigation
2013

Celebrating a public holiday in middle of the week finally gave me some extra time to play around with OpenShift.

 

If you are just starting with Arquillian to test persistence this article might come in handy:

http://arquillian.org/guides/testing_java_persistence/

 

Use Arquillian to test directly in OpenShift

You can use Arquillian to test your application directly in OpenShift. Lets go through the common issues and how to get around them.

 

You need to treat OpenShift's AS instance as remote container. In your projects pom.xml add a dependency to jboss-as-arquillian-container-remote:

 

        <dependency>
            <groupId>org.jboss.as</groupId>
            <artifactId>jboss-as-arquillian-container-remote</artifactId>
            <scope>test</scope>
        </dependency>

 

(just use parent's pom dependency management take care of the version)

 

If you try to run this configuration while running rhc client tool port forwarding you will run into the following exception (pasting here if anyone is googling for it):

 

May 08, 2013 3:53:24 PM org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate$1 call
WARNING: Exception encountered during export of archive
org.jboss.shrinkwrap.api.exporter.ArchiveExportException: Failed to write asset to output: /junit/extensions/TestDecorator.class
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase$3.handle(StreamExporterDelegateBase.java:272)
          at org.jboss.shrinkwrap.impl.base.io.IOUtil.closeOnComplete(IOUtil.java:219)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase.processNode(StreamExporterDelegateBase.java:233)
          at org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate.processNode(AbstractExporterDelegate.java:105)
          at org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate.processNode(AbstractExporterDelegate.java:109)
          at org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate.processNode(AbstractExporterDelegate.java:109)
          at org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate.doExport(AbstractExporterDelegate.java:95)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase.access$001(StreamExporterDelegateBase.java:50)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase$1.call(StreamExporterDelegateBase.java:121)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase$1.call(StreamExporterDelegateBase.java:116)
          at org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate$1.call(JdkZipExporterDelegate.java:124)
          at org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate$1.call(JdkZipExporterDelegate.java:118)
          at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
          at java.util.concurrent.FutureTask.run(FutureTask.java:166)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
          at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Pipe closed
          at java.io.PipedInputStream.checkStateForReceive(PipedInputStream.java:261)
          at java.io.PipedInputStream.receive(PipedInputStream.java:227)
          at java.io.PipedOutputStream.write(PipedOutputStream.java:149)
          at java.util.zip.DeflaterOutputStream.deflate(DeflaterOutputStream.java:253)
          at java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:238)
          at org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate.closeEntry(JdkZipExporterDelegate.java:84)
          at org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate.closeEntry(JdkZipExporterDelegate.java:40)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase$2.execute(StreamExporterDelegateBase.java:265)
          at org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase$2.execute(StreamExporterDelegateBase.java:233)
          at org.jboss.shrinkwrap.impl.base.io.IOUtil.closeOnComplete(IOUtil.java:217)
          ... 15 more

 

This is because ARQ failed to authenticate with the server. You will need to add a management user.

 

Creating a management user

Unfortunately, your instance in OpenShift does not come with the necessary scripting (add-user.sh script). So lets run it locally on your instance and add a user:

 

[rhusar@x220 jboss-eap-6.0]$ ./bin/add-user.sh 

 

and feed it with your user details. This will generate a password hash which you need to feed to your OpenShift's container configuration:

 

[rhusar@x220 jboss-eap-6.0]$ cat standalone/configuration/mgmt-users.properties | grep admin
admin=c7817ab300e18384b8217c6f7669814f

 

Now, you can SSH into your OpenShift instance add the generated user to the server's mgmt-users.properties file (there is probably a better way to do this via the git repository). You will find instructions how to ssh in the web console:

 

https://openshift.redhat.com/app/console/applications/myapplication

 

Afterwards, you will need to restart the server, click on the restart icon from the console and wait a few minutes.

 

Update arquillian.xml

Now, configure arquillian.xml in your project to pick up these credentials:

 

    <!-- Remote on OpenShift with port-forwarding -->
    <container qualifier="openshift-eap6" default="true">
         <configuration>
            <property name="managementAddress">127.0.0.1</property>
            <property name="managementPort">9999</property>
            <property name="username">admin</property>
            <property name="password">mL8oA4sctCe2epf</property>
        </configuration>
    </container>

 

Now run your tests (mvn test) and voila!

 

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 45.172s
[INFO] Finished at: Wed May 08 15:52:43 CEST 2013
[INFO] Final Memory: 33M/332M
[INFO] ------------------------------------------------------------------------

 

Err, that was not so fast!

Oops, 45 seconds with sample application with 1 deployment? That doesn't seem useful in all cases.

 

What if we could test only with the database in OpenShift?

So how about you want to test your persistence layer, not necessarily testing in OpenShift's container, but use database running in OpenShift? The client tooling makes this feasible.

 

First, start the port forwarding client:

[rhusar@x220 myapplication]$ rhc port-forward myapplication
Checking available ports ... done
Forwarding ports ...

To connect to a service running on OpenShift, use the Local address 

Service Local               OpenShift
------- -------------- ---- ----------------
java    127.0.0.1:3528  =>  127.5.190.1:3528
java    127.0.0.1:4447  =>  127.5.190.1:4447
java    127.0.0.1:5445  =>  127.5.190.1:5445
java    127.0.0.1:5455  =>  127.5.190.1:5455
java    127.0.0.1:8080  =>  127.5.190.1:8080
java    127.0.0.1:9990  =>  127.5.190.1:9990
java    127.0.0.1:9999  =>  127.5.190.1:9999
mysqld  127.0.0.1:3306  =>  127.5.190.1:3306

Press CTRL-C to terminate port forwarding

 

This is pretty neat! The rhc client is forwarding all ports, which is useful in most cases but if you want to run your container on the same ports, you will run into:

 

The server is already running! Managed containers does not support connecting to running server instances due to the possible 
harmful effect of connecting to the wrong server. Please stop server before running or change to another type of container.(..)

 

Since rhc client does not support selective forwarding of ports, we will need to switch to a different port for our local managed instance. Just tell the configuration to offset the ports by a constant number like this:

 

    <!-- Managed -->
    <container qualifier="local-eap6-managed" default="true">
        <configuration>
            <property name="jbossHome">target/jboss-eap-6.0</property>

            <!-- Do not overlap ports with port forward -->
            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=100</property>
            <property name="managementPort">10099</property>
        </configuration>
    </container>

 

Now, the same test with starting and stopping of the AS instance took only few seconds:

 

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.033s
[INFO] Finished at: Wed May 08 16:20:36 CEST 2013
[INFO] Final Memory: 30M/343M
[INFO] ------------------------------------------------------------------------

 

Also, make sure that you bundled a persistence.xml or data source with the port forwarded host and port.

 

Happy persistence testing!