blob: 579fde49ef0467f9314c80cfb72fe8c7d044adf2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.analysis.os.linux.core.tests.contextswitch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.tracecompass.analysis.os.linux.core.contextswitch.KernelContextSwitchAnalysis;
import org.eclipse.tracecompass.analysis.os.linux.core.tests.Activator;
import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.trace.TmfXmlKernelTraceStub;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Test suite for the {@link KernelContextSwitchAnalysis} class
*
* @author Matthew Khouzam
*/
public class ContextSwitchProviderTest {
private static final String CPU_USAGE_FILE = "testfiles/cpu_analysis.xml";
private ITmfTrace fTrace;
private KernelContextSwitchAnalysis fModule;
private static void deleteSuppFiles(ITmfTrace trace) {
/* Remove supplementary files */
File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
for (File file : suppDir.listFiles()) {
file.delete();
}
}
/**
* Setup the trace for the tests
*/
@Before
public void setUp() {
ITmfTrace trace = new TmfXmlKernelTraceStub();
IPath filePath = Activator.getAbsoluteFilePath(CPU_USAGE_FILE);
IStatus status = trace.validate(null, filePath.toOSString());
if (!status.isOK()) {
fail(status.getException().getMessage());
}
try {
trace.initTrace(null, filePath.toOSString(), TmfEvent.class);
} catch (TmfTraceException e) {
fail(e.getMessage());
}
deleteSuppFiles(trace);
((TmfTrace) trace).traceOpened(new TmfTraceOpenedSignal(this, trace, null));
fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelContextSwitchAnalysis.class, KernelContextSwitchAnalysis.ID);
assertNotNull(fModule);
fTrace = trace;
}
/**
* Clean up
*/
@After
public void tearDown() {
deleteSuppFiles(fTrace);
fTrace.dispose();
}
/**
* Test that the analysis executes without problems
*/
@Test
public void testAnalysisExecution() {
/* Make sure the analysis hasn't run yet */
assertNull(fModule.getStateSystem());
/* Execute the analysis */
assertTrue(TmfTestHelper.executeAnalysis(fModule));
assertNotNull(fModule.getStateSystem());
}
/**
* Test that the state system is returned with the expected results
*/
@Test
public void testReturnedStateSystem() {
fModule.schedule();
fModule.waitForCompletion();
ITmfStateSystem ss = fModule.getStateSystem();
assertNotNull(ss);
assertEquals(1L, ss.getStartTime());
assertEquals(25L, ss.getCurrentEndTime());
try {
int cpusQuark = ss.getQuarkAbsolute(Attributes.CPUS);
/*
* There should be 2 CPU entries: 0 and 1 and 3 process entries
* under each
*/
List<Integer> cpuQuarks = ss.getSubAttributes(cpusQuark, false);
assertEquals(2, cpuQuarks.size());
/* Proc 2 on CPU 0 should run from 1 to 20 seconds */
int proc2Quark = ss.getQuarkAbsolute(Attributes.CPUS, "0");
ITmfStateInterval interval = ss.querySingleState(2L, proc2Quark);
assertEquals(1L, interval.getStartTime());
assertEquals(19L, interval.getEndTime());
/*
* Query at the end and make sure all processes on all CPU have the
* expected values
*/
List<ITmfStateInterval> state = ss.queryFullState(25L);
int quark = ss.getQuarkAbsolute("CPUs", "0");
assertEquals(3L, state.get(quark).getStateValue().unboxLong());
quark = ss.getQuarkAbsolute("CPUs", "1");
assertEquals(5L, state.get(quark).getStateValue().unboxLong());
state = ss.queryFullState(19L);
quark = ss.getQuarkAbsolute("CPUs", "0");
assertEquals(1L, state.get(quark).getStateValue().unboxLong());
quark = ss.getQuarkAbsolute("CPUs", "1");
assertEquals(4L, state.get(quark).getStateValue().unboxLong());
} catch (AttributeNotFoundException | StateSystemDisposedException e) {
fail(e.getMessage());
}
}
/**
* Test the
* {@link KernelContextSwitchAnalysis#getContextSwitchesRange(long, long)}
* method.
*/
@Test
public void testUsageInRange() {
fModule.schedule();
fModule.waitForCompletion();
/* This range should query the total range */
Map<Integer, Long> expected = new HashMap<>();
expected.put(0, 2L);
expected.put(1, 6L);
expected.put(-1, 8L);
Map<Integer, Long> resultMap = fModule.getContextSwitchesRange(0L, 30L);
assertEquals(expected, resultMap);
/* Verify a range when a process runs at the start */
expected.clear();
expected.put(0, 1L);
expected.put(1, 0L);
expected.put(-1, 1L);
resultMap = fModule.getContextSwitchesRange(22L, 25L);
assertEquals(expected, resultMap);
/* Verify a range when a process runs at the end */
expected.clear();
expected.put(0, 0L);
expected.put(1, 2L);
expected.put(-1, 2L);
resultMap = fModule.getContextSwitchesRange(1L, 4L);
assertEquals(expected, resultMap);
/* Verify a range when a process runs at start and at the end */
expected.clear();
expected.put(0, 0L);
expected.put(1, 2L);
expected.put(-1, 2L);
resultMap = fModule.getContextSwitchesRange(4L, 13L);
assertEquals(expected, resultMap);
}
/**
* Test the usage in invalid circumstances
*/
@Test
public void testInvalid() {
Map<Integer, Long> resultMap = fModule.getContextSwitchesRange(0L, 30L);
assertEquals(Collections.EMPTY_MAP, resultMap);
fModule.schedule();
fModule.waitForCompletion();
resultMap = fModule.getContextSwitchesRange(30L, 0L);
assertEquals(Collections.EMPTY_MAP, resultMap);
resultMap = fModule.getContextSwitchesRange(0L, 0L);
assertEquals(Collections.EMPTY_MAP, resultMap);
resultMap = fModule.getContextSwitchesRange(-30L, 0L);
assertEquals(Collections.EMPTY_MAP, resultMap);
}
}