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
.lttng2
.kernel
.core
.tests
.analysis
.vm
;
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
.fail
;
19 import static org
.junit
.Assume
.assumeTrue
;
21 import java
.util
.Collection
;
22 import java
.util
.List
;
24 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
25 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.KernelAnalysisModule
;
26 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.vm
.VcpuStateValues
;
27 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.vm
.VmAttributes
;
28 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.vm
.module
.VirtualMachineCpuAnalysis
;
29 import org
.eclipse
.tracecompass
.lttng2
.lttng
.kernel
.core
.tests
.shared
.vm
.VmTestExperiment
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
31 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
32 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
33 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
34 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
35 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
36 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTrace
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.experiment
.TmfExperiment
;
42 import org
.junit
.Test
;
44 import com
.google
.common
.collect
.Multimap
;
47 * Test suite for the {@link VirtualMachineCpuAnalysis} class
49 * @author Geneviève Bastien
51 public class VirtualMachineAnalysisTest
{
53 private static void verifyStateIntervals(String testId
, List
<ITmfStateInterval
> intervals
, int[] expectedStarts
, ITmfStateValue
[] expectedValues
) {
54 int expectedCount
= expectedStarts
.length
- 1;
56 assertEquals(testId
+ ": Interval count", expectedCount
, intervals
.size());
57 for (int i
= 0; i
< expectedCount
; i
++) {
58 ITmfStateInterval interval
= intervals
.get(i
);
59 assertEquals(testId
+ ": Start time of interval " + i
, expectedStarts
[i
], interval
.getStartTime());
60 long actualEnd
= (i
== expectedCount
- 1) ?
(expectedStarts
[i
+ 1]) : (expectedStarts
[i
+ 1]) - 1;
61 assertEquals(testId
+ ": End time of interval " + i
, actualEnd
, interval
.getEndTime());
62 assertEquals(testId
+ ": Expected value of interval " + i
, expectedValues
[i
], interval
.getStateValue());
66 private static void verifyIntervalsWithMask(String testId
, Collection
<ITmfStateInterval
> intervals
, int[] expectedStarts
, int[] expectedEnds
, ITmfStateValue
[] expectedValues
, int mask
) {
67 int expectedCount
= expectedStarts
.length
- 1;
69 assertEquals(testId
+ ": Interval count", expectedCount
, intervals
.size());
71 for (ITmfStateInterval interval
: intervals
) {
72 assertEquals(testId
+ ": Start time of interval " + i
, expectedStarts
[i
], interval
.getStartTime());
73 assertEquals(testId
+ ": End time of interval " + i
, expectedEnds
[i
], interval
.getEndTime());
74 assertEquals(testId
+ ": Expected value of interval " + i
, expectedValues
[i
].unboxInt() & mask
, interval
.getStateValue().unboxInt() & mask
);
80 * Test the analysis execution with stub traces of a virtual machine with
81 * one virtual machine and one CPU
84 public void testStubTracesOneQemuKvm() {
86 assumeTrue(VmTestExperiment
.ONE_QEMUKVM
.exists());
87 TmfExperiment experiment
= VmTestExperiment
.ONE_QEMUKVM
.getExperiment(true);
90 for (ITmfTrace trace
: experiment
.getTraces()) {
91 ((TmfTrace
) trace
).traceOpened(new TmfTraceOpenedSignal(this, trace
, null));
95 * TODO For now, make sure the LttngKernelAnalysis have been run for
96 * each trace before running the analysis. When event request precedence
97 * is implemented, we can remove this
99 for (ITmfTrace trace
: experiment
.getTraces()) {
100 trace
= checkNotNull(trace
);
101 for (KernelAnalysisModule module
: TmfTraceUtils
.getAnalysisModulesOfClass(trace
, KernelAnalysisModule
.class)) {
103 module
.waitForCompletion();
106 /* End of TODO block */
108 experiment
.traceOpened(new TmfTraceOpenedSignal(this, experiment
, null));
109 VirtualMachineCpuAnalysis module
= null;
110 for (VirtualMachineCpuAnalysis mod
: TmfTraceUtils
.getAnalysisModulesOfClass(experiment
, VirtualMachineCpuAnalysis
.class)) {
114 assertNotNull(module
);
116 if (!module
.waitForCompletion()) {
117 fail("Module did not complete properly");
121 /* Check the state system */
122 ITmfStateSystem ss
= module
.getStateSystem();
126 vmQuark
= ss
.getQuarkAbsolute(VmAttributes
.VIRTUAL_MACHINES
);
128 List
<Integer
> guestQuarks
= ss
.getSubAttributes(vmQuark
, false);
129 assertEquals("Number of guests", 1, guestQuarks
.size());
130 List
<Integer
> vcpuQuarks
= ss
.getSubAttributes(guestQuarks
.get(0), false);
131 assertEquals("Number of virtual CPUs", 1, vcpuQuarks
.size());
132 Integer statusQuark
= ss
.getQuarkRelative(vcpuQuarks
.get(0), VmAttributes
.STATUS
);
134 /* Check the intervals for the virtual CPU */
135 List
<ITmfStateInterval
> intervals
= StateSystemUtils
.queryHistoryRange(ss
, statusQuark
, ss
.getStartTime(), ss
.getCurrentEndTime());
137 /* Expected interval values for the virtual CPU */
138 int[] expectedStarts
= { 1, 60, 75, 95, 100, 150, 155, 195, 210, 245, 260, 295, 300, 350, 355, 375 };
139 ITmfStateValue
[] expectedValues
= { TmfStateValue
.nullValue(),
140 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_UNKNOWN
),
141 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
142 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
143 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
| VcpuStateValues
.VCPU_PREEMPT
),
144 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
145 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
146 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
147 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
148 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
149 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
150 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
151 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
| VcpuStateValues
.VCPU_PREEMPT
),
152 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
| VcpuStateValues
.VCPU_VMM
),
153 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
) };
154 verifyStateIntervals("Virtual CPU", intervals
, expectedStarts
, expectedValues
);
156 /* Check the status of the guest's threads */
157 int[] expectedStartsT130
= { 10, 35, 75, 175, 195, 225, 275, 295, 300, 350, 375 };
158 int[] expectedEndsT130
= { 34, 74, 174, 224, 209, 274, 374, 299, 349, 354, 375 };
159 ITmfStateValue
[] expectedValuesT30
= { TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
160 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
161 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
162 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
163 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
164 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
165 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
166 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
167 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
168 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
169 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
) };
171 int[] expectedStartsT131
= { 10, 35, 75, 95, 100, 150, 175, 225, 245, 275, 375 };
172 int[] expectedEndsT131
= { 34, 74, 174, 99, 149, 154, 224, 274, 259, 374, 375 };
173 ITmfStateValue
[] expectedValuesT31
= { TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
174 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
175 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
176 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
177 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
178 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
179 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
180 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
),
181 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_PREEMPT
),
182 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_IDLE
),
183 TmfStateValue
.newValueInt(VcpuStateValues
.VCPU_RUNNING
) };
185 Multimap
<Integer
, ITmfStateInterval
> threadIntervals
= module
.getUpdatedThreadIntervals(guestQuarks
.get(0), ss
.getStartTime(), ss
.getCurrentEndTime(), 1, new NullProgressMonitor());
186 verifyIntervalsWithMask("Thread 130", threadIntervals
.get(130), expectedStartsT130
, expectedEndsT130
, expectedValuesT30
, VcpuStateValues
.VCPU_PREEMPT
);
187 verifyIntervalsWithMask("Thread 131", threadIntervals
.get(131), expectedStartsT131
, expectedEndsT131
, expectedValuesT31
, VcpuStateValues
.VCPU_PREEMPT
);
189 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
190 fail(e
.getMessage());
192 experiment
.dispose();