swtbot: Add SWTBotTimeGraph and update SWTBotSash
[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, 2016 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
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Map.Entry;
22
23 import org.apache.log4j.ConsoleAppender;
24 import org.apache.log4j.Logger;
25 import org.apache.log4j.SimpleLayout;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.graphics.Rectangle;
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.junit.SWTBotJunit4ClassRunner;
32 import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
33 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
34 import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
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.SWTBotTimeGraph;
39 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
40 import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
41 import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
42 import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;
43 import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartView;
44 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
45 import org.eclipse.ui.IFolderLayout;
46 import org.eclipse.ui.IPageLayout;
47 import org.eclipse.ui.IPerspectiveFactory;
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54
55 /**
56 * Test common time axis for views
57 *
58 * @author Matthew Khouzam
59 */
60 @RunWith(SWTBotJunit4ClassRunner.class)
61 public class TmfAlignTimeAxisTest {
62
63 /**
64 * wait for throttler (2x the throttler time)
65 */
66 private static final int SYNC_DELAY = 1000;
67 private static final String TRACE_START = "<trace>";
68 private static final String EVENT_BEGIN = "<event timestamp=\"";
69 private static final String EVENT_MIDDLE = " \" name=\"event\"><field name=\"field\" value=\"";
70 private static final String EVENT_END = "\" type=\"int\" />" + "</event>";
71 private static final String TRACE_END = "</trace>";
72
73 private static final String PROJET_NAME = "TestAxisAlignment";
74 private static final int NUM_EVENTS = 100;
75 /**
76 * Using a small ratio for the editor so that other views have enough space
77 * to be drawn, even when a low screen resolution is used.
78 */
79 private static final float EDITOR_AREA_RATIO = 0.10f;
80
81 /** The Log4j logger instance. */
82 private static final Logger fLogger = Logger.getRootLogger();
83 private static SWTWorkbenchBot fBot;
84
85 private static String makeEvent(int ts, int val) {
86 return EVENT_BEGIN + Integer.toString(ts) + EVENT_MIDDLE + Integer.toString(val) + EVENT_END + "\n";
87 }
88
89 private static File fLocation;
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 WaitUtils.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, callstack and timechart are
156 * aligned. The histogram is moved, we check that the callstack and
157 * timechart follow.
158 */
159 @Test
160 public void testMoveHistogramOthersFollow() {
161 fBot = new SWTWorkbenchBot();
162 switchToPerspective(AlignPerspectiveFactory1.ID);
163 testAligned(HistogramView.ID, CallStackView.ID, TimeChartView.ID);
164 }
165
166 /**
167 * Test 3 views, none overlap, the histogram, callstack and timechart are
168 * aligned. The callstack is moved, we check that the histogram and
169 * timechart follow.
170 */
171 @Test
172 public void testMoveCallstackOthersFollow() {
173 fBot = new SWTWorkbenchBot();
174 switchToPerspective(AlignPerspectiveFactory1.ID);
175 testAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
176 }
177
178 /**
179 * Test 3 views, overlap on the resizing view. The histogram and timechart
180 * are overlapping, and the callstack is aligned. The histogram is moved, we
181 * check that the callstack follows. The hidden timechart is not checked.
182 */
183 @Test
184 public void testOverlappingHistogramMove() {
185 fBot = new SWTWorkbenchBot();
186 switchToPerspective(AlignPerspectiveFactory2.ID);
187 testAligned(HistogramView.ID, CallStackView.ID);
188 }
189
190 /**
191 * Test 3 views, overlap on the resizing view. The histogram and timechart
192 * are overlapping, and the callstack is aligned. The callstack is moved, we
193 * check that the histogram follows. The hidden timechart is not checked.
194 */
195 @Test
196 public void testOverlappingCallstackMove() {
197 fBot = new SWTWorkbenchBot();
198 switchToPerspective(AlignPerspectiveFactory2.ID);
199 testAligned(CallStackView.ID, HistogramView.ID);
200 }
201
202 /**
203 * Test 3 views. No overlap. The histogram and timechart are aligned, but
204 * the callstack is not aligned. The histogram is moved, we check that the
205 * timechart follows and that the callstack does NOT follow.
206 */
207 @Test
208 public void testNotOverlappingHistogramMove() {
209 fBot = new SWTWorkbenchBot();
210 switchToPerspective(AlignPerspectiveFactory3.ID);
211 testAligned(HistogramView.ID, TimeChartView.ID);
212 testNotAligned(HistogramView.ID, CallStackView.ID);
213 }
214
215 /**
216 * Test 3 views. No overlap. The histogram and timechart are aligned, but
217 * the callstack is not aligned. The callstack is moved, we check that the
218 * histogram and timechart do NOT follow.
219 */
220 @Test
221 public void testNotOverlappingCallstackMove() {
222 fBot = new SWTWorkbenchBot();
223 switchToPerspective(AlignPerspectiveFactory3.ID);
224 testNotAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
225 }
226
227 private static void switchToPerspective(String id) {
228 // switch to the proper perspective and wait for views to align
229 SWTBotUtils.switchToPerspective(id);
230 WaitUtils.waitForJobs();
231 SWTBotUtils.delay(SYNC_DELAY);
232 }
233
234 private static AbstractSWTBot<?> getAlignmentControl(String viewId) {
235 SWTBotView viewBot = fBot.viewById(viewId);
236 switch (viewId) {
237 case HistogramView.ID:
238 case CallStackView.ID:
239 return new SWTBotSash(viewBot.bot().widget(WidgetOfType.widgetOfType(Sash.class)));
240 case TimeChartView.ID:
241 return new SWTBotTimeGraph(viewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class)));
242 default:
243 return null;
244 }
245 }
246
247 private static void testAligned(String masterView, String... slaveViews) {
248 final int offset = 50;
249
250 // select alignment controls and get their original alignment positions
251 AbstractSWTBot<?> master = getAlignmentControl(masterView);
252 int masterOrigin = getAlignmentPosition(master);
253 Map<AbstractSWTBot<?>, Integer> slaveMap = new HashMap<>();
254 for (String slaveView : slaveViews) {
255 AbstractSWTBot<?> slave = getAlignmentControl(slaveView);
256 int slaveOrigin = getAlignmentPosition(slave);
257 slaveMap.put(slave, slaveOrigin);
258 }
259
260 // change master position
261 setAlignmentPosition(master, masterOrigin + offset);
262
263 // check resulting alignment positions, slaves follow
264 assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
265 for (Entry<AbstractSWTBot<?>, Integer> slave : slaveMap.entrySet()) {
266 assertEquals(slave.getValue() + offset, getAlignmentPosition(slave.getKey()), 2);
267 }
268
269 // reset original alignment position
270 setAlignmentPosition(master, masterOrigin);
271 }
272
273 private static void testNotAligned(String masterView, String... nonSlaveViews) {
274 final int offset = 50;
275
276 // select alignment controls and get their original alignment positions
277 AbstractSWTBot<?> master = getAlignmentControl(masterView);
278 int masterOrigin = getAlignmentPosition(master);
279 Map<AbstractSWTBot<?>, Integer> nonSlaveMap = new HashMap<>();
280 for (String nonSlaveView : nonSlaveViews) {
281 AbstractSWTBot<?> nonSlave = getAlignmentControl(nonSlaveView);
282 int nonSlaveOrigin = getAlignmentPosition(nonSlave);
283 nonSlaveMap.put(nonSlave, nonSlaveOrigin);
284 }
285
286 // change master position
287 setAlignmentPosition(master, masterOrigin + offset);
288
289 // check resulting alignment positions, non-slaves do not follow
290 assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
291 for (Entry<AbstractSWTBot<?>, Integer> nonSlave : nonSlaveMap.entrySet()) {
292 assertEquals((int) nonSlave.getValue(), getAlignmentPosition(nonSlave.getKey()));
293 }
294
295 // reset original alignment position
296 setAlignmentPosition(master, masterOrigin);
297 }
298
299 private static int getAlignmentPosition(AbstractSWTBot<?> control) {
300 if (control instanceof SWTBotSash) {
301 Rectangle bounds = ((SWTBotSash) control).getBounds();
302 return bounds.x + bounds.width / 2;
303 } else if (control instanceof SWTBotTimeGraph) {
304 return ((SWTBotTimeGraph) control).getNameSpace();
305 }
306 return 0;
307 }
308
309 private static void setAlignmentPosition(AbstractSWTBot<?> control, int position) {
310 if (control instanceof SWTBotSash) {
311 SWTBotSash sash = (SWTBotSash) control;
312 Rectangle bounds = sash.getBounds();
313 Point dst = new Point(position, bounds.y + bounds.height / 2);
314 sash.drag(dst);
315 } else if (control instanceof SWTBotTimeGraph) {
316 ((SWTBotTimeGraph) control).setNameSpace(position);
317 }
318 // wait for alignment
319 WaitUtils.waitForJobs();
320 SWTBotUtils.delay(SYNC_DELAY);
321 }
322
323 /**
324 * Histogram, Callstack and timechart aligned but in different sites
325 */
326 public static class AlignPerspectiveFactory1 implements IPerspectiveFactory {
327
328 /** The Perspective ID */
329 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.1"; //$NON-NLS-1$
330
331 @Override
332 public void createInitialLayout(IPageLayout layout) {
333 if (layout == null) {
334 return;
335 }
336
337 // Editor area
338 layout.setEditorAreaVisible(true);
339
340 // Editor area
341 layout.setEditorAreaVisible(true);
342
343 // Create the top left folder
344 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
345 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
346
347 // Create the top right folder
348 IFolderLayout topRightFolder = layout.createFolder("topRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
349 topRightFolder.addView(HistogramView.ID);
350
351 // Create the middle right folder
352 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.50f, "topRightFolder"); //$NON-NLS-1$
353 middleRightFolder.addView(CallStackView.ID);
354
355 // Create the bottom right folder
356 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
357 bottomRightFolder.addView(TimeChartView.ID);
358
359 // Populate menus, etc
360 layout.addPerspectiveShortcut(ID);
361 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
362 }
363
364 }
365
366 /**
367 * Timechart and Histogram share a site, all views aligned
368 */
369 public static class AlignPerspectiveFactory2 implements IPerspectiveFactory {
370
371 /** The Perspective ID */
372 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.2"; //$NON-NLS-1$
373
374 @Override
375 public void createInitialLayout(IPageLayout layout) {
376 if (layout == null) {
377 return;
378 }
379
380 // Editor area
381 layout.setEditorAreaVisible(true);
382
383 // Editor area
384 layout.setEditorAreaVisible(true);
385
386 // Create the top left folder
387 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
388 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
389
390 // Create the middle right folder
391 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
392 middleRightFolder.addView(HistogramView.ID);
393 middleRightFolder.addView(TimeChartView.ID);
394
395 // Create the bottom right folder
396 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
397 bottomRightFolder.addView(CallStackView.ID);
398
399 // Populate menus, etc
400 layout.addPerspectiveShortcut(ID);
401 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
402 }
403
404 }
405
406 /**
407 * Histogram and timechart aligned, callstack not aligned
408 */
409 public static class AlignPerspectiveFactory3 implements IPerspectiveFactory {
410
411 /** The Perspective ID */
412 public static final String ID = "org.eclipse.linuxtools.tmf.test.align.3"; //$NON-NLS-1$
413
414 @Override
415 public void createInitialLayout(IPageLayout layout) {
416 if (layout == null) {
417 return;
418 }
419
420 // Editor area
421 layout.setEditorAreaVisible(true);
422
423 // Editor area
424 layout.setEditorAreaVisible(true);
425
426 // Create the top left folder
427 IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
428 topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
429
430 IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.5f, "topLeftFolder"); //$NON-NLS-1$
431 bottomLeftFolder.addView(CallStackView.ID);
432
433 // Create the middle right folder
434 IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, EDITOR_AREA_RATIO, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
435 middleRightFolder.addView(HistogramView.ID);
436
437 // Create the bottom right folder
438 IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder"); //$NON-NLS-1$ //$NON-NLS-2$
439 bottomRightFolder.addView(TimeChartView.ID);
440
441 // Populate menus, etc
442 layout.addPerspectiveShortcut(ID);
443 layout.addNewWizardShortcut(NewTmfProjectWizard.ID);
444 }
445
446 }
447
448 }
This page took 0.040886 seconds and 5 git commands to generate.