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 java
.util
.stream
.Collectors
;
29 import java
.util
.stream
.StreamSupport
;
31 import org
.eclipse
.core
.runtime
.IPath
;
32 import org
.eclipse
.core
.runtime
.IStatus
;
33 import org
.eclipse
.jdt
.annotation
.NonNull
;
34 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.cpuusage
.KernelCpuUsageAnalysis
;
35 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelAnalysisModule
;
36 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.Activator
;
37 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tests
.stubs
.trace
.TmfXmlKernelTraceStub
;
38 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelAnalysisEventLayout
;
39 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelTrace
;
40 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
41 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
42 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
43 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
44 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
45 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
46 import org
.eclipse
.tracecompass
.statesystem
.core
.tests
.shared
.utils
.StateIntervalStub
;
47 import org
.eclipse
.tracecompass
.statesystem
.core
.tests
.shared
.utils
.StateSystemTestUtils
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEvent
;
50 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
51 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
52 import org
.eclipse
.tracecompass
.tmf
.core
.tests
.shared
.TmfTestHelper
;
53 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
54 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTrace
;
55 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
56 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
57 import org
.junit
.After
;
58 import org
.junit
.Before
;
59 import org
.junit
.Test
;
61 import com
.google
.common
.collect
.ImmutableSet
;
64 * Test suite for the {@link KernelCpuUsageAnalysis} class
66 * @author Geneviève Bastien
68 public class CpuUsageStateProviderTest
{
70 private static final String CPU_USAGE_FILE
= "testfiles/cpu_analysis.xml";
72 private IKernelTrace fTrace
;
73 private KernelCpuUsageAnalysis fModule
;
75 private static void deleteSuppFiles(ITmfTrace trace
) {
76 /* Remove supplementary files */
77 File suppDir
= new File(TmfTraceManager
.getSupplementaryFileDir(trace
));
78 for (File file
: suppDir
.listFiles()) {
84 * Setup the trace for the tests
88 IKernelTrace trace
= new TmfXmlKernelTraceStub();
89 IPath filePath
= Activator
.getAbsoluteFilePath(CPU_USAGE_FILE
);
90 IStatus status
= trace
.validate(null, filePath
.toOSString());
92 fail(status
.getException().getMessage());
95 trace
.initTrace(null, filePath
.toOSString(), TmfEvent
.class);
96 } catch (TmfTraceException e
) {
99 deleteSuppFiles(trace
);
100 ((TmfTrace
) trace
).traceOpened(new TmfTraceOpenedSignal(this, trace
, null));
102 * FIXME: Make sure this analysis is finished before running the CPU
103 * analysis. This block can be removed once analysis dependency and
104 * request precedence is implemented
106 IAnalysisModule module
= null;
107 for (IAnalysisModule mod
: TmfTraceUtils
.getAnalysisModulesOfClass(trace
, KernelAnalysisModule
.class)) {
110 assertNotNull(module
);
112 module
.waitForCompletion();
113 /* End of the FIXME block */
115 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, KernelCpuUsageAnalysis
.class, KernelCpuUsageAnalysis
.ID
);
116 assertNotNull(fModule
);
124 public void tearDown() {
125 deleteSuppFiles(fTrace
);
130 * Test that the analysis executes without problems
133 public void testAnalysisExecution() {
134 /* Make sure the analysis hasn't run yet */
135 assertNull(fModule
.getStateSystem());
137 /* Execute the analysis */
138 assertTrue(TmfTestHelper
.executeAnalysis(fModule
));
139 assertNotNull(fModule
.getStateSystem());
143 * Test that the state system is returned with the expected results
146 public void testReturnedStateSystem() {
148 fModule
.waitForCompletion();
149 ITmfStateSystem ss
= fModule
.getStateSystem();
151 assertEquals(1L, ss
.getStartTime());
152 assertEquals(25L, ss
.getCurrentEndTime());
155 int cpusQuark
= ss
.getQuarkAbsolute(Attributes
.CPUS
);
158 * There should be 2 CPU entries: 0 and 1 and 3 process entries
161 List
<Integer
> cpuQuarks
= ss
.getSubAttributes(cpusQuark
, false);
162 assertEquals(2, cpuQuarks
.size());
163 for (Integer cpuQuark
: cpuQuarks
) {
164 assertEquals(3, ss
.getSubAttributes(cpuQuark
, false).size());
167 /* Test the intervals of proc2 on CPU 0 */
168 List
<@NonNull ITmfStateInterval
> intervals
= new ArrayList
<>();
169 intervals
.add(new StateIntervalStub(1, 19, TmfStateValue
.nullValue()));
170 intervals
.add(new StateIntervalStub(20, 25, TmfStateValue
.newValueLong(19L)));
171 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "0", "2");
173 /* Test the intervals of proc 4 CPU 1 */
175 intervals
.add(new StateIntervalStub(1, 4, TmfStateValue
.nullValue()));
176 intervals
.add(new StateIntervalStub(5, 14, TmfStateValue
.newValueLong(3L)));
177 intervals
.add(new StateIntervalStub(15, 25, TmfStateValue
.newValueLong(8L)));
178 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "1", "4");
180 /* Test the intervals of proc 3 on both CPUs */
182 intervals
.add(new StateIntervalStub(1, 24, TmfStateValue
.nullValue()));
183 intervals
.add(new StateIntervalStub(25, 25, TmfStateValue
.newValueLong(5L)));
184 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "0", "3");
187 intervals
.add(new StateIntervalStub(1, 1, TmfStateValue
.nullValue()));
188 intervals
.add(new StateIntervalStub(2, 9, TmfStateValue
.newValueLong(1L)));
189 intervals
.add(new StateIntervalStub(10, 25, TmfStateValue
.newValueLong(6L)));
190 StateSystemTestUtils
.testIntervalForAttributes(ss
, intervals
, Attributes
.CPUS
, "1", "3");
193 * Query at the end and make sure all processes on all CPU have the
196 Map
<@NonNull String
@NonNull [], @NonNull ITmfStateValue
> map
= new HashMap
<>();
197 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "1"), TmfStateValue
.newValueLong(0L));
198 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "2"), TmfStateValue
.newValueLong(19L));
199 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "0", "3"), TmfStateValue
.newValueLong(5L));
200 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "1"), TmfStateValue
.newValueLong(5L));
201 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "3"), TmfStateValue
.newValueLong(6L));
202 map
.put(StateSystemTestUtils
.makeAttribute(Attributes
.CPUS
, "1", "4"), TmfStateValue
.newValueLong(8L));
203 StateSystemTestUtils
.testValuesAtTime(ss
, 25L, map
);
205 } catch (AttributeNotFoundException e
) {
206 fail(e
.getMessage());
212 * {@link KernelCpuUsageAnalysis#getCpuUsageInRange(java.util.Set, long, long)}
218 public void testUsageInRange() {
220 fModule
.waitForCompletion();
222 /* This range should query the total range */
223 Map
<String
, Long
> expected
= new HashMap
<>();
224 expected
.put("0/1", 0L);
225 expected
.put("0/2", 19L);
226 expected
.put("0/3", 5L);
227 expected
.put("1/1", 5L);
228 expected
.put("1/3", 6L);
229 expected
.put("1/4", 13L);
230 expected
.put("total", 48L);
231 expected
.put("total/1", 5L);
232 expected
.put("total/2", 19L);
233 expected
.put("total/3", 11L);
234 expected
.put("total/4", 13L);
235 expected
.put("0", 24L);
236 expected
.put("1", 24L);
237 Map
<String
, Long
> resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 0L, 30L);
238 assertEquals(expected
, resultMap
);
240 /* Verify a range when a process runs at the start */
242 expected
.put("0/1", 0L);
243 expected
.put("0/2", 0L);
244 expected
.put("0/3", 3L);
245 expected
.put("1/1", 0L);
246 expected
.put("1/3", 0L);
247 expected
.put("1/4", 3L);
248 expected
.put("total", 6L);
249 expected
.put("total/1", 0L);
250 expected
.put("total/2", 0L);
251 expected
.put("total/3", 3L);
252 expected
.put("total/4", 3L);
253 expected
.put("0", 3L);
254 expected
.put("1", 3L);
255 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 22L, 25L);
256 assertEquals(expected
, resultMap
);
258 /* Verify a range when a process runs at the end */
260 expected
.put("0/1", 0L);
261 expected
.put("0/2", 3L);
262 expected
.put("0/3", 0L);
263 expected
.put("1/1", 0L);
264 expected
.put("1/3", 1L);
265 expected
.put("1/4", 2L);
266 expected
.put("total", 6L);
267 expected
.put("total/1", 0L);
268 expected
.put("total/2", 3L);
269 expected
.put("total/3", 1L);
270 expected
.put("total/4", 2L);
271 expected
.put("0", 3L);
272 expected
.put("1", 3L);
273 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 1L, 4L);
274 assertEquals(expected
, resultMap
);
276 /* Verify a range when a process runs at start and at the end */
278 expected
.put("0/1", 0L);
279 expected
.put("0/2", 9L);
280 expected
.put("0/3", 0L);
281 expected
.put("1/1", 0L);
282 expected
.put("1/3", 5L);
283 expected
.put("1/4", 4L);
284 expected
.put("total", 18L);
285 expected
.put("total/1", 0L);
286 expected
.put("total/2", 9L);
287 expected
.put("total/3", 5L);
288 expected
.put("total/4", 4L);
289 expected
.put("0", 9L);
290 expected
.put("1", 9L);
291 resultMap
= fModule
.getCpuUsageInRange(Collections
.EMPTY_SET
, 4L, 13L);
292 assertEquals(expected
, resultMap
);
296 * Tests the cpu usage for a cpu subset within a range
299 public void testInRangeWithCpuSubset() {
302 fModule
.waitForCompletion();
304 /* Verify a range when a process runs at start and at the end */
305 Map
<String
, Long
> expected
= new HashMap
<>();
306 expected
.put("0/1", 0L);
307 expected
.put("0/2", 9L);
308 expected
.put("0/3", 0L);
309 expected
.put("total/1", 0L);
310 expected
.put("total/2", 9L);
311 expected
.put("total/3", 0L);
312 expected
.put("0", 9L);
313 expected
.put("total", 9L);
314 Map
<String
, Long
> resultMap
= fModule
.getCpuUsageInRange(Collections
.<@NonNull Integer
> singleton(0), 4L, 13L);
315 assertEquals(expected
, resultMap
);
317 /* Verify a range when a process runs at start and at the end */
319 expected
.put("1/1", 0L);
320 expected
.put("1/3", 5L);
321 expected
.put("1/4", 4L);
322 expected
.put("total/1", 0L);
323 expected
.put("total/3", 5L);
324 expected
.put("total/4", 4L);
325 expected
.put("1", 9L);
326 expected
.put("total", 9L);
327 resultMap
= fModule
.getCpuUsageInRange(ImmutableSet
.of(1, 2), 4L, 13L);
328 assertEquals(expected
, resultMap
);
333 * Test the requirements of the analysis module
336 public void testRequirements() {
337 IKernelTrace trace
= fTrace
;
338 assertNotNull(trace
);
339 IKernelAnalysisEventLayout layout
= trace
.getKernelEventLayout();
340 Set
<String
> expected
= ImmutableSet
.of(layout
.eventSchedSwitch());
342 Set
<String
> actual
= StreamSupport
.stream(fModule
.getAnalysisRequirements().spliterator(), false)
343 .flatMap(req
-> req
.getValues().stream())
344 .collect(Collectors
.toSet());
346 assertEquals(expected
, actual
);