View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact tma@netspace.net.au. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2001-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: BytesMessageTest.java,v 1.8 2004/02/03 07:31:01 tanderson Exp $ 44 */ 45 package org.exolab.jmscts.test.message.bytes; 46 47 import java.util.Arrays; 48 49 import javax.jms.BytesMessage; 50 import javax.jms.MessageFormatException; 51 52 import junit.framework.Test; 53 54 import org.exolab.jmscts.core.AbstractMessageTestCase; 55 import org.exolab.jmscts.core.MessagePopulator; 56 import org.exolab.jmscts.core.TestContext; 57 import org.exolab.jmscts.core.TestCreator; 58 import org.exolab.jmscts.test.message.util.MessageValues; 59 60 61 /*** 62 * This class tests the <code>BytesMessage</code> message type. 63 * 64 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 65 * @version $Revision: 1.8 $ 66 * @see javax.jms.BytesMessage 67 * @see AbstractMessageTestCase 68 * @jmscts.message BytesMessage 69 */ 70 public class BytesMessageTest extends AbstractMessageTestCase 71 implements MessageValues { 72 73 /*** 74 * Construct a new <code>BytesMessageTest</code> 75 * 76 * @param name the name of test case 77 */ 78 public BytesMessageTest(String name) { 79 super(name); 80 } 81 82 /*** 83 * Sets up the test suite 84 * 85 * @return an instance of this class that may be run by 86 * {@link org.exolab.jmscts.core.JMSTestRunner} 87 */ 88 public static Test suite() { 89 return TestCreator.createMessageTest(BytesMessageTest.class); 90 } 91 92 /*** 93 * Get the message populator. This implementation always returns null 94 * 95 * @return null 96 */ 97 public MessagePopulator getMessagePopulator() { 98 return null; 99 } 100 101 /*** 102 * Verifies that if a read method throws MessageFormatException or 103 * NumberFormatException, the current position of the read pointer is not 104 * be incremented, and that a subsequent read is capable of recovering 105 * from the exception by re-reading the data as a different type.<br/> 106 * NOTE: With the exception of the readUTF() method, it is difficult to 107 * conceive test cases for read methods. 108 * <ul> 109 * <li> 110 * A provider that implements BytesMessage using a DataInputStream 111 * or equivalent, is likely to only throw MessageFormatException for 112 * the readUTF() method.<br/> 113 * The other likely exceptions are MessageEOFException for stream 114 * overruns, and JMSException for any other error. 115 * </li> 116 * <li> 117 * As BytesMessage does not support conversion, NumberFormatException 118 * is unlikely to be thrown. 119 * </li> 120 * </ul> 121 * 122 * @jmscts.requirement message.bytes.read 123 * @throws Exception for any error 124 */ 125 public void testReadFailure() throws Exception { 126 TestContext context = getContext(); 127 BytesMessage message = (BytesMessage) context.getMessage(); 128 final byte illegalChar = (byte) 0xFF; 129 final byte[] invalidUTF = {0x0, 0x1, illegalChar}; 130 // first 2 bytes of a UTF are the length. 131 132 message.writeBytes(invalidUTF); 133 message.reset(); 134 try { 135 message.readUTF(); 136 fail("Expected MessageFormatException to be thrown for invalid " 137 + "UTF string"); 138 } catch (MessageFormatException expected) { 139 // the expected behaviour 140 } catch (Exception exception) { 141 fail("Expected MessageFormatException to be thrown for invalid " 142 + "UTF string, but got exception=" 143 + exception.getClass().getName() + ", message=" 144 + exception.getMessage()); 145 } 146 147 // now try and read the data as an array of bytes 148 byte[] buffer = new byte[invalidUTF.length]; 149 message.readBytes(buffer); 150 if (!Arrays.equals(invalidUTF, buffer)) { 151 fail("Byte array does not match that written"); 152 } 153 int count = message.readBytes(buffer); 154 if (count != -1) { 155 fail("Expected readBytes(byte[]) to return count=-1 to indicate " 156 + "end-of-stream, but returned count=" + count); 157 } 158 } 159 160 /*** 161 * Verifies that the BytesMessage.readBytes(byte[]) method returns -1 to 162 * indicate end-of-stream, for an empty message body. 163 * 164 * @jmscts.requirement message.bytes.method.readBytes(1) 165 * @throws Exception for any error 166 */ 167 public void testReadBytesForEmptyStream1() throws Exception { 168 TestContext context = getContext(); 169 BytesMessage message = (BytesMessage) context.getMessage(); 170 message.reset(); 171 checkEndOfStream1(message); 172 } 173 174 /*** 175 * Verifies that the BytesMessage.readBytes(byte[], int) method returns -1 176 * to indicate end-of-stream, for an empty message body. 177 * 178 * @jmscts.requirement message.bytes.method.readBytes(2) 179 * @throws Exception for any error 180 */ 181 public void testReadBytesForEmptyStream2() throws Exception { 182 TestContext context = getContext(); 183 BytesMessage message = (BytesMessage) context.getMessage(); 184 message.reset(); 185 checkEndOfStream2(message); 186 } 187 188 /*** 189 * Verifies the behaviour of the BytesMessage.readBytes(byte[]) method. 190 * 191 * @jmscts.requirement message.bytes.method.readBytes(1) 192 * @throws Exception for any error 193 */ 194 public void testReadBytes() throws Exception { 195 final int size = 256; 196 TestContext context = getContext(); 197 BytesMessage message = (BytesMessage) context.getMessage(); 198 199 byte[] bytes = populateByteArray(size, 0); 200 message.writeBytes(bytes); 201 message.reset(); 202 byte[] buffer1 = new byte[bytes.length]; 203 checkReadBytes1(message, buffer1, bytes); 204 checkEndOfStream1(message); 205 206 message.reset(); 207 byte[] buffer2 = new byte[bytes.length / 2]; 208 checkReadBytes1(message, buffer2, 209 populateByteArray(buffer2.length, 0)); 210 checkReadBytes1(message, buffer2, 211 populateByteArray(buffer2.length, buffer2.length)); 212 checkEndOfStream1(message); 213 214 message.reset(); 215 byte[] buffer3 = new byte[bytes.length * 2]; 216 checkReadBytes1(message, buffer3, bytes); 217 checkEndOfStream1(message); 218 } 219 220 /*** 221 * Verifies that the BytesMessage.readBytes(byte[], int) method can be 222 * called multiple times passing a byte array less than the length of the 223 * byte stream, and that the result matches that expected. 224 * 225 * @jmscts.requirement message.bytes.method.readBytes(2) 226 * @throws Exception for any error 227 */ 228 public void testPartialReadBytes1() throws Exception { 229 final int size = 256; 230 TestContext context = getContext(); 231 BytesMessage message = (BytesMessage) context.getMessage(); 232 233 byte[] bytes = populateByteArray(size, 0); 234 final int chunkSize = 8; 235 final int chunks = bytes.length / chunkSize; 236 237 message.writeBytes(bytes); 238 message.reset(); 239 byte[] readBytes = new byte[bytes.length]; 240 byte[] buffer = new byte[chunkSize]; 241 for (int i = 0; i < chunks; ++i) { 242 checkReadBytes2(message, buffer, buffer.length); 243 System.arraycopy(buffer, 0, readBytes, i * chunkSize, chunkSize); 244 } 245 if (!Arrays.equals(bytes, readBytes)) { 246 fail("Byte array does not match that written"); 247 } 248 checkEndOfStream2(message); 249 } 250 251 /*** 252 * Verifies that the BytesMessage.readBytes(byte[], int) method can be 253 * called multiple times passing a length parameter less than the length 254 * of the array, and that the result matches that expected. 255 * 256 * @jmscts.requirement message.bytes.method.readBytes(2) 257 * @throws Exception for any error 258 */ 259 public void testPartialReadBytes2() throws Exception { 260 final int size = 256; 261 TestContext context = getContext(); 262 BytesMessage message = (BytesMessage) context.getMessage(); 263 byte[] bytes = populateByteArray(size, 0); 264 final int chunkSize = 8; 265 final int chunks = bytes.length / chunkSize; 266 267 message.writeBytes(bytes); 268 message.reset(); 269 byte[] buffer = new byte[bytes.length]; 270 byte[] readBytes = new byte[bytes.length]; 271 for (int i = 0; i < chunks; ++i) { 272 checkReadBytes2(message, buffer, chunkSize); 273 System.arraycopy(buffer, 0, readBytes, i * chunkSize, chunkSize); 274 } 275 if (!Arrays.equals(bytes, readBytes)) { 276 fail("Byte array does not match that written"); 277 } 278 checkEndOfStream2(message); 279 } 280 281 /*** 282 * Verifies that the BytesMessage.readBytes(byte[], int) method throws 283 * IndexOutOfBoundsException for invalid length parameters 284 * 285 * @jmscts.requirement message.bytes.method.readBytes(2) 286 * @throws Exception for any error 287 */ 288 public void testReadBytesIndexException() throws Exception { 289 final int size = 10; 290 TestContext context = getContext(); 291 BytesMessage message = (BytesMessage) context.getMessage(); 292 293 byte[] buffer = new byte[size]; 294 message.reset(); 295 296 try { 297 message.readBytes(buffer, -1); 298 fail("BytesMessage.readBytes(byte[], int) should throw " 299 + "IndexOutOfBoundsException for negative length parameter"); 300 } catch (IndexOutOfBoundsException expected) { 301 // the expected behaviour 302 } catch (Exception exception) { 303 fail("BytesMessage.readBytes(byte[], int) should throw " 304 + "IndexOutOfBoundsException for negative length parameter" 305 + " but got exception=" + exception.getClass().getName() 306 + ", message=" + exception.getMessage()); 307 } 308 309 try { 310 message.readBytes(buffer, buffer.length + 1); 311 fail("BytesMessage.readBytes(byte[], int) should throw " 312 + "IndexOutOfBoundsException for invalid length parameter"); 313 } catch (IndexOutOfBoundsException expected) { 314 // the expected behaviour 315 } catch (Exception exception) { 316 fail("BytesMessage.readBytes(byte[], int) should throw " 317 + "IndexOutOfBoundsException for invalid length parameter" 318 + " but got exception=" + exception.getClass().getName() 319 + ", message=" + exception.getMessage()); 320 } 321 } 322 323 /*** 324 * Verfies that all objectified primitives can be written using the 325 * BytesMessage.writeObject() method 326 * 327 * @jmscts.requirement message.bytes.method.writeObject 328 * @throws Exception for any error 329 */ 330 public void testWriteObject() throws Exception { 331 final int size = 256; 332 TestContext context = getContext(); 333 BytesMessage message = (BytesMessage) context.getMessage(); 334 335 message.writeObject(Boolean.TRUE); 336 message.writeObject(new Byte(Byte.MAX_VALUE)); 337 message.writeObject(new Character(Character.MAX_VALUE)); 338 message.writeObject(new Short(Short.MAX_VALUE)); 339 message.writeObject(new Integer(Integer.MAX_VALUE)); 340 message.writeObject(new Float(Float.MAX_VALUE)); 341 message.writeObject(new Double(Double.MAX_VALUE)); 342 String utf = "ABCD"; 343 message.writeObject(utf); 344 byte[] bytes = populateByteArray(size, 0); 345 message.writeObject(bytes); 346 347 message.reset(); 348 349 assertEquals(true, message.readBoolean()); 350 assertEquals(Byte.MAX_VALUE, message.readByte()); 351 assertEquals(Character.MAX_VALUE, message.readChar()); 352 assertEquals(Short.MAX_VALUE, message.readShort()); 353 assertEquals(Integer.MAX_VALUE, message.readInt()); 354 assertEquals(Float.MAX_VALUE, message.readFloat(), 0.0); 355 assertEquals(Double.MAX_VALUE, message.readDouble(), 0.0); 356 assertEquals(utf, message.readUTF()); 357 byte[] buffer = new byte[bytes.length]; 358 message.readBytes(buffer); 359 assertTrue(Arrays.equals(bytes, buffer)); 360 checkEndOfStream1(message); 361 checkEndOfStream2(message); 362 } 363 364 /*** 365 * Verifies that attempting to write an invalid object using the 366 * BytesMessage.writeObject() method throws MessageFormatException 367 * 368 * @jmscts.requirement message.bytes.method.writeObject 369 * @throws Exception for any error 370 */ 371 public void testInvalidObject() throws Exception { 372 TestContext context = getContext(); 373 BytesMessage message = (BytesMessage) context.getMessage(); 374 375 try { 376 message.writeObject(new java.math.BigDecimal(0.0)); 377 fail("BytesMessage.writeObject() should only support " 378 + "objectified primitives"); 379 } catch (MessageFormatException expected) { 380 // the expected behaviour 381 } 382 } 383 384 /*** 385 * Helper to return a byte array of the specified length, populated with 386 * an incrementing sequence of values 387 * 388 * @param length the length of the array 389 * @param start the number to start the sequence at 390 * @return a new byte array 391 */ 392 private byte[] populateByteArray(int length, int start) { 393 byte[] result = new byte[length]; 394 byte j = (byte) start; 395 for (int i = 0; i < length; ++i, ++j) { 396 result[i] = j; 397 } 398 return result; 399 } 400 401 /*** 402 * Helper to invoke readBytes(byte[]) and verify that the result equals 403 * that expected 404 * 405 * @param message the message to read 406 * @param buffer the buffer to read to 407 * @param expected the expected result 408 * @throws Exception for any error 409 */ 410 private void checkReadBytes1(BytesMessage message, byte[] buffer, 411 byte[] expected) throws Exception { 412 int count = message.readBytes(buffer); 413 if (count != expected.length) { 414 fail("Expected readBytes(byte[]) to return count=" 415 + expected.length + " but returned count=" + count); 416 } 417 418 if (buffer.length > expected.length) { 419 // only compare the relevant portion of the array 420 byte[] tmp = new byte[expected.length]; 421 System.arraycopy(buffer, 0, tmp, 0, tmp.length); 422 buffer = tmp; 423 } 424 425 if (!Arrays.equals(expected, buffer)) { 426 fail("Byte array read by readBytes(byte[]) is different to that " 427 + "written"); 428 } 429 } 430 431 /*** 432 * Helper to test that readBytes(byte[]) returns -1 to indicate 433 * end-of-stream 434 * 435 * @param message the message to check 436 * @throws Exception for any error 437 */ 438 private void checkEndOfStream1(BytesMessage message) throws Exception { 439 // invoke readBytes twice on an empty stream to ensure that -1 is 440 // returned each time. 441 final int size = 10; 442 byte[] buffer = new byte[size]; 443 try { 444 for (int i = 0; i < 2; ++i) { 445 int count = message.readBytes(buffer); 446 if (count != -1) { 447 fail("Expected readBytes(byte[]) to return count=-1 to " 448 + "indicate end-of-stream, but returned count=" 449 + count); 450 } 451 } 452 } catch (Exception exception) { 453 fail("Expected readBytes(byte[]) to return count=-1 to indicate " 454 + "end-of-stream, but threw exception=" 455 + exception.getClass().getName() + ", message=" 456 + exception.getMessage()); 457 } 458 } 459 460 /*** 461 * Helper to invoke readBytes(byte[], int) 462 * 463 * @param message the message to read 464 * @param buffer the buffer to read to 465 * @param length the number of bytes to read 466 * @throws Exception for any error 467 */ 468 private void checkReadBytes2(BytesMessage message, byte[] buffer, 469 int length) 470 throws Exception { 471 int count = message.readBytes(buffer, length); 472 if (count != length) { 473 fail("Expected readBytes(byte[], int) to return count=" 474 + length + " but returned count=" + count); 475 } 476 } 477 478 /*** 479 * Helper to test that readBytes(byte[], int) returns -1 to indicate 480 * end-of-stream 481 * 482 * @param message the message to check 483 * @throws Exception for any error 484 */ 485 private void checkEndOfStream2(BytesMessage message) throws Exception { 486 // invoke readBytes twice on an empty stream to ensure that -1 is 487 // returned each time. 488 final int size = 10; 489 byte[] buffer = new byte[size]; 490 try { 491 for (int i = 0; i < 2; ++i) { 492 int count = message.readBytes(buffer, buffer.length); 493 if (count != -1) { 494 fail("Expected readBytes(byte[], int) to return count=-1" 495 + "to indicate end-of-stream, but returned count=" 496 + count); 497 } 498 } 499 } catch (Exception exception) { 500 fail("Expected readBytes(byte[], int) to return count=-1 to " 501 + "indicate end-of-stream, but threw exception=" 502 + exception.getClass().getName() + ", message=" 503 + exception.getMessage()); 504 } 505 } 506 507 }

This page was automatically generated by Maven