blob: 26db007682c70523fd7c5f6b488ae98de0f2e039 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2007 The University of Manchester
*
* Modifications to the initial code base are copyright of their
* respective authors, or their employers as appropriate.
*
* This program 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 2.1 of
* the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package net.sf.taverna.t2.workflowmodel.processor.iteration.impl;
import net.sf.taverna.t2.workflowmodel.processor.iteration.CrossProduct;
import net.sf.taverna.t2.workflowmodel.processor.iteration.DotProduct;
import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationTypeMismatchException;
import net.sf.taverna.t2.workflowmodel.processor.iteration.MissingIterationInputException;
import net.sf.taverna.t2.workflowmodel.processor.iteration.NamedInputPortNode;
import junit.framework.TestCase;
import java.util.Map;
import java.util.HashMap;
/**
* Test the type check functionality now built into the iteration system,
* exercises the iteration strategy and the strategy stack with a combination of
* simple and staged iteration to check whether the type checker is getting
* sensible results out.
*
* @author Tom Oinn
*
*/
public class IterationTypeCheckerTest extends TestCase {
private IterationStrategyImpl getISDot(int depthA, int depthB) {
IterationStrategyImpl is1 = new IterationStrategyImpl();
NamedInputPortNode nipn1 = new NamedInputPortNode("a", depthA);
NamedInputPortNode nipn2 = new NamedInputPortNode("b", depthB);
is1.addInput(nipn1);
is1.addInput(nipn2);
DotProduct dp = new DotProduct();
nipn1.setParent(dp);
nipn2.setParent(dp);
dp.setParent(is1.getTerminalNode());
return is1;
}
private IterationStrategyImpl getISCross(int depthA, int depthB) {
IterationStrategyImpl is1 = new IterationStrategyImpl();
NamedInputPortNode nipn1 = new NamedInputPortNode("a", depthA);
NamedInputPortNode nipn2 = new NamedInputPortNode("b", depthB);
is1.addInput(nipn1);
is1.addInput(nipn2);
CrossProduct cp = new CrossProduct();
nipn1.setParent(cp);
nipn2.setParent(cp);
cp.setParent(is1.getTerminalNode());
return is1;
}
private Map<String, Integer> getDepths(String[] names, int[] depths) {
Map<String, Integer> result = new HashMap<String, Integer>();
for (int i = 0; i < names.length; i++) {
result.put(names[i], depths[i]);
}
return result;
}
/**
* Test simple iteration type check based on dot products
*
* @throws IterationTypeMismatchException
*/
public void testDotUnstagedIteration()
throws IterationTypeMismatchException {
IterationStrategyImpl isi = getISDot(0, 0);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 1 })) == 1);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 2, 2 })) == 2);
isi = getISDot(0, 1);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 2 })) == 1);
}
/**
* Test a simple iteration based on a cross product
*
* @throws IterationTypeMismatchException
*/
public void testCrossUnstagedIteration()
throws IterationTypeMismatchException {
IterationStrategyImpl isi = getISCross(0, 0);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 1 })) == 2);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 2, 2 })) == 4);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 2 })) == 3);
isi = getISCross(0, 1);
assertTrue(isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 2 })) == 2);
}
/**
* Test that attempting to typecheck a mismatched dot product produces a
* type mismatch exception
*
*/
public void testValidationFailureWithDot() {
try {
IterationStrategyImpl isi = getISDot(0, 0);
isi.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 2 }));
fail("should have failed due to mismatch");
} catch (IterationTypeMismatchException itme) {
// Correct behaviour, this should cause a mismatch
}
}
/**
* Fundamentally pointless, combining two cross product iteration strategies
* is the same as using the last one directly but we can check this
*
* @throws IterationTypeMismatchException
* @throws MissingIterationInputException
*/
public void testStagedCombinationOfCross()
throws IterationTypeMismatchException,
MissingIterationInputException {
IterationStrategyStackImpl iss;
iss = new IterationStrategyStackImpl();
iss.addStrategy(getISCross(1, 1));
iss.addStrategy(getISCross(0, 0));
assertTrue(iss.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 2, 2 })) == 4);
}
/**
* Fundamentally pointless, combining two dot product iteration strategies
* is the same as using the last one directly but we can check this
*
* @throws IterationTypeMismatchException
* @throws MissingIterationInputException
*/
public void testStagedCombinationOfDot()
throws IterationTypeMismatchException,
MissingIterationInputException {
IterationStrategyStackImpl iss;
iss = new IterationStrategyStackImpl();
iss.addStrategy(getISDot(1, 1));
iss.addStrategy(getISDot(0, 0));
assertTrue(iss.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 2, 2 })) == 2);
// Should pass because the single items (depth 0) are promoted to single
// item lists before being passed into the iteration system so are
// effectively both depth 1 going into the second stage which then
// iterates to produce an index array length of 1
assertTrue(iss.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 0, 0 })) == 1);
// Slightly strange superficially that this should work, but in fact
// what happens is that the first single item is lifted to a list before
// being passed to the iteration strategy. The result is that it's fine
// to match with the dot product against the other list as neither at
// this point have index arrays, then in the second stage both are lists
// to be iterated over and both have single length index arrays.
assertTrue(iss.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 1, 0 })) == 1);
}
/**
* Test whether Paul's example of iterating with dot product then cross
* product can typecheck in a single staged iteration. This was an example
* where the user had two lists of folders (a1, a2, b1, b2, c1, c2) and
* wanted to compare all the contents of each 'a' folder with the other 'a'
* folder and so on, doing a dot match to only compare a1 and a2 then a
* cross product join within each pair to compare all contents of a1 with
* all contents of a2. This appears to work!
*/
public void testStagedCombinationOfDotAndCross()
throws IterationTypeMismatchException,
MissingIterationInputException {
IterationStrategyStackImpl iss;
iss = new IterationStrategyStackImpl();
iss.addStrategy(getISDot(1, 1));
iss.addStrategy(getISCross(0, 0));
assertTrue(iss.getIterationDepth(getDepths(new String[] { "a", "b" },
new int[] { 2, 2 })) == 3);
}
}