/** * Copyright 2015 Otto (GmbH & Co KG) * * 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 com.ottogroup.bi.spqr.pipeline.component.operator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import com.ottogroup.bi.spqr.exception.RequiredInputMissingException; import com.ottogroup.bi.spqr.pipeline.message.StreamingDataMessage; import com.ottogroup.bi.spqr.pipeline.queue.StreamingMessageQueueConsumer; import com.ottogroup.bi.spqr.pipeline.queue.StreamingMessageQueueProducer; import com.ottogroup.bi.spqr.pipeline.queue.strategy.StreamingMessageQueueWaitStrategy; /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment} * @author mnxfst * @since Mar 11, 2015 */ public class DirectResponseOperatorRuntimeEnvironmentTest { private static ExecutorService executorService = Executors.newCachedThreadPool(); @AfterClass public static void shutdown() { if(executorService != null) executorService.shutdownNow(); } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided null as input to processing node id parameter */ @Test public void testConstructor_withNullProcessingNodeIdInput() { try { new DirectResponseOperatorRuntimeEnvironment(null, "pipe-id", Mockito.mock(DirectResponseOperator.class), Mockito.mock(StreamingMessageQueueConsumer.class), Mockito.mock(StreamingMessageQueueProducer.class)); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided null as input to pipeline id parameter */ @Test public void testConstructor_withNullPipelineIdInput() { try { new DirectResponseOperatorRuntimeEnvironment("proc-id", null, Mockito.mock(DirectResponseOperator.class), Mockito.mock(StreamingMessageQueueConsumer.class), Mockito.mock(StreamingMessageQueueProducer.class)); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided null as input to operator parameter which must lead to a {@link RequiredInputMissingException} */ @Test public void testConstructor_withNullOperatorInput() { try { new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id", null, Mockito.mock(StreamingMessageQueueConsumer.class), Mockito.mock(StreamingMessageQueueProducer.class)); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided null as input to queue consumer parameter which must lead to a {@link RequiredInputMissingException} */ @Test public void testConstructor_withNullConsumerInput() { try { new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",Mockito.mock(DirectResponseOperator.class), null, Mockito.mock(StreamingMessageQueueProducer.class)); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided null as input to queue producer parameter which must lead to a {@link RequiredInputMissingException} */ @Test public void testConstructor_withNullProducerInput() { try { new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",Mockito.mock(DirectResponseOperator.class), Mockito.mock(StreamingMessageQueueConsumer.class), null); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",DirectResponseOperator, StreamingMessageQueueConsumer, StreamingMessageQueueProducer)} * being provided valid input. The {@link DirectResponseOperatorRuntimeEnvironment#isRunning()} method must show true now */ @Test public void testConstructor_withValidInput() throws RequiredInputMissingException { DirectResponseOperatorRuntimeEnvironment env = new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",Mockito.mock(DirectResponseOperator.class), Mockito.mock(StreamingMessageQueueConsumer.class), Mockito.mock(StreamingMessageQueueProducer.class)); Assert.assertTrue("The environment must be running", env.isRunning()); } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment} being provided valid input to constructor and some messages on the input queue * which must be processed but lead to an error. No output must be available at the output queue but the environment must be still alive. */ @Test public void testConstructor_withMessagesToProcessAndFailingOperator() throws RequiredInputMissingException, InterruptedException { StreamingDataMessage inputMessage = new StreamingDataMessage("test".getBytes(), System.currentTimeMillis()); DirectResponseOperator operator = Mockito.mock(DirectResponseOperator.class); Mockito.when(operator.onMessage(inputMessage)).thenThrow(new RuntimeException("Failed to process message")); StreamingMessageQueueConsumer queueConsumer = Mockito.mock(StreamingMessageQueueConsumer.class); StreamingMessageQueueWaitStrategy queueConsumerStrategy = Mockito.mock(StreamingMessageQueueWaitStrategy.class); Mockito.when(queueConsumer.getWaitStrategy()).thenReturn(queueConsumerStrategy); Mockito.when(queueConsumerStrategy.waitFor(queueConsumer)).thenReturn(inputMessage); StreamingMessageQueueProducer queueProducer = Mockito.mock(StreamingMessageQueueProducer.class); StreamingMessageQueueWaitStrategy queueProducerStrategy = Mockito.mock(StreamingMessageQueueWaitStrategy.class); Mockito.when(queueProducer.getWaitStrategy()).thenReturn(queueProducerStrategy); DirectResponseOperatorRuntimeEnvironment env = new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",operator, queueConsumer, queueProducer); executorService.submit(env); Mockito.verify(queueProducer).getWaitStrategy(); Mockito.verify(queueConsumer).getWaitStrategy(); Mockito.verify(operator, Mockito.timeout(500).atLeastOnce()).onMessage(inputMessage); Mockito.verify(queueConsumerStrategy, Mockito.timeout(500).atLeastOnce()).waitFor(queueConsumer); Mockito.verify(queueProducerStrategy, Mockito.never()).forceLockRelease(); Mockito.verify(queueProducer, Mockito.never()).insert(inputMessage); Assert.assertTrue("The environment must be running", env.isRunning()); } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment} being provided valid input to constructor and some messages on the input queue * which must be processed and forwarded to the output queue. */ @Test public void testConstructor_withMessagesToProcess() throws RequiredInputMissingException, InterruptedException { StreamingDataMessage inputMessage = new StreamingDataMessage("test".getBytes(), System.currentTimeMillis()); DirectResponseOperator operator = Mockito.mock(DirectResponseOperator.class); Mockito.when(operator.onMessage(inputMessage)).thenReturn(new StreamingDataMessage[]{inputMessage}); StreamingMessageQueueConsumer queueConsumer = Mockito.mock(StreamingMessageQueueConsumer.class); StreamingMessageQueueWaitStrategy queueConsumerStrategy = Mockito.mock(StreamingMessageQueueWaitStrategy.class); Mockito.when(queueConsumer.getWaitStrategy()).thenReturn(queueConsumerStrategy); Mockito.when(queueConsumerStrategy.waitFor(queueConsumer)).thenReturn(inputMessage); StreamingMessageQueueProducer queueProducer = Mockito.mock(StreamingMessageQueueProducer.class); StreamingMessageQueueWaitStrategy queueProducerStrategy = Mockito.mock(StreamingMessageQueueWaitStrategy.class); Mockito.when(queueProducer.getWaitStrategy()).thenReturn(queueProducerStrategy); DirectResponseOperatorRuntimeEnvironment env = new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",operator, queueConsumer, queueProducer); executorService.submit(env); Mockito.verify(queueProducer).getWaitStrategy(); Mockito.verify(queueConsumer).getWaitStrategy(); Mockito.verify(operator, Mockito.timeout(500).atLeastOnce()).onMessage(inputMessage); Mockito.verify(queueConsumerStrategy, Mockito.timeout(500).atLeastOnce()).waitFor(queueConsumer); Mockito.verify(queueProducerStrategy, Mockito.timeout(500).atLeastOnce()).forceLockRelease(); Mockito.verify(queueProducer, Mockito.timeout(500).atLeastOnce()).insert(inputMessage); Assert.assertTrue("The environment must be running", env.isRunning()); } /** * Test case for {@link DirectResponseOperatorRuntimeEnvironment#shutdown()} where the environment previously received valid data. * The attached mock objects must register the shut down attempt */ @Test public void testShutdown_withValidSetup() throws RequiredInputMissingException { StreamingDataMessage inputMessage = new StreamingDataMessage("test".getBytes(), System.currentTimeMillis()); DirectResponseOperator operator = Mockito.mock(DirectResponseOperator.class); Mockito.when(operator.onMessage(inputMessage)).thenReturn(new StreamingDataMessage[]{inputMessage}); StreamingMessageQueueConsumer queueConsumer = Mockito.mock(StreamingMessageQueueConsumer.class); Mockito.when(queueConsumer.next()).thenReturn(inputMessage); StreamingMessageQueueProducer queueProducer = Mockito.mock(StreamingMessageQueueProducer.class); DirectResponseOperatorRuntimeEnvironment env = new DirectResponseOperatorRuntimeEnvironment("proc-id", "pipe-id",operator, queueConsumer, queueProducer); Assert.assertTrue("The environment must be running", env.isRunning()); env.shutdown(); Mockito.verify(operator, Mockito.timeout(500)).shutdown(); } }