/************************************************************************************** https://camel-extra.github.io This program 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 3 of the License, or (at your option) any later version. This program 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. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. http://www.gnu.org/licenses/lgpl-3.0-standalone.html ***************************************************************************************/ package org.apacheextras.camel.component.zeromq; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.EndpointInject; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.spi.ExecutorServiceManager; import org.apache.camel.test.junit4.CamelTestSupport; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.zeromq.ZMQ.Context; import org.zeromq.ZMQ.Socket; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; public class ZeromqConsumerTest extends CamelTestSupport { @EndpointInject(uri = "direct:start") private Endpoint from; @SuppressWarnings("hiding") @Produce(uri = "direct:start") protected ProducerTemplate template; @EndpointInject(uri = "mock:result") private MockEndpoint to; @Mock private Processor processor; @Mock private ZeromqEndpoint endpoint; @SuppressWarnings("hiding") private ZeromqConsumer consumer; @Mock private CamelContext ctx; @Mock private ExecutorServiceManager manager; @Mock private ExecutorService executor; @Mock private AkkaSocketFactory akkaSocketFactory; @Mock private Socket socket; @Mock private AkkaContextFactory akkaContextFactory; @Mock private Context context; @Before public void before() { initMocks(this); when(endpoint.getCamelContext()).thenReturn(ctx); when(endpoint.getSocketType()).thenReturn(ZeromqSocketType.SUBSCRIBE); when(endpoint.getSocketAddress()).thenReturn("tcp://localhost:5555"); when(akkaContextFactory.createContext(anyInt())).thenReturn(context); when(akkaSocketFactory.createConsumerSocket(context, ZeromqSocketType.SUBSCRIBE)).thenReturn(socket); when(ctx.getExecutorServiceManager()).thenReturn(manager); when(manager.newFixedThreadPool(any(ZeromqConsumer.class), anyString(), anyInt())).thenReturn(executor); consumer = new ZeromqConsumer(endpoint, processor, akkaContextFactory, akkaSocketFactory); } @Test @Ignore public void connect() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(1); when(manager.newFixedThreadPool(any(ZeromqConsumer.class), anyString(), anyInt())).thenReturn(executor); // CONNECT mode by default consumer.doStart(); Thread.sleep(50); verify(socket).connect(endpoint.getSocketAddress()); } @Test public void bind() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(1); when(manager.newFixedThreadPool(any(ZeromqConsumer.class), anyString(), anyInt())).thenReturn(executor); when(endpoint.getMode()).thenReturn("BIND"); consumer.doStart(); Thread.sleep(50); verify(socket).bind(endpoint.getSocketAddress()); } @Test public void stopWithoutStartIsOk() throws Exception { consumer.stop(); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from(from).process(new Processor() { @Override public void process(Exchange exchange) throws Exception { } }).to(to); } }; } @Test public void listenerIsSubmittedOnStart() throws Exception { consumer.doStart(); verify(executor).submit(any(Runnable.class)); } @Test public void shouldStopExecutor() throws Exception { // Given consumer.doStart(); // When consumer.doStop(); // Then verify(executor).shutdownNow(); } @Test public void test1000VirtualMessages() throws Exception { // just test that the messages are passed on into the final endpoint to.expectedMessageCount(1000); Thread t = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 1000; i++) { template.sendBody("test"); } } }); t.start(); t.join(); to.assertIsSatisfied(); } @Test public void textExecutorLifecycleForStopStart() throws Exception { consumer.doStart(); verify(executor, never()).shutdownNow(); consumer.doStop(); verify(executor).shutdownNow(); // 2nd invocation should have no effect consumer.doStop(); verify(executor).shutdownNow(); } }