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