1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.analysis
.timing
.ui
.swtbot
.tests
.callgraph
;
12 import static org
.junit
.Assert
.assertEquals
;
13 import static org
.junit
.Assert
.assertNotNull
;
14 import static org
.junit
.Assert
.assertTrue
;
15 import static org
.junit
.Assert
.fail
;
17 import java
.util
.concurrent
.CountDownLatch
;
18 import java
.util
.concurrent
.TimeUnit
;
20 import org
.apache
.log4j
.ConsoleAppender
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.apache
.log4j
.SimpleLayout
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
26 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
27 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
28 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
29 import org
.eclipse
.swtbot
.swt
.finder
.results
.Result
;
30 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
31 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotCanvas
;
32 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
33 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.ISegmentStoreProvider
;
34 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.IStatistics
;
35 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.Statistics
;
36 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.tests
.flamegraph
.AggregationTreeTest
;
37 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.density
.AbstractSegmentStoreDensityViewer
;
38 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.density
.ISegmentStoreDensityViewerDataListener
;
39 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.table
.AbstractSegmentStoreTableViewer
;
40 import org
.eclipse
.tracecompass
.internal
.analysis
.timing
.ui
.callgraph
.CallGraphDensityView
;
41 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.tests
.shared
.WaitUtils
;
45 import org
.eclipse
.ui
.IViewPart
;
46 import org
.junit
.After
;
47 import org
.junit
.Assert
;
48 import org
.junit
.Before
;
49 import org
.junit
.BeforeClass
;
50 import org
.junit
.runner
.RunWith
;
51 import org
.swtchart
.ISeries
;
54 * Test the call graph density view, known as the Function Density view. The
55 * density view can change its data with respect to screen resolution, so
56 * descriptive statistics are used to check validity. This is one of the rare
57 * occasions that the error in the
58 * {@link Assert#assertEquals(double, double, double)} is actually quite useful
60 * @author Matthew Khouzam
62 @RunWith(SWTBotJunit4ClassRunner
.class)
63 public class CallGraphDensityViewTest
extends AggregationTreeTest
{
65 private static final String CALLGRAPHDENSITY_ID
= CallGraphDensityView
.ID
;
67 private final @NonNull ISegmentStoreDensityViewerDataListener fSyncListener
= new ISegmentStoreDensityViewerDataListener() {
70 public void viewDataChanged(@NonNull Iterable
<?
extends @NonNull ISegment
> newData
) {
75 public void selectedDataChanged(@Nullable Iterable
<?
extends @NonNull ISegment
> newSelectionData
) {
80 private SWTWorkbenchBot fBot
;
81 private SWTBotView fView
;
82 private CallGraphDensityView fFuncDensityView
;
83 private SWTBotTable fTableBot
;
84 private SWTBotCanvas fDensityBot
;
85 private AbstractSegmentStoreDensityViewer fDensityViewer
;
86 private AbstractSegmentStoreTableViewer fTableViewer
;
87 private CountDownLatch fLatch
;
89 /** The Log4j logger instance. */
90 private static final Logger fLogger
= Logger
.getRootLogger();
96 public static void beforeClass() {
98 SWTBotUtils
.initialize();
99 Thread
.currentThread().setName("SWTBotTest");
100 /* set up for swtbot */
101 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
102 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
103 fLogger
.removeAllAppenders();
104 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
105 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
106 SWTBotUtils
.closeView("welcome", bot
);
107 /* Switch perspectives */
108 SWTBotUtils
.switchToTracingPerspective();
109 /* Finish waiting for eclipse to load */
110 WaitUtils
.waitForJobs();
117 public void before() {
118 fBot
= new SWTWorkbenchBot();
119 SWTBotUtils
.openView(CALLGRAPHDENSITY_ID
);
120 SWTBotView view
= fBot
.viewById(CALLGRAPHDENSITY_ID
);
123 CallGraphDensityView funcDensityView
= UIThreadRunnable
.syncExec((Result
<CallGraphDensityView
>) () -> {
124 IViewPart viewRef
= fView
.getViewReference().getView(true);
125 return (viewRef
instanceof CallGraphDensityView
) ?
(CallGraphDensityView
) viewRef
: null;
127 assertNotNull(funcDensityView
);
128 fTableBot
= fView
.bot().table();
129 assertNotNull(fTableBot
);
130 fDensityBot
= fView
.bot().canvas();
131 assertNotNull(fDensityBot
);
132 fDensityViewer
= funcDensityView
.getDensityViewer();
133 assertNotNull(fDensityViewer
);
134 fLatch
= new CountDownLatch(1);
135 fDensityViewer
.removeDataListener(fSyncListener
);
136 fDensityViewer
.addDataListener(fSyncListener
);
137 fTableViewer
= funcDensityView
.getTableViewer();
138 assertNotNull(fTableViewer
);
139 SWTBotUtils
.maximize(funcDensityView
);
140 fFuncDensityView
= funcDensityView
;
147 public void after() {
148 CallGraphDensityView funcDensityView
= fFuncDensityView
;
149 assertNotNull(funcDensityView
);
150 SWTBotUtils
.maximize(funcDensityView
);
155 public void emptyStateSystemTest() {
156 super.emptyStateSystemTest();
158 assertEquals(0, fTableBot
.rowCount());
159 ISeries series
= getSeries();
160 assertNotNull(series
);
164 public void cascadeTest() {
167 assertEquals(3, fTableBot
.rowCount());
168 ISeries series
= getSeries();
169 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
170 assertEquals(3.0, sss
.getTotal(), 0.0);
171 assertEquals(0.02, sss
.getMean(), 0.02); // low mean
175 public void mergeFirstLevelCalleesTest() {
176 super.mergeFirstLevelCalleesTest();
178 assertEquals(5, fTableBot
.rowCount());
179 ISeries series
= getSeries();
180 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
181 assertEquals(5.0, sss
.getTotal(), 0.0);
182 assertEquals(0.02, sss
.getMean(), 0.03); // low mean
186 public void multiFunctionRootsSecondTest() {
187 super.multiFunctionRootsSecondTest();
189 assertEquals(4, fTableBot
.rowCount());
190 ISeries series
= getSeries();
191 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
192 assertEquals(4.0, sss
.getTotal(), 0.0);
193 assertEquals(0.02, sss
.getMean(), 0.02); // low mean
197 public void mergeSecondLevelCalleesTest() {
198 super.mergeSecondLevelCalleesTest();
200 assertEquals(8, fTableBot
.rowCount());
201 ISeries series
= getSeries();
202 double[] ySeries
= series
.getYSeries();
203 assertNotNull(ySeries
);
204 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
205 assertEquals(8.0, sss
.getTotal(), 0.0);
206 assertEquals(0.06, sss
.getMean(), 0.02); // average mean
210 public void multiFunctionRootsTest() {
211 super.multiFunctionRootsTest();
213 assertEquals(4, fTableBot
.rowCount());
214 ISeries series
= getSeries();
215 double[] ySeries
= series
.getYSeries();
216 assertNotNull(ySeries
);
217 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
218 assertEquals(4.0, sss
.getTotal(), 0.0);
219 assertEquals(0.02, sss
.getMean(), 0.02); // low mean
223 public void treeTest() {
226 assertEquals(4, fTableBot
.rowCount());
227 ISeries series
= getSeries();
228 double[] ySeries
= series
.getYSeries();
229 assertNotNull(ySeries
);
230 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
231 assertEquals(4.0, sss
.getTotal(), 0.0);
232 assertEquals(0.02, sss
.getMean(), 0.02); // low mean
236 public void largeTest() {
239 assertEquals(1000, fTableBot
.rowCount());
240 ISeries series
= getSeries();
241 double[] ySeries
= series
.getYSeries();
242 assertNotNull(ySeries
);
243 IStatistics
<@NonNull Long
> sss
= getDescriptiveStatistics(series
);
244 assertEquals(1000.0, sss
.getTotal(), 0.0);
245 assertEquals(8, sss
.getMean(), 1); // high mean
248 private ISeries
getSeries() {
249 AbstractSegmentStoreDensityViewer densityViewer
= fDensityViewer
;
250 assertNotNull(densityViewer
);
251 ISeries
[] serieses
= densityViewer
.getControl().getSeriesSet().getSeries();
252 assertNotNull(serieses
);
253 assertTrue(serieses
.length
> 0);
254 ISeries series
= serieses
[0];
255 assertNotNull(series
);
259 private void loadData() {
260 final ISegmentStoreProvider cga
= getCga();
261 UIThreadRunnable
.syncExec(() -> {
262 fTableViewer
.setData(cga
);
263 fDensityViewer
.setSegmentProvider(cga
);
264 fDensityViewer
.updateWithRange(TmfTimeRange
.ETERNITY
);
265 fDensityViewer
.refresh();
270 * timeout of the test
272 assertTrue(fLatch
.await(20, TimeUnit
.SECONDS
));
273 } catch (InterruptedException e
) {
274 fail(e
.getMessage());
280 private static IStatistics
<@NonNull Long
> getDescriptiveStatistics(ISeries series
) {
281 double[] ySeries
= series
.getYSeries();
282 assertNotNull(ySeries
);
283 IStatistics
<@NonNull Long
> stats
= new Statistics
<>();
284 for (double item
: ySeries
) {
285 stats
.update((long) (item
- 1.0));