Commit | Line | Data |
---|---|---|
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 | ||
e363eae1 | 13 | package org.eclipse.tracecompass.analysis.os.linux.core.tests.kernelanalysis; |
50a47aa6 | 14 | |
e363eae1 | 15 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
50a47aa6 GB |
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; | |
21 | ||
22 | import java.io.File; | |
23 | import java.util.Collection; | |
24 | import java.util.List; | |
25 | ||
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; | |
6d16f5a9 | 31 | import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysisModule; |
e363eae1 AM |
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; | |
698fde87 | 35 | import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.trace.TmfXmlKernelTraceStub; |
50a47aa6 GB |
36 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; |
37 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
38 | import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; | |
39 | import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; | |
40 | import org.eclipse.tracecompass.tmf.core.event.TmfEvent; | |
41 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; | |
42 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
43 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
44 | import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; | |
45 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
46 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | |
50a47aa6 GB |
47 | import org.junit.After; |
48 | import org.junit.Before; | |
49 | import org.junit.Test; | |
50 | ||
c8f45ad2 MK |
51 | import com.google.common.collect.ImmutableSet; |
52 | ||
50a47aa6 | 53 | /** |
6d16f5a9 | 54 | * Test analysis-specific methods for the {@link KernelAnalysisModule} class. |
50a47aa6 GB |
55 | * |
56 | * @author Geneviève Bastien | |
57 | */ | |
e363eae1 | 58 | public class KernelThreadInformationProviderTest { |
50a47aa6 GB |
59 | |
60 | private static final @NonNull String LTTNG_KERNEL_FILE = "testfiles/lttng_kernel_analysis.xml"; | |
e363eae1 | 61 | |
50a47aa6 | 62 | private ITmfTrace fTrace; |
6d16f5a9 | 63 | private KernelAnalysisModule fModule; |
50a47aa6 GB |
64 | |
65 | private static void deleteSuppFiles(ITmfTrace trace) { | |
66 | /* Remove supplementary files */ | |
67 | File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace)); | |
68 | for (File file : suppDir.listFiles()) { | |
69 | file.delete(); | |
70 | } | |
71 | } | |
72 | ||
73 | /** | |
74 | * Setup the trace for the tests | |
75 | */ | |
76 | @Before | |
77 | public void setUp() { | |
698fde87 | 78 | ITmfTrace trace = new TmfXmlKernelTraceStub(); |
50a47aa6 | 79 | IPath filePath = Activator.getAbsoluteFilePath(LTTNG_KERNEL_FILE); |
1d83ed07 | 80 | IStatus status = trace.validate(null, filePath.toOSString()); |
50a47aa6 GB |
81 | if (!status.isOK()) { |
82 | fail(status.getException().getMessage()); | |
83 | } | |
84 | try { | |
1d83ed07 | 85 | trace.initTrace(null, filePath.toOSString(), TmfEvent.class); |
50a47aa6 GB |
86 | } catch (TmfTraceException e) { |
87 | fail(e.getMessage()); | |
88 | } | |
1d83ed07 AM |
89 | deleteSuppFiles(trace); |
90 | ((TmfTrace) trace).traceOpened(new TmfTraceOpenedSignal(this, trace, null)); | |
50a47aa6 | 91 | IAnalysisModule module = null; |
6d16f5a9 | 92 | for (IAnalysisModule mod : TmfTraceUtils.getAnalysisModulesOfClass(trace, KernelAnalysisModule.class)) { |
50a47aa6 GB |
93 | module = mod; |
94 | } | |
95 | assertNotNull(module); | |
96 | module.schedule(); | |
97 | module.waitForCompletion(); | |
6d16f5a9 | 98 | fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID); |
1d83ed07 | 99 | fTrace = trace; |
50a47aa6 GB |
100 | } |
101 | ||
102 | /** | |
103 | * Clean up | |
104 | */ | |
105 | @After | |
106 | public void tearDown() { | |
107 | deleteSuppFiles(fTrace); | |
108 | fTrace.dispose(); | |
109 | } | |
110 | ||
111 | /** | |
112 | * Test the | |
6d16f5a9 | 113 | * {@link KernelThreadInformationProvider#getThreadIds(KernelAnalysisModule)} |
50a47aa6 GB |
114 | * method |
115 | */ | |
116 | @Test | |
117 | public void testGetThreadQuarks() { | |
6d16f5a9 | 118 | KernelAnalysisModule module = checkNotNull(fModule); |
e363eae1 | 119 | Collection<Integer> threadIds = KernelThreadInformationProvider.getThreadIds(module); |
c8f45ad2 | 120 | assertEquals(ImmutableSet.<Integer>of(10,11,20,21,30,100), threadIds); |
50a47aa6 GB |
121 | } |
122 | ||
123 | /** | |
124 | * Test the | |
6d16f5a9 | 125 | * {@link KernelThreadInformationProvider#getThreadOnCpu(KernelAnalysisModule, long, long)} |
50a47aa6 GB |
126 | * method |
127 | */ | |
128 | @Test | |
129 | public void testGetThreadOnCpu() { | |
6d16f5a9 | 130 | KernelAnalysisModule module = checkNotNull(fModule); |
50a47aa6 GB |
131 | |
132 | /* Check with invalid timestamps */ | |
e363eae1 | 133 | Integer tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, -1); |
50a47aa6 GB |
134 | assertNull(tid); |
135 | ||
e363eae1 | 136 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 80); |
50a47aa6 GB |
137 | assertNull(tid); |
138 | ||
139 | /* Check with invalid cpus */ | |
e363eae1 | 140 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 2, 20); |
50a47aa6 GB |
141 | assertNull(tid); |
142 | ||
e363eae1 | 143 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, -1, 20); |
50a47aa6 GB |
144 | assertNull(tid); |
145 | ||
146 | /* Check valid values */ | |
e363eae1 | 147 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 4); |
50a47aa6 GB |
148 | assertNull(tid); |
149 | ||
e363eae1 | 150 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 15); |
50a47aa6 GB |
151 | assertNull(tid); |
152 | ||
e363eae1 | 153 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 15); |
50a47aa6 GB |
154 | assertEquals(Integer.valueOf(11), tid); |
155 | ||
e363eae1 | 156 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 29); |
50a47aa6 GB |
157 | assertEquals(Integer.valueOf(20), tid); |
158 | ||
e363eae1 | 159 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 30); |
50a47aa6 GB |
160 | assertEquals(Integer.valueOf(21), tid); |
161 | ||
e363eae1 | 162 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 59); |
50a47aa6 GB |
163 | assertEquals(Integer.valueOf(11), tid); |
164 | ||
e363eae1 | 165 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 59); |
50a47aa6 GB |
166 | assertEquals(Integer.valueOf(30), tid); |
167 | ||
e363eae1 | 168 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 60); |
50a47aa6 GB |
169 | assertEquals(Integer.valueOf(11), tid); |
170 | ||
e363eae1 | 171 | tid = KernelThreadInformationProvider.getThreadOnCpu(module, 1, 60); |
50a47aa6 GB |
172 | assertEquals(Integer.valueOf(21), tid); |
173 | ||
174 | } | |
175 | ||
176 | /** | |
177 | * Test the | |
6d16f5a9 | 178 | * {@link KernelThreadInformationProvider#getParentPid(KernelAnalysisModule, Integer, long)} |
50a47aa6 GB |
179 | * method |
180 | */ | |
181 | @Test | |
182 | public void testGetPpid() { | |
6d16f5a9 | 183 | KernelAnalysisModule module = checkNotNull(fModule); |
50a47aa6 GB |
184 | |
185 | /* Check with invalid timestamps */ | |
e363eae1 | 186 | Integer ppid = KernelThreadInformationProvider.getParentPid(module, 11, -1); |
50a47aa6 GB |
187 | assertNull(ppid); |
188 | ||
e363eae1 | 189 | ppid = KernelThreadInformationProvider.getParentPid(module, 11, 80); |
50a47aa6 GB |
190 | assertNull(ppid); |
191 | ||
192 | /* Check with invalid cpus */ | |
e363eae1 | 193 | ppid = KernelThreadInformationProvider.getParentPid(module, -4, 20); |
50a47aa6 GB |
194 | assertNull(ppid); |
195 | ||
e363eae1 | 196 | ppid = KernelThreadInformationProvider.getParentPid(module, 12, 20); |
50a47aa6 GB |
197 | assertNull(ppid); |
198 | ||
199 | /* Check values with no parent */ | |
e363eae1 | 200 | ppid = KernelThreadInformationProvider.getParentPid(module, 10, 20); |
50a47aa6 GB |
201 | assertEquals(Integer.valueOf(0), ppid); |
202 | ||
e363eae1 | 203 | ppid = KernelThreadInformationProvider.getParentPid(module, 30, 60); |
50a47aa6 GB |
204 | assertEquals(Integer.valueOf(0), ppid); |
205 | ||
206 | /* Check parent determined at statedump */ | |
e363eae1 | 207 | ppid = KernelThreadInformationProvider.getParentPid(module, 11, 4); |
50a47aa6 GB |
208 | assertNull(ppid); |
209 | ||
e363eae1 | 210 | ppid = KernelThreadInformationProvider.getParentPid(module, 11, 5); |
50a47aa6 GB |
211 | assertEquals(Integer.valueOf(10), ppid); |
212 | ||
213 | /* Check parent after process fork */ | |
e363eae1 | 214 | ppid = KernelThreadInformationProvider.getParentPid(module, 21, 25); |
50a47aa6 GB |
215 | assertEquals(Integer.valueOf(20), ppid); |
216 | ||
e363eae1 | 217 | ppid = KernelThreadInformationProvider.getParentPid(module, 21, 70); |
50a47aa6 GB |
218 | assertEquals(Integer.valueOf(20), ppid); |
219 | ||
220 | } | |
221 | ||
222 | /** | |
6d16f5a9 | 223 | * Test the {@link KernelThreadInformationProvider#getExecutableName(KernelAnalysisModule, Integer)} method |
50a47aa6 GB |
224 | */ |
225 | @Test | |
226 | public void testGetExecutableName() { | |
6d16f5a9 | 227 | KernelAnalysisModule module = checkNotNull(fModule); |
e363eae1 | 228 | |
50a47aa6 | 229 | /* Check with invalid threads */ |
e363eae1 | 230 | String execName = KernelThreadInformationProvider.getExecutableName(module, 101); |
50a47aa6 GB |
231 | assertNull(execName); |
232 | ||
e363eae1 | 233 | execName = KernelThreadInformationProvider.getExecutableName(module, -2); |
50a47aa6 GB |
234 | assertNull(execName); |
235 | ||
236 | /* Check valid value */ | |
e363eae1 | 237 | execName = KernelThreadInformationProvider.getExecutableName(module, 20); |
50a47aa6 GB |
238 | assertEquals("proc20", execName); |
239 | ||
240 | /* Check valid value with process name change in history */ | |
e363eae1 | 241 | execName = KernelThreadInformationProvider.getExecutableName(module, 21); |
50a47aa6 GB |
242 | assertEquals("proc21", execName); |
243 | ||
244 | } | |
245 | ||
246 | private static void testIntervals(String info, List<ITmfStateInterval> intervals, ITmfStateValue[] values) { | |
247 | assertEquals(info + " interval count", values.length, intervals.size()); | |
248 | for (int i = 0; i < values.length; i++) { | |
249 | assertEquals(info + " interval " + i, values[i], intervals.get(i).getStateValue()); | |
250 | } | |
251 | } | |
252 | ||
253 | /** | |
254 | * Test the | |
6d16f5a9 | 255 | * {@link KernelThreadInformationProvider#getStatusIntervalsForThread(KernelAnalysisModule, Integer, long, long, long, IProgressMonitor)} |
50a47aa6 GB |
256 | * method |
257 | */ | |
258 | @Test | |
259 | public void testGetStatusIntervalsForThread() { | |
6d16f5a9 | 260 | KernelAnalysisModule module = checkNotNull(fModule); |
50a47aa6 GB |
261 | |
262 | IProgressMonitor monitor = new NullProgressMonitor(); | |
263 | Integer process21 = 21; | |
264 | Integer process20 = 20; | |
265 | ||
266 | /* Check invalid time ranges */ | |
e363eae1 | 267 | List<ITmfStateInterval> intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, -15, -5, 3, monitor); |
50a47aa6 GB |
268 | assertTrue(intervals.isEmpty()); |
269 | ||
e363eae1 | 270 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 80, 1500000000L, 50, monitor); |
50a47aa6 GB |
271 | assertTrue(intervals.isEmpty()); |
272 | ||
273 | /* Check invalid quarks */ | |
e363eae1 | 274 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, -1, 0, 70L, 3, monitor); |
50a47aa6 GB |
275 | assertTrue(intervals.isEmpty()); |
276 | ||
e363eae1 | 277 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, 0, 0, 70L, 3, monitor); |
50a47aa6 GB |
278 | assertTrue(intervals.isEmpty()); |
279 | ||
280 | /* Check different time ranges and resolutions */ | |
281 | ITmfStateValue[] values = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE, | |
282 | StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE, StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE, | |
283 | StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE }; | |
e363eae1 | 284 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 0, 70L, 3, monitor); |
50a47aa6 GB |
285 | testIntervals("tid 21 [0,70,3]", intervals, values); |
286 | ||
287 | ITmfStateValue[] values2 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE, | |
288 | StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE }; | |
e363eae1 | 289 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 1, 70L, 30, monitor); |
50a47aa6 GB |
290 | testIntervals("tid 21 [0,70,30]", intervals, values2); |
291 | ||
292 | ITmfStateValue[] values3 = { StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE, | |
293 | StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE }; | |
e363eae1 | 294 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 25, 50L, 3, monitor); |
50a47aa6 GB |
295 | testIntervals("tid 21 [25,50,3]", intervals, values3); |
296 | ||
a810c240 | 297 | ITmfStateValue[] values4 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE, |
50a47aa6 | 298 | StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE, StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE }; |
e363eae1 | 299 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 0, 70L, 3, monitor); |
50a47aa6 GB |
300 | testIntervals("tid 20 [0,70,3]", intervals, values4); |
301 | ||
302 | ITmfStateValue[] values5 = { TmfStateValue.nullValue(), StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE }; | |
e363eae1 | 303 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 1, 70L, 30, monitor); |
50a47aa6 GB |
304 | testIntervals("tid 20 [0,70,30]", intervals, values5); |
305 | ||
306 | ITmfStateValue[] values6 = { StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE, | |
307 | StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE }; | |
e363eae1 | 308 | intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 25, 50L, 3, monitor); |
50a47aa6 GB |
309 | testIntervals("tid 20 [25,50,3]", intervals, values6); |
310 | ||
311 | } | |
312 | ||
313 | } |