/******************************************************************************* * Copyright (c) 2016 Ericsson * * 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.timing.ui.swtbot.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.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.Result; import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; import org.eclipse.swtbot.swt.finder.widgets.SWTBotCanvas; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics; import org.eclipse.tracecompass.analysis.timing.core.statistics.Statistics; import org.eclipse.tracecompass.analysis.timing.core.tests.flamegraph.AggregationTreeTest; import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density.AbstractSegmentStoreDensityViewer; import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density.ISegmentStoreDensityViewerDataListener; import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer; import org.eclipse.tracecompass.internal.analysis.timing.ui.callgraph.CallGraphDensityView; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils; import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils; import org.eclipse.ui.IViewPart; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.swtchart.ISeries; /** * Test the call graph density view, known as the Function Density view. The * density view can change its data with respect to screen resolution, so * descriptive statistics are used to check validity. This is one of the rare * occasions that the error in the * {@link Assert#assertEquals(double, double, double)} is actually quite useful * * @author Matthew Khouzam */ public class CallGraphDensityViewTest extends AggregationTreeTest { private static final String CALLGRAPHDENSITY_ID = CallGraphDensityView.ID; private final @NonNull ISegmentStoreDensityViewerDataListener fSyncListener = new ISegmentStoreDensityViewerDataListener() { @Override public void dataChanged(List<ISegment> newData) { fLatch.countDown(); } @Override public void dataSelectionChanged(@Nullable List<@NonNull ISegment> newSelectionData) { // do nothing } }; private SWTWorkbenchBot fBot; private SWTBotView fView; private CallGraphDensityView fFuncDensityView; private SWTBotTable fTableBot; private SWTBotCanvas fDensityBot; private AbstractSegmentStoreDensityViewer fDensityViewer; private AbstractSegmentStoreTableViewer fTableViewer; private CountDownLatch fLatch; /** The Log4j logger instance. */ private static final Logger fLogger = Logger.getRootLogger(); /** * Initialization */ @BeforeClass public static void beforeClass() { SWTBotUtils.initialize(); Thread.currentThread().setName("SWTBotTest"); /* set up for swtbot */ SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US"; fLogger.removeAllAppenders(); fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); SWTWorkbenchBot bot = new SWTWorkbenchBot(); SWTBotUtils.closeView("welcome", bot); /* Switch perspectives */ SWTBotUtils.switchToTracingPerspective(); /* Finish waiting for eclipse to load */ WaitUtils.waitForJobs(); } /** * Setup for the test */ @Before public void before() { fBot = new SWTWorkbenchBot(); SWTBotUtils.openView(CALLGRAPHDENSITY_ID); SWTBotView view = fBot.viewById(CALLGRAPHDENSITY_ID); assertNotNull(view); fView = view; CallGraphDensityView funcDensityView = UIThreadRunnable.syncExec((Result<CallGraphDensityView>) () -> { IViewPart viewRef = fView.getViewReference().getView(true); return (viewRef instanceof CallGraphDensityView) ? (CallGraphDensityView) viewRef : null; }); assertNotNull(funcDensityView); fTableBot = fView.bot().table(); assertNotNull(fTableBot); fDensityBot = fView.bot().canvas(); assertNotNull(fDensityBot); fDensityViewer = funcDensityView.getDensityViewer(); assertNotNull(fDensityViewer); fLatch = new CountDownLatch(1); fDensityViewer.removeDataListener(fSyncListener); fDensityViewer.addDataListener(fSyncListener); fTableViewer = funcDensityView.getTableViewer(); assertNotNull(fTableViewer); SWTBotUtils.maximize(funcDensityView); fFuncDensityView = funcDensityView; } /** * Reset */ @After public void after() { CallGraphDensityView funcDensityView = fFuncDensityView; assertNotNull(funcDensityView); SWTBotUtils.maximize(funcDensityView); } @Override public void emptyStateSystemTest() { super.emptyStateSystemTest(); loadData(); assertEquals(0, fTableBot.rowCount()); ISeries series = getSeries(); assertNotNull(series); } @Override public void cascadeTest() { super.cascadeTest(); loadData(); assertEquals(3, fTableBot.rowCount()); ISeries series = getSeries(); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(3.0, sss.getTotal(), 0.0); assertEquals(0.02, sss.getMean(), 0.02); // low mean } @Override public void mergeFirstLevelCalleesTest() { super.mergeFirstLevelCalleesTest(); loadData(); assertEquals(5, fTableBot.rowCount()); ISeries series = getSeries(); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(5.0, sss.getTotal(), 0.0); assertEquals(0.02, sss.getMean(), 0.03); // low mean } @Override public void multiFunctionRootsSecondTest() { super.multiFunctionRootsSecondTest(); loadData(); assertEquals(4, fTableBot.rowCount()); ISeries series = getSeries(); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(4.0, sss.getTotal(), 0.0); assertEquals(0.02, sss.getMean(), 0.02); // low mean } @Override public void mergeSecondLevelCalleesTest() { super.mergeSecondLevelCalleesTest(); loadData(); assertEquals(8, fTableBot.rowCount()); ISeries series = getSeries(); double[] ySeries = series.getYSeries(); assertNotNull(ySeries); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(8.0, sss.getTotal(), 0.0); assertEquals(0.06, sss.getMean(), 0.02); // average mean } @Override public void multiFunctionRootsTest() { super.multiFunctionRootsTest(); loadData(); assertEquals(4, fTableBot.rowCount()); ISeries series = getSeries(); double[] ySeries = series.getYSeries(); assertNotNull(ySeries); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(4.0, sss.getTotal(), 0.0); assertEquals(0.02, sss.getMean(), 0.02); // low mean } @Override public void treeTest() { super.treeTest(); loadData(); assertEquals(4, fTableBot.rowCount()); ISeries series = getSeries(); double[] ySeries = series.getYSeries(); assertNotNull(ySeries); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(4.0, sss.getTotal(), 0.0); assertEquals(0.02, sss.getMean(), 0.02); // low mean } @Override public void largeTest() { super.largeTest(); loadData(); assertEquals(1000, fTableBot.rowCount()); ISeries series = getSeries(); double[] ySeries = series.getYSeries(); assertNotNull(ySeries); IStatistics<@NonNull Long> sss = getDescriptiveStatistics(series); assertEquals(1000.0, sss.getTotal(), 0.0); assertEquals(8, sss.getMean(), 1); // high mean } private ISeries getSeries() { AbstractSegmentStoreDensityViewer densityViewer = fDensityViewer; assertNotNull(densityViewer); ISeries[] serieses = densityViewer.getControl().getSeriesSet().getSeries(); assertNotNull(serieses); assertTrue(serieses.length > 0); ISeries series = serieses[0]; assertNotNull(series); return series; } private void loadData() { final ISegmentStoreProvider cga = getCga(); UIThreadRunnable.syncExec(() -> { fTableViewer.setData(cga); fDensityViewer.setSegmentProvider(cga); fDensityViewer.updateWithRange(TmfTimeRange.ETERNITY); fDensityViewer.refresh(); }); if (cga != null) { try { /* * timeout of the test */ assertTrue(fLatch.await(20, TimeUnit.SECONDS)); } catch (InterruptedException e) { fail(e.getMessage()); } } } private static IStatistics<@NonNull Long> getDescriptiveStatistics(ISeries series) { double[] ySeries = series.getYSeries(); assertNotNull(ySeries); IStatistics<@NonNull Long> stats = new Statistics<>(); for (double item : ySeries) { stats.update((long) (item - 1.0)); } return stats; } }