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
;
17 import org
.eclipse
.core
.runtime
.FileLocator
;
18 import org
.eclipse
.core
.runtime
.preferences
.IEclipsePreferences
;
19 import org
.eclipse
.core
.runtime
.preferences
.InstanceScope
;
20 import org
.eclipse
.jdt
.annotation
.NonNull
;
21 import org
.eclipse
.osgi
.util
.NLS
;
22 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
23 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
24 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
25 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
26 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
27 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotToolbarButton
;
28 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
29 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeColumn
;
30 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
31 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
32 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimePreferencesConstants
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimePreferences
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestampFormat
;
39 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
40 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
.SWTBotTestCondition
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.timegraph
.AbstractTimeGraphView
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
46 import org
.junit
.Before
;
47 import org
.junit
.Test
;
48 import org
.junit
.runner
.RunWith
;
51 * SWTBot tests for column sorting in the Control Flow view.
53 * @author Bernd Hufmann
55 @SuppressWarnings("restriction")
56 @RunWith(SWTBotJunit4ClassRunner
.class)
57 public class ControlFlowViewSortingTest
extends KernelTestBase
{
59 // ------------------------------------------------------------------------
61 // ------------------------------------------------------------------------
62 private static final String FILTER_ACTION
= "Show View Filters";
63 private static final String FILTER_DIALOG_TITLE
= "Filter";
64 private static final String UNCHECK_ALL
= "Uncheck all";
65 private static final String CHECK_SUBTREE
= "Check subtree";
66 private static final String OK_BUTTON
= "OK";
68 private static final String PROCESS_COLUMN
= "Process";
69 private static final int PROCESS_COLUMN_ID
= 0;
70 private static final String TID_COLUMN
= "TID";
71 private static final int TID_COLUMN_ID
= 1;
72 private static final String PTID_COLUMN
= "PTID";
73 private static final String BIRTH_COLUMN
= "Birth time";
74 private static final int BIRTH_COLUMN_ID
= 3;
75 private static final String TRACE_COLUMN
= "Trace";
77 private static final String SYSTEMD_PROCESS_NAME
= "systemd";
78 private static final long SYSTEMD_BIRTHTIME
= 1361214078967531336L;
79 private static final String SYSTEMD_TID
= "1";
81 private static final String KTHREAD_PROCESS_NAME
= "kthreadd";
82 private static final long KTHREAD_BIRTHTIME
= 1361214078967533536L;
83 private static final String KTHREAD_TID
= "2";
85 private static final String LTTNG_CONSUMER_PROCESS_NAME
= "lttng-consumerd";
86 private static final long LTTNG_CONSUMER_BIRTHTIME
= 1361214078963717040L;
87 private static final String LTTNG_CONSUMER_TID
= "4034";
89 private static final @NonNull ITmfTimestamp TRACE_START_TIME
= TmfTimestamp
.create(1361214078963711320L, ITmfTimestamp
.NANOSECOND_SCALE
);
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
95 private SWTBotView fViewBot
;
97 // ------------------------------------------------------------------------
99 // ------------------------------------------------------------------------
105 public void before() {
108 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
109 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, "GMT-05:00");
110 TmfTimestampFormat
.updateDefaultFormats();
112 String tracePath
= FileLocator
.toFileURL(CtfTestTrace
.SYNC_DEST
.getTraceURL()).getPath();
113 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, tracePath
, KERNEL_TRACE_TYPE
);
114 fViewBot
= fBot
.viewByTitle("Control Flow");
117 } catch (IOException e
) {
123 public void after() {
124 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
125 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, TmfTimePreferences
.getDefaultPreferenceMap().get(ITmfTimePreferencesConstants
.TIME_ZONE
));
126 TmfTimestampFormat
.updateDefaultFormats();
130 // ------------------------------------------------------------------------
132 // ------------------------------------------------------------------------
134 * UI test of sorting of processes in CFV based on column selection. To verify that the sorting
135 * was executed correctly, the test will use bot.waitUntil() the column content has the right
139 public void testColumnSorting() {
140 fBot
.waitUntil(ConditionHelpers
.timeGraphIsReadyCondition((AbstractTimeGraphView
) fViewBot
.getViewReference().getPart(false), new TmfTimeRange(TRACE_START_TIME
, TRACE_START_TIME
), TRACE_START_TIME
));
142 // Create a known state
144 final SWTBotTree tree
= fViewBot
.bot().tree();
145 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(fBot
, tree
, SYSTEMD_PROCESS_NAME
);
148 testProcessSorting(tree
);
149 testTidSorting(tree
);
150 testPidSorting(tree
);
151 testBirthtimeSorting(tree
);
152 testTraceSorting(tree
);
155 // ------------------------------------------------------------------------
157 // ------------------------------------------------------------------------
158 private void applyFilter() {
159 // Select only certain root nodes and their children but filter out rest
160 SWTBotToolbarButton filterButton
= fViewBot
.toolbarButton(FILTER_ACTION
);
161 filterButton
.click();
162 SWTBotShell shell
= fBot
.shell(FILTER_DIALOG_TITLE
).activate();
164 SWTBot bot
= shell
.bot();
165 SWTBotTree treeBot
= bot
.tree();
166 bot
.button(UNCHECK_ALL
).click();
168 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
169 Integer checked
= UIThreadRunnable
.syncExec(treeCheckCounter
);
170 assertEquals("default", 0, checked
.intValue());
172 // select root nodes and their children
173 checkFilterTreeItems(bot
, treeBot
, SYSTEMD_PROCESS_NAME
);
174 checkFilterTreeItems(bot
, treeBot
, KTHREAD_PROCESS_NAME
);
175 checkFilterTreeItems(bot
, treeBot
, LTTNG_CONSUMER_PROCESS_NAME
);
177 bot
.button(OK_BUTTON
).click();
180 private static void checkFilterTreeItems(SWTBot bot
, SWTBotTree treeBot
, String process
) {
181 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(bot
, treeBot
, process
);
183 bot
.button(CHECK_SUBTREE
).click();
184 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
185 UIThreadRunnable
.syncExec(treeCheckCounter
);
188 private static void testProcessSorting(final SWTBotTree tree
) {
189 SWTBotTreeColumn column
= tree
.header(PROCESS_COLUMN
);
190 String
[] expected
= { KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
};
192 /* Sort direction Up */
193 SWTBotTestCondition condition
= getSortCondition(PROCESS_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
194 clickColumn(tree
, column
, condition
);
196 /* Sort direction Down */
197 condition
= getSortCondition(PROCESS_COLUMN
, 0, expected
, tree
, true);
198 clickColumn(tree
, column
, condition
);
201 private static void testTidSorting(final SWTBotTree tree
) {
202 String
[] expected
= { SYSTEMD_TID
, KTHREAD_TID
, LTTNG_CONSUMER_TID
};
203 SWTBotTreeColumn column
= tree
.header(TID_COLUMN
);
204 /* Sort direction Up */
205 SWTBotTestCondition condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, false);
206 clickColumn(tree
, column
, condition
);
208 /* Sort direction Down */
209 condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, true);
210 clickColumn(tree
, column
, condition
);
214 * Note: In this test systemd and kthreadd have PTID 0 where
215 * lttng-consumerd has PTID -1 that is unknown. Currently
216 * in CFV PTID is only shown when it's greater than 0.
218 private static void testPidSorting(final SWTBotTree tree
) {
219 SWTBotTreeColumn column
= tree
.header(PTID_COLUMN
);
220 String
[] expected
= { LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
};
221 /* Sort direction Up */
222 SWTBotTestCondition condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
223 clickColumn(tree
, column
, condition
);
225 /* Sort direction Down */
226 String
[] expected2
= { SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
};
227 condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected2
, tree
, false);
228 clickColumn(tree
, column
, condition
);
231 private static void testBirthtimeSorting(final SWTBotTree tree
) {
232 SWTBotTreeColumn column
= tree
.header(BIRTH_COLUMN
);
233 String
[] expected
= {
234 Utils
.formatTime(LTTNG_CONSUMER_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
235 Utils
.formatTime(SYSTEMD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
236 Utils
.formatTime(KTHREAD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
) };
238 /* Sort direction Up */
239 SWTBotTestCondition condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, false);
240 clickColumn(tree
, column
, condition
);
242 /* Sort direction Down */
243 condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, true);
244 clickColumn(tree
, column
, condition
);
248 * Note: In this test only one trace is visualized in CFV.
249 * Sorting is done based on birth time (up direction).
250 * The implementation in CFV won't change the order when changing
253 private static void testTraceSorting(final SWTBotTree tree
) {
254 SWTBotTreeColumn column
= tree
.header(TRACE_COLUMN
);
255 String
[] expected
= { LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
};
257 /* Sort direction Up */
258 SWTBotTestCondition condition
= getSortCondition(TRACE_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
259 clickColumn(tree
, column
, condition
);
261 /* Sort direction Down */
262 condition
= getSortCondition(TRACE_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
263 clickColumn(tree
, column
, condition
);
266 private static void clickColumn(final SWTBotTree tree
, SWTBotTreeColumn processColumn
, SWTBotTestCondition condition
) {
267 processColumn
.click();
268 fBot
.waitUntil(condition
);
271 private static SWTBotTestCondition
getSortCondition(final String testCase
, final int cell
, final String
[] expected
, final SWTBotTree tree
, final boolean reverse
) {
272 return new SWTBotTestCondition() {
274 public boolean test() throws Exception
{
275 SWTBotTreeItem
[] items
= tree
.getAllItems();
277 for (int i
= expected
.length
- 1; i
> 0; i
--) {
278 if (!expected
[i
].equals(items
[expected
.length
- (i
+ 1)].cell(cell
))) {
283 for (int i
= 0; i
< expected
.length
; i
++) {
284 if (!expected
[i
].equals(items
[i
].cell(cell
))) {
292 public String
getFailureMessage() {
293 return NLS
.bind("Test Case: \'{0}\' failed!", testCase
);