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
;
20 import java
.io
.IOException
;
21 import java
.net
.URISyntaxException
;
22 import java
.util
.List
;
24 import org
.apache
.log4j
.Logger
;
25 import org
.apache
.log4j
.varia
.NullAppender
;
26 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
27 import org
.eclipse
.core
.runtime
.FileLocator
;
28 import org
.eclipse
.core
.runtime
.IPath
;
29 import org
.eclipse
.core
.runtime
.Path
;
30 import org
.eclipse
.osgi
.util
.NLS
;
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
.keyboard
.Keystrokes
;
36 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
37 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
38 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
39 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotButton
;
40 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotCombo
;
41 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
42 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
43 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
44 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
45 import org
.eclipse
.tracecompass
.ctf
.core
.tests
.shared
.LttngTraceGenerator
;
46 import org
.eclipse
.tracecompass
.tmf
.remote
.ui
.swtbot
.tests
.TmfRemoteUISWTBotTestPlugin
;
47 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectElement
;
48 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
52 import org
.junit
.BeforeClass
;
53 import org
.junit
.Test
;
54 import org
.junit
.runner
.RunWith
;
57 * Test the Fetch Remote Traces wizard.
59 @RunWith(SWTBotJunit4ClassRunner
.class)
60 public class FetchRemoteTracesTest
{
62 private static final String CONNECTION_NODE_NAME
= "node1";
63 private static final String CONNECTION_NODE_TEXT
= CONNECTION_NODE_NAME
+ " (file://)";
64 private static final String LTTNG_TRACE_FILE_PATTERN
= ".*synthetic.*";
65 private static final String FETCH_COMMAND_NAME
= "Fetch Remote Traces...";
66 private static final String PROFILE_NAME
= "new profile";
67 private static final String PROJECT_EXPLORER
= "Project Explorer";
68 private static final String PROJECT_NAME
= "Test";
69 private static final String SYSLOG_FILE_PATTERN
= ".*syslog";
70 private static final String TRACE_GROUP_NODE_TEXT
;
71 private static final String TRACE_LOCATION
;
72 private static final String TRACE_TYPE_LTTNG
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
73 private static final String TRACE_TYPE_SYSLOG
= "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog";
74 private static final String WELCOME_NAME
= "welcome";
76 private static SWTWorkbenchBot fBot
;
79 String traceLocation
= "";
81 IPath resourcesPath
= new Path("resources");
82 File resourcesFile
= getBundleFile(resourcesPath
);
83 // Create a sub directory to test the trace folders at the same time
84 IPath subDirFullPath
= new Path(resourcesFile
.getAbsolutePath()).append("generated");
85 File subDirFile
= new File(subDirFullPath
.toOSString());
88 IPath generatedTraceFullPath
= subDirFullPath
.append("synthetic-trace");
89 File generatedTraceFile
= new File(generatedTraceFullPath
.toOSString());
90 LttngTraceGenerator
.generateLttngTrace(generatedTraceFile
);
91 traceLocation
= new Path(resourcesFile
.getAbsolutePath()).toString();
92 } catch (IOException e
) {
94 } catch (URISyntaxException e
) {
97 TRACE_LOCATION
= traceLocation
;
98 TRACE_GROUP_NODE_TEXT
= TRACE_LOCATION
+ " (recursive)";
101 private static File
getBundleFile(IPath relativePath
) throws URISyntaxException
, IOException
{
102 return new File(FileLocator
.toFileURL(FileLocator
.find(TmfRemoteUISWTBotTestPlugin
.getDefault().getBundle(), relativePath
, null)).toURI());
105 /** Test Class setup */
107 public static void init() {
108 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
109 SWTBotUtils
.initialize();
110 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
111 Logger
.getRootLogger().addAppender(new NullAppender());
112 fBot
= new SWTWorkbenchBot();
114 SWTBotUtils
.closeView(WELCOME_NAME
, fBot
);
116 SWTBotUtils
.switchToTracingPerspective();
117 /* finish waiting for eclipse to load */
118 SWTBotUtils
.waitForJobs();
121 private static class TraceCountCondition
extends DefaultCondition
{
123 private final TmfProjectElement fProject
;
124 private final int fExpectedCount
;
126 public TraceCountCondition(TmfProjectElement project
, int expectedNumber
) {
128 fExpectedCount
= expectedNumber
;
132 public boolean test() throws Exception
{
133 return fProject
.getTracesFolder().getTraces().size() == fExpectedCount
;
137 public String
getFailureMessage() {
138 return NLS
.bind("The project {0} does not contain {1} traces.", fProject
.getName(), fExpectedCount
);
143 * Test creating a profile, fetching all using the profile.
146 public void testImportAll() {
147 testImport(new Runnable() {
154 final TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
155 fBot
.waitUntil(new TraceCountCondition(project
, 2));
156 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
157 assertEquals(2, traces
.size());
158 testTrace(traces
.get(0), CONNECTION_NODE_NAME
+ "/resources/generated/synthetic-trace", TRACE_TYPE_LTTNG
);
159 testTrace(traces
.get(1), CONNECTION_NODE_NAME
+ "/resources/syslog", TRACE_TYPE_SYSLOG
);
165 * Test creating a profile, fetching only one trace
168 public void testImportOnlyOne() {
169 testImport(new Runnable() {
172 SWTBotTree tree
= fBot
.tree();
173 fBot
.button("Deselect All").click();
174 int length
= tree
.getAllItems().length
;
175 assertTrue(length
> 0);
176 // Selecting the second trace under node > traceGroup
177 SWTBotTreeItem node
= getTreeItem(fBot
, tree
, new String
[] { CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
}).getNode(1);
178 assertEquals("syslog", node
.getText());
184 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
185 fBot
.waitUntil(new TraceCountCondition(project
, 1));
186 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
187 assertEquals(1, traces
.size());
188 testTrace(traces
.get(0), CONNECTION_NODE_NAME
+ "/resources/syslog", TRACE_TYPE_SYSLOG
);
194 * Test creating a profile, fetching nothing
197 public void testImportNothing() {
198 testImport(new Runnable() {
201 fBot
.button("Deselect All").click();
206 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
207 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
208 assertEquals(0, traces
.size());
214 * Test to verify that empty files are omitted.
217 public void testEmptyFile() {
218 testImport(new Runnable() {
221 SWTBotTree tree
= fBot
.tree();
222 fBot
.button("Deselect All").click();
223 int length
= tree
.getAllItems().length
;
224 assertTrue(length
> 0);
226 SWTBotTreeItem groupNode
= getTreeItem(fBot
, tree
, new String
[] { CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
});
228 * Currently there are 3 items at the location where 1 file has 0 bytes.
229 * Verify that empty file is not shown.
231 assertEquals(2, groupNode
.getItems().length
);
236 TmfProjectElement project
= TmfProjectRegistry
.getProject(ResourcesPlugin
.getWorkspace().getRoot().getProject(PROJECT_NAME
), true);
237 List
<TmfTraceElement
> traces
= project
.getTracesFolder().getTraces();
238 assertEquals(0, traces
.size());
245 * Test editing a profile
248 public void testEditProfile() {
249 openRemoteProfilePreferences();
251 openRemoteProfilePreferences();
253 // The first tree is the preference "categories" on the left side, we
255 SWTBotTree tree
= fBot
.tree(1);
257 final String
[] traceGroupNodePath
= new String
[] { PROFILE_NAME
, CONNECTION_NODE_TEXT
, TRACE_GROUP_NODE_TEXT
};
259 // Initial order of traces
260 SWTBotTreeItem traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
261 SWTBotTreeItem
[] traceNodes
= traceGroupNode
.getItems();
262 assertEquals(2, traceNodes
.length
);
263 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
264 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
266 // Test moving down a trace element
267 SWTBotTreeItem traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
269 fBot
.button("Move Down").click();
270 traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
271 traceNodes
= traceGroupNode
.getItems();
272 assertEquals(2, traceNodes
.length
);
273 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[0].getText());
274 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
276 // Test moving down a trace element
277 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
279 fBot
.button("Move Up").click();
280 traceGroupNode
= getTreeItem(fBot
, tree
, traceGroupNodePath
);
281 traceNodes
= traceGroupNode
.getItems();
282 assertEquals(2, traceNodes
.length
);
283 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
284 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
287 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
288 traceNode
.select().contextMenu("Copy").click();
289 traceNode
.contextMenu("Paste").click();
290 traceNodes
= traceGroupNode
.getItems();
291 assertEquals(3, traceNodes
.length
);
292 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
293 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
294 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[2].getText());
297 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
298 traceNode
.select().contextMenu("Cut").click();
299 traceNode
= traceGroupNode
.getNode(SYSLOG_FILE_PATTERN
);
300 traceNode
.select().contextMenu("Paste").click();
301 traceNodes
= traceGroupNode
.getItems();
302 assertEquals(3, traceNodes
.length
);
303 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
304 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[1].getText());
305 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[2].getText());
308 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
309 traceNode
.select().contextMenu("Delete").click();
310 traceNodes
= traceGroupNode
.getItems();
311 assertEquals(2, traceNodes
.length
);
312 assertEquals(SYSLOG_FILE_PATTERN
, traceNodes
[0].getText());
313 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[1].getText());
314 // Copy to test Paste after Delete
315 traceNode
= traceGroupNode
.getNode(LTTNG_TRACE_FILE_PATTERN
);
316 traceNode
.select().contextMenu("Copy").click();
317 traceNode
= traceGroupNode
.select(SYSLOG_FILE_PATTERN
, LTTNG_TRACE_FILE_PATTERN
);
318 traceNode
.pressShortcut(Keystrokes
.DELETE
);
319 traceNodes
= traceGroupNode
.getItems();
320 assertEquals(0, traceNodes
.length
);
321 // Paste after Delete
322 traceGroupNode
.contextMenu("Paste").click();
323 traceNodes
= traceGroupNode
.getItems();
324 assertEquals(1, traceNodes
.length
);
325 assertEquals(LTTNG_TRACE_FILE_PATTERN
, traceNodes
[0].getText());
326 fBot
.button("OK").click();
330 private static void testImport(Runnable selectionFunctor
, Runnable verifyTracesFunctor
) {
331 SWTBotUtils
.createProject(PROJECT_NAME
);
332 SWTBotUtils
.waitForJobs();
333 SWTBotView projectExplorerBot
= fBot
.viewByTitle(PROJECT_EXPLORER
);
334 assertNotNull("Cannot find " + PROJECT_EXPLORER
, projectExplorerBot
);
335 projectExplorerBot
.show();
336 SWTBotTreeItem treeItem
= getTracesFolderTreeItem(projectExplorerBot
);
338 treeItem
.contextMenu(FETCH_COMMAND_NAME
).click();
340 fBot
.button("Manage Profiles").click();
344 assertEquals(PROFILE_NAME
, fBot
.comboBoxWithLabel("Profile name:").getText());
345 assertEquals(CONNECTION_NODE_TEXT
, fBot
.textWithLabel("Nodes:").getText());
347 // Make sure if we go to the next page and come back that the first page
348 // still has valid values
349 SWTBotButton button
= fBot
.button("Next >");
350 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
352 button
= fBot
.button("< Back");
353 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
355 assertEquals(PROFILE_NAME
, fBot
.comboBoxWithLabel("Profile name:").getText());
356 assertEquals(CONNECTION_NODE_TEXT
, fBot
.textWithLabel("Nodes:").getText());
358 button
= fBot
.button("Next >");
359 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
362 selectionFunctor
.run();
364 SWTBotShell shell
= fBot
.activeShell();
366 button
= fBot
.button("Finish");
367 fBot
.waitUntil(Conditions
.widgetIsEnabled(button
));
369 fBot
.waitUntil(Conditions
.shellCloses(shell
));
370 SWTBotUtils
.waitForJobs();
372 verifyTracesFunctor
.run();
373 fBot
.closeAllEditors();
374 SWTBotUtils
.deleteProject(PROJECT_NAME
, fBot
);
378 private static void createProfile() {
379 fBot
.button("Add").click();
381 // The first tree is the preference "categories" on the left side, we
383 SWTBotTree tree
= fBot
.tree(1);
385 SWTBotTreeItem treeNode
= getTreeItem(fBot
, tree
, PROFILE_NAME
, "name (ssh://userinfo@host:22)");
387 SWTBotText uriLabel
= fBot
.textWithLabel("URI:");
388 uriLabel
.setText("file://");
389 SWTBotText nodeNameLabel
= fBot
.textWithLabel("Node name:");
390 nodeNameLabel
.setText(CONNECTION_NODE_NAME
);
392 SWTBotTreeItem traceRootNode
= treeNode
.getNode("/rootpath");
393 traceRootNode
.select();
394 SWTBotText pathLabel
= fBot
.textWithLabel("Root path:");
395 pathLabel
.setText(TRACE_LOCATION
);
396 fBot
.checkBox("Recursive").select();
398 // Add the ctf file pattern
399 treeNode
= traceRootNode
.getNode(".*");
401 SWTBotText filePatternLabel
= fBot
.textWithLabel("File pattern:");
402 filePatternLabel
.setText(LTTNG_TRACE_FILE_PATTERN
);
404 // Add the syslog file pattern
405 traceRootNode
.contextMenu("New Trace").click();
406 treeNode
= traceRootNode
.getNode(".*");
408 filePatternLabel
= fBot
.textWithLabel("File pattern:");
409 filePatternLabel
.setText(SYSLOG_FILE_PATTERN
);
410 SWTBotCombo combo
= fBot
.comboBoxWithLabel("Trace type:");
411 combo
.setSelection("Test trace : Test Syslog");
413 fBot
.button("OK").click();
416 private static void testTrace(TmfTraceElement tmfTraceElement
, String expectedTracePath
, String traceType
) {
417 assertEquals(traceType
, tmfTraceElement
.getTraceType());
418 IPath tracePath
= new Path(tmfTraceElement
.getElementPath());
419 assertEquals(expectedTracePath
, tracePath
.toString());
420 SWTBotUtils
.openEditor(fBot
, PROJECT_NAME
, tracePath
);
423 private static void deleteProfile() {
424 openRemoteProfilePreferences();
426 // The second tree is the remote profiles tree on the right side
427 SWTBotTree tree
= fBot
.tree(1);
428 SWTBotTreeItem treeNode
= tree
.getTreeItem(PROFILE_NAME
);
430 fBot
.button("Remove").click();
431 assertEquals(0, tree
.getAllItems().length
);
432 fBot
.button("OK").click();
435 private static SWTBotTreeItem
getTreeItem(SWTWorkbenchBot bot
, SWTBotTree tree
, String
... nodeNames
) {
436 if (nodeNames
.length
== 0) {
440 SWTBotTreeItem currentNode
= tree
.getTreeItem(nodeNames
[0]);
441 for (int i
= 1; i
< nodeNames
.length
; i
++) {
442 String nodeName
= nodeNames
[i
];
443 bot
.waitUntil(ConditionHelpers
.IsTreeChildNodeAvailable(nodeName
, currentNode
));
444 SWTBotTreeItem newNode
= currentNode
.getNode(nodeName
);
445 currentNode
= newNode
;
451 private static void openRemoteProfilePreferences() {
452 SWTBotShell preferencesShell
= SWTBotUtils
.openPreferences(fBot
);
454 // The first tree is the preference "categories" on the left side
455 SWTBot bot
= preferencesShell
.bot();
456 SWTBotTree tree
= bot
.tree(0);
457 SWTBotTreeItem treeNode
= tree
.getTreeItem("Tracing");
460 bot
.waitUntil(ConditionHelpers
.IsTreeChildNodeAvailable("Remote Profiles", treeNode
));
461 treeNode
= treeNode
.getNode("Remote Profiles");
465 private static SWTBotTreeItem
getTracesFolderTreeItem(SWTBotView projectExplorerBot
) {
466 SWTBotTreeItem treeItem
= projectExplorerBot
.bot().tree().getTreeItem(PROJECT_NAME
);
469 return treeItem
.getNode("Traces [0]");