d57be3115910c77841c96514d68b7055df093cca
[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 }
152
153 /**
154 * Test 3 views, none overlap, the histogram, the callstack and the
155 * timechart are aligned, the histogram is moved, callstack and timechart
156 * follow
157 */
158 @Test
159 public void testMoveHistogramCallstackFollows() {
160 fBot = new SWTWorkbenchBot();
161 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
162 testOverlap(HistogramView.ID, CallStackView.ID);
163 }
164
165 /**
166 * Test 3 views, none overlap, the histogram, the callstack and the
167 * timechart are aligned, the callstack is moved, histogram and timechart
168 * follow
169 */
170 @Test
171 public void testMoveCallstackHistogramFollows() {
172 fBot = new SWTWorkbenchBot();
173 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
174 testOverlap(CallStackView.ID, HistogramView.ID);
175 }
176
177 /**
178 * Test 3 views, overlap on the resizing view. The timechart and callstack
179 * are overlapping. Test that when the histogram moves, the timechart
180 * follows. Hidden views are not tested as their state does not matter until
181 * they are displayed
182 */
183 @Test
184 public void testOverlappingHistogramMove() {
185 fBot = new SWTWorkbenchBot();
186 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
187 testOverlap(HistogramView.ID, CallStackView.ID);
188 }
189
190 /**
191 * Test 3 views, overlap on the resizing view. The timechart and callstack
192 * are overlapping. Test that when the timechart moves, the histogram
193 * follows. Hidden views are not tested as their state does not matter until
194 * they are displayed
195 */
196 @Test
197 public void testOverlappingTimechartMove() {
198 fBot = new SWTWorkbenchBot();
199 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
200 testOverlap(CallStackView.ID, HistogramView.ID);
201 }
202
203 /**
204 * Test 3 views. No overlap. The callstack is not aligned with the
205 * histogram, the histogram is moved, we check that the callstack does NOT
206 * follow
207 */
208 @Test
209 public void testNotOverlappingHistogramMove() {
210 fBot = new SWTWorkbenchBot();
211 testNonOverlap(HistogramView.ID, CallStackView.ID);
212 }
213
214 /**
215 * Test 3 views. No overlap. The callstack is not aligned with the
216 * histogram, the callstack is moved, we check that the histogram does NOT
217 * follow
218 */
219 @Test
220 public void testNotOverlappingCallstackMove() {
221 fBot = new SWTWorkbenchBot();
222 testNonOverlap(CallStackView.ID, HistogramView.ID);
223 }
224
225 private static void testNonOverlap(String vId1, String vId2) {
226 final int offset = 100;
227 // switch to the proper perspective and wait for views to align
228 SWTBotUtils.switchToPerspective(AlignPerspectiveFactory3.ID);
229 SWTBotUtils.waitForJobs();
230 SWTBotUtils.delay(SYNC_DELAY);
231 // get views
232 SWTBotView masterView = fBot.viewById(vId1);
233 SWTBotView slaveView = fBot.viewById(vId2);
234 final Sash slaveSash = slaveView.bot().widget(SASH_MATCHER, 0);
235 SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
236 Point before = slaveSashBot.getPoint();
237 // move master and wait for slaves to follow
238 drag(masterView, offset);
239 SWTBotUtils.waitForJobs();
240 SWTBotUtils.delay(SYNC_DELAY);
241 // verify that the slave did not follow
242 assertEquals(before, slaveSashBot.getPoint());
243 // put everything back the way it was
244 drag(masterView, -offset);
245 SWTBotUtils.delay(SYNC_DELAY);
246 }
247
248 private static final class SashMatcher extends BaseMatcher<Sash> {
249 @Override
250 public boolean matches(Object item) {
251 return (item instanceof Sash);
252 }
253
254 @Override
255 public void describeTo(Description description) {
256 }
257 }
258
259 private static final class SashFormMatcher extends BaseMatcher<SashForm> {
260 @Override
261 public boolean matches(Object item) {
262 return (item instanceof SashForm);
263 }
264
265 @Override
266 public void describeTo(Description description) {
267 }
268 }
269
270 /**
271 * Simulate a drag operation using "setWeights"
272 */
273 private static void drag(final SWTBotView view, final int offset) {
274 // this is the final sash form
275 final SashForm sashForm = view.bot().widget(new SashFormMatcher(), 0);
276 assertNotNull(sashForm);
277 // resize widgets using sashform
278 UIThreadRunnable.syncExec(new VoidResult() {
279 @Override
280 public void run() {
281 int[] originalWeights = sashForm.getWeights();
282 int[] newWeights = Arrays.copyOf(originalWeights, originalWeights.length);
283 newWeights[0] += offset;
284 newWeights[1] -= offset;
285 sashForm.setWeights(newWeights);
286 sashForm.getParent().layout();
287 }
288 });
289 // send update signals
290 UIThreadRunnable.syncExec(new VoidResult() {
291 @Override
292 public void run() {
293 sashForm.getChildren()[0].notifyListeners(SWT.Resize, null);
294 sashForm.getChildren()[1].notifyListeners(SWT.Resize, null);
295 /*
296 * This one is the most important, the previous two are added to
297 * be a good citizen, this event (selection) is the one that
298 * triggers an alignment
299 */
300 sashForm.getChildren()[2].notifyListeners(SWT.Selection, null);
301 }
302 });
303 }
304
305 private static void testOverlap(String masterView, String slaveView) {
306 final int offset = 100;
307 final int delta = offset / 2;
308 // wait for the perspective switch to propagate alignments
309 SWTBotUtils.waitForJobs();
310 SWTBotUtils.delay(SYNC_DELAY);
311 // select master and slave parts to observe
312 SWTBotView masterViewBot = fBot.viewById(masterView);
313 final Sash masterSash = masterViewBot.bot().widget(SASH_MATCHER, 0);
314 SWTBotSash masterSashBot = new SWTBotSash(masterSash, null);
315
316 SWTBotView slaveViewBot = fBot.viewById(slaveView);
317 final Sash slaveSash = slaveViewBot.bot().widget(SASH_MATCHER, 0);
318 SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
319
320 double masterOriginalSashX = masterSashBot.getPoint().x;
321 // check that the views are already aligned
322 assertEquals("Approx align", masterOriginalSashX, slaveSashBot.getPoint().x, delta);
323 // move sash and wait for alignment
324 drag(masterViewBot, offset);
325 SWTBotUtils.waitForJobs();
326 SWTBotUtils.delay(SYNC_DELAY);
327 // check results
328 double masterNewSashX = masterSashBot.getPoint().x;
329 assertEquals("Approx align", masterNewSashX, slaveSashBot.getPoint().x, delta);
330 assertEquals(masterOriginalSashX, masterNewSashX - offset, delta);
331 // put things back the way they were
332 drag(masterViewBot, -offset);
333 SWTBotUtils.delay(SYNC_DELAY);
334 }
335
336 /**
337 * Histogram, Callstack and timechart aligned but in different sites
338 */
339 public static class AlignPerspectiveFactory1 implements IPerspectiveFactory {
340
341 /** The Perspective ID */
342 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.1"; //$NON-NLS-1$
343
344 @Override
345 public void createInitialLayout(IPageLayout layout) {
346 if (layout == null) {
347 return;
348 }
349
350 // Editor area
351 layout.setEditorAreaVisible(true);
352
353 // Editor area
354 layout.setEditorAreaVisible(true);
355
356 // Create the top left folder
357 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
358 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
359
360 // Create the top right folder
361 IFolderLayout topRightFolder = layout.createFolder("topRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
362 topRightFolder.addView(HistogramView.ID);
363
364 // Create the middle right folder
365 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.50f, "topRightFolder"); //$NON-NLS-1$
366 middleRightFolder.addView(CallStackView.ID);
367
368 // Create the bottom right folder
369 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
370 bottomRightFolder.addView(TimeChartView.ID);
371
372 // Populate menus, etc
373 layout.addPerspectiveShortcut(ID);
374 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
375 }
376
377 }
378
379 /**
380 * Timechart and Histogram share a site, all views aligned
381 */
382 public static class AlignPerspectiveFactory2 implements IPerspectiveFactory {
383
384 /** The Perspective ID */
385 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.2"; //$NON-NLS-1$
386
387 @Override
388 public void createInitialLayout(IPageLayout layout) {
389 if (layout == null) {
390 return;
391 }
392
393 // Editor area
394 layout.setEditorAreaVisible(true);
395
396 // Editor area
397 layout.setEditorAreaVisible(true);
398
399 // Create the top left folder
400 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
401 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
402
403 // Create the middle right folder
404 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
405 middleRightFolder.addView(HistogramView.ID);
406 middleRightFolder.addView(TimeChartView.ID);
407
408 // Create the bottom right folder
409 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
410 bottomRightFolder.addView(CallStackView.ID);
411
412 // Populate menus, etc
413 layout.addPerspectiveShortcut(ID);
414 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
415 }
416
417 }
418
419 /**
420 * Histogram and timechart aligned, callstack not aligned
421 */
422 public static class AlignPerspectiveFactory3 implements IPerspectiveFactory {
423
424 /** The Perspective ID */
425 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.3"; //$NON-NLS-1$
426
427 @Override
428 public void createInitialLayout(IPageLayout layout) {
429 if (layout == null) {
430 return;
431 }
432
433 // Editor area
434 layout.setEditorAreaVisible(true);
435
436 // Editor area
437 layout.setEditorAreaVisible(true);
438
439 // Create the top left folder
440 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
441 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
442
443 IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.5f, "topLeftFolder"); //$NON-NLS-1$
444 bottomLeftFolder.addView(CallStackView.ID);
445
446 // Create the middle right folder
447 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
448 middleRightFolder.addView(HistogramView.ID);
449
450 // Create the bottom right folder
451 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
452 bottomRightFolder.addView(TimeChartView.ID);
453
454 // Populate menus, etc
455 layout.addPerspectiveShortcut(ID);
456 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
457 }
458
459 }
460
461 }
This page took 0.041184 seconds and 4 git commands to generate.