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
.cpuusage
;
15 import static org
.junit
.Assert
.assertEquals
;
16 import static org
.junit
.Assert
.assertNotNull
;
17 import static org
.junit
.Assert
.assertNull
;
18 import static org
.junit
.Assert
.assertTrue
;
19 import static org
.junit
.Assert
.fail
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collections
;
24 import java
.util
.HashMap
;
25 import java
.util
.List
;
28 import org
.eclipse
.core
.runtime
.IPath
;
29 import org
.eclipse
.core
.runtime
.IStatus
;
30 import org
.eclipse
.jdt
.annotation
.NonNull
;
31 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.cpuusage
.KernelCpuUsageAnalysis
;
32 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelAnalysisModule
;
33 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.Activator
;
34 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.stubs
.trace
.TmfXmlKernelTraceStub
;
35 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
36 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
37 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
38 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
39 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
40 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
41 import org
.eclipse
.tracecompass
.statesystem
.core
.tests
.shared
.utils
.StateIntervalStub
;
42 import org
.eclipse
.tracecompass
.statesystem
.core
.tests
.shared
.utils
.StateSystemTestUtils
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEvent
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.tests
.shared
.TmfTestHelper
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTrace
;
50 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
51 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
52 import org
.junit
.After
;
53 import org
.junit
.Before
;
54 import org
.junit
.Test
;
56 import com
.google
.common
.collect
.ImmutableSet
;
59 * Test suite for the {@link KernelCpuUsageAnalysis} class
61 * @author Geneviève Bastien
63 public class CpuUsageStateProviderTest
{
65 private static final String CPU_USAGE_FILE
= "testfiles/cpu_analysis.xml";
67 private ITmfTrace fTrace
;
68 private KernelCpuUsageAnalysis fModule
;
70 private static void deleteSuppFiles(ITmfTrace trace
) {
71 /* Remove supplementary files */
72 File suppDir
= new File(TmfTraceManager
.getSupplementaryFileDir(trace
));
73 for (File file
: suppDir
.listFiles()) {
79 * Setup the trace for the tests
83 ITmfTrace trace
= new TmfXmlKernelTraceStub();
84 IPath filePath
= Activator
.getAbsoluteFilePath(CPU_USAGE_FILE
);
85 IStatus status
= trace
.validate(null, filePath
.toOSString());
87 fail(status
.getException().getMessage());
90 trace
.initTrace(null, filePath
.toOSString(), TmfEvent
.class);
91 } catch (TmfTraceException e
) {
94 deleteSuppFiles(trace
);
95 ((TmfTrace
) trace
).traceOpened(new TmfTraceOpenedSignal(this, trace
, null));
97 * FIXME: Make sure this analysis is finished before running the CPU
98 * analysis. This block can be removed once analysis dependency and
99 * request precedence is implemented
101 IAnalysisModule module
= null;
102 for (IAnalysisModule mod
: TmfTraceUtils
.getAnalysisModulesOfClass(trace
, KernelAnalysisModule
.class)) {
105 assertNotNull(module
);
107 module
.waitForCompletion();
108 /* End of the FIXME block */
110 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, KernelCpuUsageAnalysis
.class, KernelCpuUsageAnalysis
.ID
);
111 assertNotNull(fModule
);
119 public void tearDown() {
120 deleteSuppFiles(fTrace
);
125 * Test that the analysis executes without problems
128 public void testAnalysisExecution() {
129 /* Make sure the analysis hasn't run yet */
130 assertNull(fModule
.getStateSystem());
132 /* Execute the analysis */
133 assertTrue(TmfTestHelper
.executeAnalysis(fModule
));
134 assertNotNull(fModule
.getStateSystem());
138 * Test that the state system is returned with the expected results
141 public void testReturnedStateSystem() {
143 fModule
.waitForCompletion();
144 ITmfStateSystem ss
= fModule
.getStateSystem();
146 assertEquals(1L, ss
.getStartTime());
147 assertEquals(25L, ss
.getCurrentEndTime());
150 int cpusQuark
= ss
.getQuarkAbsolute(Attributes
.CPUS
);
153 * There should be 2 CPU entries: 0 and 1 and 3 process entries
156 List
<Integer
> cpuQuarks
= ss
.getSubAttributes(cpusQuark
, false);
157 assertEquals(2, cpuQuarks
.size());
158 for (Integer cpuQuark
: cpuQuarks
) {
159 assertEquals(3, ss
.getSubAttributes(cpuQuark
, false).size());
162 /* Test the intervals of proc2 on CPU 0 */
163 List
<@NonNull ITmfStateInterval
> intervals
= new ArrayList
<>();
164 intervals
.add(new StateIntervalStub(1, 19, TmfStateValue
.nullValue()));
165 intervals
.add(new StateIntervalStub(20, 25, TmfStateValue
.newValueLong(19L)));
166 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "0", "2");
168 /* Test the intervals of proc 4 CPU 1 */
170 intervals
.add(new StateIntervalStub(1, 4, TmfStateValue
.nullValue()));
171 intervals
.add(new StateIntervalStub(5, 14, TmfStateValue
.newValueLong(3L)));
172 intervals
.add(new StateIntervalStub(15, 25, TmfStateValue
.newValueLong(8L)));
173 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "1", "4");
175 /* Test the intervals of proc 3 on both CPUs */
177 intervals
.add(new StateIntervalStub(1, 24, TmfStateValue
.nullValue()));
178 intervals
.add(new StateIntervalStub(25, 25, TmfStateValue
.newValueLong(5L)));
179 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "0", "3");
182 intervals
.add(new StateIntervalStub(1, 1, TmfStateValue
.nullValue()));
183 intervals
.add(new StateIntervalStub(2, 9, TmfStateValue
.newValueLong(1L)));
184 intervals
.add(new StateIntervalStub(10, 25, TmfStateValue
.newValueLong(6L)));
185 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "1", "3");
188 * Query at the end and make sure all processes on all CPU have the
191 Map
<@NonNull String
@NonNull [], @NonNull ITmfStateValue
> map
= new HashMap
<>();
192 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "1"), TmfStateValue
.newValueLong(0L));
193 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "2"), TmfStateValue
.newValueLong(19L));
194 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "3"), TmfStateValue
.newValueLong(5L));
195 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "1"), TmfStateValue
.newValueLong(5L));
196 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "3"), TmfStateValue
.newValueLong(6L));
197 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "4"), TmfStateValue
.newValueLong(8L));
198 StateSystemTestUtils
.testValuesAtTime(ss
, 25L, map
);
200 } catch (AttributeNotFoundException e
) {
201 fail(e
.getMessage());
207 * {@link KernelCpuUsageAnalysis#getCpuUsageInRange(java.util.Set, long, long)}
213 public void testUsageInRange() {
215 fModule
.waitForCompletion();
217 /* This range should query the total range */
218 Map
<String
, Long
> expected
= new HashMap
<>();
219 expected
.put("0/1", 0L);
220 expected
.put("0/2", 19L);
221 expected
.put("0/3", 5L);
222 expected
.put("1/1", 5L);
223 expected
.put("1/3", 6L);
224 expected
.put("1/4", 13L);
225 expected
.put("total", 48L);
226 expected
.put("total/1", 5L);
227 expected
.put("total/2", 19L);
228 expected
.put("total/3", 11L);
229 expected
.put("total/4", 13L);
230 expected
.put("0", 24L);
231 expected
.put("1", 24L);
232 Map
<String
, Long
> resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 0L, 30L);
233 assertEquals(expected
, resultMap
);
235 /* Verify a range when a process runs at the start */
237 expected
.put("0/1", 0L);
238 expected
.put("0/2", 0L);
239 expected
.put("0/3", 3L);
240 expected
.put("1/1", 0L);
241 expected
.put("1/3", 0L);
242 expected
.put("1/4", 3L);
243 expected
.put("total", 6L);
244 expected
.put("total/1", 0L);
245 expected
.put("total/2", 0L);
246 expected
.put("total/3", 3L);
247 expected
.put("total/4", 3L);
248 expected
.put("0", 3L);
249 expected
.put("1", 3L);
250 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 22L, 25L);
251 assertEquals(expected
, resultMap
);
253 /* Verify a range when a process runs at the end */
255 expected
.put("0/1", 0L);
256 expected
.put("0/2", 3L);
257 expected
.put("0/3", 0L);
258 expected
.put("1/1", 0L);
259 expected
.put("1/3", 1L);
260 expected
.put("1/4", 2L);
261 expected
.put("total", 6L);
262 expected
.put("total/1", 0L);
263 expected
.put("total/2", 3L);
264 expected
.put("total/3", 1L);
265 expected
.put("total/4", 2L);
266 expected
.put("0", 3L);
267 expected
.put("1", 3L);
268 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 1L, 4L);
269 assertEquals(expected
, resultMap
);
271 /* Verify a range when a process runs at start and at the end */
273 expected
.put("0/1", 0L);
274 expected
.put("0/2", 9L);
275 expected
.put("0/3", 0L);
276 expected
.put("1/1", 0L);
277 expected
.put("1/3", 5L);
278 expected
.put("1/4", 4L);
279 expected
.put("total", 18L);
280 expected
.put("total/1", 0L);
281 expected
.put("total/2", 9L);
282 expected
.put("total/3", 5L);
283 expected
.put("total/4", 4L);
284 expected
.put("0", 9L);
285 expected
.put("1", 9L);
286 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 4L, 13L);
287 assertEquals(expected
, resultMap
);
291 * Tests the cpu usage for a cpu subset within a range
294 public void testInRangeWithCpuSubset() {
297 fModule
.waitForCompletion();
299 /* Verify a range when a process runs at start and at the end */
300 Map
<String
, Long
> expected
= new HashMap
<>();
301 expected
.put("0/1", 0L);
302 expected
.put("0/2", 9L);
303 expected
.put("0/3", 0L);
304 expected
.put("total/1", 0L);
305 expected
.put("total/2", 9L);
306 expected
.put("total/3", 0L);
307 expected
.put("0", 9L);
308 expected
.put("total", 9L);
309 Map
<String
, Long
> resultMap
= fModule
.getCpuUsageInRange(Collections
.<@NonNull Integer
> singleton(0), 4L, 13L);
310 assertEquals(expected
, resultMap
);
312 /* Verify a range when a process runs at start and at the end */
314 expected
.put("1/1", 0L);
315 expected
.put("1/3", 5L);
316 expected
.put("1/4", 4L);
317 expected
.put("total/1", 0L);
318 expected
.put("total/3", 5L);
319 expected
.put("total/4", 4L);
320 expected
.put("1", 9L);
321 expected
.put("total", 9L);
322 resultMap
= fModule
.getCpuUsageInRange(ImmutableSet
.of(1,2), 4L, 13L);
323 assertEquals(expected
, resultMap
);