From 3099d9b5e42a502215b59bcd88e1cb67d20bbe35 Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Tue, 25 Feb 2014 18:04:15 +0100 Subject: [PATCH] Hardened the tests for the new data mining components --- ...estAbstractParallelProcessorFinishing.java | 8 ++-- ...elProcessorWithManySimpleInstructions.java | 11 +++-- .../components/TestAbstractProcessor.java | 47 +++++++++++++++++++ .../components/TestFilteringProcessors.java | 1 + .../TestParallelExtractionProcessor.java | 38 +++++++++++---- ...llelMultiDimensionalGroupingProcessor.java | 27 ++++++++++- ...ningOfAbstractSimpleParallelProcessor.java | 8 ++-- ...llelMultiDimensionalGroupingProcessor.java | 4 ++ 8 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractProcessor.java diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorFinishing.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorFinishing.java index 461938407c1..83a983ce428 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorFinishing.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorFinishing.java @@ -6,6 +6,7 @@ import static org.junit.Assert.fail; import java.util.Collection; import java.util.HashSet; +import java.util.concurrent.Callable; import org.junit.Before; import org.junit.Test; @@ -59,10 +60,10 @@ public class TestAbstractParallelProcessorFinishing { private AbstractSimpleParallelProcessor createProcessor(Collection> receivers) { return new AbstractSimpleParallelProcessor(ConcurrencyTestsUtil.getExecutor(), receivers) { @Override - protected Runnable createInstruction(Integer partialElement) { - return new Runnable() { + protected Callable createInstruction(Integer partialElement) { + return new Callable() { @Override - public void run() { + public Integer call() { while (instructionIsWorking) { try { Thread.sleep(100); @@ -70,6 +71,7 @@ public class TestAbstractParallelProcessorFinishing { fail("Instruction was interrupted."); } } + return 0; } }; } diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorWithManySimpleInstructions.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorWithManySimpleInstructions.java index a0ab4a9cbaa..83eea28e658 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorWithManySimpleInstructions.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractParallelProcessorWithManySimpleInstructions.java @@ -5,12 +5,12 @@ import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Collection; +import java.util.concurrent.Callable; import org.junit.Before; import org.junit.Test; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; -import com.sap.sse.datamining.test.components.util.InputForwardingInstruction; import com.sap.sse.datamining.test.util.ConcurrencyTestsUtil; public class TestAbstractParallelProcessorWithManySimpleInstructions { @@ -37,8 +37,13 @@ public class TestAbstractParallelProcessorWithManySimpleInstructions { receivers.add(receiver); processor = new AbstractSimpleParallelProcessor(ConcurrencyTestsUtil.getExecutor(), receivers) { @Override - protected Runnable createInstruction(Integer partialElement) { - return new InputForwardingInstruction(partialElement, getResultReceivers()); + protected Callable createInstruction(final Integer element) { + return new Callable() { + @Override + public Integer call() throws Exception { + return element; + } + }; } }; } diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractProcessor.java new file mode 100644 index 00000000000..60983f8bf0d --- /dev/null +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestAbstractProcessor.java @@ -0,0 +1,47 @@ +package com.sap.sse.datamining.components; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.util.Collection; +import java.util.HashSet; + +import org.junit.Before; +import org.junit.Test; + +import com.sap.sse.datamining.impl.components.AbstractProcessor; + +public class TestAbstractProcessor { + + private Collection> receivers; + private boolean receiverWasToldToFinish; + + @Before + public void initializeReceivers() { + Processor receiver = new Processor() { + @Override + public void onElement(Integer element) { + } + @Override + public void finish() throws InterruptedException { + receiverWasToldToFinish = true; + } + }; + + receivers = new HashSet<>(); + receivers.add(receiver); + } + + @Test + public void testFinishing() throws InterruptedException { + Processor processor = new AbstractProcessor(receivers) { + @Override + protected Integer processElement(Integer element) { + return null; + } + }; + processor.finish(); + assertThat(receiverWasToldToFinish, is(true)); + } + +} diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestFilteringProcessors.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestFilteringProcessors.java index d4f5f353090..20fdf940db8 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestFilteringProcessors.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestFilteringProcessors.java @@ -12,6 +12,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; +import com.sap.sse.datamining.impl.components.ParallelFilteringProcessor; import com.sap.sse.datamining.test.util.ConcurrencyTestsUtil; public class TestFilteringProcessors { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelExtractionProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelExtractionProcessor.java index 9cf7fbc10de..9850b82e56d 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelExtractionProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelExtractionProcessor.java @@ -30,6 +30,11 @@ public class TestParallelExtractionProcessor { private Function getCrossSumFunction; + /** + * A function that is invalid with the type {@link Number} and will return null with every invocation. + */ + private Function invalidFunction; + @Before public void initializeReceivers() { receivedValues = new HashMap<>(); @@ -49,9 +54,12 @@ public class TestParallelExtractionProcessor { } @Before - public void initializeExtractionFunction() { - Method extractionMethod = FunctionTestsUtil.getMethodFromClass(Number.class, "getCrossSum"); - getCrossSumFunction = FunctionFactory.createMethodWrappingFunction(extractionMethod); + public void initializeExtractionFunctions() { + Method getCrossSumMethod = FunctionTestsUtil.getMethodFromClass(Number.class, "getCrossSum"); + getCrossSumFunction = FunctionFactory.createMethodWrappingFunction(getCrossSumMethod); + + Method invalidMethod = FunctionTestsUtil.getMethodFromSimpleClassWithMarkedMethod("sideEffectFreeValue"); + invalidFunction = FunctionFactory.createMethodWrappingFunction(invalidMethod); } @Test @@ -59,10 +67,27 @@ public class TestParallelExtractionProcessor { Processor> processor = new ParallelGroupedElementsValueExtractionProcessor(ConcurrencyTestsUtil.getExecutor(), receivers, getCrossSumFunction); Collection> elements = createElements(); processElements(processor, elements); + ConcurrencyTestsUtil.sleepFor(100); //Giving the processor time to finish the instructions + Collection> expectedReceivedValues = buildExpectedReceivedValues(elements); verifyThatExpectedElementsHaveBeenReceived(expectedReceivedValues); } + private void verifyThatExpectedElementsHaveBeenReceived(Collection> expectedReceivedValues) { + for (GroupedDataEntry expectedReceivedValue : expectedReceivedValues) { + assertThat("The expected value '" + expectedReceivedValue + "' wasn't received.", receivedValues.containsKey(expectedReceivedValue.getKey()), is(true)); + assertThat(receivedValues.get(expectedReceivedValue.getKey()), is(expectedReceivedValue.getDataEntry())); + } + } + + @Test + public void testValueExtractionWithInvalidFunction() { + Processor> processor = new ParallelGroupedElementsValueExtractionProcessor(ConcurrencyTestsUtil.getExecutor(), receivers, invalidFunction); + processElements(processor, createElements()); + ConcurrencyTestsUtil.sleepFor(100); //Giving the processor time to finish the instructions + assertThat("Values have been received, but the processor function is invalid.", receivedValues.isEmpty(), is(true)); + } + private Collection> createElements() { Collection> elements = new ArrayList<>(); elements.add(new GroupedDataEntry(new GenericGroupKey(1), new Number(1))); @@ -88,11 +113,4 @@ public class TestParallelExtractionProcessor { return expectedReceivedValues; } - private void verifyThatExpectedElementsHaveBeenReceived(Collection> expectedReceivedValues) { - for (GroupedDataEntry expectedReceivedValue : expectedReceivedValues) { - assertThat("The expected value '" + expectedReceivedValue + "' wasn't received.", receivedValues.containsKey(expectedReceivedValue.getKey()), is(true)); - assertThat(receivedValues.get(expectedReceivedValue.getKey()), is(expectedReceivedValue.getDataEntry())); - } - } - } diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelMultiDimensionalGroupingProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelMultiDimensionalGroupingProcessor.java index 90c6197e87e..d4cad0cc69d 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelMultiDimensionalGroupingProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestParallelMultiDimensionalGroupingProcessor.java @@ -3,6 +3,7 @@ package com.sap.sse.datamining.components; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -10,6 +11,7 @@ import java.util.Collection; import org.junit.Before; import org.junit.Test; +import com.sap.sse.datamining.factories.FunctionFactory; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.components.ParallelMultiDimensionalGroupingProcessor; @@ -19,10 +21,12 @@ import com.sap.sse.datamining.shared.impl.CompoundGroupKey; import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.test.components.util.Number; import com.sap.sse.datamining.test.util.ConcurrencyTestsUtil; +import com.sap.sse.datamining.test.util.FunctionTestsUtil; public class TestParallelMultiDimensionalGroupingProcessor { private Processor> processor; + private Collection>> receivers; private GroupedDataEntry groupedElement; @@ -37,13 +41,34 @@ public class TestParallelMultiDimensionalGroupingProcessor { public void finish() throws InterruptedException { } }; - Collection>> receivers = new ArrayList<>(); + receivers = new ArrayList<>(); receivers.add(receiver); + Collection> dimensions = new ArrayList>(); dimensions.add(new MethodWrappingFunction<>(Number.class.getMethod("getLength", new Class[0]), int.class)); dimensions.add(new MethodWrappingFunction<>(Number.class.getMethod("getCrossSum", new Class[0]), int.class)); + processor = new ParallelMultiDimensionalGroupingProcessor(ConcurrencyTestsUtil.getExecutor(), receivers, dimensions); } + + @Test(expected=IllegalArgumentException.class) + public void testConstructionWithNullDimensions() { + new ParallelMultiDimensionalGroupingProcessor<>(ConcurrencyTestsUtil.getExecutor(), receivers, null); + } + + @Test(expected=IllegalArgumentException.class) + public void testConstructionWithEmptyDimensions() { + Iterable> dimensions = new ArrayList<>(); + new ParallelMultiDimensionalGroupingProcessor<>(ConcurrencyTestsUtil.getExecutor(), receivers, dimensions); + } + + @Test(expected=IllegalArgumentException.class) + public void testConstructionWithFunctionsInsteadOfDimensions() { + Collection> functions = new ArrayList<>(); + Method method = FunctionTestsUtil.getMethodFromSimpleClassWithMarkedMethod("sideEffectFreeValue"); + functions.add(FunctionFactory.createMethodWrappingFunction(method)); + new ParallelMultiDimensionalGroupingProcessor<>(ConcurrencyTestsUtil.getExecutor(), receivers, functions); + } @Test public void testGroupKeyGeneration() { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestPartitioningOfAbstractSimpleParallelProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestPartitioningOfAbstractSimpleParallelProcessor.java index 95475ce7d67..cc6f1280ef5 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestPartitioningOfAbstractSimpleParallelProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/components/TestPartitioningOfAbstractSimpleParallelProcessor.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertThat; import java.util.HashSet; import java.util.Iterator; +import java.util.concurrent.Callable; import org.junit.Test; @@ -26,10 +27,11 @@ public class TestPartitioningOfAbstractSimpleParallelProcessor { } @Override - protected Runnable createInstruction(Integer partialElement) { - return new Runnable() { + protected Callable createInstruction(Integer partialElement) { + return new Callable() { @Override - public void run() { + public Integer call() throws Exception { + return 0; } }; } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelMultiDimensionalGroupingProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelMultiDimensionalGroupingProcessor.java index 8e04401e71c..a84a4c156d6 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelMultiDimensionalGroupingProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelMultiDimensionalGroupingProcessor.java @@ -24,6 +24,10 @@ public class ParallelMultiDimensionalGroupingProcessor } private void verifyThatDimensionsAreDimensions(Iterable> dimensions) { + if (dimensions == null) { + throw new IllegalArgumentException("The given dimensions mustn't be null."); + } + int size = 0; for (Function possibleDimension : dimensions) { size++;