Mittwoch, 2. März 2011

Integration test with jetty & maven

Hey all,
these days I have tested some integration test stuff with the jetty plugin. First time I found a "how to" for maven-jetty-plugin:6.1.26 which work well for me. Then I would to extend my integration test and have found the "jetty-maven-plugin". Between version 6 and 7 the plugin was renamed. That is a little bit confusion if you searches the internet and find different "how to's". 

However, I find out the solution for my test cases. All my integration tests are standalone test projects, so there is no dependency (without using classes and webapps) to the business components.
  1. start a webApp and send some HTTP stuff to the webApp.
  2. start two webApps, webApp "A" depends (via HTTP) on webApp "B". Then send some HTTP stuff to the webApp "A". WebApp "A" then calls webApp "B".
  3. same as 2. but the webApps are on different ports.
 At first, you have to get your webApps to be started. Therefore I've used the "maven-dependency-plugin":

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-dependency-plugin</artifactId>
 <version>2.2</version>
 <executions>
  <execution>
   <id>copy</id>
   <phase>package</phase>
   <goals>
    <goal>copy</goal>
   </goals>
   <configuration>
    <artifactItems>
     <artifactItem>
      <groupId>com.foo.bar<groupId>
      <artifactId>webAppA</artifactId>
      <version>00.02-SNAPSHOT</version>
      <type>war</type>
      <overWrite>true</overWrite>
      <outputDirectory>target/webapps</outputDirectory>
      <destFileName>webAppA.war</destFileName>
     </artifactItem>
     <artifactItem>
      <groupId>com.foo.bar</groupId>
      <artifactId>webAppB</artifactId>
      <version>00.02-SNAPSHOT</version>
      <type>war</type>
      <overWrite>true</overWrite>
      <outputDirectory>target/webapps</outputDirectory>
      <destFileName>webAppB</destFileName>
     </artifactItem>
    </artifactItems>
   </configuration>
  </execution>
 </executions> 

</plugin>

As you can see, the "maven-dependency-plugin" is execute while the "package phase"!.
The next step is to start the container with the apps. I do not explain the scenarios for testcase 1. and 2. because I'm sure everybody can derive the first 2 cases from the 3. example ;-)
  1. Define two connectors on different ports and give them a name.
  2. Define the contextHandlers and configure the dependency to the connector.
  3. Define the loginService.
  4. Configure the Execution of the jetty plugin.
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>8.0.0.M2</version>
    <configuration>
        <connectors>
            <connector implementation= "org.eclipse.jetty.server.nio.SelectChannelConnector">
                <port>8090</port>
                <name>instance_8090</name>
            </connector>
            <connector implementation= "org.eclipse.jetty.server.nio.SelectChannelConnector">
                <port>8080</port>
                <name>instance_8080</name>
            </connector>
        </connectors>
        <contextHandlers>
            <contextHandler implementation= "org.eclipse.jetty.webapp.WebAppContext">
                <contextPath>/webAppA</contextPath>
                <war>${basedir}/target/webapps/webAppA.war</war>
                <connectorNames><item>instance_8090</item></connectorNames>
            </contextHandler>
            <contextHandler implementation= "org.eclipse.jetty.webapp.WebAppContext">
                <contextPath>/webAppB</contextPath>
                <war>${basedir}/target/webapps/webAppB.war</war>
                <connectorNames><item>instance_8090</item></connectorNames>
            </contextHandler>
        </contextHandlers>
        <loginServices>
            <loginService implementation= "org.eclipse.jetty.security.HashLoginService">
                <name>Test Realm</name>
                <config>${basedir}/src/etc/realm.properties</config>
            </loginService>
        </loginServices>
        <stopKey>foo</stopKey>
        <stopPort>9999</stopPort>
    </configuration>
    <executions>
        <execution>
            <id>start-jetty</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <scanIntervalSeconds>0</scanIntervalSeconds>
                <daemon>true</daemon>
            </configuration>
        </execution>
        <execution>
            <id>stop-jetty</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>                   
        <dependency>
            <groupId>oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.2.0</version>
        </dependency>
    </dependencies>
</plugin>
 

If you have some dependencies that are not available in you webApps (for example the jdbc driver which should be provided from the container), so add the dependencies to the jetty plugin as shown in the sample above.


I don't know why the plugIn needs the realm, but without it I've trouble.The content of my "realm.properties" is:
username: test[manager]


Now we should add the ability to execute the integration tests. Therefore add the "maven-failsafe-plugin":

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Hint: I've problems to find the right maven repo for the yetti plugIn, so maybe you can save a bit time with that: "http://repo2.maven.org/maven2"

After configured your integration test project as above, you can start jetty with "mvn jetty:run" or you can execute your integration test incl. starting and stopping yetti with "mvn clean install".

You fiind the documentation of the plugIn here: http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin.

and no have some fun...
          ...while testing your apps.

Donnerstag, 10. Februar 2011

Maven & Testing

Most developers know the Maven Surefire Plugin but just a few know about the possibility to share testcase code. And another few know the support for integration tests.

Maven Failsafe Plugin
is designed for running integration tests

Guide to using attached tests
Many times you may want to reuse the tests that you have created for a project in another. For example if you have written foo-core and it contains test code in the ${basedir}/src/test/java it would be useful to package up those compiled tests in a JAR and deploy them for general reuse.

Dienstag, 8. Februar 2011

[maven] adding a jar as resource to a webapp


I'd suggest it could be a JAR containing an Applet.

The maven-dependency-plugin might help You out. Use on of the following
approaches:

Thanks to Marc Rohlfs 
for the answer  in the mailing list!

Separating Deployment from Development

This problem  I have in almost each project! The "tomcat" JNDI solution is a way that we have tried in a project. For unit test, we have initialized our own JNDI context, for starting without tomcat.
 

http://blog.artifact-software.com/tech/?p=58

If you have a larger environment, you will be in the "JNDI hell" really soon ,-)  The server.xml isn't a clear way to handle a big set of properties for different environments and many projects.
 

A database will be the better solution. But then maybe you should have an administration inferface other than sql and a view where you can view the properties for a project in a certain environment (don't forget the security than!). 

Misgivings about the database could be handled by exporting the properties at startup or at deployment! Maybe an in memory db is a more failsafe way. But if you have problems with the failure safety of your database, you have a problem anyway ;-)
 

Fredy

Montag, 7. Februar 2011

open service lifecyle collaboration

Open Services for Lifecycle Collaboration (also known as OSLC or Open Services) is a community and set of specifications for Linked Lifecycle Data. The community’s goal is to help product and software delivery teams by making it easier to use lifecycle tools in combination. The OSLC community is creating open, public descriptions of resources and interfaces for sharing the things that teams rely on, like change requests, test cases, defects, requirements and user stories.

http://open-services.net

Buchtipp: Software Architecture in Practice

Ein Buchtipp von Martin Fowler & Jez Humble:

Software Architecture in Practice (SEI Series in Software Engineering)

handbook of software architecture.

The Handbook of Software Architecture is a concise reference on the design of software-intensive systems. Written for software architects, developers, and project managers, the Handbook presents the fundamentals of software architecture, covering contemporary best practices for specifying, visualizing, documenting, governing, and evolving a system's significant design decisions. The center of this work presents the as-built architecture of a variety of software-intensive systems selected from across the industry and from across the world.


http://www.handbookofsoftwarearchitecture.com

2000-2010 by Grady Booch

Donnerstag, 13. Januar 2011

XML Entity and URI Resolvers

Bei meinem Kunden wollen wir eine Menge von xsd Files als Bibliothek in einem jar zur Verfügung stellen. Mit Hilfe des Spring Resource Mechanismus ist es recht einfach die xsd's aus dem classpath zu laden. Problematisch sind allerding in der xsd referenzierte Entitites.

Nach einigem probieren und Suchen sind wir auf den org.xml.sax.EntityResolver gestoßen, der die Lösung unseres Problems zu sein scheint. Allerdings ist man recht schnell aufgeschmissen wenn man den publicId bzw. systemId Mechanismus nicht kennt.

In diesem Zusammenhang bin ich auf den Artikel http://xml.apache.org/commons/components/resolver/resolver-article.html gestoßen, dieser beschreibt das Problem sehr gut und bietet einen Einstieg in die ‚OASIS XML Catalogs‘.

doIt!