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