/*******************************************************************************
 * Copyright (c) 2016 É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.incubator.callstack.core.tests.callgraph;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Objects;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.incubator.analysis.core.concepts.AggregatedCallSite;
import org.eclipse.tracecompass.incubator.analysis.core.concepts.ICpuTimeProvider;
import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel;
import org.eclipse.tracecompass.incubator.analysis.core.model.ModelManager;
import org.eclipse.tracecompass.incubator.callstack.core.base.ICallStackElement;
import org.eclipse.tracecompass.incubator.callstack.core.callgraph.CallGraph;
import org.eclipse.tracecompass.incubator.callstack.core.tests.flamechart.CallStackTestBase;
import org.eclipse.tracecompass.incubator.callstack.core.tests.stubs.CallStackAnalysisStub;
import org.eclipse.tracecompass.incubator.internal.analysis.core.model.CompositeHostModel;
import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.InstrumentedCallStackElement;
import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.AggregatedCalledFunction;
import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.CallGraphAnalysis;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.junit.After;
import org.junit.Test;

/**
 * Test the callgraph analysis with the call stack trace and module
 *
 * @author Geneviève Bastien
 */
public class CallGraphWithCallStackAnalysisTest extends CallStackTestBase {

    /**
     * Clean up the memory
     */
    @After
    public void cleanUp() {
        // Model objects use weak hash map, we garbage-collect here to make sure
        // there are no artefacts in memory
        System.gc();
    }

    /**
     * Test tha callgraph with a small trace
     */
    @Test
    public void testCallGraph() {
        CallStackAnalysisStub cga = getModule();
        CallGraph cg = cga.getCallGraph();

        try {
            Collection<ICallStackElement> elements = cg.getElements();
            for (ICallStackElement group : elements) {
                String firstLevelName = group.getName();
                switch (firstLevelName) {
                case "1":
                    verifyProcess1(cg, group);
                    break;
                case "5":
                    verifyProcess5(cg, group);
                    break;
                default:
                    fail("Unknown process in callstack");
                }
            }
        } finally {
            cga.dispose();
        }
    }

    private static void verifyProcess1(CallGraph cg, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = cg.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "2":
                assertEquals(2, children.size());
                for (AggregatedCallSite child : children) {
                    assertTrue(child instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction func = (AggregatedCalledFunction) child;
                    switch (getCallSiteSymbol(func).resolve(Collections.emptySet())) {
                    case "op1":
                        assertEquals(9, func.getDuration());
                        assertEquals(5, func.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                        assertEquals(1, func.getNbCalls());
                        assertEquals(1, func.getProcessId());
                        assertEquals(1, func.getCallees().size());
                        AggregatedCalledFunction next = (AggregatedCalledFunction) func.getCallees().iterator().next();
                        assertNotNull(next);
                        assertEquals(4, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(1, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                        break;
                    case "op4":
                        assertEquals(8, func.getDuration());
                        assertEquals(8, func.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                        assertEquals(1, func.getNbCalls());
                        assertEquals(1, func.getProcessId());
                        assertEquals(0, func.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 2" + getCallSiteSymbol(func));
                    }
                }
                break;
            case "3":
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertEquals("op2", getCallSiteSymbol(func).resolve(Collections.emptySet()));

                assertEquals(17, func.getDuration());
                assertEquals(10, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(1, func.getProcessId());
                assertEquals(2, func.getCallees().size());
                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op3":
                        assertEquals(1, next.getDuration());
                        assertEquals(1, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    case "op2":
                        assertEquals(6, next.getDuration());
                        assertEquals(6, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 2" + getCallSiteSymbol(func));
                    }
                }

                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

    private static void verifyProcess5(CallGraph cg, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = cg.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "6": {
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op1", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(19, func.getDuration());
                assertEquals(3, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(3, func.getCallees().size());

                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op2":
                    {
                        assertEquals(3, next.getDuration());
                        assertEquals(2, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    case "op3":
                    {
                        assertEquals(5, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(2, third.getDuration());
                        assertEquals(2, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op1", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    case "op4":
                        assertEquals(8, next.getDuration());
                        assertEquals(8, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op4", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(0, next.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for second level of tid 6");
                    }
                }
            }
                break;
            case "7": {
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op5", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(19, func.getDuration());
                assertEquals(7, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(1, func.getCallees().size());

                // Verify children
                Iterator<AggregatedCallSite> iterator = func.getCallees().iterator();
                AggregatedCalledFunction next = (AggregatedCalledFunction) iterator.next();
                assertNotNull(next);
                assertEquals(12, next.getDuration());
                assertEquals(11, next.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                assertEquals(3, next.getNbCalls());
                assertEquals(5, next.getProcessId());
                assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                assertEquals(1, next.getCallees().size());
                AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                assertNotNull(third);
                assertEquals(1, third.getDuration());
                assertEquals(1, third.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                assertEquals(1, third.getNbCalls());
                assertEquals(5, third.getProcessId());
                assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                assertEquals(0, third.getCallees().size());
            }
                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

    private CallGraphAnalysis getCallGraphModule() throws TmfAnalysisException {
        CallGraphAnalysis cga = new CallGraphAnalysis(Objects.requireNonNull(getModule()));
        cga.setId(getModule().getId());
        cga.setTrace(getTrace());

        cga.schedule();
        cga.waitForCompletion();
        return cga;
    }

    /**
     * Test a callgraph with a callstack that provides CPU times
     *
     * @throws TmfAnalysisException
     *             Propagates exceptions
     */
    @Test
    public void testCallGraphWithCpuTime() throws TmfAnalysisException {
        IHostModel model = ModelManager.getModelFor(getTrace().getHostId());
        // Assign it to a variable because the model uses weak hash map, we
        // don't want it garbage-collected before the end of the test.
        ICpuTimeProvider cpuTimeProvider = new ICpuTimeProvider() {

            @Override
            public long getCpuTime(int tid, long start, long end) {
                // TID 7 was out of CPU from 3 to 4
                if (tid == 7) {
                    long beginTime = Math.max(start, 3);
                    long endTime = Math.min(end, 4);
                    if (endTime - beginTime > 0) {
                        return (end - start) - (endTime - beginTime);
                    }
                }
                // TID 3 was out of CPU from 8 to 11
                if (tid == 3) {
                    long beginTime = Math.max(start, 8);
                    long endTime = Math.min(end, 11);
                    if (endTime - beginTime > 0) {
                        return (end - start) - (endTime - beginTime);
                    }
                }
                // TID 2 was out of CPU from 13 to 18
                if (tid == 2) {
                    long beginTime = Math.max(start, 13);
                    long endTime = Math.min(end, 18);
                    if (endTime - beginTime > 0) {
                        return (end - start) - (endTime - beginTime);
                    }
                }
                return end - start;
            }

            @Override
            public @NonNull Collection<@NonNull String> getHostIds() {
                return Collections.singleton("callstack.xml");
            }

        };
        ((CompositeHostModel) model).setCpuTimeProvider(cpuTimeProvider);

        CallGraphAnalysis cga = getCallGraphModule();
        CallGraph callGraph = cga.getCallGraph();
        try {
            Collection<ICallStackElement> groups = callGraph.getElements();
            for (ICallStackElement group : groups) {
                String firstLevelName = group.getName();
                switch (firstLevelName) {
                case "1":
                    // Make sure the symbol key is correctly resolved
                    verifyProcess1CpuTime(callGraph, group);
                    break;
                case "5":
                    // Make sure the symbol key is correctly resolved
                    verifyProcess5CpuTime(callGraph, group);
                    break;
                default:
                    fail("Unknown process in callstack");
                }
            }
        } finally {
            cga.dispose();
        }
    }

    private static void verifyProcess1CpuTime(CallGraph callGraph, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = callGraph.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "2":
                assertEquals(2, children.size());
                for (AggregatedCallSite child : children) {
                    assertTrue(child instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction func = (AggregatedCalledFunction) child;
                    switch (getCallSiteSymbol(func).resolve(Collections.emptySet())) {
                    case "op1":
                        assertEquals(9, func.getDuration());
                        assertEquals(5, func.getSelfTime());
                        assertEquals(9, func.getCpuTime());
                        assertEquals(1, func.getNbCalls());
                        assertEquals(1, func.getProcessId());
                        assertEquals(1, func.getCallees().size());
                        AggregatedCalledFunction next = (AggregatedCalledFunction) func.getCallees().iterator().next();
                        assertNotNull(next);
                        assertEquals(4, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(4, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(1, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(1, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                        break;
                    case "op4":
                        assertEquals(8, func.getDuration());
                        assertEquals(8, func.getSelfTime());
                        assertEquals(3, func.getCpuTime());
                        assertEquals(1, func.getNbCalls());
                        assertEquals(1, func.getProcessId());
                        assertEquals(0, func.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 2: " + getCallSiteSymbol(func));
                    }
                }
                break;
            case "3":
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertEquals("op2", getCallSiteSymbol(func).resolve(Collections.emptySet()));

                assertEquals(17, func.getDuration());
                assertEquals(10, func.getSelfTime());
                assertEquals(14, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(1, func.getProcessId());
                assertEquals(2, func.getCallees().size());
                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op3":
                        assertEquals(1, next.getDuration());
                        assertEquals(1, next.getSelfTime());
                        assertEquals(1, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    case "op2":
                        assertEquals(6, next.getDuration());
                        assertEquals(6, next.getSelfTime());
                        assertEquals(3, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 3: " + getCallSiteSymbol(func));
                    }
                }

                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

    private static void verifyProcess5CpuTime(CallGraph callGraph, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = callGraph.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "6": {
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op1", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(19, func.getDuration());
                assertEquals(3, func.getSelfTime());
                assertEquals(19, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(3, func.getCallees().size());

                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op2":
                    {
                        assertEquals(3, next.getDuration());
                        assertEquals(2, next.getSelfTime());
                        assertEquals(3, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(1, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    case "op3":
                    {
                        assertEquals(5, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(5, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(2, third.getDuration());
                        assertEquals(2, third.getSelfTime());
                        assertEquals(2, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op1", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    case "op4":
                        assertEquals(8, next.getDuration());
                        assertEquals(8, next.getSelfTime());
                        assertEquals(8, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op4", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(0, next.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for second level of tid 6: " + getCallSiteSymbol(next));
                    }
                }
            }
                break;
            case "7": {
                /*
                 * pid1 --- tid2 1e1 ------------- 10x1 12e4------------20x |
                 * 3e2-------7x | 4e3--5x |-- tid3 3e2
                 * --------------------------------20x 5e3--6x 7e2--------13x
                 *
                 * pid5 --- tid6 1e1 -----------------------------------20x |
                 * 2e3 ---------7x 12e4------------20x | 4e1--6x |-- tid7 1e5
                 * -----------------------------------20x 2e2 +++ 6x 9e2 ++++
                 * 13x 15e2 ++ 19x 10e3 + 11x
                 */
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op5", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(19, func.getDuration());
                assertEquals(7, func.getSelfTime());
                assertEquals(18, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(1, func.getCallees().size());

                // Verify children
                Iterator<AggregatedCallSite> iterator = func.getCallees().iterator();
                AggregatedCalledFunction next = (AggregatedCalledFunction) iterator.next();
                assertNotNull(next);
                assertEquals(12, next.getDuration());
                assertEquals(11, next.getSelfTime());
                assertEquals(11, next.getCpuTime());
                assertEquals(3, next.getNbCalls());
                assertEquals(5, next.getProcessId());
                assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                assertEquals(1, next.getCallees().size());
                AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                assertNotNull(third);
                assertEquals(1, third.getDuration());
                assertEquals(1, third.getSelfTime());
                assertEquals(1, third.getCpuTime());
                assertEquals(1, third.getNbCalls());
                assertEquals(5, third.getProcessId());
                assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                assertEquals(0, third.getCallees().size());
            }
                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

    /**
     * Test the callgraph for a time selection, with a small trace
     */
    @Test
    public void testSelectionCallGraph() {
        CallStackAnalysisStub cga = getModule();
        CallGraph cg = cga.getCallGraph(TmfTimestamp.fromNanos(1), TmfTimestamp.fromNanos(10));
        try {
            Collection<ICallStackElement> elements = cg.getElements();
            for (ICallStackElement group : elements) {
                String firstLevelName = group.getName();
                switch (firstLevelName) {
                case "1":
                    verifyProcess1Selection(cg, group);
                    break;
                case "5":
                    verifyProcess5Selection(cg, group);
                    break;
                default:
                    fail("Unknown process in callstack");
                }
            }

            // Test that another call to the callgraph returns the exact same object
            CallGraph cg2 = cga.getCallGraph(TmfTimestamp.fromNanos(1), TmfTimestamp.fromNanos(10));
            assertTrue(cg == cg2);
        } finally {
            cga.dispose();
        }
    }

    private static void verifyProcess1Selection(CallGraph cg, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = cg.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "2":
                assertEquals(1, children.size());
                for (AggregatedCallSite child : children) {
                    assertTrue(child instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction func = (AggregatedCalledFunction) child;
                    switch (getCallSiteSymbol(func).resolve(Collections.emptySet())) {
                    case "op1":
                        assertEquals(9, func.getDuration());
                        assertEquals(5, func.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                        assertEquals(1, func.getNbCalls());
                        assertEquals(1, func.getProcessId());
                        assertEquals(1, func.getCallees().size());
                        AggregatedCalledFunction next = (AggregatedCalledFunction) func.getCallees().iterator().next();
                        assertNotNull(next);
                        assertEquals(4, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(1, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 2" + getCallSiteSymbol(func));
                    }
                }
                break;
            case "3":
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertEquals("op2", getCallSiteSymbol(func).resolve(Collections.emptySet()));

                assertEquals(7, func.getDuration());
                assertEquals(3, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(1, func.getProcessId());
                assertEquals(2, func.getCallees().size());
                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op3":
                        assertEquals(1, next.getDuration());
                        assertEquals(1, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    case "op2":
                        assertEquals(3, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(1, next.getProcessId());
                        assertEquals(0, next.getCallees().size());
                        break;
                    default:
                        fail("Unknown symbol for thread 2" + getCallSiteSymbol(func));
                    }
                }

                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

    private static void verifyProcess5Selection(CallGraph cg, ICallStackElement element) {
        Collection<ICallStackElement> secondLevels = element.getChildrenElements();
        assertEquals(2, secondLevels.size());
        for (ICallStackElement secondLevel : secondLevels) {
            assertTrue(secondLevel instanceof InstrumentedCallStackElement);
            assertTrue(secondLevel.isLeaf());
            String secondLevelName = secondLevel.getName();
            Collection<AggregatedCallSite> children = cg.getCallingContextTree(secondLevel);
            switch (secondLevelName) {
            case "6": {
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op1", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(9, func.getDuration());
                assertEquals(2, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(2, func.getCallees().size());

                for (AggregatedCallSite nextChild : func.getCallees()) {
                    assertTrue(nextChild instanceof AggregatedCalledFunction);
                    AggregatedCalledFunction next = (AggregatedCalledFunction) nextChild;
                    switch (getCallSiteSymbol(next).resolve(Collections.emptySet())) {
                    case "op2":
                    {
                        assertEquals(2, next.getDuration());
                        assertEquals(1, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(1, third.getDuration());
                        assertEquals(1, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    case "op3":
                    {
                        assertEquals(5, next.getDuration());
                        assertEquals(3, next.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                        assertEquals(1, next.getNbCalls());
                        assertEquals(5, next.getProcessId());
                        assertEquals("op3", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                        assertEquals(1, next.getCallees().size());
                        AggregatedCalledFunction third = (AggregatedCalledFunction) next.getCallees().iterator().next();
                        assertNotNull(third);
                        assertEquals(2, third.getDuration());
                        assertEquals(2, third.getSelfTime());
                        assertEquals(IHostModel.TIME_UNKNOWN, third.getCpuTime());
                        assertEquals(1, third.getNbCalls());
                        assertEquals(5, third.getProcessId());
                        assertEquals("op1", getCallSiteSymbol(third).resolve(Collections.emptySet()));
                        assertEquals(0, third.getCallees().size());
                    }
                        break;
                    default:
                        fail("Unknown symbol for second level of tid 6");
                    }
                }
            }
                break;
            case "7": {
                assertEquals(1, children.size());
                AggregatedCalledFunction func = (AggregatedCalledFunction) children.iterator().next();
                assertNotNull(func);
                assertEquals("op5", getCallSiteSymbol(func).resolve(Collections.emptySet()));
                assertEquals(9, func.getDuration());
                assertEquals(4, func.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, func.getCpuTime());
                assertEquals(1, func.getNbCalls());
                assertEquals(5, func.getProcessId());
                assertEquals(1, func.getCallees().size());

                // Verify children
                Iterator<AggregatedCallSite> iterator = func.getCallees().iterator();
                AggregatedCalledFunction next = (AggregatedCalledFunction) iterator.next();
                assertNotNull(next);
                assertEquals(5, next.getDuration());
                assertEquals(5, next.getSelfTime());
                assertEquals(IHostModel.TIME_UNKNOWN, next.getCpuTime());
                assertEquals(2, next.getNbCalls());
                assertEquals(5, next.getProcessId());
                assertEquals("op2", getCallSiteSymbol(next).resolve(Collections.emptySet()));
                assertEquals(0, next.getCallees().size());
            }
                break;
            default:
                fail("Unknown process in callstack: " + secondLevelName);
            }
        }
    }

}
