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