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: [email protected] For additional commands, e-mail: [email protected]
