/* Copyright 2009-2016 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework 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. * * The MOEA Framework 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 the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package org.moeaframework.analysis.sensitivity; import java.io.File; import java.io.IOException; import java.util.Properties; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.moeaframework.TestUtils; import org.moeaframework.core.NondominatedPopulation; import org.moeaframework.core.Problem; import org.moeaframework.core.Settings; import org.moeaframework.core.Solution; import org.moeaframework.core.Variable; import org.moeaframework.core.variable.BinaryVariable; import org.moeaframework.core.variable.Grammar; import org.moeaframework.core.variable.Permutation; import org.moeaframework.core.variable.RealVariable; import org.moeaframework.problem.AbstractProblem; import org.moeaframework.util.TypedProperties; /** * Tests the {@link ResultFileWriter} class. */ public class ResultFileWriterTest { /** * The problem used for testing. */ private Problem problem; /** * A feasible solution. */ private Solution solution1; /** * Another feasible solution. */ private Solution solution2; /** * A solution violating its constraints. */ private Solution solution3; /** * Creates the problem used for testing. */ @Before public void setUp() { problem = new AbstractProblem(3, 2, 1) { @Override public void evaluate(Solution solution) { throw new UnsupportedOperationException(); } @Override public Solution newSolution() { Solution solution = new Solution(3, 2, 1); solution.setVariable(0, new RealVariable(0.0, 1.0)); solution.setVariable(1, new BinaryVariable(5)); solution.setVariable(2, new Permutation(3)); return solution; } }; solution1 = problem.newSolution(); ((RealVariable)solution1.getVariable(0)).setValue(0.0); ((BinaryVariable)solution1.getVariable(1)).set(2, true); ((Permutation)solution1.getVariable(2)).swap(0, 2); solution1.setObjectives(new double[] { 0.0, 1.0 }); solution2 = problem.newSolution(); ((RealVariable)solution1.getVariable(0)).setValue(1.0); ((BinaryVariable)solution1.getVariable(1)).set(1, true); ((Permutation)solution1.getVariable(2)).swap(0, 1); solution2.setObjectives(new double[] { 1.0, 0.0 }); solution3 = problem.newSolution(); ((RealVariable)solution1.getVariable(0)).setValue(0.5); ((BinaryVariable)solution1.getVariable(1)).set(1, true); ((Permutation)solution1.getVariable(2)).swap(1, 2); solution3.setObjectives(new double[] { 0.5, 0.5 }); solution3.setConstraints(new double[] { -1.0 }); } /** * Removes references to shared objects so they can be garbage collected. */ @After public void tearDown() { problem = null; solution1 = null; solution2 = null; solution3 = null; } /** * Tests if special characters are escaped correctly when writing property * files. * * @throws IOException should not occur */ @Test public void testSpecialCharactersInProperties() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); Properties properties = new Properties(); properties.setProperty("\"'!@#$=:%^&*()\\\r\n//\t ", "\"'!@#$=:%^&*()\\\r\n//\t "); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, properties)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); Assert.assertEquals(properties, reader.next().getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if {@code null} properties are written correctly. * * @throws IOException should not occur */ @Test public void testNullProperties() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); Properties properties = new Properties(); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, (TypedProperties)null)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); Assert.assertEquals(properties, reader.next().getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if empty properties are written correctly. * * @throws IOException should not occur */ @Test public void testEmptyProperties() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); Properties properties = new Properties(); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, properties)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); Assert.assertEquals(properties, reader.next().getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if the population and properties are written correctly. * * @throws IOException should not occur */ @Test public void testNormal() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); population.add(solution1); population.add(solution2); Properties properties = new Properties(); properties.setProperty("foo", "bar"); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, properties)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); ResultEntry entry = reader.next(); TestUtils.assertEquals(population, entry.getPopulation()); Assert.assertEquals(properties, entry.getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if the population and properties are written correctly when * writing decision variables is disabled. * * @throws IOException should not occur */ @Test public void testNoVariables() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); population.add(solution1); population.add(solution2); Properties properties = new Properties(); properties.setProperty("foo", "bar"); try { writer = new ResultFileWriter(problem, file, false); writer.append(new ResultEntry(population, properties)); } finally { if (writer != null) { writer.close(); } } population.clear(); population.add(new Solution(solution1.getObjectives())); population.add(new Solution(solution2.getObjectives())); try { reader = new ResultFileReader(problem, file); ResultEntry entry = reader.next(); TestUtils.assertEquals(population, entry.getPopulation()); Assert.assertEquals(properties, entry.getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if constraint violating solutions are not written, and that * empty populations are written correctly. * * @throws IOException should not occur */ @Test public void testConstrainedSolution() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); population.add(solution3); Properties properties = new Properties(); properties.setProperty("foo", "bar"); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, properties)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); ResultEntry entry = reader.next(); Assert.assertEquals(0, entry.getPopulation().size()); Assert.assertEquals(properties, entry.getProperties()); } finally { if (reader != null) { reader.close(); } } } /** * Tests if result files with multiple entries are written correctly, and * that writing can be resumed correctly. * * @throws IOException should not occur */ @Test public void testResume() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); population.add(solution1); population.add(solution2); Properties properties = new Properties(); properties.setProperty("foo", "bar"); try { writer = new ResultFileWriter(problem, file); Assert.assertEquals(0, writer.getNumberOfEntries()); writer.append(new ResultEntry(population, properties)); writer.append(new ResultEntry(population, properties)); Assert.assertEquals(2, writer.getNumberOfEntries()); } finally { if (writer != null) { writer.close(); } } try { writer = new ResultFileWriter(problem, file); Assert.assertEquals(2, writer.getNumberOfEntries()); writer.append(new ResultEntry(population, properties)); Assert.assertEquals(3, writer.getNumberOfEntries()); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); ResultEntry entry = null; Assert.assertTrue(reader.hasNext()); entry = reader.next(); TestUtils.assertEquals(population, entry.getPopulation()); Assert.assertEquals(properties, entry.getProperties()); Assert.assertTrue(reader.hasNext()); entry = reader.next(); TestUtils.assertEquals(population, entry.getPopulation()); Assert.assertEquals(properties, entry.getProperties()); Assert.assertTrue(reader.hasNext()); entry = reader.next(); TestUtils.assertEquals(population, entry.getPopulation()); Assert.assertEquals(properties, entry.getProperties()); Assert.assertFalse(reader.hasNext()); } finally { if (reader != null) { reader.close(); } } } @Test public void testUnsupportedDecisionVariable() throws IOException { File file = TestUtils.createTempFile(); final Variable variable = new Variable() { private static final long serialVersionUID = -54413529004858950L; @Override public Variable copy() { throw new UnsupportedOperationException(); } @Override public void randomize() { throw new UnsupportedOperationException(); } }; problem = new AbstractProblem(2, 2, 1) { @Override public void evaluate(Solution solution) { throw new UnsupportedOperationException(); } @Override public Solution newSolution() { Solution solution = new Solution(2, 2, 1); solution.setVariable(0, new RealVariable(0.0, 1.0)); solution.setVariable(1, variable); return solution; } }; ResultFileWriter writer = null; ResultFileReader reader = null; NondominatedPopulation population = new NondominatedPopulation(); Solution solution = problem.newSolution(); ((RealVariable)solution.getVariable(0)).setValue(0.5); solution.setObjectives(new double[] { 0.0, 1.0 }); population.add(solution); try { writer = new ResultFileWriter(problem, file); writer.append(new ResultEntry(population, (Properties)null)); } finally { if (writer != null) { writer.close(); } } try { reader = new ResultFileReader(problem, file); ResultEntry entry = reader.next(); Assert.assertEquals(1, entry.getPopulation().size()); Assert.assertArrayEquals(solution.getObjectives(), entry.getPopulation().get(0).getObjectives(), Settings.EPS); Assert.assertEquals(solution.getVariable(0), entry.getPopulation().get(0).getVariable(0)); } finally { if (reader != null) { reader.close(); } } } @Test public void testEncode() throws IOException { File file = TestUtils.createTempFile(); ResultFileWriter writer = null; try { writer = new ResultFileWriter(problem, file); RealVariable rv = new RealVariable(0.5, 0.0, 1.0); Assert.assertEquals("0.5", writer.encode(rv)); Assert.assertFalse(writer.encode(rv).matches(".*\\s.*")); BinaryVariable bv = new BinaryVariable(5); bv.set(2, true); Assert.assertEquals("00100", writer.encode(bv)); Assert.assertFalse(writer.encode(bv).matches(".*\\s.*")); Permutation p = new Permutation(5); Assert.assertEquals("0,1,2,3,4", writer.encode(p)); Assert.assertFalse(writer.encode(p).matches(".*\\s.*")); Grammar g = new Grammar(5); //Assert.assertEquals("-", writer.encode(g)); Assert.assertFalse(writer.encode(g).matches(".*\\s.*")); } finally { if (writer != null) { writer.close(); } } } }