Commit | Line | Data |
---|---|---|
b1d4e193 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 Ericsson | |
3 | * | |
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 | *******************************************************************************/ | |
9 | ||
10 | package org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.callgraph; | |
11 | ||
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; | |
16 | ||
17 | import java.util.List; | |
18 | import java.util.concurrent.CountDownLatch; | |
19 | import java.util.concurrent.TimeUnit; | |
20 | ||
21 | import org.apache.log4j.ConsoleAppender; | |
22 | import org.apache.log4j.Logger; | |
23 | import org.apache.log4j.SimpleLayout; | |
24 | import org.eclipse.jdt.annotation.NonNull; | |
25 | import org.eclipse.jdt.annotation.Nullable; | |
26 | import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; | |
27 | import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; | |
28 | import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; | |
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.segmentstore.statistics.SegmentStoreStatistics; | |
35 | import org.eclipse.tracecompass.analysis.timing.core.tests.flamegraph.AggregationTreeTest; | |
36 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density.AbstractSegmentStoreDensityViewer; | |
37 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density.ISegmentStoreDensityViewerDataListener; | |
38 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer; | |
39 | import org.eclipse.tracecompass.internal.analysis.timing.ui.callgraph.CallGraphDensityView; | |
40 | import org.eclipse.tracecompass.segmentstore.core.BasicSegment; | |
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.swtchart.ISeries; | |
51 | ||
52 | /** | |
53 | * Test the call graph density view, known as the Function Density view. The | |
54 | * density view can change its data with respect to screen resolution, so | |
55 | * descriptive statistics are used to check validity. This is one of the rare | |
56 | * occasions that the error in the | |
57 | * {@link Assert#assertEquals(double, double, double)} is actually quite useful | |
58 | * | |
59 | * @author Matthew Khouzam | |
60 | */ | |
61 | public class CallGraphDensityViewTest extends AggregationTreeTest { | |
62 | ||
63 | private static final String CALLGRAPHDENSITY_ID = CallGraphDensityView.ID; | |
64 | ||
65 | private final @NonNull ISegmentStoreDensityViewerDataListener fSyncListener = new ISegmentStoreDensityViewerDataListener() { | |
66 | @Override | |
67 | public void dataChanged(List<ISegment> newData) { | |
68 | fLatch.countDown(); | |
69 | } | |
70 | ||
71 | @Override | |
72 | public void dataSelectionChanged(@Nullable List<@NonNull ISegment> newSelectionData) { | |
73 | // do nothing | |
74 | } | |
75 | ||
76 | }; | |
77 | private SWTWorkbenchBot fBot; | |
78 | private SWTBotView fView; | |
79 | private CallGraphDensityView fFuncDensityView; | |
80 | private SWTBotTable fTableBot; | |
81 | private SWTBotCanvas fDensityBot; | |
82 | private AbstractSegmentStoreDensityViewer fDensityViewer; | |
83 | private AbstractSegmentStoreTableViewer fTableViewer; | |
84 | private CountDownLatch fLatch; | |
85 | ||
86 | /** The Log4j logger instance. */ | |
87 | private static final Logger fLogger = Logger.getRootLogger(); | |
88 | ||
89 | /** | |
90 | * Initialization | |
91 | */ | |
92 | @BeforeClass | |
93 | public static void beforeClass() { | |
94 | ||
95 | SWTBotUtils.initialize(); | |
96 | Thread.currentThread().setName("SWTBotTest"); | |
97 | /* set up for swtbot */ | |
98 | SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ | |
99 | SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US"; | |
100 | fLogger.removeAllAppenders(); | |
101 | fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); | |
102 | SWTWorkbenchBot bot = new SWTWorkbenchBot(); | |
103 | SWTBotUtils.closeView("welcome", bot); | |
104 | /* Switch perspectives */ | |
105 | SWTBotUtils.switchToTracingPerspective(); | |
106 | /* Finish waiting for eclipse to load */ | |
107 | WaitUtils.waitForJobs(); | |
108 | } | |
109 | ||
110 | /** | |
111 | * Setup for the test | |
112 | */ | |
113 | @Before | |
114 | public void before() { | |
115 | fBot = new SWTWorkbenchBot(); | |
116 | SWTBotUtils.openView(CALLGRAPHDENSITY_ID); | |
117 | SWTBotView view = fBot.viewById(CALLGRAPHDENSITY_ID); | |
118 | assertNotNull(view); | |
119 | fView = view; | |
120 | CallGraphDensityView funcDensityView = UIThreadRunnable.syncExec((Result<CallGraphDensityView>) () -> { | |
121 | IViewPart viewRef = fView.getViewReference().getView(true); | |
122 | return (viewRef instanceof CallGraphDensityView) ? (CallGraphDensityView) viewRef : null; | |
123 | }); | |
124 | assertNotNull(funcDensityView); | |
125 | fTableBot = fView.bot().table(); | |
126 | assertNotNull(fTableBot); | |
127 | fDensityBot = fView.bot().canvas(); | |
128 | assertNotNull(fDensityBot); | |
129 | fDensityViewer = funcDensityView.getDensityViewer(); | |
130 | assertNotNull(fDensityViewer); | |
131 | fLatch = new CountDownLatch(1); | |
132 | fDensityViewer.removeDataListener(fSyncListener); | |
133 | fDensityViewer.addDataListener(fSyncListener); | |
134 | fTableViewer = funcDensityView.getTableViewer(); | |
135 | assertNotNull(fTableViewer); | |
136 | SWTBotUtils.maximize(funcDensityView); | |
137 | fFuncDensityView = funcDensityView; | |
138 | } | |
139 | ||
140 | /** | |
141 | * Reset | |
142 | */ | |
143 | @After | |
144 | public void after() { | |
145 | CallGraphDensityView funcDensityView = fFuncDensityView; | |
146 | assertNotNull(funcDensityView); | |
147 | SWTBotUtils.maximize(funcDensityView); | |
148 | ||
149 | } | |
150 | ||
151 | @Override | |
152 | public void emptyStateSystemTest() { | |
153 | super.emptyStateSystemTest(); | |
154 | loadData(); | |
155 | assertEquals(0, fTableBot.rowCount()); | |
156 | ISeries series = getSeries(); | |
157 | assertNotNull(series); | |
158 | } | |
159 | ||
160 | @Override | |
161 | public void cascadeTest() { | |
162 | super.cascadeTest(); | |
163 | loadData(); | |
164 | assertEquals(3, fTableBot.rowCount()); | |
165 | ISeries series = getSeries(); | |
166 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
167 | assertEquals(3.0, sss.getTotal(), 0.0); | |
168 | assertEquals(0.02, sss.getAverage(), 0.02); // low mean | |
169 | } | |
170 | ||
171 | @Override | |
172 | public void mergeFirstLevelCalleesTest() { | |
173 | super.mergeFirstLevelCalleesTest(); | |
174 | loadData(); | |
175 | assertEquals(5, fTableBot.rowCount()); | |
176 | ISeries series = getSeries(); | |
177 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
178 | assertEquals(5.0, sss.getTotal(), 0.0); | |
179 | assertEquals(0.02, sss.getAverage(), 0.03); // low mean | |
180 | } | |
181 | ||
182 | @Override | |
183 | public void multiFunctionRootsSecondTest() { | |
184 | super.multiFunctionRootsSecondTest(); | |
185 | loadData(); | |
186 | assertEquals(4, fTableBot.rowCount()); | |
187 | ISeries series = getSeries(); | |
188 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
189 | assertEquals(4.0, sss.getTotal(), 0.0); | |
190 | assertEquals(0.02, sss.getAverage(), 0.02); // low mean | |
191 | } | |
192 | ||
193 | @Override | |
194 | public void mergeSecondLevelCalleesTest() { | |
195 | super.mergeSecondLevelCalleesTest(); | |
196 | loadData(); | |
197 | assertEquals(8, fTableBot.rowCount()); | |
198 | ISeries series = getSeries(); | |
199 | double[] ySeries = series.getYSeries(); | |
200 | assertNotNull(ySeries); | |
201 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
202 | assertEquals(8.0, sss.getTotal(), 0.0); | |
203 | assertEquals(0.06, sss.getAverage(), 0.02); // average mean | |
204 | } | |
205 | ||
206 | @Override | |
207 | public void multiFunctionRootsTest() { | |
208 | super.multiFunctionRootsTest(); | |
209 | loadData(); | |
210 | assertEquals(4, fTableBot.rowCount()); | |
211 | ISeries series = getSeries(); | |
212 | double[] ySeries = series.getYSeries(); | |
213 | assertNotNull(ySeries); | |
214 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
215 | assertEquals(4.0, sss.getTotal(), 0.0); | |
216 | assertEquals(0.02, sss.getAverage(), 0.02); // low mean | |
217 | } | |
218 | ||
219 | @Override | |
220 | public void treeTest() { | |
221 | super.treeTest(); | |
222 | loadData(); | |
223 | assertEquals(4, fTableBot.rowCount()); | |
224 | ISeries series = getSeries(); | |
225 | double[] ySeries = series.getYSeries(); | |
226 | assertNotNull(ySeries); | |
227 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
228 | assertEquals(4.0, sss.getTotal(), 0.0); | |
229 | assertEquals(0.02, sss.getAverage(), 0.02); // low mean | |
230 | } | |
231 | ||
232 | @Override | |
233 | public void largeTest() { | |
234 | super.largeTest(); | |
235 | loadData(); | |
236 | assertEquals(1000, fTableBot.rowCount()); | |
237 | ISeries series = getSeries(); | |
238 | double[] ySeries = series.getYSeries(); | |
239 | assertNotNull(ySeries); | |
240 | SegmentStoreStatistics sss = getDescriptiveStatistics(series); | |
241 | assertEquals(1000.0, sss.getTotal(), 0.0); | |
242 | assertEquals(8, sss.getAverage(), 1); // high mean | |
243 | } | |
244 | ||
245 | private ISeries getSeries() { | |
246 | AbstractSegmentStoreDensityViewer densityViewer = fDensityViewer; | |
247 | assertNotNull(densityViewer); | |
248 | ISeries[] serieses = densityViewer.getControl().getSeriesSet().getSeries(); | |
249 | assertNotNull(serieses); | |
250 | assertTrue(serieses.length > 0); | |
251 | ISeries series = serieses[0]; | |
252 | assertNotNull(series); | |
253 | return series; | |
254 | } | |
255 | ||
256 | private void loadData() { | |
257 | final ISegmentStoreProvider cga = getCga(); | |
258 | UIThreadRunnable.syncExec(() -> { | |
259 | fTableViewer.setData(cga); | |
260 | fDensityViewer.setSegmentProvider(cga); | |
261 | fDensityViewer.updateWithRange(TmfTimeRange.ETERNITY); | |
262 | fDensityViewer.refresh(); | |
263 | }); | |
264 | if (cga != null) { | |
265 | try { | |
266 | /* | |
267 | * timeout of the test | |
268 | */ | |
269 | assertTrue(fLatch.await(20, TimeUnit.SECONDS)); | |
270 | } catch (InterruptedException e) { | |
271 | fail(e.getMessage()); | |
272 | } | |
273 | } | |
274 | ||
275 | } | |
276 | ||
277 | private static SegmentStoreStatistics getDescriptiveStatistics(ISeries series) { | |
278 | double[] ySeries = series.getYSeries(); | |
279 | assertNotNull(ySeries); | |
280 | SegmentStoreStatistics sss = new SegmentStoreStatistics(); | |
281 | for (double item : ySeries) { | |
282 | sss.update(new BasicSegment(0, (long) (item - 1.0))); | |
283 | } | |
284 | return sss; | |
285 | } | |
286 | ||
287 | } |