/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * * 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 org.apache.streams.local.tasks; import org.apache.streams.core.StreamsDatum; import org.apache.streams.local.counters.StreamsTaskCounter; import org.apache.streams.local.test.processors.PassthroughDatumCounterProcessor; import org.apache.streams.local.test.providers.NumericMessageProvider; import org.apache.streams.local.test.writer.DatumCounterWriter; import org.apache.streams.util.ComponentUtils; import com.google.common.util.concurrent.Uninterruptibles; import org.junit.After; import org.junit.Test; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * */ public class BasicTasksTest { private static final String MBEAN_ID = "test_bean"; @After public void removeLocalMBeans() { try { ComponentUtils.removeAllMBeansOfDomain("org.apache.streams.local"); } catch (Exception e) { //No op. proceed to next test } } @Test public void testProviderTask() { int numMessages = 100; NumericMessageProvider provider = new NumericMessageProvider(numMessages); StreamsProviderTask task = new StreamsProviderTask(provider, false, null); BlockingQueue<StreamsDatum> outQueue = new LinkedBlockingQueue<>(); task.addOutputQueue(outQueue); //Test that adding input queues to providers is not valid BlockingQueue<StreamsDatum> inQueue = createInputQueue(numMessages); Exception exp = null; try { task.addInputQueue(inQueue); } catch (UnsupportedOperationException uoe) { exp = uoe; } assertNotNull(exp); ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(outQueue.size() != numMessages) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); if(attempts == 10) { fail("Provider task failed to output "+numMessages+" in a timely fashion."); } } service.shutdown(); try { if(!service.awaitTermination(10, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } @Test public void testProcessorTask() { int numMessages = 100; PassthroughDatumCounterProcessor processor = new PassthroughDatumCounterProcessor(""); StreamsProcessorTask task = new StreamsProcessorTask(processor); StreamsTaskCounter counter = new StreamsTaskCounter(MBEAN_ID, null, -1); task.setStreamsTaskCounter(counter); BlockingQueue<StreamsDatum> outQueue = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> inQueue = createInputQueue(numMessages); task.addOutputQueue(outQueue); task.addInputQueue(inQueue); assertEquals(numMessages, task.getInputQueues().get(0).size()); ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(inQueue.size() != 0 && outQueue.size() != numMessages) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); ++attempts; if(attempts == 10) { fail("Processor task failed to output "+numMessages+" in a timely fashion."); } } task.stopTask();; service.shutdown(); try { if(!service.awaitTermination(5, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { fail("Test Interrupted."); } assertEquals(numMessages, processor.getMessageCount()); assertEquals(numMessages, counter.getNumReceived()); assertEquals(numMessages, counter.getNumEmitted()); assertEquals(0, counter.getNumUnhandledErrors()); assertEquals(0.0, counter.getErrorRate(), 0.0); } @Test public void testWriterTask() { int numMessages = 100; DatumCounterWriter writer = new DatumCounterWriter(""); StreamsPersistWriterTask task = new StreamsPersistWriterTask(writer); StreamsTaskCounter counter = new StreamsTaskCounter(MBEAN_ID, null, -1); task.setStreamsTaskCounter(counter); BlockingQueue<StreamsDatum> outQueue = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> inQueue = createInputQueue(numMessages); Exception exp = null; try { task.addOutputQueue(outQueue); } catch (UnsupportedOperationException uoe) { exp = uoe; } assertNotNull(exp); task.addInputQueue(inQueue); assertEquals(numMessages, task.getInputQueues().get(0).size()); ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(inQueue.size() != 0 ) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); ++attempts; if(attempts == 10) { fail("Processor task failed to output "+numMessages+" in a timely fashion."); } } task.stopTask(); service.shutdown(); try { if(!service.awaitTermination(15, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { fail("Test Interrupted."); } assertEquals(numMessages, writer.getDatumsCounted()); assertEquals(numMessages, counter.getNumReceived()); assertEquals(0, counter.getNumEmitted()); assertEquals(0, counter.getNumUnhandledErrors()); assertEquals(0.0, counter.getErrorRate(), 0.0); } @Test public void testMergeTask() { int numMessages = 100; int incoming = 5; StreamsMergeTask task = new StreamsMergeTask(); BlockingQueue<StreamsDatum> outQueue = new LinkedBlockingQueue<>(); task.addOutputQueue(outQueue); for(int i=0; i < incoming; ++i) { task.addInputQueue(createInputQueue(numMessages)); } ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(outQueue.size() != incoming * numMessages ) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); ++attempts; if(attempts == 10) { assertEquals("Processor task failed to output " + (numMessages * incoming) + " in a timely fashion.", (numMessages * incoming), outQueue.size()); } } task.stopTask(); service.shutdown(); try { if(!service.awaitTermination(5, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { fail("Test Interrupted."); } } @Test public void testBranching() { int numMessages = 100; PassthroughDatumCounterProcessor processor = new PassthroughDatumCounterProcessor(""); StreamsProcessorTask task = new StreamsProcessorTask(processor); BlockingQueue<StreamsDatum> outQueue1 = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> outQueue2 = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> inQueue = createInputQueue(numMessages); task.addOutputQueue(outQueue1); task.addOutputQueue(outQueue2); task.addInputQueue(inQueue); assertEquals(numMessages, task.getInputQueues().get(0).size()); ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(inQueue.size() != 0 ) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); ++attempts; if(attempts == 10) { assertEquals("Processor task failed to output "+(numMessages)+" in a timely fashion.", 0, inQueue.size()); } } task.stopTask(); service.shutdown(); try { if(!service.awaitTermination(5, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { fail("Test Interrupted."); } assertEquals(numMessages, processor.getMessageCount()); assertEquals(numMessages, outQueue1.size()); assertEquals(numMessages, outQueue2.size()); } @Test public void testBranchingSerialization() { int numMessages = 1; PassthroughDatumCounterProcessor processor = new PassthroughDatumCounterProcessor(""); StreamsProcessorTask task = new StreamsProcessorTask(processor); BlockingQueue<StreamsDatum> outQueue1 = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> outQueue2 = new LinkedBlockingQueue<>(); BlockingQueue<StreamsDatum> inQueue = createInputQueue(numMessages); task.addOutputQueue(outQueue1); task.addOutputQueue(outQueue2); task.addInputQueue(inQueue); ExecutorService service = Executors.newFixedThreadPool(1); service.submit(task); int attempts = 0; while(inQueue.size() != 0 ) { Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); ++attempts; if(attempts == 10) { assertEquals("Processor task failed to output "+(numMessages)+" in a timely fashion.", 0, inQueue.size()); } } task.stopTask(); service.shutdown(); try { if(!service.awaitTermination(5, TimeUnit.SECONDS)){ service.shutdownNow(); fail("Service did not terminate."); } assertTrue("Task should have completed running in allotted time.", service.isTerminated()); } catch (InterruptedException e) { fail("Test Interrupted."); } assertEquals(numMessages, processor.getMessageCount()); assertEquals(numMessages, outQueue1.size()); assertEquals(numMessages, outQueue2.size()); StreamsDatum datum1 = outQueue1.poll(); StreamsDatum datum2 = outQueue2.poll(); assertNotNull(datum1); assertEquals(datum1, datum2); datum1.setDocument("a"); assertNotEquals(datum1, datum2); } private BlockingQueue<StreamsDatum> createInputQueue(int numDatums) { BlockingQueue<StreamsDatum> queue = new LinkedBlockingQueue<>(); for(int i=0; i < numDatums; ++i) { queue.add(new StreamsDatum(i)); } return queue; } }