/* * 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.Before; import org.junit.Test; import io.aeron.logbuffer.FragmentHandler; import io.aeron.logbuffer.FrameDescriptor; import io.aeron.logbuffer.Header; import io.aeron.protocol.DataHeaderFlyweight; import org.agrona.concurrent.UnsafeBuffer; import org.mockito.InOrder; import org.mockito.Mockito; import java.nio.ByteBuffer; import java.util.concurrent.locks.Lock; import static junit.framework.TestCase.assertTrue; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.*; public class SubscriptionTest { private static final String CHANNEL = "aeron:udp?endpoint=localhost:40124"; private static final int STREAM_ID_1 = 2; private static final long SUBSCRIPTION_CORRELATION_ID = 100; private static final int READ_BUFFER_CAPACITY = 1024; private static final byte FLAGS = (byte)FrameDescriptor.UNFRAGMENTED; private static final int FRAGMENT_COUNT_LIMIT = Integer.MAX_VALUE; private static final int HEADER_LENGTH = DataHeaderFlyweight.HEADER_LENGTH; private final UnsafeBuffer atomicReadBuffer = new UnsafeBuffer(ByteBuffer.allocateDirect(READ_BUFFER_CAPACITY)); private final Lock conductorLock = mock(Lock.class); private final ClientConductor conductor = mock(ClientConductor.class); private final FragmentHandler fragmentHandler = mock(FragmentHandler.class); private final Image imageOneMock = mock(Image.class); private final Header header = mock(Header.class); private final Image imageTwoMock = mock(Image.class); private final AvailableImageHandler availableImageHandlerMock = mock(AvailableImageHandler.class); private final UnavailableImageHandler unavailableImageHandlerMock = mock(UnavailableImageHandler.class); private Subscription subscription; @Before public void setUp() { when(header.flags()).thenReturn(FLAGS); when(conductor.clientLock()).thenReturn(conductorLock); subscription = new Subscription( conductor, CHANNEL, STREAM_ID_1, SUBSCRIPTION_CORRELATION_ID, availableImageHandlerMock, unavailableImageHandlerMock); } @Test public void shouldEnsureTheSubscriptionIsOpenWhenPolling() { subscription.close(); assertTrue(subscription.isClosed()); final InOrder inOrder = Mockito.inOrder(conductorLock, conductor); inOrder.verify(conductorLock).lock(); inOrder.verify(conductor).releaseSubscription(subscription); inOrder.verify(conductorLock).unlock(); } @Test public void shouldReadNothingWhenNoImages() { assertThat(subscription.poll(fragmentHandler, 1), is(0)); } @Test public void shouldReadNothingWhenThereIsNoData() { subscription.addImage(imageOneMock); assertThat(subscription.poll(fragmentHandler, 1), is(0)); } @Test public void shouldReadData() { subscription.addImage(imageOneMock); when(imageOneMock.poll(any(FragmentHandler.class), anyInt())).then( (invocation) -> { final FragmentHandler handler = (FragmentHandler)invocation.getArguments()[0]; handler.onFragment(atomicReadBuffer, HEADER_LENGTH, READ_BUFFER_CAPACITY - HEADER_LENGTH, header); return 1; }); assertThat(subscription.poll(fragmentHandler, FRAGMENT_COUNT_LIMIT), is(1)); verify(fragmentHandler).onFragment( eq(atomicReadBuffer), eq(HEADER_LENGTH), eq(READ_BUFFER_CAPACITY - HEADER_LENGTH), any(Header.class)); } @Test public void shouldReadDataFromMultipleSources() { subscription.addImage(imageOneMock); subscription.addImage(imageTwoMock); when(imageOneMock.poll(any(FragmentHandler.class), anyInt())).then( (invocation) -> { final FragmentHandler handler = (FragmentHandler)invocation.getArguments()[0]; handler.onFragment(atomicReadBuffer, HEADER_LENGTH, READ_BUFFER_CAPACITY - HEADER_LENGTH, header); return 1; }); when(imageTwoMock.poll(any(FragmentHandler.class), anyInt())).then( (invocation) -> { final FragmentHandler handler = (FragmentHandler)invocation.getArguments()[0]; handler.onFragment(atomicReadBuffer, HEADER_LENGTH, READ_BUFFER_CAPACITY - HEADER_LENGTH, header); return 1; }); assertThat(subscription.poll(fragmentHandler, FRAGMENT_COUNT_LIMIT), is(2)); } }