import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestHelper;
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ctf.core.CtfTmfTrace;
import org.eclipse.linuxtools.tmf.ctf.core.tests.shared.CtfTmfTestTrace;
import org.junit.After;
import org.junit.Before;
assertFalse(quarks.isEmpty());
}
+ /**
+ * Test the canExecute method on valid and invalid traces
+ */
+ @Test
+ public void testCanExecute() {
+ /* Test with a valid kernel trace */
+ assertTrue(fKernelAnalysisModule.canExecute(fTrace));
+
+ /* Test with a CTF trace that does not have required events */
+ assumeTrue(CtfTmfTestTrace.CYG_PROFILE.exists());
+ try (CtfTmfTrace trace = CtfTmfTestTrace.CYG_PROFILE.getTrace();) {
+ assertFalse(fKernelAnalysisModule.canExecute(trace));
+ }
+ }
+
/**
* Test for {@link LttngKernelAnalysisModule#getAnalysisRequirements()}
*/
/** The ID of this analysis module */
public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.analysis"; //$NON-NLS-1$
+ /* TODO: Are all those mandatory events really mandatory or should some of them be optional? */
private static final ImmutableSet<String> REQUIRED_EVENTS = ImmutableSet.of(
LttngStrings.EXIT_SYSCALL,
LttngStrings.IRQ_HANDLER_ENTRY,
LttngStrings.SCHED_PROCESS_FREE,
LttngStrings.STATEDUMP_PROCESS_STATE,
LttngStrings.SCHED_WAKEUP,
- LttngStrings.SCHED_WAKEUP_NEW,
+ LttngStrings.SCHED_WAKEUP_NEW
+ );
+
+ private static final ImmutableSet<String> OPTIONAL_EVENTS = ImmutableSet.of(
/* Add the prefix for syscalls */
LttngStrings.SYSCALL_PREFIX
);
+
/** The requirements as an immutable set */
private static final ImmutableSet<TmfAnalysisRequirement> REQUIREMENTS;
TmfAnalysisRequirement domainReq = new TmfAnalysisRequirement(SessionConfigStrings.CONFIG_ELEMENT_DOMAIN);
domainReq.addValue(SessionConfigStrings.CONFIG_DOMAIN_TYPE_KERNEL, ValuePriorityLevel.MANDATORY);
- REQUIREMENTS = ImmutableSet.of(domainReq, new TmfAnalysisRequirement(SessionConfigStrings.CONFIG_ELEMENT_EVENT, REQUIRED_EVENTS, ValuePriorityLevel.MANDATORY));
+ TmfAnalysisRequirement eventReq = new TmfAnalysisRequirement(SessionConfigStrings.CONFIG_ELEMENT_EVENT, REQUIRED_EVENTS, ValuePriorityLevel.MANDATORY);
+ eventReq.addValues(OPTIONAL_EVENTS, ValuePriorityLevel.OPTIONAL);
+
+ REQUIREMENTS = ImmutableSet.of(domainReq, eventReq);
}
@Override
* The trace to analyze
* @return Whether the analysis can be executed
*/
- boolean canExecute(ITmfTrace trace);
+ boolean canExecute(@NonNull ITmfTrace trace);
/**
* Schedule the execution of the analysis. If the trace has been set and is
/** Parameter is invalid */
public static String TmfAbstractAnalysisModule_InvalidParameter;
+ /** The trace to set was null */
+ public static String TmfAbstractAnalysisModule_NullTrace;
+
/** Running analysis */
public static String TmfAbstractAnalysisModule_RunningAnalysis;
@Override
public void setTrace(ITmfTrace trace) throws TmfAnalysisException {
+ if (trace == null) {
+ throw new TmfAnalysisException(Messages.TmfAbstractAnalysisModule_NullTrace);
+ }
if (fTrace != null) {
throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_TraceSetMoreThanOnce, getName()));
}
if (!canExecute(trace)) {
throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName()));
}
+
fTrace = trace;
/* Get the parameter providers for this trace */
fParameterProviders = TmfAnalysisManager.getParameterProviders(this, fTrace);
}
@Override
- public boolean canExecute(ITmfTrace trace) {
+ public boolean canExecute(@NonNull ITmfTrace trace) {
+ for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) {
+ if (!requirement.isFulfilled(trace)) {
+ return false;
+ }
+ }
return true;
}
cancel();
}
- private void execute() {
+ private void execute(@NonNull final ITmfTrace trace) {
/*
* TODO: The analysis in a job should be done at the analysis manager
fStarted = true;
}
- final ITmfTrace trace = fTrace;
/*
* Actual analysis will be run on a separate thread
*/
@Override
public IStatus schedule() {
- if (fTrace == null) {
+ final ITmfTrace trace = fTrace;
+ if (trace == null) {
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("No trace specified for analysis %s", getName())); //$NON-NLS-1$
}
- execute();
+ execute(trace);
return Status.OK_STATUS;
}
package org.eclipse.linuxtools.tmf.core.analysis;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.HashMap;
+import java.util.Map.Entry;
import java.util.Set;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
+import org.eclipse.linuxtools.tmf.core.trace.TmfEventTypeCollectionHelper;
+
/**
* Class that contains all the values associated with a type needed by an
* analysis in order to execute. Each value is peered with a level that
*/
public class TmfAnalysisRequirement {
+ /**
+ * String for requirement type 'event', that can be used by analysis
+ */
+ public static final String TYPE_EVENT = "event"; //$NON-NLS-1$
+
private final String fType;
private final Map<String, ValuePriorityLevel> fValues = new HashMap<>();
private final Set<String> fInformation = new HashSet<>();
}
}
+ /**
+ * Gets all the values associated with the requirement with a given priority
+ * level.
+ *
+ * @param level
+ * The desired level
+ * @return Set containing the values with the given priority level
+ */
+ public Set<String> getValues(ValuePriorityLevel level) {
+ synchronized (fValues) {
+ Set<String> values = new HashSet<>();
+ for (Entry<String, ValuePriorityLevel> entry : fValues.entrySet()) {
+ if (entry.getValue() == level) {
+ values.add(entry.getKey());
+ }
+ }
+ return values;
+ }
+ }
+
/**
* Gets information about the requirement.
*
return fValues.get(value);
}
}
+
+ /**
+ * Verifies whether a trace fulfills this requirement
+ *
+ * @param trace
+ * The trace on which to check for this requirement
+ * @return True if the trace has all mandatory values of this requirement
+ */
+ public boolean isFulfilled(@NonNull ITmfTrace trace) {
+ switch (fType) {
+ case TYPE_EVENT:
+ if (trace instanceof ITmfTraceWithPreDefinedEvents) {
+ Set<String> traceEvents = TmfEventTypeCollectionHelper.getEventNames(((ITmfTraceWithPreDefinedEvents) trace).getContainedEventTypes());
+ Set<String> mandatoryValues = getValues(ValuePriorityLevel.MANDATORY);
+ return traceEvents.containsAll(mandatoryValues);
+ }
+ break;
+ default:
+ return true;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return fType + ": " + fValues; //$NON-NLS-1$
+ }
}
TmfAbstractAnalysisModule_AnalysisForTrace=Analysis module: {0} for trace {1}
TmfAbstractAnalysisModule_AnalysisModule=Analysis module: {0}
TmfAbstractAnalysisModule_InvalidParameter=Parameter {0} is not valid for analysis module {1}
+TmfAbstractAnalysisModule_NullTrace=Setting a null trace to analysis module
TmfAbstractAnalysisModule_RunningAnalysis=Running analysis {0}
TmfAnalysisManager_ErrorParameterProvider=Error instantiating parameter provider
TmfAnalysisModuleHelper_ImpossibleToCreateModule=Could not instantiate module "{0}"
status.add(module.schedule());
}
} catch (TmfAnalysisException e) {
- status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
+ status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage()));
}
}
return status;