1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.remote
.ui
.swtbot
.tests
.fetch
;
15 import static org
.junit
.Assert
.assertEquals
;
16 import static org
.junit
.Assert
.assertNotNull
;
17 import static org
.junit
.Assert
.assertTrue
;
18 import static org
.junit
.Assert
.fail
;
21 import java
.io
.IOException
;
22 import java
.net
.URISyntaxException
;
23 import java
.util
.List
;
25 import org
.apache
.log4j
.Logger
;
26 import org
.apache
.log4j
.varia
.NullAppender
;
27 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
28 import org
.eclipse
.core
.runtime
.FileLocator
;
29 import org
.eclipse
.core
.runtime
.IPath
;
30 import org
.eclipse
.core
.runtime
.Path
;
31 import org
.eclipse
.jface
.bindings
.keys
.IKeyLookup
;
32 import org
.eclipse
.jface
.bindings
.keys
.KeyStroke
;
33 import org
.eclipse
.jface
.bindings
.keys
.ParseException
;
34 import org
.eclipse
.osgi
.util
.NLS
;
35 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
36 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
37 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
38 import org
.eclipse
.swtbot
.swt
.finder
.keyboard
.Keystrokes
;
39 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
40 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTUtils
;
41 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
42 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
43 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotButton
;
44 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotCombo
;
45 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
46 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
47 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
48 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
49 import org
.eclipse
.tracecompass
.ctf
.core
.tests
.shared
.LttngKernelTraceGenerator
;
50 import org
.eclipse
.tracecompass
.tmf
.remote
.ui
.swtbot
.tests
.TmfRemoteUISWTBotTestPlugin
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectElement
;
52 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
53 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
54 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
55 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
56 import org
.junit
.BeforeClass
;
57 import org
.junit
.Test
;
58 import org
.junit
.runner
.RunWith
;
61 * Test the Fetch Remote Traces wizard.
63 @RunWith(SWTBotJunit4ClassRunner
.class)
64 public class FetchRemoteTracesTest
{
66 private static final String CONNECTION_NODE_NAME
= "node1";
67 private static final String CONNECTION_NODE_TEXT
= CONNECTION_NODE_NAME
+ " (file://)";
68 private static final String LTTNG_TRACE_FILE_PATTERN
= ".*synthetic.*";
69 private static final String FETCH_COMMAND_NAME
= "Fetch Remote Traces...";
70 private static final String PROFILE_NAME
= "new profile";
71 private static final String PROJECT_EXPLORER
= "Project Explorer";
72 private static final String PROJECT_NAME
= "Test";
73 private static final String SYSLOG_FILE_PATTERN
= ".*syslog";
74 private static final String TRACE_GROUP_NODE_TEXT
;
75 private static final String TRACE_LOCATION
;
76 private static final String TRACE_TYPE_LTTNG
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
77 private static final String TRACE_TYPE_SYSLOG
= "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog";
78 private static final String WELCOME_NAME
= "welcome";
80 private static SWTWorkbenchBot fBot
;
83 String traceLocation
= "";
85 IPath resourcesPath
= new Path("resources");
86 File resourcesFile
= getBundleFile(resourcesPath
);
87 // Create a sub directory to test the trace folders at the same time
88 IPath subDirFullPath
= new Path(resourcesFile
.getAbsolutePath()).append("generated");
89 File subDirFile
= new File(subDirFullPath
.toOSString());
92 IPath generatedTraceFullPath
= subDirFullPath
.append("synthetic-trace");
93 File generatedTraceFile
= new File(generatedTraceFullPath
.toOSString());
94 LttngKernelTraceGenerator
.generateLttngKernelTrace(generatedTraceFile
);
95 traceLocation
= new Path(resourcesFile
.getAbsolutePath()).toString();
96 } catch (IOException e
) {
98 } catch (URISyntaxException e
) {
101 TRACE_LOCATION
= traceLocation
;
102 TRACE_GROUP_NODE_TEXT
= TRACE_LOCATION
+ " (recursive)";
105 private static File
getBundleFile(IPath relativePath
) throws URISyntaxException
, IOException
{
106 return new File(FileLocator
.toFileURL(FileLocator
.find(TmfRemoteUISWTBotTestPlugin
.getDefault().getBundle(), relativePath
, null)).toURI());
109 /** Test Class setup */
111 public static void init() {
112 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
113 SWTBotUtils
.failIfUIThread();
114 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
115 Logger
.getRootLogger().addAppender(new NullAppender());
116 fBot
= new SWTWorkbenchBot();
118 SWTBotUtils
.closeView(WELCOME_NAME
, fBot
);
120 SWTBotUtils
.switchToTracingPerspective();
121 /* finish waiting for eclipse to load */
122 SWTBotUtils
.waitForJobs();
125 private static class TraceCountCondition
extends DefaultCondition
{
127 private final TmfProjectElement fProject
;
128 private final int fExpectedCount
;
130 public TraceCountCondition(TmfProjectElement project
, int expectedNumber
) {
132 fExpectedCount
= expectedNumber
;
136 public boolean test() throws Exception
{
137 return fProject
.getTracesFolder().getTraces().size() == fExpectedCount
;
141 public String
getFailureMessage() {
142 return NLS
.bind("The project {0} does not contain {1} traces.", fProject
.getName(), fExpectedCount
);
147 * Test creating a profile, fetching all using the profile.
150 public void testImportAll() {
151 testImport(new Runnable() {
158 final TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
159 fBot
.waitUntil(new TraceCountCondition(project
, 2));
160 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
161 assertEquals(2, traces
.size());
162 testTrace(traces
.get(0), CONNECTION_NODE_NAME
+ "/resources/generated/synthetic-trace", TRACE_TYPE_LTTNG
);
163 testTrace(traces
.get(1), CONNECTION_NODE_NAME
+ "/resources/syslog", TRACE_TYPE_SYSLOG
);
169 * Test creating a profile, fetching only one trace
172 public void testImportOnlyOne() {
173 testImport(new Runnable() {
176 SWTBotTree tree
= fBot
.tree();
177 fBot
.button("Deselect All").click();
178 int length
= tree
.getAllItems().length
;
179 assertTrue(length
> 0);
180 // Selecting the second trace under node > traceGroup
181 SWTBotTreeItem node
= getTreeItem(fBot
, tree
, new String
[] { CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
}).getNode(1);
182 assertEquals("syslog", node
.getText());
188 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
189 fBot
.waitUntil(new TraceCountCondition(project
, 1));
190 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
191 assertEquals(1, traces
.size());
192 testTrace(traces
.get(0), CONNECTION_NODE_NAME
+ "/resources/syslog", TRACE_TYPE_SYSLOG
);
198 * Test creating a profile, fetching nothing
201 public void testImportNothing() {
202 testImport(new Runnable() {
205 fBot
.button("Deselect All").click();
210 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
211 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
212 assertEquals(0, traces
.size());
218 * Test to verify that empty files are omitted.
221 public void testEmptyFile() {
222 testImport(new Runnable() {
225 SWTBotTree tree
= fBot
.tree();
226 fBot
.button("Deselect All").click();
227 int length
= tree
.getAllItems().length
;
228 assertTrue(length
> 0);
230 SWTBotTreeItem groupNode
= getTreeItem(fBot
, tree
, new String
[] { CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
});
232 * Currently there are 3 items at the location where 1 file has 0 bytes.
233 * Verify that empty file is not shown.
235 assertEquals(2, groupNode
.getItems().length
);
240 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
241 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
242 assertEquals(0, traces
.size());
249 * Test editing a profile
252 public void testEditProfile() {
253 openRemoteProfilePreferences();
255 openRemoteProfilePreferences();
257 // The first tree is the preference "categories" on the left side, we
259 SWTBotTree tree
= fBot
.tree(1);
261 final String
[] traceGroupNodePath
= new String
[] { PROFILE_NAME
, CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
};
263 // Initial order of traces
264 SWTBotTreeItem traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
265 SWTBotTreeItem
[] traceNodes
= traceGroupNode
.getItems();
266 assertEquals(2, traceNodes
.length
);
267 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
268 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
270 // Test moving down a trace element
271 SWTBotTreeItem traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
273 fBot
.button("Move Down").click();
274 traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
275 traceNodes
= traceGroupNode
.getItems();
276 assertEquals(2, traceNodes
.length
);
277 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[0].getText());
278 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
280 // Test moving down a trace element
281 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
283 fBot
.button("Move Up").click();
284 traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
285 traceNodes
= traceGroupNode
.getItems();
286 assertEquals(2, traceNodes
.length
);
287 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
288 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
291 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
292 traceNode
.select().contextMenu("Copy").click();
293 traceNode
.contextMenu("Paste").click();
294 traceNodes
= traceGroupNode
.getItems();
295 assertEquals(3, traceNodes
.length
);
296 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
297 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
298 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[2].getText());
301 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
302 traceNode
.select().contextMenu("Cut").click();
303 traceNode
= traceGroupNode
.getNode(SYSLOG_FILE_PATTERN
);
304 traceNode
.select().contextMenu("Paste").click();
305 traceNodes
= traceGroupNode
.getItems();
306 assertEquals(3, traceNodes
.length
);
307 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
308 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
309 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[2].getText());
312 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
313 traceNode
.select().contextMenu("Delete").click();
314 traceNodes
= traceGroupNode
.getItems();
315 assertEquals(2, traceNodes
.length
);
316 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[0].getText());
317 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
318 // Copy to test Paste after Delete
319 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
320 traceNode
.select().contextMenu("Copy").click();
321 traceNode
= traceGroupNode
.select(SYSLOG_FILE_PATTERN
, LTTNG_TRACE_FILE_PATTERN
);
322 traceNode
.pressShortcut(Keystrokes
.DELETE
);
323 traceNodes
= traceGroupNode
.getItems();
324 assertEquals(0, traceNodes
.length
);
325 // Paste after Delete
326 traceGroupNode
.contextMenu("Paste").click();
327 traceNodes
= traceGroupNode
.getItems();
328 assertEquals(1, traceNodes
.length
);
329 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
330 fBot
.button("OK").click();
334 private static void testImport(Runnable selectionFunctor
, Runnable verifyTracesFunctor
) {
335 SWTBotUtils
.createProject(PROJECT_NAME
);
336 SWTBotUtils
.waitForJobs();
337 SWTBotView projectExplorerBot
= fBot
.viewByTitle(PROJECT_EXPLORER
);
338 assertNotNull("Cannot find " + PROJECT_EXPLORER
, projectExplorerBot
);
339 projectExplorerBot
.show();
340 SWTBotTreeItem treeItem
= getTracesFolderTreeItem(projectExplorerBot
);
342 treeItem
.contextMenu(FETCH_COMMAND_NAME
).click();
344 fBot
.button("Manage Profiles").click();
348 assertEquals(PROFILE_NAME
, fBot
.comboBoxWithLabel("Profile name:").getText());
349 assertEquals(CONNECTION_NODE_TEXT
, fBot
.textWithLabel("Nodes:").getText());
351 // Make sure if we go to the next page and come back that the first page
352 // still has valid values
353 SWTBotButton button
= fBot
.button("Next >");
354 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
356 button
= fBot
.button("< Back");
357 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
359 assertEquals(PROFILE_NAME
, fBot
.comboBoxWithLabel("Profile name:").getText());
360 assertEquals(CONNECTION_NODE_TEXT
, fBot
.textWithLabel("Nodes:").getText());
362 button
= fBot
.button("Next >");
363 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
366 selectionFunctor
.run();
368 SWTBotShell shell
= fBot
.activeShell();
370 button
= fBot
.button("Finish");
371 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
373 fBot
.waitUntil(Conditions
.shellCloses(shell
));
374 SWTBotUtils
.waitForJobs();
376 verifyTracesFunctor
.run();
377 fBot
.closeAllEditors();
378 SWTBotUtils
.deleteProject(PROJECT_NAME
, fBot
);
382 private static void createProfile() {
383 fBot
.button("Add").click();
385 // The first tree is the preference "categories" on the left side, we
387 SWTBotTree tree
= fBot
.tree(1);
389 SWTBotTreeItem treeNode
= getTreeItem(fBot
, tree
, PROFILE_NAME
, "name (ssh://userinfo@host:22)");
391 SWTBotText uriLabel
= fBot
.textWithLabel("URI:");
392 uriLabel
.setText("file://");
393 SWTBotText nodeNameLabel
= fBot
.textWithLabel("Node name:");
394 nodeNameLabel
.setText(CONNECTION_NODE_NAME
);
396 SWTBotTreeItem traceRootNode
= treeNode
.getNode("/rootpath");
397 traceRootNode
.select();
398 SWTBotText pathLabel
= fBot
.textWithLabel("Root path:");
399 pathLabel
.setText(TRACE_LOCATION
);
400 fBot
.checkBox("Recursive").select();
402 // Add the ctf file pattern
403 treeNode
= traceRootNode
.getNode(".*");
405 SWTBotText filePatternLabel
= fBot
.textWithLabel("File pattern:");
406 filePatternLabel
.setText(LTTNG_TRACE_FILE_PATTERN
);
408 // Add the syslog file pattern
409 traceRootNode
.contextMenu("New Trace").click();
410 treeNode
= traceRootNode
.getNode(".*");
412 filePatternLabel
= fBot
.textWithLabel("File pattern:");
413 filePatternLabel
.setText(SYSLOG_FILE_PATTERN
);
414 SWTBotCombo combo
= fBot
.comboBoxWithLabel("Trace type:");
415 combo
.setSelection("Test trace : Test Syslog");
417 fBot
.button("OK").click();
420 private static void testTrace(TmfTraceElement tmfTraceElement
, String expectedTracePath
, String traceType
) {
421 assertEquals(traceType
, tmfTraceElement
.getTraceType());
422 IPath tracePath
= new Path(tmfTraceElement
.getElementPath());
423 assertEquals(expectedTracePath
, tracePath
.toString());
424 SWTBotUtils
.openEditor(fBot
, PROJECT_NAME
, tracePath
);
427 private static void deleteProfile() {
428 openRemoteProfilePreferences();
430 // The second tree is the remote profiles tree on the right side
431 SWTBotTree tree
= fBot
.tree(1);
432 SWTBotTreeItem treeNode
= tree
.getTreeItem(PROFILE_NAME
);
434 fBot
.button("Remove").click();
435 assertEquals(0, tree
.getAllItems().length
);
436 fBot
.button("OK").click();
439 private static SWTBotTreeItem
getTreeItem(SWTWorkbenchBot bot
, SWTBotTree tree
, String
... nodeNames
) {
440 if (nodeNames
.length
== 0) {
444 SWTBotTreeItem currentNode
= tree
.getTreeItem(nodeNames
[0]);
445 for (int i
= 1; i
< nodeNames
.length
; i
++) {
446 String nodeName
= nodeNames
[i
];
447 bot
.waitUntil(ConditionHelpers
.IsTreeChildNodeAvailable(nodeName
, currentNode
));
448 SWTBotTreeItem newNode
= currentNode
.getNode(nodeName
);
449 currentNode
= newNode
;
455 private static void openRemoteProfilePreferences() {
456 if (SWTUtils
.isMac()) {
457 // On Mac, the Preferences menu item is under the application name.
458 // For some reason, we can't access the application menu anymore so
459 // we use the keyboard shortcut.
461 fBot
.activeShell().pressShortcut(KeyStroke
.getInstance(IKeyLookup
.COMMAND_NAME
+ "+"), KeyStroke
.getInstance(","));
462 } catch (ParseException e
) {
466 fBot
.menu("Window").menu("Preferences").click();
469 fBot
.waitUntil(Conditions
.shellIsActive("Preferences"));
471 // The first tree is the preference "categories" on the left side
472 SWTBotTree tree
= fBot
.tree(0);
473 SWTBotTreeItem treeNode
= tree
.getTreeItem("Tracing");
476 fBot
.waitUntil(ConditionHelpers
.IsTreeChildNodeAvailable("Remote Profiles", treeNode
));
477 treeNode
= treeNode
.getNode("Remote Profiles");
481 private static SWTBotTreeItem
getTracesFolderTreeItem(SWTBotView projectExplorerBot
) {
482 SWTBotTreeItem treeItem
= projectExplorerBot
.bot().tree().getTreeItem(PROJECT_NAME
);
485 return treeItem
.getNode("Traces [0]");