os.linux: Add some util methods to check thread state
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core.tests / src / org / eclipse / tracecompass / analysis / os / linux / core / tests / kernel / KernelThreadInformationProviderTest.java
CommitLineData
50a47aa6 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
50a47aa6
GB
3 *
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 *
9 * Contributors:
10 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
0f7a12d3 13package org.eclipse.tracecompass.analysis.os.linux.core.tests.kernel;
50a47aa6 14
e363eae1 15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
50a47aa6
GB
16import static org.junit.Assert.assertEquals;
17import static org.junit.Assert.assertNotNull;
18import static org.junit.Assert.assertNull;
19import static org.junit.Assert.assertTrue;
50a47aa6
GB
20
21import java.io.File;
22import java.util.Collection;
3fef638d 23import java.util.Collections;
50a47aa6 24import java.util.List;
3fef638d 25import java.util.Set;
50a47aa6 26
50a47aa6 27import org.eclipse.core.runtime.IProgressMonitor;
50a47aa6
GB
28import org.eclipse.core.runtime.NullProgressMonitor;
29import org.eclipse.jdt.annotation.NonNull;
0f7a12d3
AM
30import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
31import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelThreadInformationProvider;
32import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues;
0783ea52
GB
33import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.LinuxTestCase;
34import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.kernel.KernelAnalysisTestFactory;
50a47aa6
GB
35import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
36import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
37import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
38import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
50a47aa6
GB
39import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
40import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
41import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
42import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
43import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
50a47aa6
GB
44import org.junit.After;
45import org.junit.Before;
46import org.junit.Test;
47
c8f45ad2
MK
48import com.google.common.collect.ImmutableSet;
49
50a47aa6 50/**
6d16f5a9 51 * Test analysis-specific methods for the {@link KernelAnalysisModule} class.
50a47aa6
GB
52 *
53 * @author Geneviève Bastien
54 */
e363eae1 55public class KernelThreadInformationProviderTest {
50a47aa6 56
0783ea52 57 private static final @NonNull LinuxTestCase KERNEL_TEST_CASE = KernelAnalysisTestFactory.KERNEL_SCHED;
e363eae1 58
50a47aa6 59 private ITmfTrace fTrace;
6d16f5a9 60 private KernelAnalysisModule fModule;
50a47aa6
GB
61
62 private static void deleteSuppFiles(ITmfTrace trace) {
63 /* Remove supplementary files */
64 File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
65 for (File file : suppDir.listFiles()) {
66 file.delete();
67 }
68 }
69
70 /**
71 * Setup the trace for the tests
72 */
73 @Before
74 public void setUp() {
0783ea52 75 ITmfTrace trace = KERNEL_TEST_CASE.getKernelTrace();
1d83ed07
AM
76 deleteSuppFiles(trace);
77 ((TmfTrace) trace).traceOpened(new TmfTraceOpenedSignal(this, trace, null));
50a47aa6 78 IAnalysisModule module = null;
6d16f5a9 79 for (IAnalysisModule mod : TmfTraceUtils.getAnalysisModulesOfClass(trace, KernelAnalysisModule.class)) {
50a47aa6
GB
80 module = mod;
81 }
82 assertNotNull(module);
83 module.schedule();
84 module.waitForCompletion();
6d16f5a9 85 fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
1d83ed07 86 fTrace = trace;
50a47aa6
GB
87 }
88
89 /**
90 * Clean up
91 */
92 @After
93 public void tearDown() {
94 deleteSuppFiles(fTrace);
95 fTrace.dispose();
96 }
97
98 /**
99 * Test the
6d16f5a9 100 * {@link KernelThreadInformationProvider#getThreadIds(KernelAnalysisModule)}
50a47aa6
GB
101 * method
102 */
103 @Test
104 public void testGetThreadQuarks() {
6d16f5a9 105 KernelAnalysisModule module = checkNotNull(fModule);
e363eae1 106 Collection<Integer> threadIds = KernelThreadInformationProvider.getThreadIds(module);
c8f45ad2 107 assertEquals(ImmutableSet.<Integer>of(10,11,20,21,30,100), threadIds);
50a47aa6
GB
108 }
109
110 /**
111 * Test the
6d16f5a9 112 * {@link KernelThreadInformationProvider#getThreadOnCpu(KernelAnalysisModule, long, long)}
50a47aa6
GB
113 * method
114 */
115 @Test
116 public void testGetThreadOnCpu() {
6d16f5a9 117 KernelAnalysisModule module = checkNotNull(fModule);
50a47aa6
GB
118
119 /* Check with invalid timestamps */
e363eae1 120 Integer tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, -1);
50a47aa6
GB
121 assertNull(tid);
122
c422f500 123 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 90);
50a47aa6
GB
124 assertNull(tid);
125
126 /* Check with invalid cpus */
e363eae1 127 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 2, 20);
50a47aa6
GB
128 assertNull(tid);
129
e363eae1 130 tid = KernelThreadInformationProvider.getThreadOnCpu(module, -1, 20);
50a47aa6
GB
131 assertNull(tid);
132
133 /* Check valid values */
e363eae1 134 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 4);
50a47aa6
GB
135 assertNull(tid);
136
e363eae1 137 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 15);
50a47aa6
GB
138 assertNull(tid);
139
e363eae1 140 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 15);
50a47aa6
GB
141 assertEquals(Integer.valueOf(11), tid);
142
e363eae1 143 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 29);
50a47aa6
GB
144 assertEquals(Integer.valueOf(20), tid);
145
e363eae1 146 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 30);
50a47aa6
GB
147 assertEquals(Integer.valueOf(21), tid);
148
e363eae1 149 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 59);
50a47aa6
GB
150 assertEquals(Integer.valueOf(11), tid);
151
e363eae1 152 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 59);
50a47aa6
GB
153 assertEquals(Integer.valueOf(30), tid);
154
e363eae1 155 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 60);
50a47aa6
GB
156 assertEquals(Integer.valueOf(11), tid);
157
e363eae1 158 tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 60);
50a47aa6
GB
159 assertEquals(Integer.valueOf(21), tid);
160
161 }
162
3fef638d
AM
163 /**
164 * Test the {@link KernelThreadInformationProvider#getThreadsOfCpus} method.
165 */
166 @Test
167 public void testGetThreadsOfCpus() {
168 KernelAnalysisModule module = checkNotNull(fModule);
169 final long start = 45L;
170 final long end = 65L;
171
172 /*
173 * The test trace considers all scheduled out processes to remain in the
174 * "wait for cpu" state. In this particular case, the util method means
175 * "has ever run on CPU X".
176 */
177
178 Set<Integer> tids = KernelThreadInformationProvider.getThreadsOfCpus(module, Collections.singleton(0L), start, end);
179 assertNotNull(tids);
180 /*
181 * Only threads 11 and 100 should be present, due to the sched_switch at
182 * t=35.
183 */
184 assertEquals(ImmutableSet.of(11, 100), tids);
185
186 tids = KernelThreadInformationProvider.getThreadsOfCpus(module, Collections.singleton(1L), start, end);
187 assertNotNull(tids);
188 /* Only threads 10, 20, 21, 30 get scheduled on CPU 1. */
189 assertEquals(ImmutableSet.of(10, 20, 21, 30), tids);
190 }
191
192 /**
193 * Test the {@link KernelThreadInformationProvider#getActiveThreadsForRange}
194 * method.
195 */
196 @Test
197 public void testIsThreadActiveRange() {
198 KernelAnalysisModule module = checkNotNull(fModule);
199 final long start = 45L;
200 final long end = 65L;
201
202 /* Thread 30 should be active in the range */
203 Set<Integer> tids = KernelThreadInformationProvider.getActiveThreadsForRange(module, start, end);
204 assertNotNull(tids);
205 assertTrue(tids.contains(30));
206
207 // TODO Check for non-active states too. Unfortunately the test trace
208 // wrongly considers all processes to be in a active (value=5) state all
209 // the time.
210 }
211
50a47aa6
GB
212 /**
213 * Test the
6d16f5a9 214 * {@link KernelThreadInformationProvider#getParentPid(KernelAnalysisModule, Integer, long)}
50a47aa6
GB
215 * method
216 */
217 @Test
218 public void testGetPpid() {
6d16f5a9 219 KernelAnalysisModule module = checkNotNull(fModule);
50a47aa6
GB
220
221 /* Check with invalid timestamps */
e363eae1 222 Integer ppid = KernelThreadInformationProvider.getParentPid(module, 11, -1);
50a47aa6
GB
223 assertNull(ppid);
224
c422f500 225 ppid = KernelThreadInformationProvider.getParentPid(module, 11, 90);
50a47aa6
GB
226 assertNull(ppid);
227
228 /* Check with invalid cpus */
e363eae1 229 ppid = KernelThreadInformationProvider.getParentPid(module, -4, 20);
50a47aa6
GB
230 assertNull(ppid);
231
e363eae1 232 ppid = KernelThreadInformationProvider.getParentPid(module, 12, 20);
50a47aa6
GB
233 assertNull(ppid);
234
235 /* Check values with no parent */
e363eae1 236 ppid = KernelThreadInformationProvider.getParentPid(module, 10, 20);
50a47aa6
GB
237 assertEquals(Integer.valueOf(0), ppid);
238
e363eae1 239 ppid = KernelThreadInformationProvider.getParentPid(module, 30, 60);
50a47aa6
GB
240 assertEquals(Integer.valueOf(0), ppid);
241
242 /* Check parent determined at statedump */
e363eae1 243 ppid = KernelThreadInformationProvider.getParentPid(module, 11, 4);
50a47aa6
GB
244 assertNull(ppid);
245
e363eae1 246 ppid = KernelThreadInformationProvider.getParentPid(module, 11, 5);
50a47aa6
GB
247 assertEquals(Integer.valueOf(10), ppid);
248
249 /* Check parent after process fork */
e363eae1 250 ppid = KernelThreadInformationProvider.getParentPid(module, 21, 25);
50a47aa6
GB
251 assertEquals(Integer.valueOf(20), ppid);
252
e363eae1 253 ppid = KernelThreadInformationProvider.getParentPid(module, 21, 70);
50a47aa6
GB
254 assertEquals(Integer.valueOf(20), ppid);
255
256 }
257
258 /**
6d16f5a9 259 * Test the {@link KernelThreadInformationProvider#getExecutableName(KernelAnalysisModule, Integer)} method
50a47aa6
GB
260 */
261 @Test
262 public void testGetExecutableName() {
6d16f5a9 263 KernelAnalysisModule module = checkNotNull(fModule);
e363eae1 264
50a47aa6 265 /* Check with invalid threads */
e363eae1 266 String execName = KernelThreadInformationProvider.getExecutableName(module, 101);
50a47aa6
GB
267 assertNull(execName);
268
e363eae1 269 execName = KernelThreadInformationProvider.getExecutableName(module, -2);
50a47aa6
GB
270 assertNull(execName);
271
272 /* Check valid value */
e363eae1 273 execName = KernelThreadInformationProvider.getExecutableName(module, 20);
50a47aa6
GB
274 assertEquals("proc20", execName);
275
276 /* Check valid value with process name change in history */
e363eae1 277 execName = KernelThreadInformationProvider.getExecutableName(module, 21);
50a47aa6
GB
278 assertEquals("proc21", execName);
279
280 }
281
282 private static void testIntervals(String info, List<ITmfStateInterval> intervals, ITmfStateValue[] values) {
283 assertEquals(info + " interval count", values.length, intervals.size());
284 for (int i = 0; i < values.length; i++) {
285 assertEquals(info + " interval " + i, values[i], intervals.get(i).getStateValue());
286 }
287 }
288
289 /**
290 * Test the
6d16f5a9 291 * {@link KernelThreadInformationProvider#getStatusIntervalsForThread(KernelAnalysisModule, Integer, long, long, long, IProgressMonitor)}
50a47aa6
GB
292 * method
293 */
294 @Test
295 public void testGetStatusIntervalsForThread() {
6d16f5a9 296 KernelAnalysisModule module = checkNotNull(fModule);
50a47aa6
GB
297
298 IProgressMonitor monitor = new NullProgressMonitor();
299 Integer process21 = 21;
300 Integer process20 = 20;
301
302 /* Check invalid time ranges */
e363eae1 303 List<ITmfStateInterval> intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, -15, -5, 3, monitor);
50a47aa6
GB
304 assertTrue(intervals.isEmpty());
305
c422f500 306 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 90, 1500000000L, 50, monitor);
50a47aa6
GB
307 assertTrue(intervals.isEmpty());
308
309 /* Check invalid quarks */
e363eae1 310 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, -1, 0, 70L, 3, monitor);
50a47aa6
GB
311 assertTrue(intervals.isEmpty());
312
e363eae1 313 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, 0, 0, 70L, 3, monitor);
50a47aa6
GB
314 assertTrue(intervals.isEmpty());
315
316 /* Check different time ranges and resolutions */
317 ITmfStateValue[] values = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE,
2e3a31c4
FG
318 StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE, StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE,
319 StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE };
e363eae1 320 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 0, 70L, 3, monitor);
50a47aa6
GB
321 testIntervals("tid 21 [0,70,3]", intervals, values);
322
2e3a31c4
FG
323 ITmfStateValue[] values2 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE,
324 StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE };
e363eae1 325 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 1, 70L, 30, monitor);
50a47aa6
GB
326 testIntervals("tid 21 [0,70,30]", intervals, values2);
327
328 ITmfStateValue[] values3 = { StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE,
2e3a31c4 329 StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE };
e363eae1 330 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 25, 50L, 3, monitor);
50a47aa6
GB
331 testIntervals("tid 21 [25,50,3]", intervals, values3);
332
a810c240 333 ITmfStateValue[] values4 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE,
50a47aa6 334 StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE, StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE };
e363eae1 335 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 0, 70L, 3, monitor);
50a47aa6
GB
336 testIntervals("tid 20 [0,70,3]", intervals, values4);
337
338 ITmfStateValue[] values5 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE };
e363eae1 339 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 1, 70L, 30, monitor);
50a47aa6
GB
340 testIntervals("tid 20 [0,70,30]", intervals, values5);
341
342 ITmfStateValue[] values6 = { StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE,
343 StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE };
e363eae1 344 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 25, 50L, 3, monitor);
50a47aa6
GB
345 testIntervals("tid 20 [25,50,3]", intervals, values6);
346
c422f500
MK
347 ITmfStateValue[] values7 = { StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE };
348 intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 80L, 85L, 3, monitor);
349 testIntervals("tid 20 [80,85,3]", intervals, values7);
350
50a47aa6
GB
351 }
352
353}
This page took 0.06868 seconds and 5 git commands to generate.