/** * */ package de.osmembrane.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.awt.Point; import java.awt.geom.Point2D; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import de.osmembrane.Application; import de.osmembrane.model.persistence.FileException; import de.osmembrane.model.persistence.FileType; import de.osmembrane.model.pipeline.AbstractConnector; import de.osmembrane.model.pipeline.AbstractFunction; import de.osmembrane.model.pipeline.AbstractFunctionGroup; import de.osmembrane.model.pipeline.AbstractFunctionPrototype; import de.osmembrane.model.pipeline.AbstractPipeline; import de.osmembrane.model.pipeline.ConnectorException; import de.osmembrane.model.pipeline.ConnectorType; import de.osmembrane.model.pipeline.CopyType; import de.osmembrane.resources.Constants; import de.osmembrane.tools.Tools; /** * Tests the pipeline. * * @author tobias_kuhn * */ public class PipelineTest { private static AbstractFunction prototype; /** * pipeline under test */ private static AbstractPipeline pl; private static URL TEST_FILE_NAME; static { try { TEST_FILE_NAME = new File(new File( System.getProperty("java.io.tmpdir")), "test.tmp").toURI() .toURL(); } catch (MalformedURLException e) { TEST_FILE_NAME = null; } } /** * Initiates a full testable {@link Application}, then selects the first * function to satisfy the conditions, that * * <ul> * <li>at least 1 in-connector</li> * <li>at least 1 out-connector</li> * <li>the first in-connector is of type entity</li> * <li>the first out-connector is of type entity</li> * <li>the first in-connector allows exactly 1 connection</li> * <li>at least 2 tasks available</li> * </ul> * * Tests are performed on this function prototype then * * @throws Exception */ @BeforeClass public static void setUpBeforeClass() throws Exception { Application a = new Application(); a.createModels(); a.initiate(); pl = ModelProxy.getInstance().getPipeline(); AbstractFunctionPrototype afp = ModelProxy.getInstance().getFunctions(); for (AbstractFunctionGroup afg : afp.getFunctionGroups()) { for (AbstractFunction af : afg.getFunctions()) { if ((af.getInConnectors() != null) && (af.getInConnectors().length > 0) && (af.getOutConnectors() != null) && (af.getOutConnectors().length > 0)) { AbstractConnector firstIn = af.getInConnectors()[0]; AbstractConnector firstOut = af.getOutConnectors()[0]; if ((firstIn.getType() != ConnectorType.ENTITY) || (firstOut.getType() != ConnectorType.ENTITY) || (firstIn.getMaxConnections() != 1) || (af.getAvailableTasks().length < 2)) { continue; } prototype = af; return; } } /* for */ } /* for */ fail("No suitable function for testing found! Check the osmdefinitions!"); } /** * @throws java.lang.Exception */ @AfterClass public static void tearDownAfterClass() throws Exception { } /** * @throws java.lang.Exception */ @Before public void setUp() throws Exception { } /** * Cleans the pipeline after each test */ @After public void tearDown() { ModelProxy.getInstance().getPipeline().clear(); Tools.urlToFile(TEST_FILE_NAME).delete(); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#addFunction(de.osmembrane.model.pipeline.AbstractFunction)} * . */ @Test public void testAddFunction() { AbstractFunction newFunc = prototype .copy(CopyType.WITHOUT_VALUES_AND_POSITION); pl.addFunction(newFunc); assertEquals("not exactly 1 function present", 1, pl.getFunctions().length); assertEquals("not the correct function on the pipeline", newFunc, pl.getFunctions()[0]); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#deleteFunction(de.osmembrane.model.pipeline.AbstractFunction)} * . */ @Test public void testDeleteFunction() { AbstractFunction newFunc = prototype .copy(CopyType.WITHOUT_VALUES_AND_POSITION); pl.addFunction(newFunc); pl.deleteFunction(newFunc); assertEquals("more than 0 functions present", 0, pl.getFunctions().length); } /** * Test method for {@link de.osmembrane.model.pipeline.Pipeline#undo()} and * {@link de.osmembrane.model.pipeline.Pipeline#redo()}. * * @see Spezifikation 5.2.1, 5.2.2 * * I bet this thing covers most of the model in one go. * * @throws ConnectorException * @throws FileException */ @Test public void testUndoRedo() throws ConnectorException, FileException { TestFunction[] newFuncs = new TestFunction[3]; for (int i = 0; i < 2; i++) { AbstractFunction protoCopy = prototype .copy(CopyType.WITHOUT_VALUES_AND_POSITION); newFuncs[i] = new TestFunction(protoCopy); } final Point2D locationA = new Point2D.Double(1.0, 1.0); final Point2D locationB = new Point2D.Double(2.0, 2.0); final String taskA = newFuncs[1].getAvailableTasks()[0].getName(); final String taskB = newFuncs[1].getAvailableTasks()[1].getName(); final String paramA = "osmembrane"; final String paramB = "TESTING"; /* * Notation of values expected to be actual: ID. 012 LTPU CD * * ID = number describing the amount of steps taken. 0, 1, 2 = * newFunc[0, 1, 2] is on the pipeline * * L = location of newFunc[0] T = task of newFunc[1] P = parameter of * newFunc[2] U = task of newFunc[2] (x = not applicable, A = value A, B * = value B) * * C = connection from 0 to 1 D = connection from 1 to 2 */ /* 00. ___ xxxx __ */ pl.addFunction(newFuncs[0]); newFuncs[0].setCoordinate(locationA); /* 01. 0__ Axxx __ */ pl.addFunction(newFuncs[1]); newFuncs[1].setActiveTask(newFuncs[1].getAvailableTasks()[1]); // task b /* 02. 01_ ABxx __ */ newFuncs[0].addConnectionTo(newFuncs[1]); /* 03. 01_ ABxx C_ */ newFuncs[1].getActiveTask().getParameters()[0].setValue(paramA); // should copy this as well. AbstractFunction copyFunc = newFuncs[1].copy(CopyType.COPY_ALL); newFuncs[2] = new TestFunction(copyFunc); pl.addFunction(newFuncs[2]); /* 04. 012 ABAB C_ */ newFuncs[1].setActiveTask(newFuncs[1].getAvailableTasks()[0]); // task a /* 05. 012 AAAB C_ */ newFuncs[1].addConnectionTo(newFuncs[2]); /* 06. 012 AAAB CD */ newFuncs[0].setCoordinate(locationB); /* 07. 012 BAAB CD */ newFuncs[2].setActiveTask(newFuncs[2].getAvailableTasks()[0]); // task a /* 08. 012 BAAA CD */ newFuncs[2].getActiveTask().getParameters()[0].setValue(paramB); /* 09. 012 BABA CD */ // I'd like to assert here too, since changes might get lost in 10 and // 11 assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramB); newFuncs[2].assertTaskName(taskA); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); pl.deleteFunction(newFuncs[2]); /* 10. 01_ BAxx C_ */ newFuncs[0].removeConnectionTo(newFuncs[1]); /* 11. 01_ BAxx __ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); // parameter 2 is not applicable // task 2 is not applicable newFuncs[0].assertConnectionCountTo(newFuncs[1], 0); // connection 1-2 not applicable assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 10. 01_ BAxx C_ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); // parameter 2 is not applicable // task 2 is not applicable newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); // connection 1-2 not applicable assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 09. 012 BABA CD */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramB); newFuncs[2].assertTaskName(taskA); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 08. 012 BAAA CD */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); // parameter 2 does not apply (wrong idea before designing test) newFuncs[2].assertTaskName(taskA); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 07. 012 BAAB CD */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramA); newFuncs[2].assertTaskName(taskB); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 06. 012 AAAB CD */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramA); newFuncs[2].assertTaskName(taskB); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 05. 012 AAAB C_ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramA); newFuncs[2].assertTaskName(taskB); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 0); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 04. 012 ABAB C_ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); newFuncs[1].assertTaskName(taskB); newFuncs[2].assertParameter(0, paramA); newFuncs[2].assertTaskName(taskB); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 0); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 03. 01_ ABxx C_ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); newFuncs[1].assertTaskName(taskB); // parameter 2 is not applicable // task 2 is not applicable newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); // connection 1-2 not applicable assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 02. 01_ ABxx __ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); newFuncs[1].assertTaskName(taskB); // parameter 2 is not applicable // task 2 is not applicable newFuncs[0].assertConnectionCountTo(newFuncs[1], 0); // connection 1-2 not applicable assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 01. 0__ Axxx __ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertFalse(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationA); // task 1 is not applicable // parameter 2 is not applicable // task 2 is not applicable // connection 0-1 not applicable // connection 1-2 not applicable assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); assertTrue("undo was not available", pl.undoAvailable()); assertTrue("undo could not be done", pl.undo()); /* 00. ___ xxxx __ */ assertFalse(newFuncs[0].findOnPipeline(pl)); assertFalse(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); // location 0 is not applicable // task 1 is not applicable // parameter 2 is not applicable // task 2 is not applicable // connection 0-1 not applicable // connection 1-2 not applicable // does this count as a change? -> No, eclipse behaves the same way :) assertTrue("pipeline is the same, but has changed?", pl.isSaved()); // saving should not corrupt the undo/redo pl.savePipeline(TEST_FILE_NAME); // we now trust that the single steps perform correctly. // so perform most redos at once. assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 01. 0__ Axxx __ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 02. 01_ ABxx __ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 03. 01_ ABxx C_ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 04. 012 ABAB C_ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 05. 012 AAAB C_ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 06. 012 AAAB CD */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 07. 012 BAAB CD */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 08. 012 BAAA CD */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 09. 012 BABA CD */ // I'd like to assert here too, since changes might get lost in 10 and // 11 assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertTrue(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); newFuncs[2].assertParameter(0, paramB); newFuncs[2].assertTaskName(taskA); newFuncs[0].assertConnectionCountTo(newFuncs[1], 1); newFuncs[1].assertConnectionCountTo(newFuncs[2], 1); assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 10. 01_ BAxx C_ */ assertTrue("redo was not available", pl.redoAvailable()); assertTrue("redo could not be done", pl.redo()); /* 11. 01_ BAxx __ */ assertTrue(newFuncs[0].findOnPipeline(pl)); assertTrue(newFuncs[1].findOnPipeline(pl)); assertFalse(newFuncs[2].findOnPipeline(pl)); newFuncs[0].assertLocation(locationB); newFuncs[1].assertTaskName(taskA); // parameter 2 is not applicable // task 2 is not applicable newFuncs[0].assertConnectionCountTo(newFuncs[1], 0); // connection 1-2 not applicable } /** * Creates a small, cozy pipeline. * * @throws ConnectorException */ private void examplePipeline() throws ConnectorException { AbstractFunction[] newFuncs = new AbstractFunction[3]; for (int i = 0; i < 3; i++) { newFuncs[i] = prototype.copy(CopyType.WITHOUT_VALUES_AND_POSITION); newFuncs[i].setCoordinate(new Point(i, 1)); } pl.addFunction(newFuncs[0]); pl.addFunction(newFuncs[1]); pl.addFunction(newFuncs[2]); newFuncs[0].addConnectionTo(newFuncs[2]); newFuncs[1].setActiveTask(newFuncs[1].getAvailableTasks()[1]); newFuncs[1].getActiveTask().getParameters()[0].setValue(TEST_FILE_NAME .toString()); } /** * Asserts the pipeline is small, warm and cozy. */ private void assertExamplePipeline() { // recreate the order using the locations AbstractFunction[] newFuncs = new AbstractFunction[3]; for (int i = 0; i < pl.getFunctions().length; i++) { AbstractFunction af = pl.getFunctions()[i]; newFuncs[i] = af; } assertNotNull(newFuncs[0]); assertNotNull(newFuncs[1]); assertNotNull(newFuncs[2]); TestFunction[] testFuncs = { new TestFunction(newFuncs[0]), new TestFunction(newFuncs[1]), new TestFunction(newFuncs[2]) }; testFuncs[0].assertConnectionCountTo(testFuncs[2], 1); testFuncs[0].assertConnectionCountTo(testFuncs[1], 0); testFuncs[1].assertConnectionCountTo(testFuncs[2], 0); testFuncs[1].assertTaskName(prototype.getAvailableTasks()[1].getName()); testFuncs[1].assertParameter(0, TEST_FILE_NAME.toString()); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#arrangePipeline()}. */ @Test @Ignore public void testOptimizePipeline() throws FileException, ConnectorException { pl.arrangePipeline(); fail("No idea what this is and how to test it"); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#savePipeline(java.lang.String)} * and * {@link de.osmembrane.model.pipeline.Pipeline#loadPipeline(java.lang.String)} * . * * @throws ConnectorException * @throws FileException */ @Test public void testSaveLoadPipeline() throws ConnectorException, FileException { examplePipeline(); assertExamplePipeline(); pl.savePipeline(TEST_FILE_NAME); pl.clear(); pl.loadPipeline(TEST_FILE_NAME); assertExamplePipeline(); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#backupPipeline()} and * {@link de.osmembrane.model.pipeline.Pipeline#loadPipeline(java.lang.String)} * . * * @throws ConnectorException * @throws FileException */ @Test public void testBackupLoadPipeline() throws ConnectorException, FileException { examplePipeline(); assertExamplePipeline(); pl.backupPipeline(); pl.clear(); pl.loadPipeline(Constants.DEFAULT_BACKUP_FILE); assertExamplePipeline(); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#importPipeline(java.lang.String, de.osmembrane.model.persistence.FileType)} * . */ @Test @Ignore public void testImportPipeline() { fail("Not yet implemented"); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#exportPipeline(java.lang.String, de.osmembrane.model.persistence.FileType)} * . */ @Test @Ignore public void testExportPipeline() { fail("Not yet implemented"); } /** * Test method for * {@link de.osmembrane.model.pipeline.Pipeline#generate(de.osmembrane.model.persistence.FileType)} * . * * @throws IllegalAccessException * @throws IllegalArgumentException */ @Test public void testGenerate() throws IllegalArgumentException, IllegalAccessException { AbstractFunction af = prototype.copy(CopyType.COPY_ALL); pl.addFunction(af); String result = pl.generate(FileType.BASH); assertNotNull(result); assertTrue(result.contains(af.getActiveTask().getName())); } /** * Test method for {@link de.osmembrane.model.pipeline.Pipeline#isSaved()}. * * @throws FileException */ @Test public void testIsSaved() throws FileException { pl.clear(); assertTrue("pipeline empty, but not saved. huh?", pl.isSaved()); pl.addFunction(prototype.copy(CopyType.WITHOUT_VALUES_AND_POSITION)); assertFalse("pipeline changed without saving, but saved. huh?", pl.isSaved()); pl.savePipeline(TEST_FILE_NAME); assertTrue("pipeline saved, but not saved. huh?", pl.isSaved()); } }