lttng.ui.test: Enable SymbolMap test
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.ust.ui.swtbot.tests / src / org / eclipse / tracecompass / lttng2 / ust / ui / swtbot / tests / CallStackViewTest.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.lttng2.ust.ui.swtbot.tests;
14
15 import static org.junit.Assert.*;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.net.URISyntaxException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24 import java.util.stream.Collectors;
25
26 import org.apache.log4j.ConsoleAppender;
27 import org.apache.log4j.Logger;
28 import org.apache.log4j.SimpleLayout;
29 import org.eclipse.core.runtime.FileLocator;
30 import org.eclipse.jdt.annotation.NonNull;
31 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
32 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
33 import org.eclipse.swtbot.swt.finder.SWTBot;
34 import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
35 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
36 import org.eclipse.swtbot.swt.finder.waits.Conditions;
37 import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
38 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
39 import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
40 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
41 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
42 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
43 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
44 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
45 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
46 import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
47 import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
48 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
49 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
50 import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
51 import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
52 import org.junit.After;
53 import org.junit.Before;
54 import org.junit.BeforeClass;
55 import org.junit.Test;
56 import org.junit.runner.RunWith;
57
58 import com.google.common.collect.ImmutableList;
59
60 /**
61 * Test for the Call Stack view in trace compass
62 */
63 @RunWith(SWTBotJunit4ClassRunner.class)
64 public class CallStackViewTest {
65
66 private static final String UST_ID = "org.eclipse.linuxtools.lttng2.ust.tracetype";
67
68 private static final String PROJECT_NAME = "TestForCallstack";
69
70 /** The Log4j logger instance. */
71 private static final Logger fLogger = Logger.getRootLogger();
72 private static SWTWorkbenchBot fBot;
73
74 /**
75 * Timestamps of consecutive events in the trace
76 */
77 private static final long TIMESTAMPS[] = new long[] {
78 1378850463804898643l,
79 1378850463804899057l,
80 1378850463804900219l,
81 1378850463804900678l,
82 1378850463804901308l,
83 1378850463804901909l,
84 1378850463804902763l,
85 1378850463804903168l,
86 1378850463804903766l,
87 1378850463804904165l,
88 1378850463804904970l,
89 };
90
91 /**
92 * Stack frames of consecutive events in the trace
93 */
94 private static final String[] STACK_FRAMES[] = new String[][] {
95 { "0x40472b", "0x4045c8", "0x404412", "", "" },
96 { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
97 { "0x40472b", "0x4045c8", "0x404412", "", "" },
98 { "0x40472b", "0x4045c8", "", "", "" },
99 { "0x40472b", "0x4045c8", "0x404412", "", "" },
100 { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
101 { "0x40472b", "0x4045c8", "0x404412", "", "" },
102 { "0x40472b", "0x4045c8", "", "", "" },
103 { "0x40472b", "0x4045c8", "0x404412", "", "" },
104 { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
105 { "0x40472b", "0x4045c8", "0x404412", "", "" },
106 };
107
108 /** Tooltips of the toolbar buttons */
109
110 private static final @NonNull String ALIGN_VIEWS = "Align Views";
111 private static final @NonNull String CONFIGURE_SYMBOL_PROVIDERS = "Configure how the addresses are mapped to function names";
112 // Separator
113 private static final @NonNull String SORT_BY_NAME = "Sort threads by thread name";
114 private static final @NonNull String SORT_BY_ID = "Sort threads by thread id";
115 private static final @NonNull String SORT_BY_START = "Sort threads by start time";
116 // Separator
117 private static final @NonNull String SHOW_VIEW_FILTERS = "Show View Filters";
118 // Separator
119 private static final @NonNull String RESET_TIME_SCALE = "Reset the Time Scale to Default";
120 private static final @NonNull String SELECT_PREVIOUS_STATE_CHANGE = "Select Previous State Change";
121 private static final @NonNull String SELECT_NEXT_STATE_CHANGE = "Select Next State Change";
122 // Separator
123 private static final @NonNull String ADD_BOOKMARK = "Add Bookmark...";
124 private static final @NonNull String PREVIOUS_MARKER = "Previous Marker";
125 private static final @NonNull String NEXT_MARKER = "Next Marker";
126 // Separator
127 private static final @NonNull String SELECT_PREVIOUS_ITEM = "Select Previous Item";
128 private static final @NonNull String SELECT_NEXT_ITEM = "Select Next Item";
129 private static final @NonNull String ZOOM_IN = "Zoom In";
130 private static final @NonNull String ZOOM_OUT = "Zoom Out";
131 // Separator
132 private static final String PIN_VIEW = "Pin View";
133 private static final List<String> TOOLBAR_BUTTONS_TOOLTIPS = ImmutableList.of(
134 ALIGN_VIEWS, CONFIGURE_SYMBOL_PROVIDERS,
135 "",
136 SORT_BY_NAME, SORT_BY_ID, SORT_BY_START,
137 "",
138 SHOW_VIEW_FILTERS,
139 "",
140 RESET_TIME_SCALE, SELECT_PREVIOUS_STATE_CHANGE, SELECT_NEXT_STATE_CHANGE,
141 "",
142 ADD_BOOKMARK, PREVIOUS_MARKER, NEXT_MARKER,
143 "",
144 SELECT_PREVIOUS_ITEM, SELECT_NEXT_ITEM, ZOOM_IN, ZOOM_OUT,
145 "",
146 PIN_VIEW);
147
148 /**
149 * Initialization
150 */
151 @BeforeClass
152 public static void init() {
153 SWTBotUtils.initialize();
154
155 Thread.currentThread().setName("SWTBot Thread"); // for the debugger
156 /* set up for swtbot */
157 SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
158 fLogger.addAppender(new ConsoleAppender(new SimpleLayout()));
159 fBot = new SWTWorkbenchBot();
160
161 SWTBotUtils.closeView("welcome", fBot);
162
163 SWTBotUtils.switchToTracingPerspective();
164 /* finish waiting for eclipse to load */
165 WaitUtils.waitForJobs();
166 }
167
168 /**
169 * Open a trace in an editor
170 */
171 @Before
172 public void beforeTest() {
173 SWTBotUtils.createProject(PROJECT_NAME);
174 SWTBotTreeItem treeItem = SWTBotUtils.selectTracesFolder(fBot, PROJECT_NAME);
175 assertNotNull(treeItem);
176 final CtfTestTrace cygProfile = CtfTestTrace.CYG_PROFILE;
177 final File file = new File(CtfTmfTestTraceUtils.getTrace(cygProfile).getPath());
178 SWTBotUtils.openTrace(PROJECT_NAME, file.getAbsolutePath(), UST_ID);
179 SWTBotUtils.openView(CallStackView.ID);
180 WaitUtils.waitForJobs();
181 }
182
183 /**
184 * Close the editor
185 */
186 @After
187 public void tearDown() {
188 fBot.closeAllEditors();
189 SWTBotUtils.deleteProject(PROJECT_NAME, fBot);
190 }
191
192 /**
193 * Test if callstack is populated
194 */
195 @Test
196 public void testOpenCallstack() {
197 String node = "glxgears-cyg-profile";
198 String processName = "UNKNOWN";
199 String childName = "glxgears-16073";
200 List<String> expected = ImmutableList.of("0x40472b", "", "", "", "");
201
202 SWTBotView viewBot = fBot.viewById(CallStackView.ID);
203 viewBot.setFocus();
204 final SWTBotView viewBot1 = viewBot;
205 SWTBotTree tree = viewBot1.bot().tree();
206 SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(processName);
207 assertEquals(childName, treeItem.getNodes().get(0));
208 List<String> names = treeItem.getNode(childName).getNodes();
209 assertEquals(expected, names);
210 }
211
212 /**
213 * Test check callstack at a time
214 */
215 @Test
216 public void testGoToTimeAndCheckStack() {
217 goToTime(TIMESTAMPS[0]);
218
219 final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
220 viewBot.setFocus();
221 WaitUtils.waitForJobs();
222 List<String> names = getVisibleStackFrames(viewBot);
223 assertArrayEquals(STACK_FRAMES[0], names.toArray());
224 }
225
226 /**
227 * Test check callstack at a time after navigating
228 */
229 @Test
230 public void testGoToTimeGoBackAndForthAndCheckStack() {
231 int currentEventOffset = 0;
232 goToTime(TIMESTAMPS[currentEventOffset]);
233
234 final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
235 // forward 10 times
236 for (int i = 0; i < 10; i++) {
237 viewBot.toolbarPushButton(SELECT_NEXT_STATE_CHANGE).click();
238 currentEventOffset++;
239 fBot.waitUntil(ConditionHelpers.selectionInEventsTable(fBot, TIMESTAMPS[currentEventOffset]));
240 WaitUtils.waitForJobs();
241 assertArrayEquals(STACK_FRAMES[currentEventOffset], getVisibleStackFrames(viewBot).toArray());
242
243 }
244 // back twice
245 for (int i = 0; i < 2; i++) {
246 viewBot.toolbarPushButton(SELECT_PREVIOUS_STATE_CHANGE).click();
247 currentEventOffset--;
248 fBot.waitUntil(ConditionHelpers.selectionInEventsTable(fBot, TIMESTAMPS[currentEventOffset]));
249 WaitUtils.waitForJobs();
250 assertArrayEquals(STACK_FRAMES[currentEventOffset], getVisibleStackFrames(viewBot).toArray());
251 }
252 // move up and down once to make sure it doesn't explode
253 viewBot.toolbarPushButton(SELECT_PREVIOUS_ITEM).click();
254 WaitUtils.waitForJobs();
255 viewBot.toolbarPushButton(SELECT_NEXT_ITEM).click();
256 WaitUtils.waitForJobs();
257
258 // Zoom in and out too
259 viewBot.toolbarPushButton(ZOOM_IN).click();
260 WaitUtils.waitForJobs();
261 viewBot.toolbarPushButton(ZOOM_OUT).click();
262 WaitUtils.waitForJobs();
263 }
264
265 /**
266 * Test check callstack at a time with sorting, the trace is not sortable,
267 * this is a smoke test
268 */
269 @Test
270 public void testGoToTimeSortAndCheckStack() {
271 goToTime(TIMESTAMPS[0]);
272 final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
273 viewBot.setFocus();
274 viewBot.toolbarToggleButton(SORT_BY_NAME).click();
275 viewBot.toolbarToggleButton(SORT_BY_ID).click();
276 viewBot.toolbarToggleButton(SORT_BY_START).click();
277 viewBot.setFocus();
278 WaitUtils.waitForJobs();
279 List<String> names = getVisibleStackFrames(viewBot);
280 assertArrayEquals(STACK_FRAMES[0], names.toArray());
281 }
282
283 private static List<String> getVisibleStackFrames(final SWTBotView viewBot) {
284 SWTBotTree tree = viewBot.bot().tree();
285 return Arrays.stream(tree.getAllItems())
286 // Process entries
287 .flatMap(item -> Arrays.stream(item.getItems()))
288 // Thread entries
289 .flatMap(item -> Arrays.stream(item.getItems()))
290 // Callstack entries
291 .flatMap(item -> Arrays.stream(item.getItems()))
292 .map(item -> item.cell(0))
293 .collect(Collectors.toList());
294 }
295
296 private static void goToTime(long timestamp) {
297 SWTBotTable table = fBot.activeEditor().bot().table();
298 table.setFocus();
299 TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(table.widget, TmfTimestamp.fromNanos(timestamp)));
300 fBot.waitUntil(ConditionHelpers.selectionInEventsTable(fBot, timestamp));
301 }
302
303 /**
304 * Test check callstack at a time with function map
305 *
306 * @throws URISyntaxException
307 * Malformed url
308 * @throws IOException
309 * Missing file
310 */
311 @Test
312 public void testGoToTimeAndCheckStackWithNames() throws URISyntaxException, IOException {
313 goToTime(TIMESTAMPS[0]);
314 final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
315 viewBot.setFocus();
316 Object mapObj = CtfTmfTestTraceUtils.class.getResource("cyg-profile-mapping.txt");
317 assertTrue(mapObj instanceof URL);
318 URL mapUrl = (URL) mapObj;
319
320 String absoluteFile = FileLocator.toFileURL(mapUrl).getFile();
321 TmfFileDialogFactory.setOverrideFiles(absoluteFile);
322 viewBot.toolbarButton("Configure how the addresses are mapped to function names").click();
323 String shellTitle = "Symbol mapping";
324 fBot.waitUntil(Conditions.shellIsActive(shellTitle));
325 SWTBot shellBot = fBot.shell(shellTitle).bot();
326 SWTBotShell activeShell = shellBot.activeShell();
327 shellBot.radio(1).click();
328 shellBot.button("Browse...", 1).click();
329 shellBot.button("OK").click();
330 shellBot.waitUntil(Conditions.shellCloses(activeShell));
331
332 SWTBotTree tree = viewBot.bot().tree();
333 WaitUtils.waitForJobs();
334 List<String> names = new ArrayList<>();
335 for (SWTBotTreeItem swtBotTreeItem : tree.getAllItems()) {
336 for (SWTBotTreeItem items : swtBotTreeItem.getItems()) {
337 for (SWTBotTreeItem item : items.getItems()) {
338 names.add(item.cell(0));
339 }
340 }
341 }
342 assertEquals(names, ImmutableList.of("glxgears-16073"));
343 }
344
345 /**
346 * Test check callstack toolbar buttons
347 */
348 @Test
349 public void testCallstackNavigation() {
350 SWTBotView viewBot = fBot.viewById(CallStackView.ID);
351 viewBot.setFocus();
352 List<String> buttons = new ArrayList<>();
353 for (SWTBotToolbarButton swtBotToolbarButton : viewBot.getToolbarButtons()) {
354 buttons.add(swtBotToolbarButton.getToolTipText());
355 }
356 assertEquals(TOOLBAR_BUTTONS_TOOLTIPS, buttons);
357 }
358 }
This page took 0.045034 seconds and 5 git commands to generate.