Analysis: Add unit tests for the critical path module
authorFrancis Giraldeau <francis.giraldeau@gmail.com>
Tue, 30 Jun 2015 02:16:12 +0000 (22:16 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Fri, 16 Oct 2015 17:45:06 +0000 (13:45 -0400)
Change-Id: If3c2cc85675314b5278c2dfedf4dd4dec554eaab
Signed-off-by: Francis Giraldeau <francis.giraldeau@gmail.com>
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/51082
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Hudson CI
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/AllAnalysisGraphCoreTests.java
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/AllTests.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgoBoundedTest.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgorithmTest.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphBuilder.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphFactory.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphOps.java [new file with mode: 0644]

index 123a8bb768839012516b4e585e1415f7960c375d..43ac432766824d0154edf25f34ecde74d3feea9f 100644 (file)
@@ -5,9 +5,6 @@
  * made available under the terms of the Eclipse Public License v1.0 which
  * accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *   Geneviève Bastien - Initial API and implementation
  *******************************************************************************/
 
 package org.eclipse.tracecompass.analysis.graph.core.tests;
@@ -20,6 +17,7 @@ import org.junit.runners.Suite;
  */
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
+    org.eclipse.tracecompass.analysis.graph.core.tests.analysis.criticalpath.AllTests.class,
     org.eclipse.tracecompass.analysis.graph.core.tests.graph.AllTests.class
 })
 public class AllAnalysisGraphCoreTests {
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/AllTests.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/AllTests.java
new file mode 100644 (file)
index 0000000..c798691
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.analysis.criticalpath;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for the critical path package
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    TmfCriticalPathAlgoBoundedTest.class,
+})
+public class AllTests {
+
+}
+
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgoBoundedTest.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgoBoundedTest.java
new file mode 100644 (file)
index 0000000..43db003
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.analysis.criticalpath;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex;
+import org.eclipse.tracecompass.analysis.graph.core.criticalpath.ICriticalPathAlgorithm;
+import org.eclipse.tracecompass.analysis.graph.core.tests.stubs.GraphBuilder;
+import org.eclipse.tracecompass.internal.analysis.graph.core.criticalpath.CriticalPathAlgorithmBounded;
+
+/**
+ * Test the {@link CriticalPathAlgorithmBounded} critical path algorithm
+ *
+ * @author Francis Giraldeau
+ * @author Geneviève Bastien
+ */
+public class TmfCriticalPathAlgoBoundedTest extends TmfCriticalPathAlgorithmTest {
+
+    @Override
+    protected TmfGraph computeCriticalPath(TmfGraph graph, TmfVertex start) {
+        assertNotNull(graph);
+        ICriticalPathAlgorithm cp = new CriticalPathAlgorithmBounded(graph);
+        TmfGraph bounded = cp.compute(start, null);
+        return bounded;
+    }
+
+    @Override
+    protected TmfGraph getExpectedCriticalPath(GraphBuilder builder) {
+        return builder.criticalPathBounded();
+    }
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgorithmTest.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/src/org/eclipse/tracecompass/analysis/graph/core/tests/analysis/criticalpath/TmfCriticalPathAlgorithmTest.java
new file mode 100644 (file)
index 0000000..32c2d06
--- /dev/null
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.analysis.criticalpath;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.analysis.graph.core.base.IGraphWorker;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex;
+import org.eclipse.tracecompass.analysis.graph.core.tests.stubs.GraphBuilder;
+import org.eclipse.tracecompass.analysis.graph.core.tests.stubs.GraphFactory;
+import org.eclipse.tracecompass.analysis.graph.core.tests.stubs.GraphOps;
+import org.junit.Test;
+
+/**
+ * Abstract class to test the critical path algorithms
+ *
+ * @author Geneviève Bastien
+ * @author Francis Giraldeau
+ */
+public abstract class TmfCriticalPathAlgorithmTest {
+
+    /**
+     * Computes the critical path using a specific algorithm
+     *
+     * @param graph
+     *            The execution graph on which to calculate the critical path
+     * @param start
+     *            The start vertex from which to calculate the path
+     * @return The computed critical path with the tested algorithm
+     */
+    protected abstract TmfGraph computeCriticalPath(TmfGraph graph, @NonNull TmfVertex start);
+
+    /**
+     * Get the expected critical path from the builder data
+     *
+     * @param builder
+     *            The Graph builder object for this use case
+     * @return The actual critical path
+     */
+    protected abstract TmfGraph getExpectedCriticalPath(GraphBuilder builder);
+
+    private void testCriticalPath(GraphBuilder builder, IGraphWorker obj) {
+        /* Get the base graph */
+        TmfGraph main = builder.build();
+        assertNotNull(main);
+
+        /* The expected critical path */
+        TmfGraph expected = getExpectedCriticalPath(builder);
+        assertNotNull(expected);
+
+        /* The actual critical path */
+        TmfVertex head = null;
+        if (obj == null) {
+            head = main.getHead();
+        } else {
+            head = main.getHead(obj);
+        }
+        assertNotNull(head);
+        TmfGraph actual = computeCriticalPath(main, head);
+        assertNotNull(actual);
+
+        /* Check the 2 graphs are equivalent */
+        GraphOps.checkEquality(expected, actual);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_BASIC} graph
+     */
+    @Test
+    public void testCriticalPathBasic() {
+        testCriticalPath(GraphFactory.GRAPH_BASIC, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_SELF} graph
+     */
+    @Test
+    public void testCriticalPathWakeupSelf() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_SELF, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_NEW} graph
+     */
+    @Test
+    public void testCriticalPathWakeupNew() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_NEW, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_UNKNOWN} graph
+     */
+    @Test
+    public void testCriticalPathWakeupUnknown() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_UNKNOWN, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_MUTUAL} graph
+     */
+    @Test
+    public void testCriticalPathWakeupMutual() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_MUTUAL, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_NESTED} graph
+     */
+    @Test
+    public void testCriticalPathWakeupNested() {
+        testCriticalPath(GraphFactory.GRAPH_NESTED, GraphFactory.Actor0);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_OPENED} graph
+     */
+    @Test
+    public void testCriticalPathWakeupOpened() {
+        testCriticalPath(GraphFactory.GRAPH_OPENED, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_OPENED_DELAY} graph
+     */
+    @Test
+    public void testCriticalPathWakeupOpenedDelay() {
+        testCriticalPath(GraphFactory.GRAPH_OPENED_DELAY, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_MISSING} graph
+     */
+    @Test
+    public void testCriticalPathWakeupMissing() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_MISSING, null);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_EMBEDDED}
+     * graph
+     */
+    @Test
+    public void testCriticalPathWakeupEmbedded() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_EMBEDDED, GraphFactory.Actor0);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_WAKEUP_INTERLEAVE}
+     * graph
+     */
+    @Test
+    public void testCriticalPathWakeupInterleave() {
+        testCriticalPath(GraphFactory.GRAPH_WAKEUP_INTERLEAVE, GraphFactory.Actor0);
+    }
+
+    /**
+     * Test the algorithm on the {@link GraphFactory#GRAPH_NET1} graph
+     */
+    @Test
+    public void testCriticalPathWakeupNet1() {
+        testCriticalPath(GraphFactory.GRAPH_NET1, GraphFactory.Actor0);
+    }
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphBuilder.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphBuilder.java
new file mode 100644 (file)
index 0000000..0222017
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.stubs;
+
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
+
+/**
+ * Base class for graph building graph test data
+ *
+ * @author Geneviève Bastien
+ * @author Francis Giraldeau
+ */
+public abstract class GraphBuilder {
+    private final String fName;
+
+    /**
+     * Constructor
+     *
+     * @param name
+     *            Name of the graph builder
+     */
+    public GraphBuilder(String name) {
+        this.fName = name;
+    }
+
+    /**
+     * Get the graph builder name
+     *
+     * @return The graph builder name
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Build a graph with the test data
+     *
+     * @return The full graph of the test case
+     */
+    public abstract TmfGraph build();
+
+    /**
+     * Computes the critical path with bounded algorithm
+     *
+     * @return The graph corresponding to the Bounded critical path algorithm
+     */
+    public abstract TmfGraph criticalPathBounded();
+
+    /**
+     * Computes the critical path with unbounded algorithm
+     *
+     * @return The graph corresponding to the result of the Unbounded critical
+     *         path algorithm
+     */
+    public abstract TmfGraph criticalPathUnbounded();
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphFactory.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphFactory.java
new file mode 100644 (file)
index 0000000..0162f5b
--- /dev/null
@@ -0,0 +1,899 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.stubs;
+
+import org.eclipse.tracecompass.analysis.graph.core.base.IGraphWorker;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfEdge;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfEdge.EdgeType;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex;
+
+/**
+ * Factory generating various scenarios of graphs to test critical path
+ * algorithms on
+ *
+ * @author Geneviève Bastien
+ * @author Francis Giraldeau
+ */
+public class GraphFactory {
+
+    /**
+     * First default actor of a graph
+     */
+    public static final IGraphWorker Actor0 = new TestGraphWorker(0);
+
+    /**
+     * Second default actor of the graph
+     */
+    public static final TestGraphWorker Actor1 = new TestGraphWorker(1);
+
+    /**
+     * Simple RUNNING edge involving one object
+     */
+    public static final GraphBuilder GRAPH_BASIC =
+            new GraphBuilder("basic") {
+
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    return build();
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    return build();
+                }
+
+            };
+
+    /**
+     * Single object, timer starts at t2 and wakes up at t4. Blocked at t3
+     *
+     * <pre>
+     *        /   -T-   \
+     * * -R- * -R- * -B- * -R- *
+     * </pre>
+     */
+    public static final GraphBuilder GRAPH_WAKEUP_SELF =
+            new GraphBuilder("wakeup_self") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    TmfVertex vStart = new TmfVertex(1);
+                    graph.append(Actor0, vStart, EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    TmfVertex vEnd = new TmfVertex(3);
+                    graph.append(Actor0, vEnd, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    TmfEdge link = vStart.linkVertical(vEnd);
+                    link.setType(EdgeType.TIMER);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(3), EdgeType.TIMER);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(3), EdgeType.TIMER);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    return graph;
+                }
+
+            };
+
+    /**
+     * Single object, 4 vertices, blocked between 2 and 3, but nothing wakes up
+     *
+     * <pre>
+     * * -R- * -B- * -R- *
+     * </pre>
+     */
+    public static final GraphBuilder GRAPH_WAKEUP_MISSING =
+            new GraphBuilder("wakeup_missing") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+    /**
+     * Object woken from blockage by another network object
+     *
+     * <pre>
+     * * - R - * - B - * - R - *
+     *               /N
+     *             *
+     * </pre>
+     */
+    public static final GraphBuilder GRAPH_WAKEUP_UNKNOWN =
+            new GraphBuilder("wakeup_unknown") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex vIn = new TmfVertex(4);
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, vIn, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+
+                    TmfVertex vNet = new TmfVertex(3);
+                    graph.add(Actor1, vNet);
+                    graph.link(vNet, vIn, EdgeType.NETWORK);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    TmfVertex vStartBlock = new TmfVertex(2);
+                    TmfVertex vEndBlock = new TmfVertex(4);
+                    graph.append(Actor0, vStartBlock, EdgeType.RUNNING);
+                    graph.add(Actor0, vEndBlock);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+
+                    TmfVertex vStartOther = new TmfVertex(2);
+                    TmfVertex vEndOther = new TmfVertex(3);
+                    graph.add(Actor1, vStartOther);
+                    graph.append(Actor1, vEndOther, EdgeType.UNKNOWN);
+
+                    graph.link(vStartBlock, vStartOther);
+                    graph.link(vEndOther, vEndBlock, EdgeType.NETWORK);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    TmfVertex vStartBlock = new TmfVertex(3);
+                    TmfVertex vEndBlock = new TmfVertex(4);
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, vStartBlock, EdgeType.UNKNOWN);
+                    graph.add(Actor0, vEndBlock);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+                    TmfEdge link = vStartBlock.linkVertical(vEndBlock);
+                    link.setType(EdgeType.NETWORK);
+
+                    return graph;
+                }
+            };
+
+    /**
+     * Object woken from blockage by another running object that was created by
+     * first object
+     *
+     * <pre>
+     * * -R- * -R- * -B- * -R- *
+     *         \         |
+     *          *  -R-   *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_WAKEUP_NEW =
+            new GraphBuilder("wakeup_new") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex vSrcLink = new TmfVertex(2);
+                    TmfVertex vBlockEnd = new TmfVertex(6);
+                    TmfVertex vDstLink = new TmfVertex(3);
+                    TmfVertex vWakeup = new TmfVertex(6);
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, vSrcLink, EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    graph.append(Actor0, vBlockEnd, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(8), EdgeType.RUNNING);
+
+                    graph.add(Actor1, vDstLink);
+                    graph.append(Actor1, vWakeup, EdgeType.RUNNING);
+
+                    graph.link(vSrcLink, vDstLink);
+                    graph.link(vWakeup, vBlockEnd);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex vBlockStart = new TmfVertex(4);
+                    TmfVertex vBlockEnd = new TmfVertex(6);
+                    TmfVertex vDstLink = new TmfVertex(4);
+                    TmfVertex vWakeup = new TmfVertex(6);
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, vBlockStart, EdgeType.RUNNING);
+                    graph.add(Actor0, vBlockEnd);
+                    graph.append(Actor0, new TmfVertex(8), EdgeType.RUNNING);
+
+                    graph.add(Actor1, vDstLink);
+                    graph.append(Actor1, vWakeup, EdgeType.RUNNING);
+
+                    graph.link(vBlockStart, vDstLink);
+                    graph.link(vWakeup, vBlockEnd);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex vSrcLink = new TmfVertex(2);
+                    TmfVertex vBlockEnd = new TmfVertex(6);
+                    TmfVertex vDstLink = new TmfVertex(3);
+                    TmfVertex vWakeup = new TmfVertex(6);
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, vSrcLink, EdgeType.RUNNING);
+                    graph.add(Actor0, vBlockEnd);
+                    graph.append(Actor0, new TmfVertex(8), EdgeType.RUNNING);
+
+                    graph.add(Actor1, vDstLink);
+                    graph.append(Actor1, vWakeup, EdgeType.RUNNING);
+
+                    graph.link(vSrcLink, vDstLink);
+                    graph.link(vWakeup, vBlockEnd);
+                    return graph;
+                }
+            };
+
+    /**
+     * Two objects join to unblock the first but with delay
+     *
+     * <pre>
+     * 0: * --R-- * --B-- * --R-- *
+     *              /
+     * 1: * -R- * --R-- *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_OPENED_DELAY =
+            new GraphBuilder("opened") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(3), EdgeType.RUNNING);
+                    TmfVertex v1 = new TmfVertex(6);
+                    graph.append(Actor0, v1, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(9), EdgeType.RUNNING);
+                    graph.add(Actor1, new TmfVertex(0));
+                    TmfVertex v2 = new TmfVertex(2);
+                    graph.append(Actor1, v2, EdgeType.RUNNING);
+                    graph.append(Actor1, new TmfVertex(5), EdgeType.RUNNING);
+                    graph.link(v2, v1);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    TmfVertex v1 = new TmfVertex(3);
+                    graph.append(Actor0, v1, EdgeType.RUNNING);
+                    TmfVertex v2 = new TmfVertex(3);
+                    TmfVertex v3 = new TmfVertex(6);
+                    graph.add(Actor1, v2);
+                    graph.add(Actor0, v3);
+                    graph.link(v1, v2);
+                    graph.link(v2, v3);
+                    graph.append(Actor0, new TmfVertex(9), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+    /**
+     * Two objects join to unblock the first without delay
+     *
+     * <pre>
+     * * --R-- * --B-- * --R-- *
+     *                 |
+     * * -------R----- * --R-- *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_OPENED =
+            new GraphBuilder("opened") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(3), EdgeType.RUNNING);
+                    TmfVertex v1 = new TmfVertex(6);
+                    graph.append(Actor0, v1, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(9), EdgeType.RUNNING);
+                    graph.add(Actor1, new TmfVertex(0));
+                    TmfVertex v2 = new TmfVertex(6);
+                    graph.append(Actor1, v2, EdgeType.RUNNING);
+                    graph.append(Actor1, new TmfVertex(9), EdgeType.RUNNING);
+                    graph.link(v2, v1);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    graph.add(Actor0, new TmfVertex(0));
+                    TmfVertex v1 = new TmfVertex(3);
+                    graph.append(Actor0, v1, EdgeType.RUNNING);
+                    TmfVertex v2 = new TmfVertex(3);
+                    TmfVertex v3 = new TmfVertex(6);
+                    graph.add(Actor1, v2);
+                    graph.append(Actor1, v3, EdgeType.RUNNING);
+                    TmfVertex v4 = new TmfVertex(6);
+                    graph.add(Actor0, v4);
+                    graph.link(v1, v2);
+                    graph.link(v3, v4);
+                    graph.append(Actor0, new TmfVertex(9), EdgeType.RUNNING);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+    /**
+     * Two objects are blocked and mutually unblock at different times
+     *
+     * <pre>
+     * 0: * -R- * -R- * -R- * -B- * -R- *
+     *                |           |
+     * 1: * -R- * -B- * -R- * -R- * -R- *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_WAKEUP_MUTUAL =
+            new GraphBuilder("wakeup_mutual") {
+                @Override
+                public TmfGraph build() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Wakeup = new TmfVertex(2);
+                    TmfVertex v0Unblock = new TmfVertex(4);
+                    TmfVertex v1Unblock = new TmfVertex(2);
+                    TmfVertex v1Wakeup = new TmfVertex(4);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, v0Wakeup, EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(3), EdgeType.RUNNING);
+                    graph.append(Actor0, v0Unblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(5), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, new TmfVertex(0));
+                    graph.append(Actor1, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor1, v1Unblock, EdgeType.BLOCKED);
+                    graph.append(Actor1, new TmfVertex(3), EdgeType.RUNNING);
+                    graph.append(Actor1, v1Wakeup, EdgeType.RUNNING);
+                    graph.append(Actor1, new TmfVertex(5), EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0Wakeup, v1Unblock);
+                    graph.link(v1Wakeup, v0Unblock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0StartBlock = new TmfVertex(3);
+                    TmfVertex v0EndBlock = new TmfVertex(4);
+                    TmfVertex v1StartBlock = new TmfVertex(3);
+                    TmfVertex v1EndBlock = new TmfVertex(4);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, v0StartBlock, EdgeType.RUNNING);
+                    graph.add(Actor0, v0EndBlock);
+                    graph.append(Actor0, new TmfVertex(5), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1StartBlock);
+                    graph.append(Actor1, v1EndBlock, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0StartBlock, v1StartBlock);
+                    graph.link(v1EndBlock, v0EndBlock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Wakeup = new TmfVertex(2);
+                    TmfVertex v0Unblock = new TmfVertex(4);
+                    TmfVertex v1Unblock = new TmfVertex(2);
+                    TmfVertex v1Wakeup = new TmfVertex(4);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, v0Wakeup, EdgeType.RUNNING);
+                    graph.add(Actor0, v0Unblock);
+                    graph.append(Actor0, new TmfVertex(5), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1Unblock);
+                    graph.append(Actor1, new TmfVertex(3), EdgeType.RUNNING);
+                    graph.append(Actor1, v1Wakeup, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0Wakeup, v1Unblock);
+                    graph.link(v1Wakeup, v0Unblock);
+                    return graph;
+                }
+            };
+
+    /**
+     * Many objects wakeup the first object, the calls are embedded
+     *
+     * <pre>
+     * 0: * -R- * -R- * -R- * -B- * -B- * -R- *
+     *          |     |           |     |
+     * 1:       |     * --- R --- *     |
+     *          |                       |
+     * 2:       *    ------ R ------    *
+     * ...
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_WAKEUP_EMBEDDED =
+            new GraphBuilder("wakeup_embeded") {
+                private TestGraphWorker fActor2 = new TestGraphWorker(2);
+
+                @Override
+                public TmfGraph build() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0FirstFork = new TmfVertex(2);
+                    TmfVertex v0SecondFork = new TmfVertex(4);
+                    TmfVertex v0FirstUnblock = new TmfVertex(8);
+                    TmfVertex v0SecondUnblock = new TmfVertex(10);
+                    TmfVertex v1In = new TmfVertex(4);
+                    TmfVertex v1Out = new TmfVertex(8);
+                    TmfVertex v2In = new TmfVertex(2);
+                    TmfVertex v2Out = new TmfVertex(10);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, v0FirstFork, EdgeType.RUNNING);
+                    graph.append(Actor0, v0SecondFork, EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+                    graph.append(Actor0, v0FirstUnblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, v0SecondUnblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Out, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Out, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0FirstFork, v2In);
+                    graph.link(v0SecondFork, v1In);
+                    graph.link(v1Out, v0FirstUnblock);
+                    graph.link(v2Out, v0SecondUnblock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0StartBlock = new TmfVertex(6);
+                    TmfVertex v0FirstUnblock = new TmfVertex(8);
+                    TmfVertex v0SecondUnblock = new TmfVertex(10);
+                    TmfVertex v1In = new TmfVertex(6);
+                    TmfVertex v1Out = new TmfVertex(8);
+                    TmfVertex v2In = new TmfVertex(8);
+                    TmfVertex v2Out = new TmfVertex(10);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    graph.append(Actor0, v0StartBlock, EdgeType.RUNNING);
+                    graph.add(Actor0, v0FirstUnblock);
+                    graph.add(Actor0, v0SecondUnblock);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Out, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Out, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0StartBlock, v1In);
+                    graph.link(v1Out, v0FirstUnblock);
+                    graph.link(v0FirstUnblock, v2In);
+                    graph.link(v2Out, v0SecondUnblock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+    /**
+     * Many objects wakeup the first object, the calls interleave
+     *
+     * <pre>
+     * 0: * -R- * -R- * -R- * -B- * -B- * -R- *
+     *          |     |           |     |
+     * 1:       * ------ R ------ *     |
+     *                |                 |
+     * 2:             * ------ R ------ *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_WAKEUP_INTERLEAVE =
+            new GraphBuilder("wakeup_interleave") {
+                private TestGraphWorker fActor2 = new TestGraphWorker(2);
+
+                @Override
+                public TmfGraph build() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0FirstFork = new TmfVertex(2);
+                    TmfVertex v0SecondFork = new TmfVertex(4);
+                    TmfVertex v0FirstUnblock = new TmfVertex(8);
+                    TmfVertex v0SecondUnblock = new TmfVertex(10);
+                    TmfVertex v1In = new TmfVertex(2);
+                    TmfVertex v1Out = new TmfVertex(8);
+                    TmfVertex v2In = new TmfVertex(4);
+                    TmfVertex v2Out = new TmfVertex(10);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, v0FirstFork, EdgeType.RUNNING);
+                    graph.append(Actor0, v0SecondFork, EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(6), EdgeType.RUNNING);
+                    graph.append(Actor0, v0FirstUnblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, v0SecondUnblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Out, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Out, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0FirstFork, v1In);
+                    graph.link(v0SecondFork, v2In);
+                    graph.link(v1Out, v0FirstUnblock);
+                    graph.link(v2Out, v0SecondUnblock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0StartBlock = new TmfVertex(6);
+                    TmfVertex v0FirstUnblock = new TmfVertex(8);
+                    TmfVertex v0SecondUnblock = new TmfVertex(10);
+                    TmfVertex v1In = new TmfVertex(6);
+                    TmfVertex v1Out = new TmfVertex(8);
+                    TmfVertex v2In = new TmfVertex(8);
+                    TmfVertex v2Out = new TmfVertex(10);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(2), EdgeType.RUNNING);
+                    graph.append(Actor0, new TmfVertex(4), EdgeType.RUNNING);
+                    graph.append(Actor0, v0StartBlock, EdgeType.RUNNING);
+                    graph.add(Actor0, v0FirstUnblock);
+                    graph.add(Actor0, v0SecondUnblock);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Out, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Out, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0StartBlock, v1In);
+                    graph.link(v1Out, v0FirstUnblock);
+                    graph.link(v0FirstUnblock, v2In);
+                    graph.link(v2Out, v0SecondUnblock);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+    /**
+     * Objects block when creating new ones, nesting the blocks
+     *
+     * <pre>
+     * ...
+     * 0: * -R- * --------------B-------------- * -R- *
+     *          |                               |
+     * 1:       * -R- * --------B-------- * -R- *
+     *                |                   |
+     * 2:             * -R- * --B-- * -R- *
+     *                      |       |
+     * 3:                   * --R-- *
+     * </pre>
+     */
+    public static GraphBuilder GRAPH_NESTED =
+            new GraphBuilder("wakeup_nested") {
+                private final TestGraphWorker fActor2 = new TestGraphWorker(2);
+                private final TestGraphWorker fActor3 = new TestGraphWorker(3);
+
+                @Override
+                public TmfGraph build() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Fork = new TmfVertex(1);
+                    TmfVertex v0Return = new TmfVertex(6);
+                    TmfVertex v1In = new TmfVertex(1);
+                    TmfVertex v1Fork = new TmfVertex(2);
+                    TmfVertex v1Return = new TmfVertex(5);
+                    TmfVertex v1End = new TmfVertex(6);
+                    TmfVertex v2In = new TmfVertex(2);
+                    TmfVertex v2Fork = new TmfVertex(3);
+                    TmfVertex v2Return = new TmfVertex(4);
+                    TmfVertex v2End = new TmfVertex(5);
+                    TmfVertex v3In = new TmfVertex(3);
+                    TmfVertex v3End = new TmfVertex(4);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, v0Fork, EdgeType.RUNNING);
+                    graph.append(Actor0, v0Return, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(7), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Fork, EdgeType.RUNNING);
+                    graph.append(Actor1, v1Return, EdgeType.BLOCKED);
+                    graph.append(Actor1, v1End, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Fork, EdgeType.RUNNING);
+                    graph.append(fActor2, v2Return, EdgeType.BLOCKED);
+                    graph.append(fActor2, v2End, EdgeType.RUNNING);
+
+                    /* Add actor 3's vertices and edges */
+                    graph.add(fActor3, v3In);
+                    graph.append(fActor3, v3End, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0Fork, v1In);
+                    graph.link(v1Fork, v2In);
+                    graph.link(v2Fork, v3In);
+                    graph.link(v3End, v2Return);
+                    graph.link(v2End, v1Return);
+                    graph.link(v1End, v0Return);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Fork = new TmfVertex(1);
+                    TmfVertex v0Return = new TmfVertex(6);
+                    TmfVertex v1In = new TmfVertex(1);
+                    TmfVertex v1Fork = new TmfVertex(2);
+                    TmfVertex v1Return = new TmfVertex(5);
+                    TmfVertex v1End = new TmfVertex(6);
+                    TmfVertex v2In = new TmfVertex(2);
+                    TmfVertex v2Fork = new TmfVertex(3);
+                    TmfVertex v2Return = new TmfVertex(4);
+                    TmfVertex v2End = new TmfVertex(5);
+                    TmfVertex v3In = new TmfVertex(3);
+                    TmfVertex v3End = new TmfVertex(4);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, v0Fork, EdgeType.RUNNING);
+                    graph.add(Actor0, v0Return);
+                    graph.append(Actor0, new TmfVertex(7), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1In);
+                    graph.append(Actor1, v1Fork, EdgeType.RUNNING);
+                    graph.add(Actor1, v1Return);
+                    graph.append(Actor1, v1End, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2In);
+                    graph.append(fActor2, v2Fork, EdgeType.RUNNING);
+                    graph.add(fActor2, v2Return);
+                    graph.append(fActor2, v2End, EdgeType.RUNNING);
+
+                    /* Add actor 3's vertices and edges */
+                    graph.add(fActor3, v3In);
+                    graph.append(fActor3, v3End, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0Fork, v1In);
+                    graph.link(v1Fork, v2In);
+                    graph.link(v2Fork, v3In);
+                    graph.link(v3End, v2Return);
+                    graph.link(v2End, v1Return);
+                    graph.link(v1End, v0Return);
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    return criticalPathBounded();
+                }
+            };
+
+    /**
+     * An object is blocked until a few other objects exchange network messages
+     *
+     * <pre>
+     * 0: * -R- * ----------------------- B ---------------------- * -R- *
+     *                                                             |
+     * 1:              * -R- * -R- *                               |
+     *                        \  ----N----  \                      |
+     * 2:                              * -R- * -R- *               |
+     *                                        \  ----N----  \      |
+     * 3:                                              * -R- * -R- *
+     * </pre>
+     */
+    public static final GraphBuilder GRAPH_NET1 =
+            new GraphBuilder("wakeup_net1") {
+                private TestGraphWorker fActor2 = new TestGraphWorker(2);
+                private TestGraphWorker fActor3 = new TestGraphWorker(3);
+
+                @Override
+                public TmfGraph build() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Unblock = new TmfVertex(11);
+                    TmfVertex v1Send = new TmfVertex(4);
+                    TmfVertex v2Rcv = new TmfVertex(7);
+                    TmfVertex v2Send = new TmfVertex(8);
+                    TmfVertex v3Rcv = new TmfVertex(10);
+                    TmfVertex v3End = new TmfVertex(11);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, new TmfVertex(1), EdgeType.RUNNING);
+                    graph.append(Actor0, v0Unblock, EdgeType.BLOCKED);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, new TmfVertex(3));
+                    graph.append(Actor1, v1Send, EdgeType.RUNNING);
+                    graph.append(Actor1, new TmfVertex(5), EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, new TmfVertex(6));
+                    graph.append(fActor2, v2Rcv, EdgeType.RUNNING);
+                    graph.append(fActor2, v2Send, EdgeType.RUNNING);
+
+                    /* Add actor 3's vertices and edges */
+                    graph.add(fActor3, new TmfVertex(9));
+                    graph.append(fActor3, v3Rcv, EdgeType.RUNNING);
+                    graph.append(fActor3, v3End, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v1Send, v2Rcv, EdgeType.NETWORK);
+                    graph.link(v2Send, v3Rcv, EdgeType.NETWORK);
+                    graph.link(v3End, v0Unblock);
+
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathBounded() {
+                    /* Initialize some vertices */
+                    TmfGraph graph = new TmfGraph();
+                    TmfVertex v0Fork = new TmfVertex(1);
+                    TmfVertex v0Unblock = new TmfVertex(11);
+                    TmfVertex v1Start = new TmfVertex(1);
+                    TmfVertex v1Send = new TmfVertex(4);
+                    TmfVertex v2Rcv = new TmfVertex(7);
+                    TmfVertex v2Send = new TmfVertex(8);
+                    TmfVertex v3Rcv = new TmfVertex(10);
+                    TmfVertex v3End = new TmfVertex(11);
+
+                    /* Add actor 0's vertices and edges */
+                    graph.add(Actor0, new TmfVertex(0));
+                    graph.append(Actor0, v0Fork, EdgeType.RUNNING);
+                    graph.add(Actor0, v0Unblock);
+                    graph.append(Actor0, new TmfVertex(12), EdgeType.RUNNING);
+
+                    /* Add actor 1's vertices and edges */
+                    graph.add(Actor1, v1Start);
+                    graph.append(Actor1, new TmfVertex(3), EdgeType.UNKNOWN);
+                    graph.append(Actor1, v1Send, EdgeType.RUNNING);
+
+                    /* Add actor 2's vertices and edges */
+                    graph.add(fActor2, v2Rcv);
+                    graph.append(fActor2, v2Send, EdgeType.RUNNING);
+
+                    /* Add actor 3's vertices and edges */
+                    graph.add(fActor3, v3Rcv);
+                    graph.append(fActor3, v3End, EdgeType.RUNNING);
+
+                    /* Add vertical links */
+                    graph.link(v0Fork, v1Start);
+                    graph.link(v1Send, v2Rcv, EdgeType.NETWORK);
+                    graph.link(v2Send, v3Rcv, EdgeType.NETWORK);
+                    graph.link(v3End, v0Unblock);
+
+                    return graph;
+                }
+
+                @Override
+                public TmfGraph criticalPathUnbounded() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphOps.java b/analysis/org.eclipse.tracecompass.analysis.graph.core.tests/stubs/org/eclipse/tracecompass/analysis/graph/core/tests/stubs/GraphOps.java
new file mode 100644 (file)
index 0000000..cc1d316
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.graph.core.tests.stubs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.tracecompass.analysis.graph.core.base.IGraphWorker;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfEdge;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfGraph;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex;
+import org.eclipse.tracecompass.analysis.graph.core.base.TmfVertex.EdgeDirection;
+
+/**
+ * Class that implements static operations on vertices and edges. The sets of
+ * nodes and vertices can then be transformed to a graph.
+ *
+ * @author Geneviève Bastien
+ * @author Francis Giraldeau
+ */
+public class GraphOps {
+
+    /**
+     * Check whether 2 graphs are identical
+     *
+     * @param g1
+     *            The first graph to compare
+     * @param g2
+     *            The second graph
+     */
+    public static void checkEquality(TmfGraph g1, TmfGraph g2) {
+        assertEquals("Graph size", g1.size(), g2.size());
+        Set<IGraphWorker> obj1 = g1.getWorkers();
+        Set<IGraphWorker> obj2 = g2.getWorkers();
+        assertEquals("Graph objects", obj1, obj2);
+        for (IGraphWorker graphObject : obj1) {
+            assertNotNull(graphObject);
+            List<TmfVertex> nodesOf1 = g1.getNodesOf(graphObject);
+            List<TmfVertex> nodesOf2 = g2.getNodesOf(graphObject);
+            for (int i = 0; i < nodesOf1.size(); i++) {
+                TmfVertex v1 = nodesOf1.get(i);
+                TmfVertex v2 = nodesOf2.get(i);
+                assertEquals("Node timestamps", v1.getTs(), v2.getTs());
+                /* Check each edge */
+                for (EdgeDirection dir : EdgeDirection.values()) {
+                    if (dir == null) {
+                        throw new NullPointerException();
+                    }
+                    TmfEdge edge1 = v1.getEdge(dir);
+                    TmfEdge edge2 = v2.getEdge(dir);
+                    if (edge1 == null) {
+                        assertNull(edge2);
+                        continue;
+                    }
+                    assertNotNull(edge2);
+                    assertEquals("Edge type for " + graphObject + ", node " + i, edge1.getType(), edge2.getType());
+                    assertEquals("Edge duration for " + graphObject + ", node " + i + " edge direction " + dir, edge1.getDuration(), edge2.getDuration());
+                    assertEquals("From objects for " + graphObject + ", node " + i, g1.getParentOf(edge1.getVertexFrom()), g2.getParentOf(edge2.getVertexFrom()));
+                    assertEquals("To objects for" + graphObject + ", node " + i, g1.getParentOf(edge1.getVertexTo()), g2.getParentOf(edge2.getVertexTo()));
+                }
+            }
+        }
+    }
+
+}
This page took 0.039269 seconds and 5 git commands to generate.