From 9963f746dbacb04996a1debc2c2f799e9e439dee Mon Sep 17 00:00:00 2001 From: Felix Reimann Date: Fri, 9 Feb 2018 14:25:04 +0100 Subject: [PATCH] tests for sequential and parallel completer and module --- .../SequentialIndividualCompleter.java | 55 +++---- .../IndividualCompleterModuleTest.java | 41 ++++++ .../ParallelIndividualCompleterTest.java | 59 ++++++++ .../SequentialIndividualCompleterTest.java | 137 ++++++++++++++++++ 4 files changed, 266 insertions(+), 26 deletions(-) create mode 100644 opt4j-core/src/test/java/org/opt4j/core/common/completer/IndividualCompleterModuleTest.java create mode 100644 opt4j-core/src/test/java/org/opt4j/core/common/completer/ParallelIndividualCompleterTest.java create mode 100644 opt4j-core/src/test/java/org/opt4j/core/common/completer/SequentialIndividualCompleterTest.java diff --git a/opt4j-core/src/main/java/org/opt4j/core/common/completer/SequentialIndividualCompleter.java b/opt4j-core/src/main/java/org/opt4j/core/common/completer/SequentialIndividualCompleter.java index 06dbc2a6..85c11c0e 100644 --- a/opt4j-core/src/main/java/org/opt4j/core/common/completer/SequentialIndividualCompleter.java +++ b/opt4j-core/src/main/java/org/opt4j/core/common/completer/SequentialIndividualCompleter.java @@ -1,26 +1,20 @@ /******************************************************************************* * Copyright (c) 2014 Opt4J * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the + * Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ - package org.opt4j.core.common.completer; import java.util.Arrays; @@ -44,13 +38,11 @@ /** *

- * The {@link SequentialIndividualCompleter} completes the {@link Individual}s - * sequentially. + * The {@link SequentialIndividualCompleter} completes the {@link Individual}s sequentially. *

*

- * It updates the {@link State} of the {@link Individual} according to the state - * of the completion process. It uses {@link Control} between the different - * (possibly time consuming) completion steps to allow the user to control the + * It updates the {@link State} of the {@link Individual} according to the state of the completion process. It uses + * {@link Control} between the different (possibly time consuming) completion steps to allow the user to control the * completion process. *

* @@ -74,7 +66,8 @@ public class SequentialIndividualCompleter implements IndividualCompleter { * the evaluator */ @Inject - public SequentialIndividualCompleter(Control control, Decoder decoder, Evaluator evaluator) { + public SequentialIndividualCompleter(Control control, Decoder decoder, + Evaluator evaluator) { super(); this.control = control; this.decoder = decoder; @@ -102,8 +95,7 @@ public void complete(Iterable iterable) throws Termination /* * (non-Javadoc) * - * @see - * org.opt4j.core.optimizer.Completer#complete(org.opt4j.core.Individual[]) + * @see org.opt4j.core.optimizer.Completer#complete(org.opt4j.core.Individual[]) */ @Override public void complete(Individual... individuals) throws TerminationException { @@ -111,6 +103,12 @@ public void complete(Individual... individuals) throws TerminationException { complete(list); } + /** + * Evaluates the phenotype of the {@link Individual}. After this operation, the {@link Individual} is in + * {@link State} {@link State#EVALUATED} and {@link Individual#getObjectives()} returns the {@link Objectives}. + * + * @param individual + */ protected void evaluate(Individual individual) { State state = individual.getState(); @@ -127,6 +125,12 @@ protected void evaluate(Individual individual) { } } + /** + * Decodes the {@link Genotype} of the {@link Individual}. After this operation, the {@link Individual} is in + * {@link State} {@link State#PHENOTYPED} and {@link Individual#getPhenotype()} returns the phenotype. + * + * @param individual + */ protected void decode(Individual individual) { State state = individual.getState(); @@ -143,8 +147,7 @@ protected void decode(Individual individual) { private Set objectives = null; /** - * Check if the given {@link Objectives} have the same length as prior - * evaluated ones. + * Check if the given {@link Objectives} have the same length as prior evaluated ones. * * @param objectives * the objectives to check diff --git a/opt4j-core/src/test/java/org/opt4j/core/common/completer/IndividualCompleterModuleTest.java b/opt4j-core/src/test/java/org/opt4j/core/common/completer/IndividualCompleterModuleTest.java new file mode 100644 index 00000000..53ae5b46 --- /dev/null +++ b/opt4j-core/src/test/java/org/opt4j/core/common/completer/IndividualCompleterModuleTest.java @@ -0,0 +1,41 @@ +package org.opt4j.core.common.completer; + +import org.junit.Assert; +import org.junit.Test; +import org.opt4j.core.common.completer.IndividualCompleterModule.Type; +import org.opt4j.core.common.completer.SequentialIndividualCompleterTest.MockProblemModule; +import org.opt4j.core.optimizer.IndividualCompleter; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class IndividualCompleterModuleTest { + @Test + public void getType() { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setType(Type.PARALLEL); + Assert.assertEquals(Type.PARALLEL, module.getType()); + } + + @Test + public void configSequential() { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setType(Type.SEQUENTIAL); + + Injector injector = Guice.createInjector(new MockProblemModule(), module); + IndividualCompleter completer = injector.getInstance(IndividualCompleter.class); + + Assert.assertEquals(SequentialIndividualCompleter.class, completer.getClass()); + } + + @Test + public void configParallel() { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setType(Type.PARALLEL); + + Injector injector = Guice.createInjector(new MockProblemModule(), module); + IndividualCompleter completer = injector.getInstance(IndividualCompleter.class); + + Assert.assertEquals(ParallelIndividualCompleter.class, completer.getClass()); + } +} diff --git a/opt4j-core/src/test/java/org/opt4j/core/common/completer/ParallelIndividualCompleterTest.java b/opt4j-core/src/test/java/org/opt4j/core/common/completer/ParallelIndividualCompleterTest.java new file mode 100644 index 00000000..9a0c8c59 --- /dev/null +++ b/opt4j-core/src/test/java/org/opt4j/core/common/completer/ParallelIndividualCompleterTest.java @@ -0,0 +1,59 @@ +package org.opt4j.core.common.completer; + +import org.junit.Assert; +import org.junit.Test; +import org.opt4j.core.Individual; +import org.opt4j.core.IndividualFactory; +import org.opt4j.core.common.completer.IndividualCompleterModule.Type; +import org.opt4j.core.common.completer.SequentialIndividualCompleterTest.MockProblemModule; +import org.opt4j.core.optimizer.TerminationException; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class ParallelIndividualCompleterTest { + + @Test(expected = IllegalArgumentException.class) + public void invalidThreadCount() { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setThreads(0); + module.setType(Type.PARALLEL); + Injector injector = Guice.createInjector(new MockProblemModule(), module); + + injector.getInstance(ParallelIndividualCompleter.class); + } + + @Test + public void optimizationStopped() { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setThreads(4); + module.setType(Type.PARALLEL); + Injector injector = Guice.createInjector(new MockProblemModule(), module); + + ParallelIndividualCompleter completer = injector.getInstance(ParallelIndividualCompleter.class); + + completer.optimizationStopped(null); + Assert.assertTrue(completer.executor.isShutdown()); + Assert.assertTrue(completer.executor.isShutdown()); + } + + @Test + public void complete() throws TerminationException { + IndividualCompleterModule module = new IndividualCompleterModule(); + module.setThreads(4); + module.setType(Type.PARALLEL); + Injector injector = Guice.createInjector(new MockProblemModule(), module); + + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + Individual i2 = factory.create(); + + ParallelIndividualCompleter completer = injector.getInstance(ParallelIndividualCompleter.class); + + completer.complete(i1, i2); + Assert.assertTrue(i1.isEvaluated()); + Assert.assertTrue(i2.isEvaluated()); + + completer.complete(i1); + } +} diff --git a/opt4j-core/src/test/java/org/opt4j/core/common/completer/SequentialIndividualCompleterTest.java b/opt4j-core/src/test/java/org/opt4j/core/common/completer/SequentialIndividualCompleterTest.java new file mode 100644 index 00000000..ddba58c5 --- /dev/null +++ b/opt4j-core/src/test/java/org/opt4j/core/common/completer/SequentialIndividualCompleterTest.java @@ -0,0 +1,137 @@ +package org.opt4j.core.common.completer; + +import org.junit.Assert; +import org.junit.Test; +import org.opt4j.core.Genotype; +import org.opt4j.core.Individual; +import org.opt4j.core.Individual.State; +import org.opt4j.core.IndividualFactory; +import org.opt4j.core.Objective; +import org.opt4j.core.Objectives; +import org.opt4j.core.config.annotations.Ignore; +import org.opt4j.core.genotype.BooleanGenotype; +import org.opt4j.core.optimizer.TerminationException; +import org.opt4j.core.problem.Creator; +import org.opt4j.core.problem.Decoder; +import org.opt4j.core.problem.Evaluator; +import org.opt4j.core.problem.ProblemModule; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class SequentialIndividualCompleterTest { + private static String object = "test"; + private static Objectives objectives = new Objectives(); + + protected static class MockProblem implements Creator, Decoder, Evaluator { + + @Override + public Genotype create() { + return new BooleanGenotype(); + } + + @Override + public Object decode(Genotype genotype) { + return object; + } + + @Override + public Objectives evaluate(Object phenotype) { + objectives.add(new Objective("x"), 1); + return objectives; + } + } + + @Ignore + protected static class MockProblemModule extends ProblemModule { + @Override + protected void config() { + bindProblem(MockProblem.class, MockProblem.class, MockProblem.class); + } + } + + @Test + public void decode() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + Assert.assertTrue(i1.getState().equals(State.GENOTYPED)); + completer.decode(i1); + Assert.assertTrue(i1.getState().equals(State.PHENOTYPED)); + Assert.assertTrue(i1.getPhenotype() == object); + } + + @Test(expected = IllegalStateException.class) + public void decodePhenotyped() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + completer.decode(i1); + completer.decode(i1); + } + + @Test + public void evaluate() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + i1.setPhenotype("my phenotype"); + Assert.assertTrue(i1.getState().equals(State.PHENOTYPED)); + completer.evaluate(i1); + Assert.assertTrue(i1.getState().equals(State.EVALUATED)); + // Assert.assertTrue(i1.getObjectives() == objectives); + } + + @Test(expected = IllegalStateException.class) + public void evaluateEvaluated() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + i1.setPhenotype("my phenotype"); + completer.evaluate(i1); + completer.evaluate(i1); + } + + @Test(expected = AssertionError.class) + public void evaluateDifferentObjectivesSize() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + Individual i2 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + i1.setPhenotype("my phenotype"); + i2.setPhenotype("my other phenotype"); + completer.evaluate(i1); + objectives.add(new Objective("y"), 4); + completer.evaluate(i2); + } + + @Test + public void complete() throws TerminationException { + Injector injector = Guice.createInjector(new MockProblemModule()); + IndividualFactory factory = injector.getInstance(IndividualFactory.class); + Individual i1 = factory.create(); + + SequentialIndividualCompleter completer = injector.getInstance(SequentialIndividualCompleter.class); + + completer.complete(i1); + + Assert.assertTrue(i1.isEvaluated()); + Assert.assertTrue(i1.isEvaluated()); + } + +}