1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
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 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.kernelanalysis
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
16 import static org
.junit
.Assert
.assertEquals
;
17 import static org
.junit
.Assert
.assertNotNull
;
18 import static org
.junit
.Assert
.assertNull
;
19 import static org
.junit
.Assert
.assertTrue
;
20 import static org
.junit
.Assert
.fail
;
23 import java
.util
.Collection
;
24 import java
.util
.List
;
26 import org
.eclipse
.core
.runtime
.IPath
;
27 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
28 import org
.eclipse
.core
.runtime
.IStatus
;
29 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
30 import org
.eclipse
.jdt
.annotation
.NonNull
;
31 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.KernelAnalysis
;
32 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.KernelThreadInformationProvider
;
33 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.StateValues
;
34 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.Activator
;
35 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
36 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
37 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEvent
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTrace
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
46 import org
.eclipse
.tracecompass
.tmf
.tests
.stubs
.trace
.xml
.TmfXmlTraceStub
;
47 import org
.junit
.After
;
48 import org
.junit
.Before
;
49 import org
.junit
.Test
;
52 * Test analysis-specific methods for the {@link KernelAnalysis} class.
54 * @author Geneviève Bastien
56 public class KernelThreadInformationProviderTest
{
58 private static final @NonNull String LTTNG_KERNEL_FILE
= "testfiles/lttng_kernel_analysis.xml";
60 private ITmfTrace fTrace
;
61 private KernelAnalysis fModule
;
63 private static void deleteSuppFiles(ITmfTrace trace
) {
64 /* Remove supplementary files */
65 File suppDir
= new File(TmfTraceManager
.getSupplementaryFileDir(trace
));
66 for (File file
: suppDir
.listFiles()) {
72 * Setup the trace for the tests
76 fTrace
= new TmfXmlTraceStub();
77 IPath filePath
= Activator
.getAbsoluteFilePath(LTTNG_KERNEL_FILE
);
78 IStatus status
= fTrace
.validate(null, filePath
.toOSString());
80 fail(status
.getException().getMessage());
83 fTrace
.initTrace(null, filePath
.toOSString(), TmfEvent
.class);
84 } catch (TmfTraceException e
) {
87 deleteSuppFiles(fTrace
);
88 ((TmfTrace
) fTrace
).traceOpened(new TmfTraceOpenedSignal(this, fTrace
, null));
89 IAnalysisModule module
= null;
90 for (IAnalysisModule mod
: TmfTraceUtils
.getAnalysisModulesOfClass(fTrace
, KernelAnalysis
.class)) {
93 assertNotNull(module
);
95 module
.waitForCompletion();
96 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(fTrace
, KernelAnalysis
.class, KernelAnalysis
.ID
);
103 public void tearDown() {
104 deleteSuppFiles(fTrace
);
110 * {@link KernelThreadInformationProvider#getThreadIds(KernelAnalysis)}
114 public void testGetThreadQuarks() {
115 KernelAnalysis module
= checkNotNull(fModule
);
116 Collection
<Integer
> threadIds
= KernelThreadInformationProvider
.getThreadIds(module
);
117 assertEquals(7, threadIds
.size());
122 * {@link KernelThreadInformationProvider#getThreadOnCpu(KernelAnalysis, long, long)}
126 public void testGetThreadOnCpu() {
127 KernelAnalysis module
= checkNotNull(fModule
);
129 /* Check with invalid timestamps */
130 Integer tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, -1);
133 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, 80);
136 /* Check with invalid cpus */
137 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 2, 20);
140 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, -1, 20);
143 /* Check valid values */
144 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, 4);
147 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, 15);
150 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 1, 15);
151 assertEquals(Integer
.valueOf(11), tid
);
153 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 1, 29);
154 assertEquals(Integer
.valueOf(20), tid
);
156 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 1, 30);
157 assertEquals(Integer
.valueOf(21), tid
);
159 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, 59);
160 assertEquals(Integer
.valueOf(11), tid
);
162 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 1, 59);
163 assertEquals(Integer
.valueOf(30), tid
);
165 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 0, 60);
166 assertEquals(Integer
.valueOf(11), tid
);
168 tid
= KernelThreadInformationProvider
.getThreadOnCpu(module
, 1, 60);
169 assertEquals(Integer
.valueOf(21), tid
);
175 * {@link KernelThreadInformationProvider#getParentPid(KernelAnalysis, Integer, long)}
179 public void testGetPpid() {
180 KernelAnalysis module
= checkNotNull(fModule
);
182 /* Check with invalid timestamps */
183 Integer ppid
= KernelThreadInformationProvider
.getParentPid(module
, 11, -1);
186 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 11, 80);
189 /* Check with invalid cpus */
190 ppid
= KernelThreadInformationProvider
.getParentPid(module
, -4, 20);
193 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 12, 20);
196 /* Check values with no parent */
197 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 10, 20);
198 assertEquals(Integer
.valueOf(0), ppid
);
200 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 30, 60);
201 assertEquals(Integer
.valueOf(0), ppid
);
203 /* Check parent determined at statedump */
204 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 11, 4);
207 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 11, 5);
208 assertEquals(Integer
.valueOf(10), ppid
);
210 /* Check parent after process fork */
211 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 21, 25);
212 assertEquals(Integer
.valueOf(20), ppid
);
214 ppid
= KernelThreadInformationProvider
.getParentPid(module
, 21, 70);
215 assertEquals(Integer
.valueOf(20), ppid
);
220 * Test the {@link KernelThreadInformationProvider#getExecutableName(KernelAnalysis, Integer)} method
223 public void testGetExecutableName() {
224 KernelAnalysis module
= checkNotNull(fModule
);
226 /* Check with invalid threads */
227 String execName
= KernelThreadInformationProvider
.getExecutableName(module
, 101);
228 assertNull(execName
);
230 execName
= KernelThreadInformationProvider
.getExecutableName(module
, -2);
231 assertNull(execName
);
233 /* Check valid value */
234 execName
= KernelThreadInformationProvider
.getExecutableName(module
, 20);
235 assertEquals("proc20", execName
);
237 /* Check valid value with process name change in history */
238 execName
= KernelThreadInformationProvider
.getExecutableName(module
, 21);
239 assertEquals("proc21", execName
);
243 private static void testIntervals(String info
, List
<ITmfStateInterval
> intervals
, ITmfStateValue
[] values
) {
244 assertEquals(info
+ " interval count", values
.length
, intervals
.size());
245 for (int i
= 0; i
< values
.length
; i
++) {
246 assertEquals(info
+ " interval " + i
, values
[i
], intervals
.get(i
).getStateValue());
252 * {@link KernelThreadInformationProvider#getStatusIntervalsForThread(KernelAnalysis, Integer, long, long, long, IProgressMonitor)}
256 public void testGetStatusIntervalsForThread() {
257 KernelAnalysis module
= checkNotNull(fModule
);
259 IProgressMonitor monitor
= new NullProgressMonitor();
260 Integer process21
= 21;
261 Integer process20
= 20;
263 /* Check invalid time ranges */
264 List
<ITmfStateInterval
> intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process21
, -15, -5, 3, monitor
);
265 assertTrue(intervals
.isEmpty());
267 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process21
, 80, 1500000000L, 50, monitor
);
268 assertTrue(intervals
.isEmpty());
270 /* Check invalid quarks */
271 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, -1, 0, 70L, 3, monitor
);
272 assertTrue(intervals
.isEmpty());
274 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, 0, 0, 70L, 3, monitor
);
275 assertTrue(intervals
.isEmpty());
277 /* Check different time ranges and resolutions */
278 ITmfStateValue
[] values
= { TmfStateValue
.nullValue(), StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
,
279 StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
, StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
,
280 StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
};
281 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process21
, 0, 70L, 3, monitor
);
282 testIntervals("tid 21 [0,70,3]", intervals
, values
);
284 ITmfStateValue
[] values2
= { TmfStateValue
.nullValue(), StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
,
285 StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
};
286 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process21
, 1, 70L, 30, monitor
);
287 testIntervals("tid 21 [0,70,30]", intervals
, values2
);
289 ITmfStateValue
[] values3
= { StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
,
290 StateValues
.PROCESS_STATUS_RUN_SYSCALL_VALUE
};
291 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process21
, 25, 50L, 3, monitor
);
292 testIntervals("tid 21 [25,50,3]", intervals
, values3
);
294 ITmfStateValue
[] values4
= { TmfStateValue
.nullValue(), StateValues
.PROCESS_STATUS_WAIT_UNKNOWN_VALUE
,
295 StateValues
.PROCESS_STATUS_RUN_USERMODE_VALUE
, StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
};
296 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process20
, 0, 70L, 3, monitor
);
297 testIntervals("tid 20 [0,70,3]", intervals
, values4
);
299 ITmfStateValue
[] values5
= { TmfStateValue
.nullValue(), StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
};
300 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process20
, 1, 70L, 30, monitor
);
301 testIntervals("tid 20 [0,70,30]", intervals
, values5
);
303 ITmfStateValue
[] values6
= { StateValues
.PROCESS_STATUS_RUN_USERMODE_VALUE
,
304 StateValues
.PROCESS_STATUS_WAIT_FOR_CPU_VALUE
};
305 intervals
= KernelThreadInformationProvider
.getStatusIntervalsForThread(module
, process20
, 25, 50L, 3, monitor
);
306 testIntervals("tid 20 [25,50,3]", intervals
, values6
);