import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
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.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
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;
private static final String CPU_USAGE_FILE = "testfiles/cpu_analysis.xml";
- private ITmfTrace fTrace;
+ private IKernelTrace fTrace;
private KernelCpuUsageAnalysis fModule;
private static void deleteSuppFiles(ITmfTrace trace) {
*/
@Before
public void setUp() {
- ITmfTrace trace = new TmfXmlKernelTraceStub();
+ IKernelTrace trace = new TmfXmlKernelTraceStub();
IPath filePath = Activator.getAbsoluteFilePath(CPU_USAGE_FILE);
IStatus status = trace.validate(null, filePath.toOSString());
if (!status.isOK()) {
expected.put("total/4", 4L);
expected.put("1", 9L);
expected.put("total", 9L);
- resultMap = fModule.getCpuUsageInRange(ImmutableSet.of(1,2), 4L, 13L);
+ resultMap = fModule.getCpuUsageInRange(ImmutableSet.of(1, 2), 4L, 13L);
assertEquals(expected, resultMap);
}
+
+ /**
+ * Test the requirements of the analysis module
+ */
+ @Test
+ public void testRequirements() {
+ IKernelTrace trace = fTrace;
+ assertNotNull(trace);
+ IKernelAnalysisEventLayout layout = trace.getKernelEventLayout();
+ Set<String> expected = ImmutableSet.of(layout.eventSchedSwitch());
+
+ Set<String> actual = StreamSupport.stream(fModule.getAnalysisRequirements().spliterator(), false)
+ .flatMap(req -> req.getValues().stream())
+ .collect(Collectors.toSet());
+
+ assertEquals(expected, actual);
+ }
}
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.DefaultEventLayout;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.KernelEventLayoutRequirement;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator;
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.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement.ValuePriorityLevel;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+
/**
* This analysis module computes the CPU usage of a system from a kernel trace.
* It requires the LTTng Kernel analysis module to have accurate CPU usage data.
/** Idle process thread ID */
public static final String TID_ZERO = "0"; //$NON-NLS-1$
- @Override
- protected ITmfStateProvider createStateProvider() {
- ITmfTrace trace = checkNotNull(getTrace());
+ /** The requirements as an immutable set */
+ private static final KernelEventLayoutRequirement LAYOUT_REQUIREMENT;
+ private static final SetMultimap<IKernelAnalysisEventLayout, TmfAnalysisRequirement> LAYOUT_REQ_MAP = NonNullUtils.checkNotNull(HashMultimap.create());
+
+ static {
+ LAYOUT_REQUIREMENT = new KernelEventLayoutRequirement(ImmutableSet.of((l) -> l.eventSchedSwitch()), ValuePriorityLevel.MANDATORY);
+ }
+
+ private static IKernelAnalysisEventLayout getLayout(@Nullable ITmfTrace trace) {
IKernelAnalysisEventLayout layout;
if (trace instanceof IKernelTrace) {
/* Fall-back to the base LttngEventLayout */
layout = DefaultEventLayout.getInstance();
}
+ return layout;
+ }
+
+ @Override
+ protected ITmfStateProvider createStateProvider() {
+ ITmfTrace trace = checkNotNull(getTrace());
+ IKernelAnalysisEventLayout layout = getLayout(trace);
return new KernelCpuUsageStateProvider(trace, layout);
}
}
}
+ @Override
+ public Iterable<TmfAnalysisRequirement> getAnalysisRequirements() {
+ ITmfTrace trace = getTrace();
+ IKernelAnalysisEventLayout layout = getLayout(trace);
+ Set<TmfAnalysisRequirement> reqs = LAYOUT_REQ_MAP.get(layout);
+ if (reqs.isEmpty()) {
+ reqs= ImmutableSet.of(LAYOUT_REQUIREMENT.instanciateRequirements(layout));
+ LAYOUT_REQ_MAP.putAll(layout, reqs);
+ }
+ return reqs;
+ }
+
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.os.linux.core.trace;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisEventRequirement;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement.ValuePriorityLevel;
+
+import com.google.common.collect.ImmutableList.Builder;
+
+/**
+ * This class is a pre-requirement class who will instanciate at runtime the
+ * actual requirements depending on a trace's event layout
+ *
+ * @author Geneviève Bastien
+ * @since 2.0
+ */
+public class KernelEventLayoutRequirement {
+
+ /**
+ * Functional interface that maps a layout to an event name
+ */
+ @FunctionalInterface
+ public interface ILayoutToEventName {
+ /**
+ * This method will return the event name mapped by this requirement
+ * from the layout. The returned event name may be <code>null</code> in
+ * some layouts.
+ *
+ * @param layout
+ * The event layout of the trace
+ * @return The event name
+ */
+ @Nullable String getEventName(IKernelAnalysisEventLayout layout);
+ }
+
+ private final Set<ILayoutToEventName> fEventNames;
+ private final ValuePriorityLevel fLevel;
+
+ /**
+ * Constructor
+ *
+ * @param layoutReqs
+ * The layout mappings this requirement represents
+ * @param level
+ * Whether the requirement represented by these mapping is
+ * mandatory or optional
+ */
+ public KernelEventLayoutRequirement(Set<ILayoutToEventName> layoutReqs, ValuePriorityLevel level) {
+ fEventNames = layoutReqs;
+ fLevel = level;
+ }
+
+ /**
+ * Build a real requirement from the layout mapping to be matched with a
+ * real trace's layout
+ *
+ * @param layout
+ * The event layout from which to build the requirements.
+ * @return The real requirement
+ */
+ public TmfAnalysisRequirement instanciateRequirements(IKernelAnalysisEventLayout layout) {
+ Builder<String> events = new Builder<>();
+ for (ILayoutToEventName eventNameLayout : fEventNames) {
+ String eventName = eventNameLayout.getEventName(layout);
+ if (eventName != null) {
+ events.add(eventName);
+ }
+ }
+ return new TmfAnalysisEventRequirement(events.build(), fLevel);
+ }
+
+}