1 /*******************************************************************************
2 * Copyright (c) 2016 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
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.lttng2
.kernel
.ui
.swtbot
.tests
;
12 import static org
.junit
.Assert
.assertEquals
;
13 import static org
.junit
.Assert
.fail
;
15 import java
.io
.IOException
;
16 import java
.net
.URISyntaxException
;
17 import java
.nio
.file
.Paths
;
19 import org
.eclipse
.core
.runtime
.FileLocator
;
20 import org
.eclipse
.core
.runtime
.preferences
.IEclipsePreferences
;
21 import org
.eclipse
.core
.runtime
.preferences
.InstanceScope
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.osgi
.util
.NLS
;
24 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
25 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
26 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
27 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
28 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
29 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotToolbarButton
;
30 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
31 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeColumn
;
32 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
33 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
34 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimePreferencesConstants
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimePreferences
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestampFormat
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
.SWTBotTestCondition
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.timegraph
.AbstractTimeGraphView
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
46 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
47 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
48 import org
.junit
.Before
;
49 import org
.junit
.Test
;
50 import org
.junit
.runner
.RunWith
;
53 * SWTBot tests for column sorting in the Control Flow view.
55 * @author Bernd Hufmann
57 @SuppressWarnings("restriction")
58 @RunWith(SWTBotJunit4ClassRunner
.class)
59 public class ControlFlowViewSortingTest
extends KernelTestBase
{
61 // ------------------------------------------------------------------------
63 // ------------------------------------------------------------------------
64 private static final String TRACE_NAME
= "scp_dest";
65 private static final String FILTER_ACTION
= "Show View Filters";
66 private static final String FILTER_DIALOG_TITLE
= "Filter";
67 private static final String UNCHECK_ALL
= "Uncheck all";
68 private static final String CHECK_SUBTREE
= "Check subtree";
69 private static final String OK_BUTTON
= "OK";
71 private static final String PROCESS_COLUMN
= "Process";
72 private static final int PROCESS_COLUMN_ID
= 0;
73 private static final String TID_COLUMN
= "TID";
74 private static final int TID_COLUMN_ID
= 1;
75 private static final String PTID_COLUMN
= "PTID";
76 private static final String BIRTH_COLUMN
= "Birth time";
77 private static final int BIRTH_COLUMN_ID
= 3;
79 private static final String SYSTEMD_PROCESS_NAME
= "systemd";
80 private static final long SYSTEMD_BIRTHTIME
= 1361214078967531336L;
81 private static final String SYSTEMD_TID
= "1";
83 private static final String KTHREAD_PROCESS_NAME
= "kthreadd";
84 private static final long KTHREAD_BIRTHTIME
= 1361214078967533536L;
85 private static final String KTHREAD_TID
= "2";
87 private static final String LTTNG_CONSUMER_PROCESS_NAME
= "lttng-consumerd";
88 private static final long LTTNG_CONSUMER_BIRTHTIME
= 1361214078963717040L;
89 private static final String LTTNG_CONSUMER_TID
= "4034";
91 private static final @NonNull ITmfTimestamp TRACE_START_TIME
= TmfTimestamp
.create(1361214078963711320L, ITmfTimestamp
.NANOSECOND_SCALE
);
93 // ------------------------------------------------------------------------
95 // ------------------------------------------------------------------------
97 private SWTBotView fViewBot
;
99 // ------------------------------------------------------------------------
101 // ------------------------------------------------------------------------
107 public void before() {
110 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
111 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, "GMT-05:00");
112 TmfTimestampFormat
.updateDefaultFormats();
114 String tracePath
= Paths
.get(FileLocator
.toFileURL(CtfTestTrace
.SYNC_DEST
.getTraceURL()).toURI()).toString();
115 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, tracePath
, KERNEL_TRACE_TYPE
);
116 fViewBot
= fBot
.viewByTitle("Control Flow");
119 } catch (IOException
| URISyntaxException e
) {
125 public void after() {
126 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
127 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, TmfTimePreferences
.getDefaultPreferenceMap().get(ITmfTimePreferencesConstants
.TIME_ZONE
));
128 TmfTimestampFormat
.updateDefaultFormats();
132 // ------------------------------------------------------------------------
134 // ------------------------------------------------------------------------
136 * UI test of sorting of processes in CFV based on column selection. To verify that the sorting
137 * was executed correctly, the test will use bot.waitUntil() the column content has the right
141 public void testColumnSorting() {
142 fBot
.waitUntil(ConditionHelpers
.timeGraphIsReadyCondition((AbstractTimeGraphView
) fViewBot
.getViewReference().getPart(false), new TmfTimeRange(TRACE_START_TIME
, TRACE_START_TIME
), TRACE_START_TIME
));
144 // Create a known state
146 final SWTBotTree tree
= fViewBot
.bot().tree();
147 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(fBot
, tree
, TRACE_NAME
, SYSTEMD_PROCESS_NAME
);
150 testProcessSorting(tree
);
151 testTidSorting(tree
);
152 testPidSorting(tree
);
153 testBirthtimeSorting(tree
);
156 // ------------------------------------------------------------------------
158 // ------------------------------------------------------------------------
159 private void applyFilter() {
160 // Select only certain root nodes and their children but filter out rest
161 SWTBotToolbarButton filterButton
= fViewBot
.toolbarButton(FILTER_ACTION
);
162 filterButton
.click();
163 SWTBotShell shell
= fBot
.shell(FILTER_DIALOG_TITLE
).activate();
165 SWTBot bot
= shell
.bot();
166 SWTBotTree treeBot
= bot
.tree();
167 bot
.button(UNCHECK_ALL
).click();
169 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
170 Integer checked
= UIThreadRunnable
.syncExec(treeCheckCounter
);
171 assertEquals("default", 0, checked
.intValue());
173 // select root nodes and their children
174 checkFilterTreeItems(bot
, treeBot
, SYSTEMD_PROCESS_NAME
);
175 checkFilterTreeItems(bot
, treeBot
, KTHREAD_PROCESS_NAME
);
176 checkFilterTreeItems(bot
, treeBot
, LTTNG_CONSUMER_PROCESS_NAME
);
178 bot
.button(OK_BUTTON
).click();
181 private static void checkFilterTreeItems(SWTBot bot
, SWTBotTree treeBot
, String process
) {
182 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(bot
, treeBot
, TRACE_NAME
, process
);
184 bot
.button(CHECK_SUBTREE
).click();
185 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
186 UIThreadRunnable
.syncExec(treeCheckCounter
);
189 private static void testProcessSorting(final SWTBotTree tree
) {
190 SWTBotTreeColumn column
= tree
.header(PROCESS_COLUMN
);
191 String
[] expected
= { KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
};
193 /* Sort direction Up */
194 SWTBotTestCondition condition
= getSortCondition(PROCESS_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
195 clickColumn(tree
, column
, condition
);
197 /* Sort direction Down */
198 condition
= getSortCondition(PROCESS_COLUMN
, 0, expected
, tree
, true);
199 clickColumn(tree
, column
, condition
);
202 private static void testTidSorting(final SWTBotTree tree
) {
203 String
[] expected
= { SYSTEMD_TID
, KTHREAD_TID
, LTTNG_CONSUMER_TID
};
204 SWTBotTreeColumn column
= tree
.header(TID_COLUMN
);
205 /* Sort direction Up */
206 SWTBotTestCondition condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, false);
207 clickColumn(tree
, column
, condition
);
209 /* Sort direction Down */
210 condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, true);
211 clickColumn(tree
, column
, condition
);
215 * Note: In this test systemd and kthreadd have PTID 0 where
216 * lttng-consumerd has PTID -1 that is unknown. Currently
217 * in CFV PTID is only shown when it's greater than 0.
219 private static void testPidSorting(final SWTBotTree tree
) {
220 SWTBotTreeColumn column
= tree
.header(PTID_COLUMN
);
221 String
[] expected
= { LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
};
222 /* Sort direction Up */
223 SWTBotTestCondition condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
224 clickColumn(tree
, column
, condition
);
226 /* Sort direction Down */
227 String
[] expected2
= { SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
};
228 condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected2
, tree
, false);
229 clickColumn(tree
, column
, condition
);
232 private static void testBirthtimeSorting(final SWTBotTree tree
) {
233 SWTBotTreeColumn column
= tree
.header(BIRTH_COLUMN
);
234 String
[] expected
= {
235 Utils
.formatTime(LTTNG_CONSUMER_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
236 Utils
.formatTime(SYSTEMD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
237 Utils
.formatTime(KTHREAD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
) };
239 /* Sort direction Up */
240 SWTBotTestCondition condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, false);
241 clickColumn(tree
, column
, condition
);
243 /* Sort direction Down */
244 condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, true);
245 clickColumn(tree
, column
, condition
);
248 private static void clickColumn(final SWTBotTree tree
, SWTBotTreeColumn processColumn
, SWTBotTestCondition condition
) {
249 processColumn
.click();
250 fBot
.waitUntil(condition
);
253 private static SWTBotTestCondition
getSortCondition(final String testCase
, final int cell
, final String
[] expected
, final SWTBotTree tree
, final boolean reverse
) {
254 return new SWTBotTestCondition() {
256 public boolean test() throws Exception
{
257 SWTBotTreeItem
[] items
= tree
.getTreeItem(TRACE_NAME
).getItems();
259 for (int i
= expected
.length
- 1; i
> 0; i
--) {
260 if (!expected
[i
].equals(items
[expected
.length
- (i
+ 1)].cell(cell
))) {
265 for (int i
= 0; i
< expected
.length
; i
++) {
266 if (!expected
[i
].equals(items
[i
].cell(cell
))) {
274 public String
getFailureMessage() {
275 return NLS
.bind("Test Case: {0} failed!", testCase
);