tmf: Bug 476148: Fix time range synchronization problem in time graph
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui.swtbot.tests / src / org / eclipse / tracecompass / tmf / ui / swtbot / tests / viewers / events / TmfAlignTimeAxisTest.java
CommitLineData
6ae4e885
MK
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made 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 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.tmf.ui.swtbot.tests.viewers.events;
14
15import static org.junit.Assert.assertEquals;
16import static org.junit.Assert.assertNotNull;
17
18import java.io.File;
19import java.io.IOException;
20import java.util.Arrays;
21
22import org.apache.log4j.ConsoleAppender;
23import org.apache.log4j.Logger;
24import org.apache.log4j.SimpleLayout;
25import org.eclipse.swt.SWT;
26import org.eclipse.swt.custom.SashForm;
27import org.eclipse.swt.graphics.Point;
28import org.eclipse.swt.widgets.Sash;
29import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
30import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
31import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
32import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
33import org.eclipse.swtbot.swt.finder.results.VoidResult;
34import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
35import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
36import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard;
37import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotSash;
38import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
39import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
40import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;
41import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartView;
42import org.eclipse.ui.IFolderLayout;
43import org.eclipse.ui.IPageLayout;
44import org.eclipse.ui.IPerspectiveFactory;
45import org.hamcrest.BaseMatcher;
46import org.hamcrest.Description;
47import org.junit.After;
48import org.junit.AfterClass;
49import org.junit.Before;
50import org.junit.BeforeClass;
51import org.junit.Test;
52import org.junit.runner.RunWith;
53
54/**
55 * Test common time axis for views
56 *
57 * @author Matthew Khouzam
58 */
59@RunWith(SWTBotJunit4ClassRunner.class)
60public class TmfAlignTimeAxisTest {
61
62 /**
63 * wait for throttler (2x the throttler time)
64 */
65 private static final int SYNC_DELAY = 1000;
66 private static final String TRACE_START = "<trace>";
67 private static final String EVENT_BEGIN = "<event timestamp=\"";
68 private static final String EVENT_MIDDLE = " \" name=\"event\"><field name=\"field\" value=\"";
69 private static final String EVENT_END = "\" type=\"int\" />" + "</event>";
70 private static final String TRACE_END = "</trace>";
71
72 private static final String PROJET_NAME = "TestAxisAlignment";
73 private static final int NUM_EVENTS = 100;
74
75 /** The Log4j logger instance. */
76 private static final Logger fLogger = Logger.getRootLogger();
77 private static SWTWorkbenchBot fBot;
78
79 private static String makeEvent(int ts, int val) {
80 return EVENT_BEGIN + Integer.toString(ts) + EVENT_MIDDLE + Integer.toString(val) + EVENT_END + "\n";
81 }
82
83 private static File fLocation;
84 private static final BaseMatcher<Sash> SASH_MATCHER = new SashMatcher();
85
86 /**
87 * Initialization, creates a temp trace
88 *
89 * @throws IOException
90 * should not happen
91 */
92 @BeforeClass
93 public static void init() throws IOException {
94 SWTBotUtils.failIfUIThread();
95 Thread.currentThread().setName("SWTBot Thread"); // for the debugger
96 /* set up for swtbot */
97 SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
98 fLogger.removeAllAppenders();
99 fLogger.addAppender(new ConsoleAppender(new SimpleLayout()));
100 SWTWorkbenchBot bot = new SWTWorkbenchBot();
101
102 SWTBotUtils.closeView("welcome", bot);
103
104 SWTBotUtils.switchToTracingPerspective();
105 /* finish waiting for eclipse to load */
106 SWTBotUtils.waitForJobs();
107 fLocation = File.createTempFile("sample", ".xml");
108 try (BufferedRandomAccessFile braf = new BufferedRandomAccessFile(fLocation, "rw")) {
109 braf.writeBytes(TRACE_START);
110 for (int i = 0; i < NUM_EVENTS; i++) {
111 braf.writeBytes(makeEvent(i * 100, i % 4));
112 }
113 braf.writeBytes(TRACE_END);
114 }
115 SWTBotUtils.createProject(PROJET_NAME);
116 SWTBotUtils.selectTracesFolder(bot, PROJET_NAME);
117 }
118
119 /**
120 * Delete file
121 */
122 @AfterClass
123 public static void cleanup() {
124 SWTBotUtils.deleteProject(PROJET_NAME, new SWTWorkbenchBot());
125 fLocation.delete();
126 fLogger.removeAllAppenders();
127 }
128
129 /**
130 * Open the trace
131 */
132 @Before
133 public void before() {
134 SWTBotUtils.openTrace(PROJET_NAME, fLocation.getAbsolutePath(), "org.eclipse.linuxtools.tmf.core.tests.xmlstub");
135 }
136
137 /**
138 * Close the trace
139 */
140 @After
141 public void after() {
142 SWTWorkbenchBot bot = new SWTWorkbenchBot();
143 bot.activeEditor().close();
144 }
145
146 /**
147 * Test 3 views, none overlap, the histogram, the callstack and the
148 * timechart are aligned, the histogram is moved, callstack and timechart
149 * follow
150 */
151 @Test
152 public void testMoveHistogramCallstackFollows() {
153 fBot = new SWTWorkbenchBot();
154 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
155 testOverlap(HistogramView.ID, CallStackView.ID);
156 }
157
158 /**
159 * Test 3 views, none overlap, the histogram, the callstack and the
160 * timechart are aligned, the callstack is moved, histogram and timechart
161 * follow
162 */
163 @Test
164 public void testMoveCallstackHistogramFollows() {
165 fBot = new SWTWorkbenchBot();
166 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
167 testOverlap(CallStackView.ID, HistogramView.ID);
168 }
169
170 /**
171 * Test 3 views, overlap on the resizing view. The timechart and callstack
172 * are overlapping. Test that when the histogram moves, the timechart
173 * follows. Hidden views are not tested as their state does not matter until
174 * they are displayed
175 */
176 @Test
177 public void testOverlappingHistogramMove() {
178 fBot = new SWTWorkbenchBot();
179 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
180 testOverlap(HistogramView.ID, CallStackView.ID);
181 }
182
183 /**
184 * Test 3 views, overlap on the resizing view. The timechart and callstack
185 * are overlapping. Test that when the timechart moves, the histogram
186 * follows. Hidden views are not tested as their state does not matter until
187 * they are displayed
188 */
189 @Test
190 public void testOverlappingTimechartMove() {
191 fBot = new SWTWorkbenchBot();
192 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
193 testOverlap(CallStackView.ID, HistogramView.ID);
194 }
195
196 /**
197 * Test 3 views. No overlap. The callstack is not aligned with the
198 * histogram, the histogram is moved, we check that the callstack does NOT
199 * follow
200 */
201 @Test
202 public void testNotOverlappingHistogramMove() {
203 fBot = new SWTWorkbenchBot();
204 testNonOverlap(HistogramView.ID, CallStackView.ID);
205 }
206
207 /**
208 * Test 3 views. No overlap. The callstack is not aligned with the
209 * histogram, the callstack is moved, we check that the histogram does NOT
210 * follow
211 */
212 @Test
213 public void testNotOverlappingCallstackMove() {
214 fBot = new SWTWorkbenchBot();
215 testNonOverlap(CallStackView.ID, HistogramView.ID);
216 }
217
218 private static void testNonOverlap(String vId1, String vId2) {
219 final int offset = 100;
220 // switch to the proper perspective and wait for views to align
221 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory3.ID);
222 SWTBotUtils.waitForJobs();
223 SWTBotUtils.delay(SYNC_DELAY);
224 // get views
225 SWTBotView masterView = fBot.viewById(vId1);
226 SWTBotView slaveView = fBot.viewById(vId2);
227 final Sash slaveSash = slaveView.bot().widget(SASH_MATCHER, 0);
228 SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
229 Point before = slaveSashBot.getPoint();
230 // move master and wait for slaves to follow
231 drag(masterView, offset);
232 SWTBotUtils.waitForJobs();
233 SWTBotUtils.delay(SYNC_DELAY);
234 // verify that the slave did not follow
235 assertEquals(before, slaveSashBot.getPoint());
236 // put everything back the way it was
237 drag(masterView, -offset);
238 SWTBotUtils.delay(SYNC_DELAY);
239 }
240
241 private static final class SashMatcher extends BaseMatcher<Sash> {
242 @Override
243 public boolean matches(Object item) {
244 return (item instanceof Sash);
245 }
246
247 @Override
248 public void describeTo(Description description) {
249 }
250 }
251
252 private static final class SashFormMatcher extends BaseMatcher<SashForm> {
253 @Override
254 public boolean matches(Object item) {
255 return (item instanceof SashForm);
256 }
257
258 @Override
259 public void describeTo(Description description) {
260 }
261 }
262
263 /**
264 * Simulate a drag operation using "setWeights"
265 */
266 private static void drag(final SWTBotView view, final int offset) {
267 // this is the final sash form
268 final SashForm sashForm = view.bot().widget(new SashFormMatcher(), 0);
269 assertNotNull(sashForm);
270 // resize widgets using sashform
271 UIThreadRunnable.syncExec(new VoidResult() {
272 @Override
273 public void run() {
274 int[] originalWeights = sashForm.getWeights();
275 int[] newWeights = Arrays.copyOf(originalWeights, originalWeights.length);
276 newWeights[0] += offset;
277 newWeights[1] -= offset;
278 sashForm.setWeights(newWeights);
279 sashForm.getParent().layout();
280 }
281 });
282 // send update signals
283 UIThreadRunnable.syncExec(new VoidResult() {
284 @Override
285 public void run() {
286 sashForm.getChildren()[0].notifyListeners(SWT.Resize, null);
287 sashForm.getChildren()[1].notifyListeners(SWT.Resize, null);
288 /*
289 * This one is the most important, the previous two are added to
290 * be a good citizen, this event (selection) is the one that
291 * triggers an alignment
292 */
293 sashForm.getChildren()[2].notifyListeners(SWT.Selection, null);
294 }
295 });
296 }
297
298 private static void testOverlap(String masterView, String slaveView) {
299 final int offset = 100;
300 final int delta = offset / 2;
301 // wait for the perspective switch to propagate alignments
302 SWTBotUtils.waitForJobs();
303 SWTBotUtils.delay(SYNC_DELAY);
304 // select master and slave parts to observe
305 SWTBotView masterViewBot = fBot.viewById(masterView);
306 final Sash masterSash = masterViewBot.bot().widget(SASH_MATCHER, 0);
307 SWTBotSash masterSashBot = new SWTBotSash(masterSash, null);
308
309 SWTBotView slaveViewBot = fBot.viewById(slaveView);
310 final Sash slaveSash = slaveViewBot.bot().widget(SASH_MATCHER, 0);
311 SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
312
313 double masterOriginalSashX = masterSashBot.getPoint().x;
314 // check that the views are already aligned
315 assertEquals("Approx align", masterOriginalSashX, slaveSashBot.getPoint().x, delta);
316 // move sash and wait for alignment
317 drag(masterViewBot, offset);
318 SWTBotUtils.waitForJobs();
319 SWTBotUtils.delay(SYNC_DELAY);
320 // check results
321 double masterNewSashX = masterSashBot.getPoint().x;
322 assertEquals("Approx align", masterNewSashX, slaveSashBot.getPoint().x, delta);
323 assertEquals(masterOriginalSashX, masterNewSashX - offset, delta);
324 // put things back the way they were
325 drag(masterViewBot, -offset);
326 SWTBotUtils.delay(SYNC_DELAY);
327 }
328
329 /**
330 * Histogram, Callstack and timechart aligned but in different sites
331 */
332 public static class AlignPerspectiveFactory1 implements IPerspectiveFactory {
333
334 /** The Perspective ID */
335 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.1"; //$NON-NLS-1$
336
337 @Override
338 public void createInitialLayout(IPageLayout layout) {
339 if (layout == null) {
340 return;
341 }
342
343 // Editor area
344 layout.setEditorAreaVisible(true);
345
346 // Editor area
347 layout.setEditorAreaVisible(true);
348
349 // Create the top left folder
350 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
351 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
352
353 // Create the top right folder
354 IFolderLayout topRightFolder = layout.createFolder("topRightFolder", IPageLayout.BOTTOM, 0.30f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
355 topRightFolder.addView(HistogramView.ID);
356
357 // Create the middle right folder
358 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.50f, "topRightFolder"); //$NON-NLS-1$
359 middleRightFolder.addView(CallStackView.ID);
360
361 // Create the bottom right folder
362 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
363 bottomRightFolder.addView(TimeChartView.ID);
364
365 // Populate menus, etc
366 layout.addPerspectiveShortcut(ID);
367 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
368 }
369
370 }
371
372 /**
373 * Timechart and Histogram share a site, all views aligned
374 */
375 public static class AlignPerspectiveFactory2 implements IPerspectiveFactory {
376
377 /** The Perspective ID */
378 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.2"; //$NON-NLS-1$
379
380 @Override
381 public void createInitialLayout(IPageLayout layout) {
382 if (layout == null) {
383 return;
384 }
385
386 // Editor area
387 layout.setEditorAreaVisible(true);
388
389 // Editor area
390 layout.setEditorAreaVisible(true);
391
392 // Create the top left folder
393 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
394 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
395
396 // Create the middle right folder
397 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.40f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
398 middleRightFolder.addView(HistogramView.ID);
399 middleRightFolder.addView(TimeChartView.ID);
400
401 // Create the bottom right folder
402 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
403 bottomRightFolder.addView(CallStackView.ID);
404
405 // Populate menus, etc
406 layout.addPerspectiveShortcut(ID);
407 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
408 }
409
410 }
411
412 /**
413 * Histogram and timechart aligned, callstack not aligned
414 */
415 public static class AlignPerspectiveFactory3 implements IPerspectiveFactory {
416
417 /** The Perspective ID */
418 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.3"; //$NON-NLS-1$
419
420 @Override
421 public void createInitialLayout(IPageLayout layout) {
422 if (layout == null) {
423 return;
424 }
425
426 // Editor area
427 layout.setEditorAreaVisible(true);
428
429 // Editor area
430 layout.setEditorAreaVisible(true);
431
432 // Create the top left folder
433 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
434 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
435
436 IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.5f, "topLeftFolder"); //$NON-NLS-1$
437 bottomLeftFolder.addView(CallStackView.ID);
438
439 // Create the middle right folder
440 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.40f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
441 middleRightFolder.addView(HistogramView.ID);
442
443 // Create the bottom right folder
444 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
445 bottomRightFolder.addView(TimeChartView.ID);
446
447 // Populate menus, etc
448 layout.addPerspectiveShortcut(ID);
449 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
450 }
451
452 }
453
454}
This page took 0.046274 seconds and 5 git commands to generate.