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