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
.osgi
.util
.NLS
;
21 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
22 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
23 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
24 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
25 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
26 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotToolbarButton
;
27 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
28 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeColumn
;
29 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
30 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
31 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimePreferencesConstants
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestampFormat
;
34 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
.SWTBotTestCondition
;
35 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
36 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
37 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
38 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
39 import org
.junit
.Before
;
40 import org
.junit
.Test
;
41 import org
.junit
.runner
.RunWith
;
44 * SWTBot tests for column sorting in the Control Flow view.
46 * @author Bernd Hufmann
48 @SuppressWarnings("restriction")
49 @RunWith(SWTBotJunit4ClassRunner
.class)
50 public class ControlFlowViewSortingTest
extends KernelTestBase
{
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
55 private static final String FILTER_ACTION
= "Show View Filters";
56 private static final String FILTER_DIALOG_TITLE
= "Filter";
57 private static final String UNCHECK_ALL
= "Uncheck all";
58 private static final String CHECK_SUBTREE
= "Check subtree";
59 private static final String OK_BUTTON
= "OK";
61 private static final String PROCESS_COLUMN
= "Process";
62 private static final int PROCESS_COLUMN_ID
= 0;
63 private static final String TID_COLUMN
= "TID";
64 private static final int TID_COLUMN_ID
= 1;
65 private static final String PTID_COLUMN
= "PTID";
66 private static final String BIRTH_COLUMN
= "Birth time";
67 private static final int BIRTH_COLUMN_ID
= 3;
68 private static final String TRACE_COLUMN
= "Trace";
70 private static final String SYSTEMD_PROCESS_NAME
= "systemd";
71 private static final long SYSTEMD_BIRTHTIME
= 1361214078967531336L;
72 private static final String SYSTEMD_TID
= "1";
74 private static final String KTHREAD_PROCESS_NAME
= "kthreadd";
75 private static final long KTHREAD_BIRTHTIME
= 1361214078967533536L;
76 private static final String KTHREAD_TID
= "2";
78 private static final String LTTNG_CONSUMER_PROCESS_NAME
= "lttng-consumerd";
79 private static final long LTTNG_CONSUMER_BIRTHTIME
= 1361214078963717040L;
80 private static final String LTTNG_CONSUMER_TID
= "4034";
82 // ------------------------------------------------------------------------
84 // ------------------------------------------------------------------------
86 private SWTBotView fViewBot
;
88 // ------------------------------------------------------------------------
90 // ------------------------------------------------------------------------
96 public void before() {
99 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
100 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, "GMT-05:00");
101 TmfTimestampFormat
.updateDefaultFormats();
103 String tracePath
= FileLocator
.toFileURL(CtfTestTrace
.SYNC_DEST
.getTraceURL()).getPath();
104 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, tracePath
, KERNEL_TRACE_TYPE
);
105 fViewBot
= fBot
.viewByTitle("Control Flow");
108 } catch (IOException e
) {
114 public void after() {
115 IEclipsePreferences defaultPreferences
= InstanceScope
.INSTANCE
.getNode(Activator
.PLUGIN_ID
);
116 defaultPreferences
.put(ITmfTimePreferencesConstants
.TIME_ZONE
, "Local Time");
117 TmfTimestampFormat
.updateDefaultFormats();
121 // ------------------------------------------------------------------------
123 // ------------------------------------------------------------------------
125 * UI test of sorting of processes in CFV based on column selection. To verify that the sorting
126 * was executed correctly, the test will use bot.waitUntil() the column content has the right
130 public void testColumnSorting() {
131 // Create a known state
133 final SWTBotTree tree
= fViewBot
.bot().tree();
134 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(fBot
, tree
, SYSTEMD_PROCESS_NAME
);
137 testProcessSorting(tree
);
138 testTidSorting(tree
);
139 testPidSorting(tree
);
140 testBirthtimeSorting(tree
);
141 testTraceSorting(tree
);
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
147 private void applyFilter() {
148 // Select only certain root nodes and their children but filter out rest
149 SWTBotToolbarButton filterButton
= fViewBot
.toolbarButton(FILTER_ACTION
);
150 filterButton
.click();
151 SWTBotShell shell
= fBot
.shell(FILTER_DIALOG_TITLE
).activate();
153 SWTBot bot
= shell
.bot();
154 SWTBotTree treeBot
= bot
.tree();
155 bot
.button(UNCHECK_ALL
).click();
157 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
158 Integer checked
= UIThreadRunnable
.syncExec(treeCheckCounter
);
159 assertEquals("default", 0, checked
.intValue());
161 // select root nodes and their children
162 checkTreeItem(bot
, treeBot
, SYSTEMD_PROCESS_NAME
, 54);
163 checkTreeItem(bot
, treeBot
, KTHREAD_PROCESS_NAME
, 88);
164 checkTreeItem(bot
, treeBot
, LTTNG_CONSUMER_PROCESS_NAME
, 89);
166 bot
.button(OK_BUTTON
).click();
169 private static void checkTreeItem(SWTBot bot
, SWTBotTree treeBot
, String process
, int nbChecked
) {
170 SWTBotTreeItem item
= SWTBotUtils
.getTreeItem(bot
, treeBot
, process
);
172 bot
.button(CHECK_SUBTREE
).click();
173 TreeCheckedCounter treeCheckCounter
= new TreeCheckedCounter(treeBot
);
174 Integer checked
= UIThreadRunnable
.syncExec(treeCheckCounter
);
175 assertEquals(process
, nbChecked
, checked
.intValue());
178 private static void testProcessSorting(final SWTBotTree tree
) {
179 SWTBotTreeColumn column
= tree
.header(PROCESS_COLUMN
);
180 String
[] expected
= { KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
};
182 /* Sort direction Up */
183 SWTBotTestCondition condition
= getSortCondition(PROCESS_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
184 clickColumn(tree
, column
, condition
);
186 /* Sort direction Down */
187 condition
= getSortCondition(PROCESS_COLUMN
, 0, expected
, tree
, true);
188 clickColumn(tree
, column
, condition
);
191 private static void testTidSorting(final SWTBotTree tree
) {
192 String
[] expected
= { SYSTEMD_TID
, KTHREAD_TID
, LTTNG_CONSUMER_TID
};
193 SWTBotTreeColumn column
= tree
.header(TID_COLUMN
);
194 /* Sort direction Up */
195 SWTBotTestCondition condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, false);
196 clickColumn(tree
, column
, condition
);
198 /* Sort direction Down */
199 condition
= getSortCondition(TID_COLUMN
, TID_COLUMN_ID
, expected
, tree
, true);
200 clickColumn(tree
, column
, condition
);
204 * Note: In this test systemd and kthreadd have PTID 0 where
205 * lttng-consumerd has PTID -1 that is unknown. Currently
206 * in CFV PTID is only shown when it's greater than 0.
208 private static void testPidSorting(final SWTBotTree tree
) {
209 SWTBotTreeColumn column
= tree
.header(PTID_COLUMN
);
210 String
[] expected
= { LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
};
211 /* Sort direction Up */
212 SWTBotTestCondition condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
213 clickColumn(tree
, column
, condition
);
215 /* Sort direction Down */
216 String
[] expected2
= { SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
, LTTNG_CONSUMER_PROCESS_NAME
};
217 condition
= getSortCondition(PTID_COLUMN
, PROCESS_COLUMN_ID
, expected2
, tree
, false);
218 clickColumn(tree
, column
, condition
);
221 private static void testBirthtimeSorting(final SWTBotTree tree
) {
222 SWTBotTreeColumn column
= tree
.header(BIRTH_COLUMN
);
223 String
[] expected
= {
224 Utils
.formatTime(LTTNG_CONSUMER_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
225 Utils
.formatTime(SYSTEMD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
),
226 Utils
.formatTime(KTHREAD_BIRTHTIME
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
) };
228 /* Sort direction Up */
229 SWTBotTestCondition condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, false);
230 clickColumn(tree
, column
, condition
);
232 /* Sort direction Down */
233 condition
= getSortCondition(BIRTH_COLUMN
, BIRTH_COLUMN_ID
, expected
, tree
, true);
234 clickColumn(tree
, column
, condition
);
238 * Note: In this test only one trace is visualized in CFV.
239 * Sorting is done based on birth time (up direction).
240 * The implementation in CFV won't change the order when changing
243 private static void testTraceSorting(final SWTBotTree tree
) {
244 SWTBotTreeColumn column
= tree
.header(TRACE_COLUMN
);
245 String
[] expected
= { LTTNG_CONSUMER_PROCESS_NAME
, SYSTEMD_PROCESS_NAME
, KTHREAD_PROCESS_NAME
};
247 /* Sort direction Up */
248 SWTBotTestCondition condition
= getSortCondition(TRACE_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
249 clickColumn(tree
, column
, condition
);
251 /* Sort direction Down */
252 condition
= getSortCondition(TRACE_COLUMN
, PROCESS_COLUMN_ID
, expected
, tree
, false);
253 clickColumn(tree
, column
, condition
);
256 private static void clickColumn(final SWTBotTree tree
, SWTBotTreeColumn processColumn
, SWTBotTestCondition condition
) {
257 processColumn
.click();
258 fBot
.waitUntil(condition
);
261 private static SWTBotTestCondition
getSortCondition(final String testCase
, final int cell
, final String
[] expected
, final SWTBotTree tree
, final boolean reverse
) {
262 return new SWTBotTestCondition() {
264 public boolean test() throws Exception
{
265 SWTBotTreeItem
[] items
= tree
.getAllItems();
267 for (int i
= expected
.length
- 1; i
> 0; i
--) {
268 if (!expected
[i
].equals(items
[expected
.length
- (i
+ 1)].cell(cell
))) {
273 for (int i
= 0; i
< expected
.length
; i
++) {
274 if (!expected
[i
].equals(items
[i
].cell(cell
))) {
282 public String
getFailureMessage() {
283 return NLS
.bind("Test Case: \'{0}\' failed!", testCase
);