You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2011/12/08 21:11:55 UTC

svn commit: r1212081 - in /activemq/activemq-apollo/trunk: ./ apollo-itests/ apollo-itests/src/ apollo-itests/src/test/ apollo-itests/src/test/resources/ apollo-itests/src/test/scala/ apollo-itests/src/test/scala/org/ apollo-itests/src/test/scala/org/a...

Author: chirino
Date: Thu Dec  8 20:11:54 2011
New Revision: 1212081

URL: http://svn.apache.org/viewvc?rev=1212081&view=rev
Log:
Fixes APLO-107 : Create an apollo-itests module and port some ActiveMQ 5.x tests over to it

Patch provided by Stan Lewis.  Thanks!

Added:
    activemq/activemq-apollo/trunk/apollo-itests/
    activemq/activemq-apollo/trunk/apollo-itests/pom.xml
    activemq/activemq-apollo/trunk/apollo-itests/src/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/apollo-stomp.xml
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/AutoFailTestSupport.java
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/BrokerService.scala
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/CombinationTestSupport.java
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JMSMessageTest.java
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JmsTestSupport.java
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/StompBroker.scala
    activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/TestSupport.java
Modified:
    activemq/activemq-apollo/trunk/pom.xml

Added: activemq/activemq-apollo/trunk/apollo-itests/pom.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/pom.xml?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/pom.xml (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/pom.xml Thu Dec  8 20:11:54 2011
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.activemq</groupId>
+    <artifactId>apollo-scala</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <relativePath>../apollo-scala</relativePath>
+  </parent>
+
+  <groupId>org.apache.activemq</groupId>
+  <artifactId>apollo-itests</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <name>${project.artifactId}</name>
+  <description>General Apollo Integration/System Tests</description>
+  
+  <properties>
+    <maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version>
+    <stompjms-client-version>1.4-SNAPSHOT</stompjms-client-version>
+  </properties>
+
+  <dependencies>
+
+    <!-- Scala Support -->
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+      <scope>compile</scope>
+      <version>${scala-version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-compiler</artifactId>
+      <version>${scala-version}</version>
+      <scope>compile</scope>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jms_1.1_spec</artifactId>
+      <version>1.1.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.fusesource.stompjms</groupId>
+      <artifactId>stompjms-client</artifactId>
+      <version>${stompjms-client-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>apollo-broker</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>apollo-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>apollo-stomp</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>apollo-bdb</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jetty.aggregate</groupId>
+      <artifactId>jetty-all-server</artifactId>
+      <version>${jetty-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>apollo-web</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+      <version>${junit-version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scalatest</groupId>
+      <artifactId>scalatest_2.9.1</artifactId>
+      <version>${scalatest-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${slf4j-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.scala-tools</groupId>
+          <artifactId>maven-scala-plugin</artifactId>
+          <version>${maven-scala-plugin-version}</version>
+        </plugin>
+
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>${maven-compiler-plugin-version}</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+
+    <plugins>
+      <plugin>
+        <groupId>org.scala-tools</groupId>
+        <artifactId>maven-scala-plugin</artifactId>
+        <version>${maven-scala-plugin-version}</version>
+        <executions>
+          <execution>
+            <id>scala-compile-first</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>add-source</goal>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>scala-test-compile</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+            <testSourceDir>src/test/scala</testSourceDir>
+            <args>
+              <arg>-deprecation</arg>
+              <arg>-P:continuations:enable</arg>
+            </args>
+            <compilerPlugins>
+              <compilerPlugin>
+                <groupId>org.scala-lang.plugins</groupId>
+                <artifactId>continuations</artifactId>
+                <version>${scala-version}</version>
+              </compilerPlugin>
+              <compilerPlugin>
+                <groupId>org.fusesource.jvmassert</groupId>
+                <artifactId>jvmassert</artifactId>
+                <version>1.2</version>
+              </compilerPlugin>
+            </compilerPlugins>
+            <jvmArgs>
+              <jvmArg>-Xmx1024m</jvmArg>
+              <jvmArg>-Xss8m</jvmArg>
+            </jvmArgs>
+            <scalaVersion>${scala-version}</scalaVersion>
+          </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>${maven-compiler-plugin-version}</version>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Generate a test jar for the test cases in this package -->
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+        <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <version>${maven-surefire-plugin-version}</version>
+
+            <configuration>
+                <!-- we must turn off the use of system class loader so our tests can find stuff - otherwise ScalaSupport compiler can't find stuff -->
+                <useSystemClassLoader>false</useSystemClassLoader>
+                <!--forkMode>pertest</forkMode-->
+                <childDelegation>false</childDelegation>
+                <useFile>true</useFile>
+                <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                <failIfNoTests>false</failIfNoTests>
+            </configuration>
+        </plugin>
+
+    </plugins>
+  </build>
+  
+</project>

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/apollo-stomp.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/apollo-stomp.xml?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/apollo-stomp.xml (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/resources/apollo-stomp.xml Thu Dec  8 20:11:54 2011
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<broker xmlns="http://activemq.apache.org/schema/activemq/apollo">
+  <notes>This broker configuration is what the unit tests in this module load up.</notes>
+
+  <virtual_host id="default" purge_on_startup="true" auto_create_queues="true">
+    <host_name>localhost</host_name>
+
+    <queue name="unified.**" unified="true"/>
+
+  </virtual_host>
+
+  <connector id="tcp" protocol="stomp" bind="tcp://0.0.0.0:0"/>
+
+</broker>
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/AutoFailTestSupport.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/AutoFailTestSupport.java?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/AutoFailTestSupport.java (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/AutoFailTestSupport.java Thu Dec  8 20:11:54 2011
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo;
+
+import junit.framework.TestCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Enforces a test case to run for only an allotted time to prevent them from
+ * hanging and breaking the whole testing.
+ * 
+ * 
+ */
+
+public abstract class AutoFailTestSupport extends TestCase {
+    public static final int EXIT_SUCCESS = 0;
+    public static final int EXIT_ERROR = 1;
+    private static final Logger LOG = LoggerFactory.getLogger(AutoFailTestSupport.class);
+
+    private long maxTestTime = 5 * 60 * 1000; // 5 mins by default
+    private Thread autoFailThread;
+
+    private boolean verbose = true;
+    private boolean useAutoFail; // Disable auto fail by default
+    private AtomicBoolean isTestSuccess;
+
+    protected void setUp() throws Exception {
+        // Runs the auto fail thread before performing any setup
+        if (isAutoFail()) {
+            startAutoFailThread();
+        }
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        // Stops the auto fail thread only after performing any clean up
+        stopAutoFailThread();
+    }
+
+    /**
+     * Manually start the auto fail thread. To start it automatically, just set
+     * the auto fail to true before calling any setup methods. As a rule, this
+     * method is used only when you are not sure, if the setUp and tearDown
+     * method is propagated correctly.
+     */
+    public void startAutoFailThread() {
+        setAutoFail(true);
+        isTestSuccess = new AtomicBoolean(false);
+        autoFailThread = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    // Wait for test to finish succesfully
+                    Thread.sleep(getMaxTestTime());
+                } catch (InterruptedException e) {
+                    // This usually means the test was successful
+                } finally {
+                    // Check if the test was able to tear down succesfully,
+                    // which usually means, it has finished its run.
+                    if (!isTestSuccess.get()) {
+                        LOG.error("Test case has exceeded the maximum allotted time to run of: " + getMaxTestTime() + " ms.");
+                        dumpAllThreads(getName());
+                        System.exit(EXIT_ERROR);
+                    }
+                }
+            }
+        }, "AutoFailThread");
+
+        if (verbose) {
+            LOG.info("Starting auto fail thread...");
+        }
+
+        LOG.info("Starting auto fail thread...");
+        autoFailThread.start();
+    }
+
+    /**
+     * Manually stops the auto fail thread. As a rule, this method is used only
+     * when you are not sure, if the setUp and tearDown method is propagated
+     * correctly.
+     */
+    public void stopAutoFailThread() {
+        if (isAutoFail() && autoFailThread != null && autoFailThread.isAlive()) {
+            isTestSuccess.set(true);
+
+            if (verbose) {
+                LOG.info("Stopping auto fail thread...");
+            }
+
+            LOG.info("Stopping auto fail thread...");
+            autoFailThread.interrupt();
+        }
+    }
+
+    /**
+     * Sets the auto fail value. As a rule, this should be used only before any
+     * setup methods is called to automatically enable the auto fail thread in
+     * the setup method of the test case.
+     * 
+     * @param val
+     */
+    public void setAutoFail(boolean val) {
+        this.useAutoFail = val;
+    }
+
+    public boolean isAutoFail() {
+        return this.useAutoFail;
+    }
+
+    /**
+     * The assigned value will only be reflected when the auto fail thread has
+     * started its run. Value is in milliseconds.
+     * 
+     * @param val
+     */
+    public void setMaxTestTime(long val) {
+        this.maxTestTime = val;
+    }
+
+    public long getMaxTestTime() {
+        return this.maxTestTime;
+    }
+    
+    
+    public static void dumpAllThreads(String prefix) {
+        Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
+        for (Entry<Thread, StackTraceElement[]> stackEntry : stacks.entrySet()) {
+            System.err.println(prefix + " " + stackEntry.getKey());
+            for(StackTraceElement element : stackEntry.getValue()) {
+                System.err.println("     " + element);
+            }
+        }
+    }
+}

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/BrokerService.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/BrokerService.scala?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/BrokerService.scala (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/BrokerService.scala Thu Dec  8 20:11:54 2011
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo
+
+import javax.jms.ConnectionFactory
+
+
+/**
+ *
+ */
+trait BrokerService {
+  def start:Unit
+  def stop:Unit
+  def get_connection_factory:ConnectionFactory
+  def get_connection_uri:String
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/CombinationTestSupport.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/CombinationTestSupport.java?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/CombinationTestSupport.java (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/CombinationTestSupport.java Thu Dec  8 20:11:54 2011
@@ -0,0 +1,241 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Poor mans way of getting JUnit to run a test case through a few different
+ * combinations of options. Usage: If you have a test case called testFoo what
+ * you want to run through a few combinations, of of values for the attributes
+ * age and color, you would something like: <code>
+ *    public void initCombosForTestFoo() {
+ *        addCombinationValues( "age", new Object[]{ new Integer(21), new Integer(30) } );
+ *        addCombinationValues( "color", new Object[]{"blue", "green"} );
+ *    }
+ * </code>
+ * The testFoo test case would be run for each possible combination of age and
+ * color that you setup in the initCombosForTestFoo method. Before each
+ * combination is run, the age and color fields of the test class are set to one
+ * of the values defined. This is done before the normal setUp method is called.
+ * If you want the test combinations to show up as separate test runs in the
+ * JUnit reports, add a suite method to your test case similar to: <code>
+ *     public static Test suite() {
+ *         return suite(FooTest.class);
+ *     }
+ * </code>
+ *
+ *
+ */
+public abstract class CombinationTestSupport extends AutoFailTestSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CombinationTestSupport.class);
+
+    private HashMap<String, ComboOption> comboOptions = new HashMap<String, ComboOption>();
+    private boolean combosEvaluated;
+    private Map<String, Object> options;
+
+    static class ComboOption {
+        final String attribute;
+        final LinkedHashSet<Object> values = new LinkedHashSet<Object>();
+
+        public ComboOption(String attribute, Collection<Object> options) {
+            this.attribute = attribute;
+            this.values.addAll(options);
+        }
+    }
+
+    public void addCombinationValues(String attribute, Object[] options) {
+        ComboOption co = this.comboOptions.get(attribute);
+        if (co == null) {
+            this.comboOptions.put(attribute, new ComboOption(attribute, Arrays.asList(options)));
+        } else {
+            co.values.addAll(Arrays.asList(options));
+        }
+    }
+
+    public void runBare() throws Throwable {
+        if (combosEvaluated) {
+            super.runBare();
+        } else {
+            CombinationTestSupport[] combinations = getCombinations();
+            for (int i = 0; i < combinations.length; i++) {
+                CombinationTestSupport test = combinations[i];
+                if (getName() == null || getName().equals(test.getName())) {
+                    test.runBare();
+                }
+            }
+        }
+    }
+
+    private void setOptions(Map<String, Object> options) throws NoSuchFieldException, IllegalAccessException {
+        this.options = options;
+        for (Iterator<String> iterator = options.keySet().iterator(); iterator.hasNext();) {
+            String attribute = iterator.next();
+            Object value = options.get(attribute);
+            try {
+                Field field = getClass().getField(attribute);
+                field.set(this, value);
+            } catch (Throwable e) {
+                try {
+                    boolean found = false;
+                    String setterName = "set" + attribute.substring(0, 1).toUpperCase() +
+                                        attribute.substring(1);
+                    for(Method method : getClass().getMethods()) {
+                        if (method.getName().equals(setterName)) {
+                            method.invoke(this, value);
+                            found = true;
+                            break;
+                        }
+                    }
+
+                    if (!found) {
+                        throw new NoSuchMethodError("No setter found for field: " + attribute);
+                    }
+
+                } catch(Throwable ex) {
+                    LOG.info("Could not set field '" + attribute + "' to value '" + value +
+                             "', make sure the field exists and is public or has a setter.");
+                }
+            }
+        }
+    }
+
+    private CombinationTestSupport[] getCombinations() {
+        try {
+            Method method = getClass().getMethod("initCombos", (Class[])null);
+            method.invoke(this, (Object[])null);
+        } catch (Throwable e) {
+        }
+
+        String name = getName().split(" ")[0];
+        String comboSetupMethodName = "initCombosFor" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
+        try {
+            Method method = getClass().getMethod(comboSetupMethodName, (Class[])null);
+            method.invoke(this, (Object[])null);
+        } catch (Throwable e) {
+        }
+
+        try {
+            ArrayList<HashMap<String, Object>> expandedOptions = new ArrayList<HashMap<String, Object>>();
+            expandCombinations(new ArrayList<ComboOption>(comboOptions.values()), expandedOptions);
+
+            if (expandedOptions.isEmpty()) {
+                combosEvaluated = true;
+                return new CombinationTestSupport[] {this};
+            } else {
+
+                ArrayList<CombinationTestSupport> result = new ArrayList<CombinationTestSupport>();
+                // Run the test case for each possible combination
+                for (Iterator<HashMap<String, Object>> iter = expandedOptions.iterator(); iter.hasNext();) {
+                    CombinationTestSupport combo = (CombinationTestSupport)TestSuite.createTest(getClass(), name);
+                    combo.combosEvaluated = true;
+                    combo.setOptions(iter.next());
+                    result.add(combo);
+                }
+
+                CombinationTestSupport rc[] = new CombinationTestSupport[result.size()];
+                result.toArray(rc);
+                return rc;
+            }
+        } catch (Throwable e) {
+            combosEvaluated = true;
+            return new CombinationTestSupport[] {this};
+        }
+
+    }
+
+    private void expandCombinations(List<ComboOption> optionsLeft, List<HashMap<String, Object>> expandedCombos) {
+        if (!optionsLeft.isEmpty()) {
+            HashMap<String, Object> map;
+            if (comboOptions.size() == optionsLeft.size()) {
+                map = new HashMap<String, Object>();
+                expandedCombos.add(map);
+            } else {
+                map = expandedCombos.get(expandedCombos.size() - 1);
+            }
+
+            LinkedList<ComboOption> l = new LinkedList<ComboOption>(optionsLeft);
+            ComboOption comboOption = l.removeLast();
+            int i = 0;
+            for (Iterator<Object> iter = comboOption.values.iterator(); iter.hasNext();) {
+                Object value = iter.next();
+                if (i != 0) {
+                    map = new HashMap<String, Object>(map);
+                    expandedCombos.add(map);
+                }
+                map.put(comboOption.attribute, value);
+                expandCombinations(l, expandedCombos);
+                i++;
+            }
+        }
+    }
+
+    public static Test suite(Class<? extends CombinationTestSupport> clazz) {
+        TestSuite suite = new TestSuite();
+
+        ArrayList<String> names = new ArrayList<String>();
+        Method[] methods = clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            String name = methods[i].getName();
+            if (names.contains(name) || !isPublicTestMethod(methods[i])) {
+                continue;
+            }
+            names.add(name);
+            Test test = TestSuite.createTest(clazz, name);
+            if (test instanceof CombinationTestSupport) {
+                CombinationTestSupport[] combinations = ((CombinationTestSupport)test).getCombinations();
+                for (int j = 0; j < combinations.length; j++) {
+                    suite.addTest(combinations[j]);
+                }
+            } else {
+                suite.addTest(test);
+            }
+        }
+        return suite;
+    }
+
+    private static boolean isPublicTestMethod(Method m) {
+        return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+    }
+
+    private static boolean isTestMethod(Method m) {
+        String name = m.getName();
+        Class<?>[] parameters = m.getParameterTypes();
+        Class<?> returnType = m.getReturnType();
+        return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
+    }
+
+    public String getName() {
+        return getName(false);
+    }
+
+    public String getName(boolean original) {
+        if (options != null && !original) {
+            return super.getName() + " " + options;
+        }
+        return super.getName();
+    }
+}

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JMSMessageTest.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JMSMessageTest.java?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JMSMessageTest.java (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JMSMessageTest.java Thu Dec  8 20:11:54 2011
@@ -0,0 +1,490 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo;
+
+import junit.framework.Test;
+
+import javax.jms.*;
+import java.net.URISyntaxException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Vector;
+
+/**
+ * Test cases used to test the JMS message consumer.
+ * 
+ * 
+ */
+public class JMSMessageTest extends JmsTestSupport {
+
+    public Destination destination;
+    public int deliveryMode = DeliveryMode.NON_PERSISTENT;
+    public int prefetch;
+    public int ackMode;
+    public DestinationType destinationType = DestinationType.QUEUE_TYPE;
+    public boolean durableConsumer;
+
+    /**
+     * Run all these tests in both marshaling and non-marshaling mode.
+     */
+    public void initCombos() {
+        addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT),
+                                                           Integer.valueOf(DeliveryMode.PERSISTENT)});
+        addCombinationValues("destinationType", new Object[] {DestinationType.QUEUE_TYPE});
+    }
+
+    public void testTextMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // Send the message.
+        {
+            TextMessage message = session.createTextMessage();
+            message.setText("Hi");
+            producer.send(message);
+        }
+
+        // Check the Message
+        {
+            TextMessage message = (TextMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertEquals("Hi", message.getText());
+        }
+
+        assertNull(consumer.receiveNoWait());
+    }
+
+    public static Test suite() {
+        return suite(JMSMessageTest.class);
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    protected ConnectionFactory createConnectionFactory() throws URISyntaxException {
+        return broker.get_connection_factory();
+    }
+
+    public void testBytesMessageLength() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // Send the message
+        {
+            BytesMessage message = session.createBytesMessage();
+            message.writeInt(1);
+            message.writeInt(2);
+            message.writeInt(3);
+            message.writeInt(4);
+            producer.send(message);
+        }
+
+        // Check the message.
+        {
+            BytesMessage message = (BytesMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertEquals(16, message.getBodyLength());
+        }
+
+        assertNull(consumer.receiveNoWait());
+    }
+
+    public void testObjectMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // send the message.
+        {
+            ObjectMessage message = session.createObjectMessage();
+            message.setObject("Hi");
+            producer.send(message);
+        }
+
+        // Check the message
+        {
+            ObjectMessage message = (ObjectMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertEquals("Hi", message.getObject());
+        }
+        assertNull(consumer.receiveNoWait());
+    }
+
+    public void testBytesMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // Send the message
+        {
+            BytesMessage message = session.createBytesMessage();
+            message.writeBoolean(true);
+            producer.send(message);
+        }
+
+        // Check the message
+        {
+            BytesMessage message = (BytesMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertTrue(message.readBoolean());
+
+            /*
+            TODO - stompjms appears to reset the stream so this check fails
+            try {
+                message.readByte();
+                fail("Expected exception not thrown.");
+            } catch (MessageEOFException e) {
+            }
+            */
+
+        }
+        assertNull(consumer.receiveNoWait());
+    }
+
+    public void testStreamMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // Send the message.
+        {
+            StreamMessage message = session.createStreamMessage();
+            message.writeString("This is a test to see how it works.");
+            producer.send(message);
+        }
+
+        // Check the message.
+        {
+            StreamMessage message = (StreamMessage)consumer.receive(1000);
+            assertNotNull(message);
+
+            // Invalid conversion should throw exception and not move the stream
+            // position.
+            /*
+            TODO - stompjms appears to a problem here that doesn't result in the right exception being thrown
+            try {
+                message.readByte();
+                fail("Should have received NumberFormatException");
+            } catch (NumberFormatException e) {
+            }
+            */
+
+            assertEquals("This is a test to see how it works.", message.readString());
+
+            // Invalid conversion should throw exception and not move the stream
+            // position.
+            try {
+                message.readByte();
+                fail("Should have received MessageEOFException");
+            } catch (MessageEOFException e) {
+            }
+        }
+        assertNull(consumer.receiveNoWait());
+    }
+
+    public void testMapMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // send the message.
+        {
+            MapMessage message = session.createMapMessage();
+            message.setBoolean("boolKey", true);
+            producer.send(message);
+        }
+
+        // get the message.
+        {
+            MapMessage message = (MapMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertTrue(message.getBoolean("boolKey"));
+        }
+        assertNull(consumer.receiveNoWait());
+    }
+
+    static class ForeignMessage implements TextMessage {
+
+        public int deliveryMode;
+
+        private String messageId;
+        private long timestamp;
+        private String correlationId;
+        private Destination replyTo;
+        private Destination destination;
+        private boolean redelivered;
+        private String type;
+        private long expiration;
+        private int priority;
+        private String text;
+        private HashMap<String, Object> props = new HashMap<String, Object>();
+
+        public String getJMSMessageID() throws JMSException {
+            return messageId;
+        }
+
+        public void setJMSMessageID(String arg0) throws JMSException {
+            messageId = arg0;
+        }
+
+        public long getJMSTimestamp() throws JMSException {
+            return timestamp;
+        }
+
+        public void setJMSTimestamp(long arg0) throws JMSException {
+            timestamp = arg0;
+        }
+
+        public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
+            return null;
+        }
+
+        public void setJMSCorrelationIDAsBytes(byte[] arg0) throws JMSException {
+        }
+
+        public void setJMSCorrelationID(String arg0) throws JMSException {
+            correlationId = arg0;
+        }
+
+        public String getJMSCorrelationID() throws JMSException {
+            return correlationId;
+        }
+
+        public Destination getJMSReplyTo() throws JMSException {
+            return replyTo;
+        }
+
+        public void setJMSReplyTo(Destination arg0) throws JMSException {
+            replyTo = arg0;
+        }
+
+        public Destination getJMSDestination() throws JMSException {
+            return destination;
+        }
+
+        public void setJMSDestination(Destination arg0) throws JMSException {
+            destination = arg0;
+        }
+
+        public int getJMSDeliveryMode() throws JMSException {
+            return deliveryMode;
+        }
+
+        public void setJMSDeliveryMode(int arg0) throws JMSException {
+            deliveryMode = arg0;
+        }
+
+        public boolean getJMSRedelivered() throws JMSException {
+            return redelivered;
+        }
+
+        public void setJMSRedelivered(boolean arg0) throws JMSException {
+            redelivered = arg0;
+        }
+
+        public String getJMSType() throws JMSException {
+            return type;
+        }
+
+        public void setJMSType(String arg0) throws JMSException {
+            type = arg0;
+        }
+
+        public long getJMSExpiration() throws JMSException {
+            return expiration;
+        }
+
+        public void setJMSExpiration(long arg0) throws JMSException {
+            expiration = arg0;
+        }
+
+        public int getJMSPriority() throws JMSException {
+            return priority;
+        }
+
+        public void setJMSPriority(int arg0) throws JMSException {
+            priority = arg0;
+        }
+
+        public void clearProperties() throws JMSException {
+        }
+
+        public boolean propertyExists(String arg0) throws JMSException {
+            return false;
+        }
+
+        public boolean getBooleanProperty(String arg0) throws JMSException {
+            return false;
+        }
+
+        public byte getByteProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public short getShortProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public int getIntProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public long getLongProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public float getFloatProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public double getDoubleProperty(String arg0) throws JMSException {
+            return 0;
+        }
+
+        public String getStringProperty(String arg0) throws JMSException {
+            return (String)props.get(arg0);
+        }
+
+        public Object getObjectProperty(String arg0) throws JMSException {
+            return props.get(arg0);
+        }
+
+        public Enumeration getPropertyNames() throws JMSException {
+            return new Vector<String>(props.keySet()).elements();
+        }
+
+        public void setBooleanProperty(String arg0, boolean arg1) throws JMSException {
+        }
+
+        public void setByteProperty(String arg0, byte arg1) throws JMSException {
+        }
+
+        public void setShortProperty(String arg0, short arg1) throws JMSException {
+        }
+
+        public void setIntProperty(String arg0, int arg1) throws JMSException {
+        }
+
+        public void setLongProperty(String arg0, long arg1) throws JMSException {
+        }
+
+        public void setFloatProperty(String arg0, float arg1) throws JMSException {
+        }
+
+        public void setDoubleProperty(String arg0, double arg1) throws JMSException {
+        }
+
+        public void setStringProperty(String arg0, String arg1) throws JMSException {
+            props.put(arg0, arg1);
+        }
+
+        public void setObjectProperty(String arg0, Object arg1) throws JMSException {
+            props.put(arg0, arg1);
+        }
+
+        public void acknowledge() throws JMSException {
+        }
+
+        public void clearBody() throws JMSException {
+        }
+
+        public void setText(String arg0) throws JMSException {
+            text = arg0;
+        }
+
+        public String getText() throws JMSException {
+            return text;
+        }
+    }
+
+    public void testForeignMessage() throws Exception {
+
+        // Receive a message with the JMS API
+        connection.start();
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        destination = createDestination(session, destinationType);
+        MessageConsumer consumer = session.createConsumer(destination);
+        MessageProducer producer = session.createProducer(destination);
+
+        // Send the message.
+        {
+            ForeignMessage message = new ForeignMessage();
+            message.text = "Hello";
+            message.setStringProperty("test", "value");
+            long timeToLive = 10000L;
+            long start = System.currentTimeMillis();
+            producer.send(message, Session.AUTO_ACKNOWLEDGE, 7, timeToLive);
+            long end = System.currentTimeMillis();
+
+
+            //validate jms spec 1.1 section 3.4.11 table 3.1
+            // JMSDestination, JMSDeliveryMode,  JMSExpiration, JMSPriority, JMSMessageID, and JMSTimestamp
+            //must be set by sending a message.
+
+            // exception for jms destination as the format is provider defined so it is only set on the copy
+            /*
+            TODO - stompjms doesn't appear to set some/all of these, needs to be sorted
+            assertNull(message.getJMSDestination());
+            assertEquals(Session.AUTO_ACKNOWLEDGE, message.getJMSDeliveryMode());
+            assertTrue(start  + timeToLive <= message.getJMSExpiration());
+            assertTrue(end + timeToLive >= message.getJMSExpiration());
+            assertEquals(7, message.getJMSPriority());
+            assertNotNull(message.getJMSMessageID());
+            assertTrue(start <= message.getJMSTimestamp());
+            assertTrue(end >= message.getJMSTimestamp());
+            */
+        }
+
+        // Validate message is OK.
+        {
+            TextMessage message = (TextMessage)consumer.receive(1000);
+            assertNotNull(message);
+            assertEquals("Hello", message.getText());
+            assertEquals("value", message.getStringProperty("test"));
+        }
+
+        assertNull(consumer.receiveNoWait());
+    }
+
+}

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JmsTestSupport.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JmsTestSupport.java?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JmsTestSupport.java (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/JmsTestSupport.java Thu Dec  8 20:11:54 2011
@@ -0,0 +1,178 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo;
+
+import javax.jms.*;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Test cases used to test the JMS message consumer.
+ * 
+ * 
+ */
+public class JmsTestSupport extends CombinationTestSupport {
+
+    static final private AtomicLong TEST_COUNTER = new AtomicLong();
+    public String userName;
+    public String password;
+    public String messageTextPrefix = "";
+
+    protected ConnectionFactory factory;
+    protected Connection connection;
+    protected BrokerService broker;
+
+    protected List<Connection> connections = Collections.synchronizedList(new ArrayList<Connection>());
+
+    enum DestinationType {
+        QUEUE_TYPE,
+        TOPIC_TYPE,
+        TEMP_QUEUE_TYPE,
+        TEMP_TOPIC_TYPE
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    //
+    // Test support methods.
+    //
+    // /////////////////////////////////////////////////////////////////
+    protected Destination createDestination(Session session, DestinationType type) throws JMSException {
+        String testMethod = getName();
+        if( testMethod.indexOf(" ")>0 ) {
+            testMethod = testMethod.substring(0, testMethod.indexOf(" "));
+        }
+        String name = "TEST." + getClass().getName() + "." +testMethod+"."+TEST_COUNTER.getAndIncrement();
+        switch (type) {
+        case QUEUE_TYPE:
+            return session.createQueue(name);
+        case TOPIC_TYPE:
+            return session.createTopic(name);
+        case TEMP_QUEUE_TYPE:
+            return session.createTemporaryQueue();
+        case TEMP_TOPIC_TYPE:
+            return session.createTemporaryTopic();
+        default:
+            throw new IllegalArgumentException("type: " + type);
+        }
+    }
+
+    protected void sendMessages(Destination destination, int count) throws Exception {
+        ConnectionFactory factory = createConnectionFactory();
+        Connection connection = factory.createConnection();
+        connection.start();
+        sendMessages(connection, destination, count);
+        connection.close();
+    }
+
+    protected void sendMessages(Connection connection, Destination destination, int count) throws JMSException {
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        sendMessages(session, destination, count);
+        session.close();
+    }
+
+    protected void sendMessages(Session session, Destination destination, int count) throws JMSException {
+        MessageProducer producer = session.createProducer(destination);
+        for (int i = 0; i < count; i++) {
+            producer.send(session.createTextMessage(messageTextPrefix  + i));
+        }
+        producer.close();
+    }
+
+    protected ConnectionFactory createConnectionFactory() throws Exception {
+        return broker.get_connection_factory();
+    }
+
+    protected BrokerService createBroker() throws Exception {
+        return new StompBroker();
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (System.getProperty("basedir") == null) {
+            File file = new File(".");
+            System.setProperty("basedir", file.getAbsolutePath());
+        }
+
+        broker = createBroker();
+        broker.start();
+        factory = createConnectionFactory();
+        connection = factory.createConnection(userName, password);
+        connections.add(connection);
+    }
+
+    protected void tearDown() throws Exception {
+        for (Iterator iter = connections.iterator(); iter.hasNext();) {
+            Connection conn = (Connection)iter.next();
+            try {
+                conn.close();
+            } catch (Throwable e) {
+            }
+            iter.remove();
+        }
+        broker.stop();
+        super.tearDown();
+    }
+
+    protected void safeClose(Connection c) {
+        try {
+            c.close();
+        } catch (Throwable e) {
+        }
+    }
+
+    protected void safeClose(Session s) {
+        try {
+            s.close();
+        } catch (Throwable e) {
+        }
+    }
+
+    protected void safeClose(MessageConsumer c) {
+        try {
+            c.close();
+        } catch (Throwable e) {
+        }
+    }
+
+    protected void safeClose(MessageProducer p) {
+        try {
+            p.close();
+        } catch (Throwable e) {
+        }
+    }
+
+    protected void profilerPause(String prompt) throws IOException {
+        if (System.getProperty("profiler") != null) {
+            pause(prompt);
+        }
+    }
+
+    protected void pause(String prompt) throws IOException {
+        System.out.println();
+        System.out.println(prompt + "> Press enter to continue: ");
+        while (System.in.read() != '\n') {
+        }
+    }
+
+}

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/StompBroker.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/StompBroker.scala?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/StompBroker.scala (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/StompBroker.scala Thu Dec  8 20:11:54 2011
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo
+
+import broker.{BrokerFactory, Broker}
+import java.net.InetSocketAddress
+import util.{Logging, ServiceControl}
+import java.util.Hashtable
+import javax.naming.InitialContext
+import javax.jms.ConnectionFactory
+
+
+/**
+ *
+ */
+class StompBroker extends BrokerService with Logging {
+
+  var broker: Broker = null
+  var port = 0
+  var started = false
+  val broker_config_uri = "xml:classpath:apollo-stomp.xml"
+
+  override def start = {
+    try {
+      info("Loading broker configuration from the classpath with URI: " + broker_config_uri)
+      broker = BrokerFactory.createBroker(broker_config_uri)
+      ServiceControl.start(broker, "Starting broker")
+      port = broker.get_socket_address.asInstanceOf[InetSocketAddress].getPort
+    }
+    catch {
+      case e:Throwable => e.printStackTrace
+      throw e
+    }
+  }
+
+  override def get_connection_factory = {
+    if (!started) {
+      start
+    }
+    val jndiConfig = new Hashtable[String, String]
+    jndiConfig.put("java.naming.factory.initial", "org.fusesource.stompjms.jndi.StompJmsInitialContextFactory")
+    jndiConfig.put("java.naming.provider.url", get_connection_uri)
+    jndiConfig.put("java.naming.security.principal", "admin")
+    jndiConfig.put("java.naming.security.credentials", "password")
+    val ctx = new InitialContext(jndiConfig)
+    ctx.lookup("ConnectionFactory").asInstanceOf[ConnectionFactory]
+  }
+  
+
+  override def get_connection_uri = "tcp://localhost:%s".format(port);
+
+  override def stop = ServiceControl.stop(broker, "Stopping broker")
+
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/TestSupport.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/TestSupport.java?rev=1212081&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/TestSupport.java (added)
+++ activemq/activemq-apollo/trunk/apollo-itests/src/test/scala/org/apache/activemq/apollo/TestSupport.java Thu Dec  8 20:11:54 2011
@@ -0,0 +1,212 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo;
+
+import org.fusesource.stompjms.StompJmsConnectionFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Map;
+import javax.jms.*;
+import javax.naming.InitialContext;
+
+/**
+ * Useful base class for unit test cases
+ * 
+ * 
+ */
+public abstract class TestSupport extends CombinationTestSupport {
+
+    protected BrokerService broker = new StompBroker();
+    protected ConnectionFactory connectionFactory;
+    protected boolean topic = true;
+    /*
+    public PersistenceAdapterChoice defaultPersistenceAdapter = PersistenceAdapterChoice.KahaDB;
+    */
+
+    /*
+    protected Message createMessage() {
+        return new ActiveMQMessage();
+    }
+    */
+
+    /*
+    protected Destination createDestination(String subject) {
+        if (topic) {
+            return new ActiveMQTopic(subject);
+        } else {
+            return new ActiveMQQueue(subject);
+        }
+    }
+    */
+    protected Destination createDestination(String subject) {
+        return null;
+    }
+
+    protected Destination createDestination() {
+        return createDestination(getDestinationString());
+    }
+
+    /**
+     * Returns the name of the destination used in this test case
+     */
+    protected String getDestinationString() {
+        return getClass().getName() + "." + getName(true);
+    }
+
+    /**
+     * @param messsage
+     * @param firstSet
+     * @param secondSet
+     */
+    protected void assertTextMessagesEqual(String messsage, Message[] firstSet, Message[] secondSet)
+        throws JMSException {
+        assertEquals("Message count does not match: " + messsage, firstSet.length, secondSet.length);
+        for (int i = 0; i < secondSet.length; i++) {
+            TextMessage m1 = (TextMessage)firstSet[i];
+            TextMessage m2 = (TextMessage)secondSet[i];
+            assertFalse("Message " + (i + 1) + " did not match : " + messsage + ": expected {" + m1
+                        + "}, but was {" + m2 + "}", m1 == null ^ m2 == null);
+            assertEquals("Message " + (i + 1) + " did not match: " + messsage + ": expected {" + m1
+                         + "}, but was {" + m2 + "}", m1.getText(), m2.getText());
+        }
+    }
+
+    protected ConnectionFactory createConnectionFactory() throws Exception {
+        return broker.get_connection_factory();
+    }
+
+    /**
+     * Factory method to create a new connection
+     */
+    protected Connection createConnection() throws Exception {
+        return getConnectionFactory().createConnection();
+    }
+
+    public ConnectionFactory getConnectionFactory() throws Exception {
+        if (connectionFactory == null) {
+            connectionFactory = createConnectionFactory();
+            assertTrue("Should have created a connection factory!", connectionFactory != null);
+        }
+        return connectionFactory;
+    }
+
+    protected String getConsumerSubject() {
+        return getSubject();
+    }
+
+    protected String getProducerSubject() {
+        return getSubject();
+    }
+
+    protected String getSubject() {
+        return getName();
+    }
+
+    public static void recursiveDelete(File f) {
+        if (f.isDirectory()) {
+            File[] files = f.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                recursiveDelete(files[i]);
+            }
+        }
+        f.delete();
+    }
+
+    public static void removeMessageStore() {
+        if (System.getProperty("activemq.store.dir") != null) {
+            recursiveDelete(new File(System.getProperty("activemq.store.dir")));
+        }
+        if (System.getProperty("derby.system.home") != null) {
+            recursiveDelete(new File(System.getProperty("derby.system.home")));
+        }
+    }
+
+    /*
+    public static DestinationStatistics getDestinationStatistics(BrokerService broker, ActiveMQDestination destination) {
+        DestinationStatistics result = null;
+        org.apache.activemq.broker.region.Destination dest = getDestination(broker, destination);
+        if (dest != null) {
+            result = dest.getDestinationStatistics();
+        }
+        return result;
+    }
+    */
+
+    /*
+    public static org.apache.activemq.broker.region.Destination getDestination(BrokerService target, ActiveMQDestination destination) {
+        org.apache.activemq.broker.region.Destination result = null;
+        for (org.apache.activemq.broker.region.Destination dest : getDestinationMap(target, destination).values()) {
+            if (dest.getName().equals(destination.getPhysicalName())) {
+                result = dest;
+                break;
+            }
+        }
+        return result;
+    }
+    */
+
+    /*
+    private static Map<ActiveMQDestination, org.apache.activemq.broker.region.Destination> getDestinationMap(BrokerService target,
+            ActiveMQDestination destination) {
+        RegionBroker regionBroker = (RegionBroker) target.getRegionBroker();
+        return destination.isQueue() ?
+                    regionBroker.getQueueRegion().getDestinationMap() :
+                        regionBroker.getTopicRegion().getDestinationMap();
+    }
+    */
+
+
+    //public static enum PersistenceAdapterChoice {KahaDB, AMQ, JDBC, MEM };
+
+    /*
+    public PersistenceAdapter setDefaultPersistenceAdapter(BrokerService broker) throws IOException {
+        return setPersistenceAdapter(broker, defaultPersistenceAdapter);
+    }
+    */
+
+    /*
+    public PersistenceAdapter setPersistenceAdapter(BrokerService broker, PersistenceAdapterChoice choice) throws IOException {
+        PersistenceAdapter adapter = null;
+        switch (choice) {
+        case AMQ:
+            adapter = new AMQPersistenceAdapter();
+            break;
+        case JDBC:
+            adapter = new JDBCPersistenceAdapter();
+            break;
+        case KahaDB:
+            adapter = new KahaDBPersistenceAdapter();
+            break;
+        case MEM:
+            adapter = new MemoryPersistenceAdapter();
+            break;
+        }
+        broker.setPersistenceAdapter(adapter);
+        return adapter;
+    }
+    */
+
+    /**
+     * Test if base directory contains spaces
+     */
+    protected void assertBaseDirectoryContainsSpaces() {
+    	assertFalse("Base directory cannot contain spaces.", new File(System.getProperty("basedir", ".")).getAbsoluteFile().toString().contains(" "));
+    }
+
+}

Modified: activemq/activemq-apollo/trunk/pom.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/pom.xml?rev=1212081&r1=1212080&r2=1212081&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/pom.xml (original)
+++ activemq/activemq-apollo/trunk/pom.xml Thu Dec  8 20:11:54 2011
@@ -172,6 +172,7 @@
     <module>apollo-web</module>
     <module>apollo-cli</module>
     <module>apollo-website</module>
+    <module>apollo-itests</module>
     <module>apollo-distro</module>
     <module>apollo-karaf-feature</module>
   </modules>