You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2014/09/23 20:20:34 UTC

[10/27] Initial drop of donated AMQP Client Code.

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsStreamMessageTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsStreamMessageTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsStreamMessageTest.java
new file mode 100644
index 0000000..b21068b
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsStreamMessageTest.java
@@ -0,0 +1,1133 @@
+/**
+ * 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.qpid.jms.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+import javax.jms.JMSException;
+import javax.jms.MessageEOFException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotReadableException;
+import javax.jms.MessageNotWriteableException;
+import javax.jms.StreamMessage;
+
+import org.apache.qpid.jms.message.JmsDefaultMessageFactory;
+import org.apache.qpid.jms.message.JmsMessageFactory;
+import org.apache.qpid.jms.message.JmsStreamMessage;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class JmsStreamMessageTest {
+
+    private final JmsMessageFactory factory = new JmsDefaultMessageFactory();
+
+    // ======= general =========
+
+    @Test
+    public void testReadWithEmptyStreamThrowsMEOFE() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        streamMessage.reset();
+
+        try {
+            streamMessage.readBoolean();
+            fail("Expected exception to be thrown as message has no content");
+        } catch (MessageEOFException meofe) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testClearBodyOnNewMessageRemovesExistingValues() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        streamMessage.writeBoolean(true);
+
+        streamMessage.clearBody();
+
+        streamMessage.writeBoolean(false);
+        streamMessage.reset();
+
+        // check we get only the value added after the clear
+        assertFalse("expected value added after the clear", streamMessage.readBoolean());
+
+        try {
+            streamMessage.readBoolean();
+            fail("Expected exception to be thrown");
+        } catch (MessageEOFException meofe) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testNewMessageIsWriteOnlyThrowsMNRE() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        try {
+            streamMessage.readBoolean();
+            fail("Expected exception to be thrown as message is not readable");
+        } catch (MessageNotReadableException mnre) {
+            // expected
+        }
+    }
+
+    /**
+     * Verify the stream position is not incremented during illegal type conversion failure.
+     * This covers every read method except readObject (which doesn't do type conversion) and
+     * readBytes(), which is tested by
+     * {@link #testIllegalTypeConvesionFailureDoesNotIncrementPosition2}
+     *
+     * Write bytes, then deliberately try to retrieve them as illegal types, then check they can
+     * be successfully read.
+     */
+    @Test
+    public void testIllegalTypeConvesionFailureDoesNotIncrementPosition1() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 0, (byte) 255, (byte) 78 };
+
+        streamMessage.writeBytes(bytes);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, String.class);
+
+        byte[] retrievedByteArray = new byte[bytes.length];
+        int readBytesLength = streamMessage.readBytes(retrievedByteArray);
+
+        assertEquals("Number of bytes read did not match original array length", bytes.length, readBytesLength);
+        assertArrayEquals("Expected array to equal retrieved bytes", bytes, retrievedByteArray);
+        assertEquals("Expected completion return value", -1, streamMessage.readBytes(retrievedByteArray));
+    }
+
+    /**
+     * Verify the stream position is not incremented during illegal type conversion failure.
+     * This test covers only readBytes, other methods are tested by
+     * {@link #testIllegalTypeConvesionFailureDoesNotIncrementPosition1}
+     *
+     * Write String, then deliberately try illegal retrieval as bytes, then check it can be
+     * successfully read.
+     */
+    @Test
+    public void testIllegalTypeConvesionFailureDoesNotIncrementPosition2() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        String stringVal = "myString";
+        streamMessage.writeString(stringVal);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+
+        assertEquals("Expected written string", stringVal, streamMessage.readString());
+    }
+
+    /**
+     * When a null stream entry is encountered, the accessor methods is type dependent and
+     * should either return null, throw NPE, or behave in the same fashion as
+     * <primitive>.valueOf(String).
+     *
+     * Test that this is the case, and in doing show demonstrate that primitive type conversion
+     * failure does not increment the stream position, as shown by not hitting the end of the
+     * stream unexpectedly.
+     */
+    @Test
+    public void testNullStreamEntryResultsInExpectedBehaviour() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        streamMessage.writeObject(null);
+        streamMessage.reset();
+
+        // expect an NFE from the primitive integral <type>.valueOf(null) conversions
+        assertGetStreamEntryThrowsNumberFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsNumberFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsNumberFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsNumberFormatException(streamMessage, Long.class);
+
+        // expect an NPE from the primitive float, double, and char <type>.valuleOf(null)
+        // conversions
+        assertGetStreamEntryThrowsNullPointerException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsNullPointerException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsNullPointerException(streamMessage, Character.class);
+
+        // expect null
+        assertNull(streamMessage.readObject());
+        streamMessage.reset(); // need to reset as read was a success
+        assertNull(streamMessage.readString());
+        streamMessage.reset(); // need to reset as read was a success
+
+        // expect completion value.
+        assertEquals(-1, streamMessage.readBytes(new byte[1]));
+        streamMessage.reset(); // need to reset as read was a success
+
+        // expect false from Boolean.valueOf(null).
+        assertFalse(streamMessage.readBoolean());
+        streamMessage.reset(); // need to reset as read was a success
+    }
+
+
+    @Test
+    public void testClearBodyAppliesCorrectState() throws JMSException {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        try {
+            streamMessage.writeObject(new Long(2));
+            streamMessage.clearBody();
+            assertFalse(streamMessage.isReadOnlyBody());
+            streamMessage.writeObject(new Long(2));
+            streamMessage.readObject();
+            fail("should throw exception");
+        } catch (MessageNotReadableException mnwe) {
+        } catch (MessageNotWriteableException mnwe) {
+            fail("should be writeable");
+        }
+    }
+
+    @Test
+    public void testResetAppliesCorrectState() throws JMSException {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        try {
+            streamMessage.writeDouble(24.5);
+            streamMessage.writeLong(311);
+        } catch (MessageNotWriteableException mnwe) {
+            fail("should be writeable");
+        }
+        streamMessage.reset();
+        try {
+            assertTrue(streamMessage.isReadOnlyBody());
+            assertEquals(streamMessage.readDouble(), 24.5, 0);
+            assertEquals(streamMessage.readLong(), 311);
+        } catch (MessageNotReadableException mnre) {
+            fail("should be readable");
+        }
+        try {
+            streamMessage.writeInt(33);
+            fail("should throw exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+    }
+
+    // ======= object =========
+
+    @Test
+    public void testWriteObjectWithIllegalTypeThrowsMFE() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        try {
+            streamMessage.writeObject(BigInteger.ONE);
+            fail("Expected exception to be thrown");
+        } catch (MessageFormatException mfe) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testWriteReadObject() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        Object nullEntryValue = null;
+        Boolean boolEntryValue = Boolean.valueOf(false);
+        Byte byteEntryValue = Byte.valueOf((byte) 1);
+        Short shortEntryValue = Short.valueOf((short) 2);
+        Integer intEntryValue = Integer.valueOf(3);
+        Long longEntryValue = Long.valueOf(4);
+        Float floatEntryValue = Float.valueOf(5.01F);
+        Double doubleEntryValue = Double.valueOf(6.01);
+        String stringEntryValue = "string";
+        Character charEntryValue = Character.valueOf('c');
+        byte[] bytes = new byte[] { (byte) 1, (byte) 170, (byte) 65 };
+
+        streamMessage.writeObject(nullEntryValue);
+        streamMessage.writeObject(boolEntryValue);
+        streamMessage.writeObject(byteEntryValue);
+        streamMessage.writeObject(shortEntryValue);
+        streamMessage.writeObject(intEntryValue);
+        streamMessage.writeObject(longEntryValue);
+        streamMessage.writeObject(floatEntryValue);
+        streamMessage.writeObject(doubleEntryValue);
+        streamMessage.writeObject(stringEntryValue);
+        streamMessage.writeObject(charEntryValue);
+        streamMessage.writeObject(bytes);
+
+        streamMessage.reset();
+
+        assertEquals("Got unexpected value from stream", nullEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", boolEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", byteEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", shortEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", intEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", longEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", floatEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", doubleEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", stringEntryValue, streamMessage.readObject());
+        assertEquals("Got unexpected value from stream", charEntryValue, streamMessage.readObject());
+        assertArrayEquals("Got unexpected value from stream", bytes, (byte[]) streamMessage.readObject());
+    }
+
+    // ======= bytes =========
+
+    /**
+     * Write bytes, then retrieve them as all of the legal type combinations
+     */
+    @Test
+    public void testWriteBytesReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] value = new byte[] { (byte) 0, (byte) 255, (byte) 78 };
+
+        streamMessage.writeBytes(value);
+        streamMessage.reset();
+
+        byte[] dest = new byte[value.length];
+
+        int readBytesLength = streamMessage.readBytes(dest);
+        assertEquals("Number of bytes read did not match expectation", value.length, readBytesLength);
+        assertArrayEquals("value not as expected", value, dest);
+    }
+
+    /**
+     * Write bytes, then retrieve them as all of the illegal type combinations to verify it
+     * fails as expected
+     */
+    @Test
+    public void testWriteBytesReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] value = new byte[] { (byte) 0, (byte) 255, (byte) 78 };
+
+        streamMessage.writeBytes(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, String.class);
+    }
+
+    @Test
+    public void testReadBytesWithNullSignalsCompletion() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+        streamMessage.writeObject(null);
+
+        streamMessage.reset();
+
+        assertEquals("Expected immediate completion signal", -1, streamMessage.readBytes(new byte[1]));
+    }
+
+    @Test
+    public void testReadBytesWithZeroLengthSource() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        streamMessage.writeBytes(new byte[0]);
+
+        streamMessage.reset();
+
+        byte[] fullRetrievedBytes = new byte[1];
+
+        assertEquals("Expected no bytes to be read, as none were written", 0, streamMessage.readBytes(fullRetrievedBytes));
+    }
+
+    @Test
+    public void testReadBytesWithZeroLengthDestination() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 11, (byte) 44, (byte) 99 };
+        streamMessage.writeBytes(bytes);
+
+        streamMessage.reset();
+
+        byte[] zeroDestination = new byte[0];
+        byte[] fullRetrievedBytes = new byte[bytes.length];
+
+        assertEquals("Expected no bytes to be read", 0, streamMessage.readBytes(zeroDestination));
+        assertEquals("Expected all bytes to be read", bytes.length, streamMessage.readBytes(fullRetrievedBytes));
+        assertArrayEquals("Expected arrays to be equal", bytes, fullRetrievedBytes);
+        assertEquals("Expected completion signal", -1, streamMessage.readBytes(zeroDestination));
+    }
+
+    @Test
+    public void testReadObjectForBytesReturnsNewArray() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 11, (byte) 44, (byte) 99 };
+        streamMessage.writeBytes(bytes);
+
+        streamMessage.reset();
+
+        byte[] retrievedBytes = (byte[]) streamMessage.readObject();
+
+        assertNotSame("Expected different array objects", bytes, retrievedBytes);
+        assertArrayEquals("Expected arrays to be equal", bytes, retrievedBytes);
+    }
+
+    @Test
+    public void testReadBytesFullWithUndersizedDestinationArrayUsingMultipleReads() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 3, (byte) 78, (byte) 253, (byte) 26, (byte) 8 };
+        assertEquals("bytes should be odd length", 1, bytes.length % 2);
+        int undersizedLength = 2;
+        int remaining = 1;
+
+        streamMessage.writeBytes(bytes);
+        streamMessage.reset();
+
+        byte[] undersizedDestination = new byte[undersizedLength];
+        byte[] fullRetrievedBytes = new byte[bytes.length];
+
+        assertEquals("Number of bytes read did not match destination array length", undersizedLength, streamMessage.readBytes(undersizedDestination));
+        int read = undersizedLength;
+        System.arraycopy(undersizedDestination, 0, fullRetrievedBytes, 0, undersizedLength);
+        assertEquals("Number of bytes read did not match destination array length", undersizedLength, streamMessage.readBytes(undersizedDestination));
+        System.arraycopy(undersizedDestination, 0, fullRetrievedBytes, read, undersizedLength);
+        read += undersizedLength;
+        assertEquals("Number of bytes read did not match expectation", remaining, streamMessage.readBytes(undersizedDestination));
+        System.arraycopy(undersizedDestination, 0, fullRetrievedBytes, read, remaining);
+        read += remaining;
+        assertArrayEquals("Expected array to equal retrieved bytes", bytes, fullRetrievedBytes);
+    }
+
+    @Test
+    public void testReadBytesFullWithPreciselySizedDestinationArray() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 11, (byte) 44, (byte) 99 };
+        streamMessage.writeBytes(bytes);
+
+        streamMessage.reset();
+
+        byte[] retrievedByteArray = new byte[bytes.length];
+        int readBytesLength = streamMessage.readBytes(retrievedByteArray);
+
+        assertEquals("Number of bytes read did not match original array length", bytes.length, readBytesLength);
+        assertArrayEquals("Expected array to equal retrieved bytes", bytes, retrievedByteArray);
+        assertEquals("Expected completion return value", -1, streamMessage.readBytes(retrievedByteArray));
+    }
+
+    @Test
+    public void testReadBytesFullWithOversizedDestinationArray() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 4, (byte) 115, (byte) 255 };
+        streamMessage.writeBytes(bytes);
+
+        streamMessage.reset();
+
+        byte[] oversizedDestination = new byte[bytes.length + 1];
+        int readBytesLength = streamMessage.readBytes(oversizedDestination);
+
+        assertEquals("Number of bytes read did not match original array length", bytes.length, readBytesLength);
+        assertArrayEquals("Expected array subset to equal retrieved bytes", bytes, Arrays.copyOfRange(oversizedDestination, 0, readBytesLength));
+    }
+
+    /**
+     * {@link StreamMessage#readBytes(byte[])} indicates:
+     *
+     * "Once the first readBytes call on a byte[] field value has been made, the full value of
+     * the field must be read before it is valid to read the next field. An attempt to read the
+     * next field before that has been done will throw a MessageFormatException."
+     *
+     * {@link StreamMessage#readObject()} indicates: "An attempt to call readObject to read a
+     * byte field value into a new byte[] object before the full value of the byte field has
+     * been read will throw a MessageFormatException."
+     *
+     * Test that these restrictions are met, and don't interfere with completing the readBytes
+     * usage.
+     */
+    @Test
+    public void testReadObjectAfterPartialReadBytesThrowsMFE() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] bytes = new byte[] { (byte) 11, (byte) 44, (byte) 99 };
+        streamMessage.writeBytes(bytes);
+
+        streamMessage.reset();
+
+        // start reading via readBytes
+        int partialLength = 2;
+        byte[] retrievedByteArray = new byte[partialLength];
+        int readBytesLength = streamMessage.readBytes(retrievedByteArray);
+
+        assertEquals(partialLength, readBytesLength);
+        assertArrayEquals("Expected array subset to equal retrieved bytes", Arrays.copyOf(bytes, partialLength), retrievedByteArray);
+
+        // check that using readObject does not return the full/remaining bytes as a new array
+        try {
+            streamMessage.readObject();
+            fail("expected exception to be thrown");
+        } catch (MessageFormatException mfe) {
+            // expected
+        }
+
+        // finish reading via reaBytes to ensure it can be completed
+        readBytesLength = streamMessage.readBytes(retrievedByteArray);
+        assertEquals(bytes.length - partialLength, readBytesLength);
+        assertArrayEquals("Expected array subset to equal retrieved bytes", Arrays.copyOfRange(bytes, partialLength, bytes.length),
+            Arrays.copyOfRange(retrievedByteArray, 0, readBytesLength));
+    }
+
+    /**
+     * Verify that setting bytes takes a copy of the array. Set bytes subset, then retrieve the
+     * entry and verify the are different arrays and the subsets are equal.
+     */
+    @Test
+    public void testWriteBytesWithOffsetAndLength() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte[] orig = "myBytesAll".getBytes();
+
+        // extract the segment containing 'Bytes'
+        int offset = 2;
+        int length = 5;
+        byte[] segment = Arrays.copyOfRange(orig, offset, offset + length);
+
+        // set the same section from the original bytes
+        streamMessage.writeBytes(orig, offset, length);
+        streamMessage.reset();
+
+        byte[] retrieved = (byte[]) streamMessage.readObject();
+
+        // verify the retrieved bytes from the stream equal the segment but are not the same
+        assertNotSame(orig, retrieved);
+        assertNotSame(segment, retrieved);
+        assertArrayEquals(segment, retrieved);
+    }
+
+    // ========= boolean ========
+
+    @Test
+    public void testWriteReadBoolean() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        boolean value = true;
+
+        streamMessage.writeBoolean(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readBoolean());
+    }
+
+    /**
+     * Set a boolean, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testWriteBooleanReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        boolean value = true;
+
+        streamMessage.writeBoolean(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, value, Boolean.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a boolean, then retrieve it as all of the illegal type combinations to verify it
+     * fails as expected
+     */
+    @Test
+    public void testSetBooleanGetIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        boolean value = true;
+
+        streamMessage.writeBoolean(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= string ========
+
+    @Test
+    public void testWriteReadString() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        String value = "myString";
+
+        streamMessage.writeString(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readString());
+    }
+
+    /**
+     * Set a string, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testWriteStringReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        String integralValue = String.valueOf(Byte.MAX_VALUE);
+        streamMessage.writeString(integralValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(integralValue), String.class);
+        assertGetStreamEntryEquals(streamMessage, true, Boolean.valueOf(integralValue), Boolean.class);
+        assertGetStreamEntryEquals(streamMessage, true, Byte.valueOf(integralValue), Byte.class);
+
+        streamMessage.clearBody();
+        integralValue = String.valueOf(Short.MAX_VALUE);
+        streamMessage.writeString(integralValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Short.valueOf(integralValue), Short.class);
+
+        streamMessage.clearBody();
+        integralValue = String.valueOf(Integer.MAX_VALUE);
+        streamMessage.writeString(integralValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Integer.valueOf(integralValue), Integer.class);
+
+        streamMessage.clearBody();
+        integralValue = String.valueOf(Long.MAX_VALUE);
+        streamMessage.writeString(integralValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Long.valueOf(integralValue), Long.class);
+
+        streamMessage.clearBody();
+        String fpValue = String.valueOf(Float.MAX_VALUE);
+        streamMessage.writeString(fpValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Float.valueOf(fpValue), Float.class);
+        assertGetStreamEntryEquals(streamMessage, true, Double.valueOf(fpValue), Double.class);
+    }
+
+    /**
+     * Set a string, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteStringReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        String stringValue = "myString";
+
+        streamMessage.writeString(stringValue);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // TODO - Support Big Strings
+    @Ignore
+    @Test
+    public void testReadBigString() throws JMSException {
+        JmsStreamMessage msg = factory.createStreamMessage();
+        // Test with a 1Meg String
+        StringBuffer bigSB = new StringBuffer(1024 * 1024);
+        for (int i = 0; i < 1024 * 1024; i++) {
+            bigSB.append('a' + i % 26);
+        }
+        String bigString = bigSB.toString();
+
+        msg.writeString(bigString);
+        msg.reset();
+        assertEquals(bigString, msg.readString());
+    }
+
+    // ========= byte ========
+
+    @Test
+    public void testWriteReadByte() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte value = (byte) 6;
+
+        streamMessage.writeByte(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readByte());
+    }
+
+    /**
+     * Set a byte, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testWriteByteReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte value = (byte) 6;
+
+        streamMessage.writeByte(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Byte.valueOf(value), Byte.class);
+        assertGetStreamEntryEquals(streamMessage, true, Short.valueOf(value), Short.class);
+        assertGetStreamEntryEquals(streamMessage, true, Integer.valueOf(value), Integer.class);
+        assertGetStreamEntryEquals(streamMessage, true, Long.valueOf(value), Long.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a byte, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteByteReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        byte value = (byte) 6;
+
+        streamMessage.writeByte(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= short ========
+
+    @Test
+    public void testWriteReadShort() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        short value = (short) 302;
+
+        streamMessage.writeShort(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readShort());
+    }
+
+    /**
+     * Set a short, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testWriteShortReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        short value = (short) 302;
+
+        streamMessage.writeShort(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Short.valueOf(value), Short.class);
+        assertGetStreamEntryEquals(streamMessage, true, Integer.valueOf(value), Integer.class);
+        assertGetStreamEntryEquals(streamMessage, true, Long.valueOf(value), Long.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a short, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteShortReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        short value = (short) 302;
+
+        streamMessage.writeShort(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= char ========
+
+    @Test
+    public void testWriteReadChar() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        char value = 'c';
+
+        streamMessage.writeChar(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readChar());
+    }
+
+    /**
+     * Set a char, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testWriteCharReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        char value = 'c';
+
+        streamMessage.writeChar(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, value, Character.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a char, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteCharReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        char value = 'c';
+
+        streamMessage.writeChar(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= int ========
+
+    @Test
+    public void testWriteReadInt() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        int value = Integer.MAX_VALUE;
+
+        streamMessage.writeInt(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readInt());
+    }
+
+    /**
+     * Set an int, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testWriteIntReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        int value = Integer.MAX_VALUE;
+
+        streamMessage.writeInt(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Integer.valueOf(value), Integer.class);
+        assertGetStreamEntryEquals(streamMessage, true, Long.valueOf(value), Long.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set an int, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteIntReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        int value = Integer.MAX_VALUE;
+
+        streamMessage.writeInt(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= long ========
+
+    @Test
+    public void testWriteReadLong() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        long value = Long.MAX_VALUE;
+
+        streamMessage.writeLong(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readLong());
+    }
+
+    /**
+     * Set a long, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testWriteLongReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        long value = Long.MAX_VALUE;
+
+        streamMessage.writeLong(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Long.valueOf(value), Long.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a long, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteLongReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        long value = Long.MAX_VALUE;
+
+        streamMessage.writeLong(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Double.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= float ========
+
+    @Test
+    public void testWriteReadFloat() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        float value = Float.MAX_VALUE;
+
+        streamMessage.writeFloat(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readFloat(), 0.0);
+    }
+
+    /**
+     * Set a float, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testWriteFloatReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        float value = Float.MAX_VALUE;
+
+        streamMessage.writeFloat(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Float.valueOf(value), Float.class);
+        assertGetStreamEntryEquals(streamMessage, true, Double.valueOf(value), Double.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a float, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteFloatReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        float value = Float.MAX_VALUE;
+
+        streamMessage.writeFloat(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= double ========
+
+    @Test
+    public void testWriteReadDouble() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        double value = Double.MAX_VALUE;
+
+        streamMessage.writeDouble(value);
+        streamMessage.reset();
+
+        assertEquals("Value not as expected", value, streamMessage.readDouble(), 0.0);
+    }
+
+    /**
+     * Set a double, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testWriteDoubleReadLegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        double value = Double.MAX_VALUE;
+
+        streamMessage.writeDouble(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryEquals(streamMessage, true, Double.valueOf(value), Double.class);
+        assertGetStreamEntryEquals(streamMessage, true, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a double, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testWriteDoubleReadIllegal() throws Exception {
+        JmsStreamMessage streamMessage = factory.createStreamMessage();
+
+        double value = Double.MAX_VALUE;
+
+        streamMessage.writeDouble(value);
+        streamMessage.reset();
+
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Boolean.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Byte.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Short.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Character.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Integer.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Long.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, Float.class);
+        assertGetStreamEntryThrowsMessageFormatException(streamMessage, byte[].class);
+    }
+
+    // ========= utility methods ========
+
+    private void assertGetStreamEntryEquals(JmsStreamMessage testMessage, boolean resetStreamAfter, Object expectedValue, Class<?> clazz) throws JMSException {
+        if (clazz == byte[].class) {
+            throw new IllegalArgumentException("byte[] values not suported");
+        }
+
+        Object actualValue = getStreamEntryUsingTypeMethod(testMessage, clazz, null);
+        assertEquals(expectedValue, actualValue);
+
+        if (resetStreamAfter) {
+            testMessage.reset();
+        }
+    }
+
+    private void assertGetStreamEntryThrowsMessageFormatException(JmsStreamMessage testMessage, Class<?> clazz) throws JMSException {
+        try {
+            getStreamEntryUsingTypeMethod(testMessage, clazz, new byte[0]);
+
+            fail("expected exception to be thrown");
+        } catch (MessageFormatException jmsMFE) {
+            // expected
+        }
+    }
+
+    private void assertGetStreamEntryThrowsNullPointerException(JmsStreamMessage testMessage, Class<?> clazz) throws JMSException {
+        try {
+            getStreamEntryUsingTypeMethod(testMessage, clazz, new byte[0]);
+
+            fail("expected exception to be thrown");
+        } catch (NullPointerException npe) {
+            // expected
+        }
+    }
+
+    private void assertGetStreamEntryThrowsNumberFormatException(JmsStreamMessage testMessage, Class<?> clazz) throws JMSException {
+        assertGetStreamEntryThrowsNumberFormatException(testMessage, clazz, null);
+    }
+
+    private void assertGetStreamEntryThrowsNumberFormatException(JmsStreamMessage testMessage, Class<?> clazz, byte[] destination) throws JMSException {
+        if (clazz == byte[].class && destination == null) {
+            throw new IllegalArgumentException("Destinatinon byte[] must be supplied");
+        }
+
+        try {
+            getStreamEntryUsingTypeMethod(testMessage, clazz, destination);
+
+            fail("expected exception to be thrown");
+        } catch (NumberFormatException nfe) {
+            // expected
+        }
+    }
+
+    private Object getStreamEntryUsingTypeMethod(JmsStreamMessage testMessage, Class<?> clazz, byte[] destination) throws JMSException {
+        if (clazz == Boolean.class) {
+            return testMessage.readBoolean();
+        } else if (clazz == Byte.class) {
+            return testMessage.readByte();
+        } else if (clazz == Character.class) {
+            return testMessage.readChar();
+        } else if (clazz == Short.class) {
+            return testMessage.readShort();
+        } else if (clazz == Integer.class) {
+            return testMessage.readInt();
+        } else if (clazz == Long.class) {
+            return testMessage.readLong();
+        } else if (clazz == Float.class) {
+            return testMessage.readFloat();
+        } else if (clazz == Double.class) {
+            return testMessage.readDouble();
+        } else if (clazz == String.class) {
+            return testMessage.readString();
+        } else if (clazz == byte[].class) {
+            return testMessage.readBytes(destination);
+        } else {
+            throw new RuntimeException("Unexpected entry type class");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsTextMessageTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsTextMessageTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsTextMessageTest.java
new file mode 100644
index 0000000..6757ab8
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsTextMessageTest.java
@@ -0,0 +1,138 @@
+/**
+ * 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.qpid.jms.message;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import javax.jms.JMSException;
+import javax.jms.MessageNotReadableException;
+import javax.jms.MessageNotWriteableException;
+
+import org.apache.qpid.jms.message.JmsDefaultMessageFactory;
+import org.apache.qpid.jms.message.JmsMessageFactory;
+import org.apache.qpid.jms.message.JmsTextMessage;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class JmsTextMessageTest {
+
+    private final JmsMessageFactory factory = new JmsDefaultMessageFactory();
+
+    @Test
+    public void testShallowCopy() throws JMSException {
+        JmsTextMessage msg = factory.createTextMessage();
+        String string = "str";
+        msg.setText(string);
+        JmsTextMessage copy = msg.copy();
+        assertTrue(msg.getText() == copy.getText());
+    }
+
+    @Test
+    public void testSetText() throws JMSException {
+        JmsTextMessage msg = factory.createTextMessage();
+        String str = "testText";
+        msg.setText(str);
+        assertEquals(msg.getText(), str);
+    }
+
+    @Test
+    public void testClearBody() throws JMSException, IOException {
+        JmsTextMessage textMessage = factory.createTextMessage();
+        textMessage.setText("string");
+        textMessage.clearBody();
+        assertFalse(textMessage.isReadOnlyBody());
+        assertNull(textMessage.getText());
+        try {
+            textMessage.setText("String");
+            textMessage.getText();
+        } catch (MessageNotWriteableException mnwe) {
+            fail("should be writeable");
+        } catch (MessageNotReadableException mnre) {
+            fail("should be readable");
+        }
+    }
+
+    @Test
+    public void testReadOnlyBody() throws JMSException {
+        JmsTextMessage textMessage = factory.createTextMessage();
+        textMessage.setText("test");
+        textMessage.setReadOnlyBody(true);
+        try {
+            textMessage.getText();
+        } catch (MessageNotReadableException e) {
+            fail("should be readable");
+        }
+        try {
+            textMessage.setText("test");
+            fail("should throw exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+    }
+
+    @Test
+    public void testWriteOnlyBody() throws JMSException { // should always be readable
+        JmsTextMessage textMessage = factory.createTextMessage();
+        textMessage.setReadOnlyBody(false);
+        try {
+            textMessage.setText("test");
+            textMessage.getText();
+        } catch (MessageNotReadableException e) {
+            fail("should be readable");
+        }
+        textMessage.setReadOnlyBody(true);
+        try {
+            textMessage.getText();
+            textMessage.setText("test");
+            fail("should throw exception");
+        } catch (MessageNotReadableException e) {
+            fail("should be readable");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+    }
+
+    // TODO - Fix toString and null body.
+    @Test
+    public void testShortText() throws Exception {
+        String shortText = "Content";
+        JmsTextMessage shortMessage = factory.createTextMessage();
+        shortMessage.setText(shortText);
+        //assertTrue(shortMessage.toString().contains("text = " + shortText));
+        assertTrue(shortMessage.getText().equals(shortText));
+
+        String longText = "Very very very very veeeeeeery loooooooooooooooooooooooooooooooooong text";
+        // String longExpectedText = "Very very very very veeeeeeery looooooooooooo...ooooong text";
+        JmsTextMessage longMessage = factory.createTextMessage();
+        longMessage.setText(longText);
+        //assertTrue(longMessage.toString().contains("text = " + longExpectedText));
+        assertTrue(longMessage.getText().equals(longText));
+    }
+
+    @Test
+    public void testNullText() throws Exception {
+        JmsTextMessage nullMessage = factory.createTextMessage();
+        nullMessage.setText(null);
+        assertNull(nullMessage.getText());
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageIdHelperTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageIdHelperTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageIdHelperTest.java
new file mode 100644
index 0000000..b168ec6
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageIdHelperTest.java
@@ -0,0 +1,496 @@
+/*
+ *
+ * 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.qpid.jms.provider.amqp.message;
+
+import static org.junit.Assert.*;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import org.apache.qpid.jms.exceptions.IdConversionException;
+import org.apache.qpid.jms.provider.amqp.message.AmqpMessageIdHelper;
+import org.apache.qpid.jms.test.QpidJmsTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AmqpMessageIdHelperTest extends QpidJmsTestCase {
+    private AmqpMessageIdHelper _messageIdHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        _messageIdHelper = new AmqpMessageIdHelper();
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#hasMessageIdPrefix(String)} returns true for strings that begin "ID:"
+     */
+    @Test
+    public void testHasIdPrefixWithPrefix() {
+        String myId = "ID:something";
+        assertTrue("'ID:' prefix should have been identified", _messageIdHelper.hasMessageIdPrefix(myId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#hasMessageIdPrefix(String)} returns false for string beings "ID" without colon.
+     */
+    @Test
+    public void testHasIdPrefixWithIDButNoColonPrefix() {
+        String myIdNoColon = "IDsomething";
+        assertFalse("'ID' prefix should not have been identified without trailing colon", _messageIdHelper.hasMessageIdPrefix(myIdNoColon));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#hasMessageIdPrefix(String)} returns false for null
+     */
+    @Test
+    public void testHasIdPrefixWithNull() {
+        String nullString = null;
+        assertFalse("null string should not result in identification as having the prefix", _messageIdHelper.hasMessageIdPrefix(nullString));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#hasMessageIdPrefix(String)} returns false for strings that doesnt have "ID:" anywhere
+     */
+    @Test
+    public void testHasIdPrefixWithoutPrefix() {
+        String myNonId = "something";
+        assertFalse("string without 'ID:' anywhere should not have been identified as having the prefix", _messageIdHelper.hasMessageIdPrefix(myNonId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#hasMessageIdPrefix(String)} returns false for strings has lowercase "id:" prefix
+     */
+    @Test
+    public void testHasIdPrefixWithLowercaseID() {
+        String myLowerCaseNonId = "id:something";
+        assertFalse("lowercase 'id:' prefix should not result in identification as having 'ID:' prefix", _messageIdHelper.hasMessageIdPrefix(myLowerCaseNonId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} strips "ID:" from strings that do begin "ID:"
+     */
+    @Test
+    public void testStripMessageIdPrefixWithPrefix() {
+        String myIdWithoutPrefix = "something";
+        String myId = "ID:" + myIdWithoutPrefix;
+        assertEquals("'ID:' prefix should have been stripped", myIdWithoutPrefix, _messageIdHelper.stripMessageIdPrefix(myId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} only strips one "ID:" from strings that
+     * begin "ID:ID:...."
+     */
+    @Test
+    public void testStripMessageIdPrefixWithDoublePrefix() {
+        String myIdWithSinglePrefix = "ID:something";
+        String myIdWithDoublePrefix = "ID:" + myIdWithSinglePrefix;
+        assertEquals("'ID:' prefix should only have been stripped once", myIdWithSinglePrefix, _messageIdHelper.stripMessageIdPrefix(myIdWithDoublePrefix));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} does not alter strings that begins "ID" without a colon.
+     */
+    @Test
+    public void testStripMessageIdPrefixWithIDButNoColonPrefix() {
+        String myIdNoColon = "IDsomething";
+        assertEquals("string without 'ID:' prefix should have been returned unchanged", myIdNoColon, _messageIdHelper.stripMessageIdPrefix(myIdNoColon));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} returns null if given null;
+     */
+    @Test
+    public void testStripMessageIdPrefixWithNull() {
+        String nullString = null;
+        assertNull("null string should have been returned", _messageIdHelper.stripMessageIdPrefix(nullString));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} does not alter string that doesn't begin "ID:"
+     */
+    @Test
+    public void testStripMessageIdPrefixWithoutIDAnywhere() {
+        String myNonId = "something";
+        assertEquals("string without 'ID:' anywhere should have been returned unchanged", myNonId, _messageIdHelper.stripMessageIdPrefix(myNonId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#stripMessageIdPrefix(String)} does not alter string with lowercase "id:"
+     */
+    @Test
+    public void testStripMessageIdPrefixWithLowercaseID() {
+        String myLowerCaseNonId = "id:something";
+        assertEquals("string with lowercase 'id:' prefix should have been returned unchanged", myLowerCaseNonId, _messageIdHelper.stripMessageIdPrefix(myLowerCaseNonId));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns null if given null
+     */
+    @Test
+    public void testToBaseMessageIdStringWithNull() {
+        String nullString = null;
+        assertNull("null string should have been returned", _messageIdHelper.toBaseMessageIdString(nullString));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} throws an IAE if given an unexpected object type.
+     */
+    @Test
+    public void testToBaseMessageIdStringThrowsIAEWithUnexpectedType() {
+        try {
+            _messageIdHelper.toBaseMessageIdString(new Object());
+            fail("expected exception not thrown");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns the given
+     * basic string unchanged
+     */
+    @Test
+    public void testToBaseMessageIdStringWithString() {
+        String stringMessageId = "myIdString";
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(stringMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", stringMessageId, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded string, when the given string happens to already begin with
+     * the {@link AmqpMessageIdHelper#AMQP_UUID_PREFIX}.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithStringBeginningWithEncodingPrefixForUUID() {
+        String uuidStringMessageId = AmqpMessageIdHelper.AMQP_UUID_PREFIX + UUID.randomUUID();
+        String expected = AmqpMessageIdHelper.AMQP_STRING_PREFIX + uuidStringMessageId;
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(uuidStringMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded string, when the given string happens to already begin with
+     * the {@link AmqpMessageIdHelper#AMQP_ULONG_PREFIX}.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithStringBeginningWithEncodingPrefixForLong() {
+        String longStringMessageId = AmqpMessageIdHelper.AMQP_ULONG_PREFIX + Long.valueOf(123456789L);
+        String expected = AmqpMessageIdHelper.AMQP_STRING_PREFIX + longStringMessageId;
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(longStringMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded string, when the given string happens to already begin with
+     * the {@link AmqpMessageIdHelper#AMQP_BINARY_PREFIX}.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithStringBeginningWithEncodingPrefixForBinary() {
+        String binaryStringMessageId = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + "0123456789ABCDEF";
+        String expected = AmqpMessageIdHelper.AMQP_STRING_PREFIX + binaryStringMessageId;
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(binaryStringMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded string (effectively twice), when the given string happens to already begin with
+     * the {@link AmqpMessageIdHelper#AMQP_STRING_PREFIX}.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithStringBeginningWithEncodingPrefixForString() {
+        String stringMessageId = AmqpMessageIdHelper.AMQP_STRING_PREFIX + "myStringId";
+        String expected = AmqpMessageIdHelper.AMQP_STRING_PREFIX + stringMessageId;
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(stringMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded UUID when given a UUID object.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithUUID() {
+        UUID uuidMessageId = UUID.randomUUID();
+        String expected = AmqpMessageIdHelper.AMQP_UUID_PREFIX + uuidMessageId.toString();
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(uuidMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded ulong when given a Long object.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithLong() {
+        Long longMessageId = Long.valueOf(123456789L);
+        String expected = AmqpMessageIdHelper.AMQP_ULONG_PREFIX + longMessageId.toString();
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(longMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded ulong when given a BigInteger object.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithBigInteger() {
+        BigInteger bigIntMessageId = BigInteger.valueOf(123456789L);
+        String expected = AmqpMessageIdHelper.AMQP_ULONG_PREFIX + bigIntMessageId.toString();
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(bigIntMessageId);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toBaseMessageIdString(String)} returns a string
+     * indicating an AMQP encoded binary when given a ByteBuffer object.
+     */
+    @Test
+    public void testToBaseMessageIdStringWithByteBufferBinary() {
+        byte[] bytes = new byte[] { (byte) 0x00, (byte) 0xAB, (byte) 0x09, (byte) 0xFF };
+        ByteBuffer buf = ByteBuffer.wrap(bytes);
+
+        String expected = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + "00AB09FF";
+
+        String baseMessageIdString = _messageIdHelper.toBaseMessageIdString(buf);
+        assertNotNull("null string should not have been returned", baseMessageIdString);
+        assertEquals("expected base id string was not returned", expected, baseMessageIdString);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns a ulong
+     * (represented as a BigInteger) when given a string indicating an
+     * encoded AMQP ulong id.
+     */
+    @Test
+    public void testToIdObjectWithEncodedUlong() throws Exception {
+        BigInteger longId = BigInteger.valueOf(123456789L);
+        String provided = AmqpMessageIdHelper.AMQP_ULONG_PREFIX + "123456789";
+
+        Object idObject = _messageIdHelper.toIdObject(provided);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", longId, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns binary
+     * (represented as a ByteBuffer) when given a string indicating an
+     * encoded AMQP binary id, using upper case hex characters
+     */
+    @Test
+    public void testToIdObjectWithEncodedBinaryUppercaseHexString() throws Exception {
+        byte[] bytes = new byte[] { (byte) 0x00, (byte) 0xAB, (byte) 0x09, (byte) 0xFF };
+        ByteBuffer binaryId = ByteBuffer.wrap(bytes);
+
+        String provided = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + "00AB09FF";
+
+        Object idObject = _messageIdHelper.toIdObject(provided);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", binaryId, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns null
+     * when given null.
+     */
+    @Test
+    public void testToIdObjectWithNull() throws Exception {
+        assertNull("null object should have been returned", _messageIdHelper.toIdObject(null));
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns binary
+     * (represented as a ByteBuffer) when given a string indicating an
+     * encoded AMQP binary id, using lower case hex characters.
+     */
+    @Test
+    public void testToIdObjectWithEncodedBinaryLowercaseHexString() throws Exception {
+        byte[] bytes = new byte[] { (byte) 0x00, (byte) 0xAB, (byte) 0x09, (byte) 0xFF };
+        ByteBuffer binaryId = ByteBuffer.wrap(bytes);
+
+        String provided = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + "00ab09ff";
+
+        Object idObject = _messageIdHelper.toIdObject(provided);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", binaryId, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns a UUID
+     * when given a string indicating an encoded AMQP uuid id.
+     */
+    @Test
+    public void testToIdObjectWithEncodedUuid() throws Exception {
+        UUID uuid = UUID.randomUUID();
+        String provided = AmqpMessageIdHelper.AMQP_UUID_PREFIX + uuid.toString();
+
+        Object idObject = _messageIdHelper.toIdObject(provided);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", uuid, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns a string
+     * when given a string without any type encoding prefix.
+     */
+    @Test
+    public void testToIdObjectWithStringContainingNoEncodingPrefix() throws Exception {
+        String stringId = "myStringId";
+
+        Object idObject = _messageIdHelper.toIdObject(stringId);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", stringId, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} returns the remainder of the
+     * provided string after removing the {@link AmqpMessageIdHelper#AMQP_STRING_PREFIX} prefix.
+     */
+    @Test
+    public void testToIdObjectWithStringContainingStringEncodingPrefix() throws Exception {
+        String suffix = "myStringSuffix";
+        String stringId = AmqpMessageIdHelper.AMQP_STRING_PREFIX + suffix;
+
+        Object idObject = _messageIdHelper.toIdObject(stringId);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", suffix, idObject);
+    }
+
+    /**
+     * Test that when given a string with with the {@link AmqpMessageIdHelper#AMQP_STRING_PREFIX} prefix
+     * and then additionally the {@link AmqpMessageIdHelper#AMQP_UUID_PREFIX}, the
+     * {@link AmqpMessageIdHelper#toIdObject(String)} method returns the remainder of the provided string
+     *  after removing the {@link AmqpMessageIdHelper#AMQP_STRING_PREFIX} prefix.
+     */
+    @Test
+    public void testToIdObjectWithStringContainingStringEncodingPrefixAndThenUuidPrefix() throws Exception {
+        String encodedUuidString = AmqpMessageIdHelper.AMQP_UUID_PREFIX + UUID.randomUUID().toString();
+        String stringId = AmqpMessageIdHelper.AMQP_STRING_PREFIX + encodedUuidString;
+
+        Object idObject = _messageIdHelper.toIdObject(stringId);
+        assertNotNull("null object should not have been returned", idObject);
+        assertEquals("expected id object was not returned", encodedUuidString, idObject);
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} throws an
+     * {@link IdConversionException} when presented with an encoded binary hex string
+     * of uneven length (after the prefix) that thus can't be converted due to each
+     * byte using 2 characters
+     */
+    @Test
+    public void testToIdObjectWithStringContainingBinaryHexThrowsICEWithUnevenLengthString() {
+        String unevenHead = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + "123";
+
+        try {
+            _messageIdHelper.toIdObject(unevenHead);
+            fail("expected exception was not thrown");
+        } catch (IdConversionException iae) {
+            // expected
+            String msg = iae.getCause().getMessage();
+            assertTrue("Message was not as expected: " + msg, msg.contains("even length"));
+        }
+    }
+
+    /**
+     * Test that {@link AmqpMessageIdHelper#toIdObject(String)} throws an
+     * {@link IdConversionException} when presented with an encoded binary hex
+     * string (after the prefix) that contains characters other than 0-9
+     * and A-F and a-f, and thus can't be converted
+     */
+    @Test
+    public void testToIdObjectWithStringContainingBinaryHexThrowsICEWithNonHexCharacters() {
+
+        // char before '0'
+        char nonHexChar = '/';
+        String nonHexString = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + nonHexChar + nonHexChar;
+
+        try {
+            _messageIdHelper.toIdObject(nonHexString);
+            fail("expected exception was not thrown");
+        } catch (IdConversionException ice) {
+            // expected
+            String msg = ice.getCause().getMessage();
+            assertTrue("Message was not as expected: " + msg, msg.contains("non-hex"));
+        }
+
+        // char after '9', before 'A'
+        nonHexChar = ':';
+        nonHexString = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + nonHexChar + nonHexChar;
+
+        try {
+            _messageIdHelper.toIdObject(nonHexString);
+            fail("expected exception was not thrown");
+        } catch (IdConversionException ice) {
+            // expected
+            String msg = ice.getCause().getMessage();
+            assertTrue("Message was not as expected: " + msg, msg.contains("non-hex"));
+        }
+
+        // char after 'F', before 'a'
+        nonHexChar = 'G';
+        nonHexString = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + nonHexChar + nonHexChar;
+
+        try {
+            _messageIdHelper.toIdObject(nonHexString);
+            fail("expected exception was not thrown");
+        } catch (IdConversionException ice) {
+            // expected
+            String msg = ice.getCause().getMessage();
+            assertTrue("Message was not as expected: " + msg, msg.contains("non-hex"));
+        }
+
+        // char after 'f'
+        nonHexChar = 'g';
+        nonHexString = AmqpMessageIdHelper.AMQP_BINARY_PREFIX + nonHexChar + nonHexChar;
+
+        try {
+            _messageIdHelper.toIdObject(nonHexString);
+            fail("expected exception was not thrown");
+        } catch (IdConversionException ice) {
+            // expected
+            String msg = ice.getCause().getMessage();
+            assertTrue("Message was not as expected: " + msg, msg.contains("non-hex"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/QpidJmsTestCase.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/QpidJmsTestCase.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/QpidJmsTestCase.java
new file mode 100644
index 0000000..414e98d
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/QpidJmsTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * 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.qpid.jms.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QpidJmsTestCase {
+    private final Logger _logger = LoggerFactory.getLogger(getClass());
+
+    private final Map<String, String> _propertiesSetForTest = new HashMap<String, String>();
+
+    @Rule
+    public TestName _testName = new TestName();
+
+    /**
+     * Set a System property for duration of this test only. The tearDown will guarantee to reset the property to its
+     * previous value after the test completes.
+     *
+     * @param property
+     *            The property to set
+     * @param value
+     *            the value to set it to, if null, the property will be cleared
+     */
+    protected void setTestSystemProperty(final String property, final String value) {
+        if (!_propertiesSetForTest.containsKey(property)) {
+            // Record the current value so we can revert it later.
+            _propertiesSetForTest.put(property, System.getProperty(property));
+        }
+
+        if (value == null) {
+            System.clearProperty(property);
+            _logger.info("Set system property '" + property + "' to be cleared");
+        } else {
+            System.setProperty(property, value);
+            _logger.info("Set system property '" + property + "' to: '" + value + "'");
+        }
+
+    }
+
+    /**
+     * Restore the System property values that were set by this test run.
+     */
+    protected void revertTestSystemProperties() {
+        if (!_propertiesSetForTest.isEmpty()) {
+            for (String key : _propertiesSetForTest.keySet()) {
+                String value = _propertiesSetForTest.get(key);
+                if (value != null) {
+                    System.setProperty(key, value);
+                    _logger.info("Reverted system property '" + key + "' to: '" + value + "'");
+                } else {
+                    System.clearProperty(key);
+                    _logger.info("Reverted system property '" + key + "' to be cleared");
+                }
+            }
+
+            _propertiesSetForTest.clear();
+        }
+    }
+
+    @After
+    public void tearDown() throws java.lang.Exception {
+        _logger.info("========== tearDown " + getTestName() + " ==========");
+        revertTestSystemProperties();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        _logger.info("========== start " + getTestName() + " ==========");
+    }
+
+    protected String getTestName() {
+        return getClass().getSimpleName() + "." + _testName.getMethodName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AbstractFrameFieldAndPayloadMatchingHandler.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AbstractFrameFieldAndPayloadMatchingHandler.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AbstractFrameFieldAndPayloadMatchingHandler.java
new file mode 100644
index 0000000..e835af3
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AbstractFrameFieldAndPayloadMatchingHandler.java
@@ -0,0 +1,112 @@
+/*
+ * 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.qpid.jms.test.testpeer;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.UnsignedLong;
+import org.hamcrest.Matcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractFrameFieldAndPayloadMatchingHandler extends FrameMatchingHandler
+{
+    private final Logger _logger = LoggerFactory.getLogger(getClass());
+
+    private final Map<Enum<?>, Matcher<?>> _fieldMatchers;
+    private Map<Enum<?>, Object> _receivedFields;
+
+    /**
+     * @param fieldMatchers a map of field matchers, keyed by enums representing the fields
+     * (the enums just need to have an ordinal number matching the AMQP spec field order,
+     * and preferably a sensible name)
+     */
+    protected AbstractFrameFieldAndPayloadMatchingHandler(FrameType frameType,
+                                                int channel,
+                                                UnsignedLong numericDescriptor,
+                                                Symbol symbolicDescriptor,
+                                                Map<Enum<?>, Matcher<?>> fieldMatchers,
+                                                Runnable onSuccess)
+    {
+        super(frameType, channel, numericDescriptor, symbolicDescriptor, onSuccess);
+        _fieldMatchers = fieldMatchers;
+    }
+
+    protected Map<Enum<?>, Matcher<?>> getMatchers()
+    {
+        return _fieldMatchers;
+    }
+
+    /**
+     * Returns the received values, keyed by enums representing the fields
+     * (the enums have an ordinal number matching the AMQP spec field order,
+     * and a sensible name)
+     */
+    @Override
+    protected Map<Enum<?>, Object> getReceivedFields()
+    {
+        return _receivedFields;
+    }
+
+    @Override
+    protected void verifyFrame(List<Object> described, Binary payload)
+    {
+        verifyFields(described);
+        verifyPayload(payload);
+    }
+
+    protected void verifyFields(List<Object> described)
+    {
+        int fieldNumber = 0;
+        HashMap<Enum<?>, Object> valueMap = new HashMap<>();
+        for(Object value : described)
+        {
+            valueMap.put(getField(fieldNumber++), value);
+        }
+
+        _receivedFields = valueMap;
+
+        _logger.debug("About to check the fields of the described type."
+                + "\n  Received:" + valueMap
+                + "\n  Expectations: " + _fieldMatchers);
+        for(Map.Entry<Enum<?>, Matcher<?>> entry : _fieldMatchers.entrySet())
+        {
+            @SuppressWarnings("unchecked")
+            Matcher<Object> matcher = (Matcher<Object>) entry.getValue();
+            Enum<?> field = entry.getKey();
+            assertThat("Field " + field + " value should match", valueMap.get(field), matcher);
+        }
+    }
+
+    /**
+     * Intended to be overridden in most cases (but not necessarily all - hence not marked as abstract)
+     */
+    protected Enum<?> getField(int fieldIndex)
+    {
+        throw new UnsupportedOperationException("getFieldName is expected to be overridden by subclass if it is required");
+    }
+
+    protected abstract void verifyPayload(Binary payload);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpDataFramer.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpDataFramer.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpDataFramer.java
new file mode 100644
index 0000000..0fb3d42
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpDataFramer.java
@@ -0,0 +1,64 @@
+/*
+ * 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.qpid.jms.test.testpeer;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.Proton;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.DescribedType;
+import org.apache.qpid.proton.codec.Data;
+
+/**
+ * Generates frames as per section 2.3.1 of the AMQP spec
+ */
+public class AmqpDataFramer
+{
+    private static final int CAPACITY = 2024;
+    private static final byte FRAME_PREAMBLE_SIZE_IN_FOUR_BYTE_WORDS = 2;
+
+    public static byte[] encodeFrame(FrameType type, int channel, DescribedType describedType, Binary payload)
+    {
+        ByteBuffer buffer = ByteBuffer.allocate(CAPACITY);  //TODO: set a proper size
+
+        buffer.position(8); // leave hole for frame header
+
+        Data frameBody = Proton.data(CAPACITY);
+        frameBody.putDescribedType(describedType);
+        frameBody.encode(buffer);
+        if(payload != null)
+        {
+            buffer.put(payload.asByteBuffer());
+        }
+
+        int frameSize = buffer.position();
+        buffer.rewind();
+        buffer.putInt(frameSize);
+        buffer.put(FRAME_PREAMBLE_SIZE_IN_FOUR_BYTE_WORDS);
+        buffer.put((byte)type.ordinal());
+        buffer.putShort((short)channel);
+
+        byte[] target = new byte[frameSize];
+
+        buffer.rewind();
+        buffer.get(target, 0, frameSize);
+        return target;
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpPeerRunnable.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpPeerRunnable.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpPeerRunnable.java
new file mode 100644
index 0000000..55b6df7
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/AmqpPeerRunnable.java
@@ -0,0 +1,25 @@
+/*
+ *
+ * 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.qpid.jms.test.testpeer;
+
+public interface AmqpPeerRunnable extends Runnable
+{
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org