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