1 /*******************************************************************************
2 * Copyright (c) 2016 École Polytechnique de Montréal
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.perf
.views
;
13 import java
.util
.Collection
;
15 import org
.eclipse
.jdt
.annotation
.NonNull
;
16 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
17 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
18 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
19 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
20 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
21 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
22 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
23 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalManager
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfWindowRangeUpdatedSignal
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
28 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
29 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
31 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
32 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
33 import org
.eclipse
.tracecompass
.tmf
.ui
.tests
.shared
.WaitUtils
;
34 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.timegraph
.AbstractTimeGraphView
;
35 import org
.eclipse
.ui
.IWorkbenchPart
;
36 import org
.junit
.After
;
37 import org
.junit
.Before
;
38 import org
.junit
.runner
.RunWith
;
41 * Base class to test the responsiveness of any views. The main method of this
42 * class, {@link #runTestWithTrace(String, String, Collection)}, will receive a
43 * collection of view IDs. For each view, the trace under test will be navigated
44 * when only the view is opened (closing all other listed views, all other
45 * opened views will remain opened) and also when all the views are opened
46 * simultaneously. In this last case, it will rename the trace so that events
47 * from when all the views are opened can be listed separately.
49 * @author Geneviève Bastien
51 @RunWith(SWTBotJunit4ClassRunner
.class)
52 public abstract class ViewsResponseTest
{
54 private static final String PROJECT_NAME
= "test";
56 private final @NonNull SWTWorkbenchBot fBot
= new SWTWorkbenchBot();
59 * Specific tests will prepare the workspace for the run. For example,
60 * concrete classes can open perspectives, open views, prepare the layout,
63 protected abstract void prepareWorkspace();
69 public void beforeClass() {
71 SWTBotUtils
.initialize();
72 Thread
.currentThread().setName("SWTBotTest");
73 /* set up for swtbot */
74 SWTBotPreferences
.TIMEOUT
= 60000; /* 60 second timeout */
75 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
76 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
77 SWTBotUtils
.closeView("welcome", bot
);
78 /* Prepare the workspace */
80 /* Finish waiting for eclipse to load */
81 WaitUtils
.waitForJobs();
84 SWTBotUtils
.createProject(PROJECT_NAME
);
88 * Deletes the project from the workspace
91 public void cleanUp() {
92 /* Close editors and delete project */
93 fBot
.closeAllEditors();
94 SWTBotUtils
.deleteProject(PROJECT_NAME
, fBot
);
97 private void closeAllViews(Collection
<String
> viewIDs
) {
98 viewIDs
.stream().forEach(id
-> {
99 SWTBotUtils
.openView(id
);
100 SWTBotUtils
.closeViewById(id
, fBot
);
105 * This method will be run when all views are still close, but the trace has
106 * been opened. For instance, if any analysis module need to have completed
107 * before the test, it can wait for completion here.
110 * The trace used for this test
112 protected abstract void beforeRunningTest(ITmfTrace trace
);
115 * Run this swtbot with the trace specified at the specified path. The trace
116 * will be navigate for each view ID separately, then, after renaming the
117 * trace, with all the views opened. After this test, all views will be
121 * The full path of the trace to open
123 * The trace type of the trace to open
125 * The IDs of the views to test.
127 protected void runTestWithTrace(String tracePath
, String traceType
, Collection
<String
> viewIDs
) {
128 closeAllViews(viewIDs
);
130 String traceName
= tracePath
.substring(tracePath
.lastIndexOf(File
.separator
, tracePath
.length() - 2) + 1, tracePath
.length() - 1);
131 SWTBotUtils
.openTrace(PROJECT_NAME
, tracePath
, traceType
);
133 // Make sure all the analyses we'll need are done
134 ITmfTrace trace
= TmfTraceManager
.getInstance().getActiveTrace();
135 beforeRunningTest(trace
);
136 WaitUtils
.waitForJobs();
140 for (String viewID
: viewIDs
) {
141 SWTBotUtils
.openView(viewID
);
142 view
= fBot
.viewById(viewID
);
144 SWTBotUtils
.closeViewById(viewID
, fBot
);
148 fBot
.closeAllEditors();
150 // If there is only 1 view to test, return
151 if (viewIDs
.size() <= 1) {
153 closeAllViews(viewIDs
);
157 // Open all the views
159 for (String viewID
: viewIDs
) {
160 SWTBotUtils
.openView(viewID
);
162 view
= fBot
.viewById(viewID
);
166 // Rename the trace, so the results appear under another trace and
168 renameTrace(traceName
, traceName
+ " full");
172 fBot
.closeAllEditors();
175 closeAllViews(viewIDs
);
178 private void renameTrace(String oldName
, String newName
) {
180 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, PROJECT_NAME
), oldName
);
182 traceItem
.contextMenu().menu("Rename...").click();
183 final String RENAME_TRACE_DIALOG_TITLE
= "Rename Trace";
184 fBot
.waitUntil(Conditions
.shellIsActive(RENAME_TRACE_DIALOG_TITLE
));
185 SWTBotShell shell
= fBot
.shell(RENAME_TRACE_DIALOG_TITLE
);
186 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
187 text
.setText(newName
);
188 shell
.bot().button("OK").click();
189 fBot
.waitUntil(Conditions
.shellCloses(shell
));
190 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
192 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, PROJECT_NAME
), newName
);
193 copiedItem
.contextMenu().menu("Open").click();
196 } catch (InterruptedException e
) {
198 WaitUtils
.waitForJobs();
201 // TODO: Add some vertical scrollings. With eventual 2D queries, that will
202 // be something to test as well
203 private void navigateTrace(SWTBotView view
) {
204 TmfTimeRange originalWindowRange
= TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange();
205 TmfTimeRange selectionRange
= TmfTraceManager
.getInstance().getCurrentTraceContext().getSelectionRange();
206 IWorkbenchPart part
= view
.getViewReference().getPart(false);
208 // Set the time range to the full trace range
209 ITmfTrace activeTrace
= TmfTraceManager
.getInstance().getActiveTrace();
210 TmfTimeRange fullRange
= new TmfTimeRange(activeTrace
.getStartTime(), activeTrace
.getEndTime());
211 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, fullRange
));
212 waitViewReady(part
, selectionRange
, fullRange
.getEndTime());
213 TmfTimeRange windowRange
= fullRange
;
215 // Zoom in 10 times 15 percent of the range and wait for the view to be
217 for (int i
= 0; i
< 10; i
++) {
218 double delta
= (windowRange
.getEndTime().getValue() - windowRange
.getStartTime().getValue()) * 0.15;
219 TmfTimeRange newWindowRange
= new TmfTimeRange(TmfTimestamp
.fromNanos((long) (windowRange
.getStartTime().toNanos() + delta
)), TmfTimestamp
.fromNanos((long) (windowRange
.getEndTime().toNanos() - delta
)));
220 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, newWindowRange
));
221 windowRange
= newWindowRange
;
222 waitViewReady(part
, selectionRange
, newWindowRange
.getEndTime());
225 // At this zoom level, go to the end
226 long scrollTime
= (windowRange
.getEndTime().toNanos() - windowRange
.getStartTime().toNanos()) / 2;
227 windowRange
= new TmfTimeRange(TmfTimestamp
.fromNanos(fullRange
.getEndTime().toNanos() - (2 * scrollTime
)), fullRange
.getEndTime());
228 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, windowRange
));
229 waitViewReady(part
, selectionRange
, windowRange
.getEndTime());
231 // Scroll back horizontally half the range at a time
232 for (int i
= 0; i
< 10; i
++) {
233 TmfTimeRange newWindowRange
= new TmfTimeRange(TmfTimestamp
.fromNanos(windowRange
.getStartTime().toNanos() - scrollTime
), TmfTimestamp
.fromNanos(windowRange
.getEndTime().toNanos() - scrollTime
));
234 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, newWindowRange
));
235 windowRange
= newWindowRange
;
236 waitViewReady(part
, selectionRange
, newWindowRange
.getEndTime());
239 // then go all the way back to the beginning
240 windowRange
= new TmfTimeRange(fullRange
.getStartTime(), TmfTimestamp
.fromNanos(fullRange
.getStartTime().toNanos() + scrollTime
));
241 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, windowRange
));
242 waitViewReady(part
, selectionRange
, windowRange
.getEndTime());
244 // and zoom out again
245 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, fullRange
));
246 waitViewReady(part
, selectionRange
, fullRange
.getEndTime());
248 // Reset the original window range
249 TmfSignalManager
.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, originalWindowRange
));
250 waitViewReady(part
, selectionRange
, originalWindowRange
.getEndTime());
253 private void waitViewReady(IWorkbenchPart part
, @NonNull TmfTimeRange selectionRange
, @NonNull ITmfTimestamp visibleTime
) {
254 if (part
instanceof AbstractTimeGraphView
) {
255 fBot
.waitUntil(ConditionHelpers
.timeGraphIsReadyCondition((AbstractTimeGraphView
) part
, selectionRange
, visibleTime
));
257 // TODO Add conditions for other kind of views