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 | ||
12 | import java.io.File; | |
13 | import java.util.Collection; | |
14 | ||
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; | |
f0beeb4a | 33 | import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils; |
143e0680 GB |
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; | |
39 | ||
40 | /** | |
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. | |
48 | * | |
49 | * @author Geneviève Bastien | |
50 | */ | |
51 | @RunWith(SWTBotJunit4ClassRunner.class) | |
52 | public abstract class ViewsResponseTest { | |
53 | ||
54 | private static final String PROJECT_NAME = "test"; | |
55 | ||
56 | private final @NonNull SWTWorkbenchBot fBot = new SWTWorkbenchBot(); | |
57 | ||
58 | /** | |
59 | * Specific tests will prepare the workspace for the run. For example, | |
60 | * concrete classes can open perspectives, open views, prepare the layout, | |
61 | * etc. | |
62 | */ | |
63 | protected abstract void prepareWorkspace(); | |
64 | ||
65 | /** | |
66 | * Things to setup | |
67 | */ | |
68 | @Before | |
69 | public void beforeClass() { | |
70 | ||
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 */ | |
79 | prepareWorkspace(); | |
80 | /* Finish waiting for eclipse to load */ | |
f0beeb4a | 81 | WaitUtils.waitForJobs(); |
143e0680 GB |
82 | |
83 | /* Create project */ | |
84 | SWTBotUtils.createProject(PROJECT_NAME); | |
85 | } | |
86 | ||
87 | /** | |
88 | * Deletes the project from the workspace | |
89 | */ | |
90 | @After | |
91 | public void cleanUp() { | |
92 | /* Close editors and delete project */ | |
93 | fBot.closeAllEditors(); | |
94 | SWTBotUtils.deleteProject(PROJECT_NAME, fBot); | |
95 | } | |
96 | ||
97 | private void closeAllViews(Collection<String> viewIDs) { | |
98 | viewIDs.stream().forEach(id -> { | |
99 | SWTBotUtils.openView(id); | |
100 | SWTBotUtils.closeViewById(id, fBot); | |
101 | }); | |
102 | } | |
103 | ||
104 | /** | |
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. | |
108 | * | |
109 | * @param trace | |
110 | * The trace used for this test | |
111 | */ | |
112 | protected abstract void beforeRunningTest(ITmfTrace trace); | |
113 | ||
114 | /** | |
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 | |
118 | * closed. | |
119 | * | |
120 | * @param tracePath | |
121 | * The full path of the trace to open | |
122 | * @param traceType | |
123 | * The trace type of the trace to open | |
124 | * @param viewIDs | |
125 | * The IDs of the views to test. | |
126 | */ | |
127 | protected void runTestWithTrace(String tracePath, String traceType, Collection<String> viewIDs) { | |
128 | closeAllViews(viewIDs); | |
129 | /* Open the trace */ | |
130 | String traceName = tracePath.substring(tracePath.lastIndexOf(File.separator, tracePath.length() - 2) + 1, tracePath.length() - 1); | |
131 | SWTBotUtils.openTrace(PROJECT_NAME, tracePath, traceType); | |
132 | ||
133 | // Make sure all the analyses we'll need are done | |
134 | ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); | |
135 | beforeRunningTest(trace); | |
f0beeb4a | 136 | WaitUtils.waitForJobs(); |
143e0680 GB |
137 | |
138 | SWTBotView view; | |
139 | ||
140 | for (String viewID : viewIDs) { | |
141 | SWTBotUtils.openView(viewID); | |
142 | view = fBot.viewById(viewID); | |
143 | navigateTrace(view); | |
144 | SWTBotUtils.closeViewById(viewID, fBot); | |
145 | } | |
146 | ||
147 | // Close the trace | |
148 | fBot.closeAllEditors(); | |
149 | ||
150 | // If there is only 1 view to test, return | |
151 | if (viewIDs.size() <= 1) { | |
152 | // Close the views | |
153 | closeAllViews(viewIDs); | |
154 | return; | |
155 | } | |
156 | ||
157 | // Open all the views | |
158 | view = null; | |
159 | for (String viewID : viewIDs) { | |
160 | SWTBotUtils.openView(viewID); | |
161 | if (view == null) { | |
162 | view = fBot.viewById(viewID); | |
163 | } | |
164 | } | |
165 | ||
166 | // Rename the trace, so the results appear under another trace and | |
167 | // navigate it | |
168 | renameTrace(traceName, traceName + " full"); | |
169 | navigateTrace(view); | |
170 | ||
171 | // Close the trace | |
172 | fBot.closeAllEditors(); | |
173 | ||
174 | // Close the views | |
175 | closeAllViews(viewIDs); | |
176 | } | |
177 | ||
178 | private void renameTrace(String oldName, String newName) { | |
179 | ||
180 | SWTBotTreeItem traceItem = SWTBotUtils.getTraceProjectItem(fBot, SWTBotUtils.selectTracesFolder(fBot, PROJECT_NAME), oldName); | |
181 | ||
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)); | |
191 | ||
192 | SWTBotTreeItem copiedItem = SWTBotUtils.getTraceProjectItem(fBot, SWTBotUtils.selectTracesFolder(fBot, PROJECT_NAME), newName); | |
193 | copiedItem.contextMenu().menu("Open").click(); | |
194 | try { | |
195 | Thread.sleep(1000); | |
196 | } catch (InterruptedException e) { | |
197 | } | |
f0beeb4a | 198 | WaitUtils.waitForJobs(); |
143e0680 GB |
199 | } |
200 | ||
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); | |
207 | ||
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; | |
214 | ||
215 | // Zoom in 10 times 15 percent of the range and wait for the view to be | |
216 | // ready | |
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()); | |
223 | } | |
224 | ||
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()); | |
230 | ||
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()); | |
237 | } | |
238 | ||
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()); | |
243 | ||
244 | // and zoom out again | |
245 | TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, fullRange)); | |
246 | waitViewReady(part, selectionRange, fullRange.getEndTime()); | |
247 | ||
248 | // Reset the original window range | |
249 | TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, originalWindowRange)); | |
250 | waitViewReady(part, selectionRange, originalWindowRange.getEndTime()); | |
251 | } | |
252 | ||
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)); | |
256 | } | |
257 | // TODO Add conditions for other kind of views | |
258 | } | |
259 | ||
260 | } |