/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.fabric.netty.codec.serialization;
import com.liferay.portal.fabric.netty.util.NettyUtil;
import com.liferay.portal.kernel.io.AnnotatedObjectOutputStream;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
import com.liferay.portal.kernel.test.ReflectionTestUtil;
import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
/**
* @author Shuyang Zhou
*/
public class AnnotatedObjectDecoderTest {
@ClassRule
public static final CodeCoverageAssertor codeCoverageAssertor =
CodeCoverageAssertor.INSTANCE;
@Before
public void setUp() {
_channelPipeline.addLast(_annotatedObjectDecoder);
ReflectionTestUtil.setFieldValue(_dateChannelHandler, "_added", true);
ReflectionTestUtil.setFieldValue(_uuidChannelHandler, "_added", true);
}
@Test
public void testAddFirstBatch() {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
}
@Test
public void testAddFirstWithName() {
_annotatedObjectDecoder.addFirst(
DateChannelHandler.class.getName(), _dateChannelHandler);
_annotatedObjectDecoder.addFirst(
UUIDChannelHandler.class.getName(), _uuidChannelHandler);
_assertChannelPipeline(_uuidChannelHandler, _dateChannelHandler);
}
@Test
public void testAddLastBatch() {
_annotatedObjectDecoder.addLast(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
}
@Test
public void testAddLastWithName() {
_annotatedObjectDecoder.addLast(
DateChannelHandler.class.getName(), _dateChannelHandler);
_annotatedObjectDecoder.addLast(
UUIDChannelHandler.class.getName(), _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
}
@Test
public void testDecode() throws Exception {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
Date date = new Date();
ByteBuf byteBuf = _toByteBuf(date);
byteBuf.markWriterIndex();
byteBuf.setIndex(0, byteBuf.writerIndex() / 2);
Assert.assertNull(_annotatedObjectDecoder.decode(null, byteBuf));
byteBuf.resetWriterIndex();
Assert.assertEquals(
date, _annotatedObjectDecoder.decode(null, byteBuf));
UUID uuid = UUID.randomUUID();
Assert.assertNull(_uuidChannelHandler.getUuid());
Assert.assertNull(
_annotatedObjectDecoder.decode(null, _toByteBuf(uuid)));
Assert.assertEquals(uuid, _uuidChannelHandler.getUuid());
}
@Test
public void testRemoveByInstance() {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
_annotatedObjectDecoder.remove(_uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler);
try {
_annotatedObjectDecoder.remove(_uuidChannelHandler);
Assert.fail();
}
catch (NoSuchElementException nsee) {
}
_assertChannelPipeline(_dateChannelHandler);
_annotatedObjectDecoder.remove(_dateChannelHandler);
try {
_annotatedObjectDecoder.remove(_dateChannelHandler);
Assert.fail();
}
catch (NoSuchElementException nsee) {
}
_assertChannelPipeline();
}
@Test
public void testRemoveByName() {
_annotatedObjectDecoder.addFirst(
DateChannelHandler.class.getName(), _dateChannelHandler);
_annotatedObjectDecoder.addFirst(
UUIDChannelHandler.class.getName(), _uuidChannelHandler);
_assertChannelPipeline(_uuidChannelHandler, _dateChannelHandler);
Assert.assertSame(
_dateChannelHandler,
_annotatedObjectDecoder.remove(DateChannelHandler.class.getName()));
_assertChannelPipeline(_uuidChannelHandler);
Assert.assertSame(
_uuidChannelHandler,
_annotatedObjectDecoder.remove(UUIDChannelHandler.class.getName()));
_assertChannelPipeline();
}
@Test
public void testRemoveByType() {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
Assert.assertSame(
_uuidChannelHandler,
_annotatedObjectDecoder.remove(UUIDChannelHandler.class));
_assertChannelPipeline(_dateChannelHandler);
try {
_annotatedObjectDecoder.remove(UUIDChannelHandler.class);
Assert.fail();
}
catch (NoSuchElementException nsee) {
}
_assertChannelPipeline(_dateChannelHandler);
Assert.assertSame(
_dateChannelHandler,
_annotatedObjectDecoder.remove(DateChannelHandler.class));
try {
_annotatedObjectDecoder.remove(DateChannelHandler.class);
Assert.fail();
}
catch (NoSuchElementException nsee) {
}
_assertChannelPipeline();
}
@Test
public void testRemoveFirst() {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
Assert.assertSame(
_dateChannelHandler, _annotatedObjectDecoder.removeFirst());
_assertChannelPipeline(_uuidChannelHandler);
Assert.assertSame(
_uuidChannelHandler, _annotatedObjectDecoder.removeFirst());
_assertChannelPipeline();
}
@Test
public void testRemoveLast() {
_annotatedObjectDecoder.addFirst(
_dateChannelHandler, _uuidChannelHandler);
_assertChannelPipeline(_dateChannelHandler, _uuidChannelHandler);
Assert.assertSame(
_uuidChannelHandler, _annotatedObjectDecoder.removeLast());
_assertChannelPipeline(_dateChannelHandler);
Assert.assertSame(
_dateChannelHandler, _annotatedObjectDecoder.removeFirst());
_assertChannelPipeline();
}
private void _assertChannelPipeline(ChannelHandler... channelHandlers) {
Map<String, ChannelHandler> map = _innerChannelPipeline.toMap();
Assert.assertEquals(map.toString(), channelHandlers.length, map.size());
Assert.assertEquals(
Arrays.asList(channelHandlers),
new ArrayList<ChannelHandler>(map.values()));
}
private ByteBuf _toByteBuf(Serializable serializable) throws IOException {
UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
new UnsyncByteArrayOutputStream();
try (AnnotatedObjectOutputStream annotatedObjectOutputStream =
new AnnotatedObjectOutputStream(unsyncByteArrayOutputStream)) {
annotatedObjectOutputStream.writeObject(serializable);
}
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeInt(unsyncByteArrayOutputStream.size());
byteBuf.writeBytes(unsyncByteArrayOutputStream.toByteArray());
return byteBuf;
}
private final AnnotatedObjectDecoder _annotatedObjectDecoder =
new AnnotatedObjectDecoder();
private final ChannelPipeline _channelPipeline =
NettyUtil.createEmptyChannelPipeline();
private final DateChannelHandler _dateChannelHandler =
new DateChannelHandler();
private final ChannelPipeline _innerChannelPipeline =
(ChannelPipeline)ReflectionTestUtil.getFieldValue(
_annotatedObjectDecoder, "_channelPipeline");
private final UUIDChannelHandler _uuidChannelHandler =
new UUIDChannelHandler();
private static class DateChannelHandler
extends ObjectDecodeChannelInboundHandler<Date> {
@Override
public Date channelRead0(
ChannelHandlerContext channelHandlerContext, Date date,
ByteBuf byteBuf) {
return date;
}
}
private static class UUIDChannelHandler
extends ObjectDecodeChannelInboundHandler<UUID> {
@Override
public UUID channelRead0(
ChannelHandlerContext channelHandlerContext, UUID uuid,
ByteBuf byteBuf) {
_uuid = uuid;
return null;
}
public UUID getUuid() {
return _uuid;
}
private UUID _uuid;
}
}