/* * Copyright 2014-2017 Real Logic Ltd. * * 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 io.aeron; import org.junit.Test; import io.aeron.command.PublicationMessageFlyweight; import io.aeron.protocol.DataHeaderFlyweight; import io.aeron.protocol.HeaderFlyweight; import io.aeron.protocol.NakFlyweight; import org.agrona.concurrent.UnsafeBuffer; import java.nio.ByteBuffer; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; public class FlyweightTest { private final ByteBuffer buffer = ByteBuffer.allocateDirect(512); private final UnsafeBuffer aBuff = new UnsafeBuffer(buffer); private final HeaderFlyweight encodeHeader = new HeaderFlyweight(); private final HeaderFlyweight decodeHeader = new HeaderFlyweight(); private final DataHeaderFlyweight encodeDataHeader = new DataHeaderFlyweight(); private final DataHeaderFlyweight decodeDataHeader = new DataHeaderFlyweight(); private final PublicationMessageFlyweight encodePublication = new PublicationMessageFlyweight(); private final PublicationMessageFlyweight decodePublication = new PublicationMessageFlyweight(); private final NakFlyweight encodeNakHeader = new NakFlyweight(); private final NakFlyweight decodeNakHeader = new NakFlyweight(); @Test public void shouldWriteCorrectValuesForGenericHeaderFields() { encodeHeader.wrap(aBuff); encodeHeader.version((short)1); encodeHeader.flags(DataHeaderFlyweight.BEGIN_AND_END_FLAGS); encodeHeader.headerType(HeaderFlyweight.HDR_TYPE_DATA); encodeHeader.frameLength(8); // little endian assertThat(buffer.get(0), is((byte)0x08)); assertThat(buffer.get(1), is((byte)0x00)); assertThat(buffer.get(2), is((byte)0x00)); assertThat(buffer.get(3), is((byte)0x00)); assertThat(buffer.get(4), is((byte)0x01)); assertThat(buffer.get(5), is((byte)0xC0)); assertThat(buffer.get(6), is((byte)HeaderFlyweight.HDR_TYPE_DATA)); assertThat(buffer.get(7), is((byte)0x00)); } @Test public void shouldReadWhatIsWrittenToGenericHeaderFields() { encodeHeader.wrap(aBuff); encodeHeader.version((short)1); encodeHeader.flags((short)0); encodeHeader.headerType(HeaderFlyweight.HDR_TYPE_DATA); encodeHeader.frameLength(8); decodeHeader.wrap(aBuff); assertThat(decodeHeader.version(), is((short)1)); assertThat(decodeHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(decodeHeader.frameLength(), is(8)); } @Test public void shouldWriteAndReadMultipleFramesCorrectly() { encodeHeader.wrap(aBuff); encodeHeader.version((short)1); encodeHeader.flags((short)0); encodeHeader.headerType(HeaderFlyweight.HDR_TYPE_DATA); encodeHeader.frameLength(8); encodeHeader.wrap(aBuff, 8, aBuff.capacity() - 8); encodeHeader.version((short)2); encodeHeader.flags((short)0x01); encodeHeader.headerType(HeaderFlyweight.HDR_TYPE_SM); encodeHeader.frameLength(8); decodeHeader.wrap(aBuff); assertThat(decodeHeader.version(), is((short)1)); assertThat(decodeHeader.flags(), is((short)0)); assertThat(decodeHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(decodeHeader.frameLength(), is(8)); decodeHeader.wrap(aBuff, 8, aBuff.capacity() - 8); assertThat(decodeHeader.version(), is((short)2)); assertThat(decodeHeader.flags(), is((short)0x01)); assertThat(decodeHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SM)); assertThat(decodeHeader.frameLength(), is(8)); } @Test public void shouldReadAndWriteDataHeaderCorrectly() { encodeDataHeader.wrap(aBuff); encodeDataHeader.version((short)1); encodeDataHeader.flags(DataHeaderFlyweight.BEGIN_AND_END_FLAGS); encodeDataHeader.headerType(HeaderFlyweight.HDR_TYPE_DATA); encodeDataHeader.frameLength(DataHeaderFlyweight.HEADER_LENGTH); encodeDataHeader.sessionId(0xdeadbeef); encodeDataHeader.streamId(0x44332211); encodeDataHeader.termId(0x99887766); decodeDataHeader.wrap(aBuff); assertThat(decodeDataHeader.version(), is((short)1)); assertThat(decodeDataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(decodeDataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(decodeDataHeader.frameLength(), is(DataHeaderFlyweight.HEADER_LENGTH)); assertThat(decodeDataHeader.sessionId(), is(0xdeadbeef)); assertThat(decodeDataHeader.streamId(), is(0x44332211)); assertThat(decodeDataHeader.termId(), is(0x99887766)); assertThat(decodeDataHeader.dataOffset(), is(DataHeaderFlyweight.HEADER_LENGTH)); } @Test public void shouldEncodeAndDecodeNakCorrectly() { encodeNakHeader.wrap(aBuff); encodeNakHeader.version((short)1); encodeNakHeader.flags((byte)0); encodeNakHeader.headerType(HeaderFlyweight.HDR_TYPE_NAK); encodeNakHeader.frameLength(NakFlyweight.HEADER_LENGTH); encodeNakHeader.sessionId(0xdeadbeef); encodeNakHeader.streamId(0x44332211); encodeNakHeader.termId(0x99887766); encodeNakHeader.termOffset(0x22334); encodeNakHeader.length(512); decodeNakHeader.wrap(aBuff); assertThat(decodeNakHeader.version(), is((short)1)); assertThat(decodeNakHeader.flags(), is((short)0)); assertThat(decodeNakHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_NAK)); assertThat(decodeNakHeader.frameLength(), is(NakFlyweight.HEADER_LENGTH)); assertThat(decodeNakHeader.sessionId(), is(0xdeadbeef)); assertThat(decodeNakHeader.streamId(), is(0x44332211)); assertThat(decodeNakHeader.termId(), is(0x99887766)); assertThat(decodeNakHeader.termOffset(), is(0x22334)); assertThat(decodeNakHeader.length(), is(512)); } @Test public void shouldEncodeAndDecodeChannelsCorrectly() { encodePublication.wrap(aBuff, 0); final String channel = "aeron:udp?endpoint=localhost:4000"; encodePublication.channel(channel); decodePublication.wrap(aBuff, 0); assertThat(decodePublication.channel(), is(channel)); } }