/**
*
*/
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());
}
}