/*
* JBoss, Home of Professional Open Source.
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates, and individual
* contributors as indicated by the @author tags.
*
* Licensed 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.xnio.channels;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.EOFException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.xnio.BufferAllocator;
import org.xnio.Buffers;
import org.xnio.ByteBufferSlicePool;
import org.xnio.LocalSocketAddress;
import org.xnio.mock.ConnectedStreamChannelMock;
/**
* Test for {@link FramedMessageChannel}.
*
* @author <a href="mailto:frainone@redhat.com">Flavia Rainone</a>
*/
public class FramedMessageChannelTestCase {
private ConnectedStreamChannelMock connectedChannel;
@Before
public void init() {
connectedChannel = new ConnectedStreamChannelMock();
}
@Test
public void receive() throws IOException {
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, ByteBuffer.allocate(15000), ByteBuffer.allocate(15000));
try {
connectedChannel.setReadDataWithLength("data");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
assertEquals(4, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
assertReadMessage(buffer, "data");
} finally {
channel.close();
}
}
@Test
public void receiveDoubleMessage() throws IOException {
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, ByteBuffer.allocate(15000), ByteBuffer.allocate(15000));
try {
connectedChannel.setReadDataWithLength("message_1");
connectedChannel.setReadDataWithLength("message_2");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
assertEquals(9, channel.receive(buffer));
assertEquals(9, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
assertReadMessage(buffer, "message_1", "message_2");
} finally {
channel.close();
}
}
@Test
public void bufferOverflowOnReceive() throws IOException {
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, ByteBuffer.allocate(15000), ByteBuffer.allocate(15000));
try {
connectedChannel.setReadDataWithLength("message");
connectedChannel.setReadDataWithLength("12");
connectedChannel.setReadDataWithLength("34");
connectedChannel.setReadDataWithLength("1");
connectedChannel.setReadDataWithLength("again");
connectedChannel.setEof();
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(2);
assertEquals(7, channel.receive(buffer));
assertReadMessage(buffer, "me");
// full buffer
assertEquals(2, channel.receive(buffer));
// empty full buffer
buffer.clear();
assertEquals(2, channel.receive(buffer));
assertReadMessage(buffer, "34");
buffer.clear();
assertEquals(1, channel.receive(buffer));
assertReadMessage(buffer, "1");
buffer.clear();
assertEquals(5, channel.receive(buffer));
assertReadMessage(buffer, "ag");
assertEquals(-1, channel.receive(buffer));
buffer.clear();
assertEquals(-1, channel.receive(buffer));
} finally {
channel.close();
}
}
@Test
public void receiveTruncatedMessage() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength("1234");
connectedChannel.setReadDataWithLength(4, "567890");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
assertEquals(4, channel.receive(buffer));
assertEquals(4, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
connectedChannel.setEof();
assertEquals(-1, channel.receive(buffer));
assertEquals(-1, channel.receive(buffer));
assertReadMessage(buffer, "12345678");
} finally {
channel.close();
}
}
@Test
public void receiveIncompleteMessage() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(6, "hello");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
assertEquals(0, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
connectedChannel.setEof();
assertEquals(-1, channel.receive(buffer));
assertEquals(-1, channel.receive(buffer));
} finally {
channel.close();
}
}
@Test
public void receiveInvalidLengthMessage() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 10, 10 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(20, "12345678901234567890");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
boolean failed = false;
try {
channel.receive(buffer);
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void receiveNegativeLengthMessage() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 10, 10 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(-8, "abcdefgh");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(10);
boolean failed = false;
try {
channel.receive(buffer);
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void receiveBrokenMessage() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(2);
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(5);
assertEquals(0, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
connectedChannel.setReadData("oh");
assertEquals(2, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
assertReadMessage(buffer, "oh");
} finally {
channel.close();
}
}
@Test
public void receiveToByteBufferArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength("receive");
connectedChannel.setReadDataWithLength("this");
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(4), ByteBuffer.allocate(4), ByteBuffer.allocate(4), ByteBuffer.allocate(4)};
assertEquals(7, channel.receive(buffer));
assertEquals(4, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
assertReadMessage(buffer[0], "rece");
assertReadMessage(buffer[1], "ivet");
assertReadMessage(buffer[2], "his");
assertReadMessage(buffer[3]);
} finally {
channel.close();
}
}
@Test
public void bufferOverflowOnReceiveToByteArray() throws IOException {
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, ByteBuffer.allocate(15000), ByteBuffer.allocate(15000));
try {
connectedChannel.setReadDataWithLength("message");
connectedChannel.setReadDataWithLength("12");
connectedChannel.setReadDataWithLength("34");
connectedChannel.setReadDataWithLength("1");
connectedChannel.setReadDataWithLength("again");
connectedChannel.setEof();
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
assertEquals(7, channel.receive(buffer));
assertReadMessage(buffer[0], "m");
assertReadMessage(buffer[1], "e");
// full buffers
assertEquals(2, channel.receive(buffer));
// make sure buffer contents haven't been overwritten
assertReadMessage(buffer[0], "m");
assertReadMessage(buffer[1], "e");
// empty buffers
buffer[0].clear();
buffer[1].clear();
assertEquals(2, channel.receive(buffer));
assertReadMessage(buffer[0], "3");
assertReadMessage(buffer[1], "4");
buffer[0].clear();
buffer[1].clear();
assertEquals(1, channel.receive(buffer));
assertReadMessage(buffer[0], "1");
buffer[0].clear();
buffer[1].clear();
assertEquals(5, channel.receive(buffer));
assertReadMessage(buffer[0], "a");
assertReadMessage(buffer[1], "g");
assertEquals(-1, channel.receive(buffer));
buffer[0].clear();
buffer[1].clear();
assertEquals(-1, channel.receive(buffer));
} finally {
channel.close();
}
}
@Test
public void receiveToByteBufferArrayWithOffset1() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength("123");
connectedChannel.setReadDataWithLength("456");
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(3), ByteBuffer.allocate(3), ByteBuffer.allocate(3),ByteBuffer.allocate(3)};
assertEquals(3, channel.receive(buffer, 1, 3));
assertEquals(3, channel.receive(buffer, 1, 3));
assertEquals(0, channel.receive(buffer, 1, 3));
assertEquals(0, buffer[0].position());
assertReadMessage(buffer[1], "123");
assertReadMessage(buffer[2], "456");
assertEquals(0, buffer[3].position());
} finally {
channel.close();
}
}
@Test
public void receiveToByteBufferArrayWithOffset2() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength("1234");
connectedChannel.setReadDataWithLength("567890");
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(3), ByteBuffer.allocate(3), ByteBuffer.allocate(3),
ByteBuffer.allocate(3)};
assertEquals(4, channel.receive(buffer, 0, 3));
assertEquals(6, channel.receive(buffer, 0, 3));
assertEquals(0, channel.receive(buffer, 0, 3));
assertReadMessage(buffer[0], "123");
assertReadMessage(buffer[1], "456");
assertReadMessage(buffer[2], "789");
assertEquals(0, buffer[3].position());
} finally {
channel.close();
}
}
@Test
public void receiveTruncatedMessageToByteArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength("1234");
connectedChannel.setReadDataWithLength(4, "567890");
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(3), ByteBuffer.allocate(3), ByteBuffer.allocate(3),
ByteBuffer.allocate(3)};
assertEquals(4, channel.receive(buffer, 0, 3));
assertEquals(4, channel.receive(buffer, 0, 3));
assertEquals(0, channel.receive(buffer, 0, 3));
connectedChannel.setEof();
assertEquals(-1, channel.receive(buffer, 0, 3));
assertEquals(-1, channel.receive(buffer, 0, 3));
assertEquals(-1, channel.receive(buffer, 0, 3));
assertReadMessage(buffer[0], "123");
assertReadMessage(buffer[1], "456");
assertReadMessage(buffer[2], "78");
assertEquals(0, buffer[3].position());
} finally {
channel.close();
}
}
@Test
public void receiveIncompleteMessageToByteArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(10, "hello");
connectedChannel.enableRead(true);
ByteBuffer[] buffer = new ByteBuffer[]{ByteBuffer.allocate(20)};
assertEquals(0, channel.receive(buffer));
assertEquals(0, channel.receive(buffer));
connectedChannel.setEof();
assertEquals(-1, channel.receive(buffer));
assertEquals(-1, channel.receive(buffer));
} finally {
channel.close();
}
}
@Test
public void receiveInvalidLengthMessageToByteArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 10, 10 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(15, "987654321098765");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(20);
boolean failed = false;
try {
channel.receive(new ByteBuffer[] {buffer});
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void receiveNegativeLengthMessageToByteArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 10, 10 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
connectedChannel.setReadDataWithLength(-3, "abc");
connectedChannel.enableRead(true);
ByteBuffer buffer = ByteBuffer.allocate(5);
boolean failed = false;
try {
channel.receive(new ByteBuffer[] {buffer});
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void send() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer buffer = ByteBuffer.allocate(20);
buffer.put("hello!".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("hello!");
} finally {
channel.close();
}
}
@Test
public void sendMultipleMessages() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer buffer = ByteBuffer.allocate(20);
buffer.put("jboss ".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
buffer.clear();
buffer.put("xnio".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
buffer.clear();
buffer.put("-api".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("jboss ", "xnio", "-api");
} finally {
channel.close();
}
}
@Test
public void sendMessageTooLarge() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 2, 2 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer buffer = ByteBuffer.allocate(20);
buffer.put("hello!".getBytes("UTF-8")).flip();
boolean failed = false;
try {
assertTrue(channel.send(buffer));
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void bufferOverflowOnSend() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 28, 28 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
// framed message channel won't be able to flush because write is disabled at connectedChannel
connectedChannel.enableWrite(false);
final ByteBuffer buffer = ByteBuffer.allocate(20);
buffer.put("hi!".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
buffer.flip();
assertTrue(channel.send(buffer));
buffer.flip();
assertTrue(channel.send(buffer));
buffer.flip();
assertTrue(channel.send(buffer));
buffer.flip();
assertFalse(channel.send(buffer));
assertWrittenMessage();
// enable write
connectedChannel.enableWrite(true);
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("hi!", "hi!", "hi!", "hi!", "hi!");
} finally {
channel.close();
}
}
@Test
public void sendByteBufferArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer[] buffer = new ByteBuffer[]{ByteBuffer.allocate(20), ByteBuffer.allocate(20)};
buffer[0].put("hello!".getBytes("UTF-8")).flip();
buffer[1].put("world!".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("hello!world!");
} finally {
channel.close();
}
}
@Test
public void sendMultipleMessagesWithBufferByteArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer[] buffer = new ByteBuffer[]{ByteBuffer.allocate(2), ByteBuffer.allocate(5)};
buffer[0].put("jb".getBytes("UTF-8")).flip();
buffer[1].put("oss ".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
buffer[0].clear(); buffer[1].clear();
buffer[0].put("xn".getBytes("UTF-8")).flip();
buffer[1].put("io".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
buffer[0].clear(); buffer[1].clear();
buffer[0].put("-a".getBytes("UTF-8")).flip();
buffer[1].put("pi".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("jboss ", "xnio", "-api");
} finally {
channel.close();
}
}
@Test
public void sendMultipleMessagesWithBufferByteArrayAndOffset() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 1000, 1000 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer[] buffer = new ByteBuffer[]{ByteBuffer.allocate(2), ByteBuffer.allocate(5), ByteBuffer.allocate(2), ByteBuffer.allocate(5)};
buffer[1].put("jboss".getBytes("UTF-8")).flip();
buffer[2].put(" ".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer, 1, 2));
assertTrue(channel.send(buffer, 1, 2));
buffer[1].clear();
buffer[1].put("xnio".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer, 1, 2));
assertTrue(channel.send(buffer, 1, 2));
buffer[1].clear();
buffer[1].put("-api".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer, 1, 2));
assertTrue(channel.send(buffer, 1, 2));
assertTrue(channel.flush());
assertWrittenMessage("jboss ", "xnio", "-api");
} finally {
channel.close();
}
}
@Test
public void sendMessageTooLargeWithByteBufferArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 2, 2 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(20)};
buffer[0].put("hello!".getBytes("UTF-8")).flip();
boolean failed = false;
try {
assertTrue(channel.send(buffer));
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
} finally {
channel.close();
}
}
@Test
public void bufferOverflowOnSendByteBufferArray() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
// framed message channel won't be able to flush because write is disabled at connectedChannel
connectedChannel.enableWrite(false);
final ByteBuffer[] buffer = new ByteBuffer[] {ByteBuffer.allocate(20)};
buffer[0].put("hello!".getBytes("UTF-8")).flip();
assertTrue(channel.send(buffer));
buffer[0].flip();
assertTrue(channel.send(buffer));
buffer[0].flip();
assertTrue(channel.send(buffer));
buffer[0].flip();
assertTrue(channel.send(buffer));
buffer[0].flip();
assertFalse(channel.send(buffer));
assertWrittenMessage();
// enable write
connectedChannel.enableWrite(true);
assertTrue(channel.send(buffer));
assertTrue(channel.flush());
assertWrittenMessage("hello!", "hello!", "hello!", "hello!", "hello!");
} finally {
channel.close();
}
}
@Test
public void shutdownWritesAndClose() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
channel.shutdownWrites();
assertTrue(channel.isWriteShutDown());
channel.flush();
final ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put("can't send".getBytes("UTF-8")).flip();
boolean eofException = false;
try {
channel.send(buffer);
} catch (EOFException e) {
eofException = true;
}
assertTrue(eofException);
eofException = false;
try {
channel.send(new ByteBuffer[]{buffer});
} catch (EOFException e) {
eofException = true;
}
assertTrue(eofException);
assertFalse(channel.isReadShutDown());
channel.close();
assertTrue(channel.isReadShutDown());
}
@Test
public void shutdownReadsAndClose() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
channel.shutdownReads();
assertTrue(channel.isReadShutDown());
assertFalse(channel.isWriteShutDown());
channel.close();
assertTrue(channel.isWriteShutDown());
}
@Test
public void close() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
channel.close();
assertTrue(channel.isWriteShutDown());
assertTrue(channel.isReadShutDown());
}
@Test
public void closeFailure() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
connectedChannel.enableFlush(false);
ByteBuffer buffer = ByteBuffer.allocate(5);
buffer.put("a".getBytes("UTF-8")).flip();
channel.send(buffer);
boolean failed = false;
try {
channel.close();
} catch (IOException e) {
failed = true;
}
assertTrue(failed);
//assertTrue(channel.isWriteShutDown());
//assertTrue(channel.isReadShutDown());
}
@Test
public void flush() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
final ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put("test".getBytes("UTF-8")).flip();
connectedChannel.enableWrite(false);
connectedChannel.enableFlush(false);
assertTrue(channel.send(buffer));
assertFalse(channel.flush());
connectedChannel.enableWrite(true);
assertFalse(channel.flush());
connectedChannel.enableFlush(true);
assertTrue(channel.flush());
connectedChannel.enableWrite(false);
connectedChannel.enableFlush(false);
buffer.flip();
assertTrue(channel.send(buffer));
channel.shutdownWrites();
assertFalse(channel.flush());
connectedChannel.enableWrite(true);
assertFalse(channel.flush());
connectedChannel.enableFlush(true);
assertTrue(channel.flush());
} finally {
channel.close();
}
}
@Test
public void getAddresses() throws IOException {
final ByteBufferSlicePool pool = new ByteBufferSlicePool(BufferAllocator.BYTE_BUFFER_ALLOCATOR, 40, 40 * 16);
final FramedMessageChannel channel = new FramedMessageChannel(connectedChannel, pool.allocate(), pool.allocate());
try {
assertSame(connectedChannel, channel.getChannel());
// getLocalAddress
connectedChannel.setLocalAddress(new InetSocketAddress(10));
assertEquals(connectedChannel.getLocalAddress(), channel.getLocalAddress());
assertEquals(connectedChannel.getLocalAddress(InetSocketAddress.class), channel.getLocalAddress(InetSocketAddress.class));
assertEquals(connectedChannel.getLocalAddress(LocalSocketAddress.class), channel.getLocalAddress(LocalSocketAddress.class));
// getPeerAddress
connectedChannel.setPeerAddress(new LocalSocketAddress("local"));
assertEquals(connectedChannel.getPeerAddress(), channel.getPeerAddress());
assertEquals(connectedChannel.getPeerAddress(LocalSocketAddress.class), channel.getPeerAddress(LocalSocketAddress.class));
assertEquals(connectedChannel.getPeerAddress(InetSocketAddress.class), channel.getPeerAddress(InetSocketAddress.class));
} finally {
channel.close();
}
}
protected final void assertReadMessage(ByteBuffer dst, String... message) {
StringBuffer stringBuffer = new StringBuffer();
for (String messageString: message) {
stringBuffer.append(messageString);
}
dst.flip();
assertEquals(stringBuffer.toString(), Buffers.getModifiedUtf8(dst));
}
protected final void assertWrittenMessage(String... message) throws UnsupportedEncodingException {
int totalLength = 0;
for (String m: message) {
totalLength += 4 + m.length();
}
ByteBuffer byteBuffer = ByteBuffer.allocate(totalLength);
for (String m: message) {
byteBuffer.putInt(m.length());
byteBuffer.put(m.getBytes("UTF-8"));
}
ByteBuffer written = connectedChannel.getWrittenBytes();
written.flip();
assertEquals(byteBuffer.limit(), written.limit());
Assert.assertArrayEquals(byteBuffer.array(), Arrays.copyOf(written.array(), totalLength));
}
}