Skip to content

Commit

Permalink
tmf: Add API to add and remove analysis modules to/from ITmfTrace
Browse files Browse the repository at this point in the history
Many analysis utilities require analysis modules to be present in the
ITmfTrace.getAnalysisModules() collection. This one is filled using the
TMF analysis framework (see IAnalysisModuleSource implementation).
The analysis framework will populate available IAnalysisModuesHelpers at
startup (plug-in defined) or when a refresh is requested (XML analysis).
For that a central storage for the modules configuration needs to be
available to be parsed which are available for all ITmfTrace extensions.
If a trace is opened a ITmfTrace instance is created and the applicable
analysis module is instantiated and stored inside the ITmfTrace object.

Right now it's not possible to update available analysis module helpers
in the TMF analysis framework based on a configuration specific for
a trace instance.

This patch allows to add analysis modules to ITmfTrace and by-pass the
TMF analysis framework and IAnalysisModuleSource extension point to
provide custom analysis.

Note that those analysis modules won't show up in the Project Explorer
and hence it's meant for the trace server use case.

[Added] API to add and remove analysis modules to/from ITmfTrace

Signed-off-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
  • Loading branch information
bhufmann committed Oct 17, 2024
1 parent 9fb2174 commit bd3d20f
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.model.CoreFilterProperty;
import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
Expand Down Expand Up @@ -103,7 +104,11 @@ protected void canceling() {
public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException {
if (trace instanceof TmfXmlTraceStub) {
TmfXmlTraceStub tmfXmlTraceStub = (TmfXmlTraceStub) trace;
tmfXmlTraceStub.addAnalysisModule(this);
try {
tmfXmlTraceStub.addAnalysisModule(this);
} catch (TmfTraceException e) {
throw new TmfAnalysisException(e.getMessage());
}
}
return super.setTrace(trace);
}
Expand Down Expand Up @@ -210,7 +215,11 @@ private static Map<String, Long> fetchSingleTraceColumnId() {

private static ITmfVirtualTableDataProvider<@NonNull TmfTreeDataModel, @NonNull VirtualTableLine> getDataProvider(@NonNull TmfExperimentStub experiment) throws TmfAnalysisException {
IAnalysisModule m = new SegmentStoreAnalysisModule(experiment);
experiment.addAnalysisModule(m);
try {
experiment.addAnalysisModule(m);
} catch (TmfTraceException e) {
throw new TmfAnalysisException(e.getMessage());
}
m.schedule();
return new SegmentStoreTableDataProvider(experiment, (ISegmentStoreProvider) m, "");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.VirtualTableLine;
import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
import org.eclipse.tracecompass.tmf.core.model.CoreFilterProperty;
import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
Expand Down Expand Up @@ -97,7 +98,11 @@ public static void init() throws TmfAnalysisException {
preFixture.setTrace(trace);
SegmentStoreAnalysisModule fixture = new SegmentStoreAnalysisModule(trace);
if (trace instanceof TmfXmlTraceStubNs) {
((TmfXmlTraceStubNs) trace).addAnalysisModule(fixture);
try {
((TmfXmlTraceStubNs) trace).addAnalysisModule(fixture);
} catch (TmfTraceException e) {
throw new TmfAnalysisException(e.getMessage());
}
}
fixture.schedule();
fixture.waitForCompletion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis;
Expand Down Expand Up @@ -97,9 +98,12 @@ public void dispose() {
public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException {
if (trace instanceof TmfXmlTraceStub) {
TmfXmlTraceStub tmfXmlTraceStub = (TmfXmlTraceStub) trace;
tmfXmlTraceStub.addAnalysisModule(this);
tmfXmlTraceStub.addAnalysisModule(fSegmentStoreProvider);

try {
tmfXmlTraceStub.addAnalysisModule(this);
tmfXmlTraceStub.addAnalysisModule(fSegmentStoreProvider);
} catch (TmfTraceException e) {
throw new TmfAnalysisException(e.getMessage());
}
}
return super.setTrace(trace);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
Expand Down Expand Up @@ -127,7 +128,11 @@ protected void canceling() {
public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException {
if (trace instanceof TmfXmlTraceStub) {
TmfXmlTraceStub tmfXmlTraceStub = (TmfXmlTraceStub) trace;
tmfXmlTraceStub.addAnalysisModule(this);
try {
tmfXmlTraceStub.addAnalysisModule(this);
} catch (TmfTraceException e) {
throw new TmfAnalysisException(e.getMessage());
}
}
return super.setTrace(trace);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Iterator;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

Expand All @@ -32,6 +33,7 @@
import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
Expand All @@ -48,6 +50,7 @@
import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis;
import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis2;
import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -450,6 +453,74 @@ public void testGetModules() {
assertTrue(count >= 2);
}

@Test
public void testGetManualModules() throws TmfAnalysisException, TmfTraceException {
/* There should not be any modules at this point */
Iterable<IAnalysisModule> modules = fTrace.getAnalysisModules();
assertFalse(modules.iterator().hasNext());

/* Open the trace, the modules should be populated */
fTrace.traceOpened(new TmfTraceOpenedSignal(this, fTrace, null));

IAnalysisModule manualModule = new TestAnalysis2("1st Manual TestAnalysis2");
assertTrue(manualModule.setTrace(fTrace));

assertNull(fTrace.getAnalysisModule(manualModule.getId()));
fTrace.addAnalysisModule(manualModule);

/*
* Make sure that manualModule is returned
*/
assertNotNull(fTrace.getAnalysisModule(manualModule.getId()));
modules = fTrace.getAnalysisModules();
assertTrue(modules.iterator().hasNext());

IAnalysisModule foundModule = null;
for (IAnalysisModule module : modules) {
if (module.getId().equals(manualModule.getId())) {
foundModule = module;
break;
}
}
assertNotNull(foundModule);

fTrace.removeAnalysisModule(manualModule.getId());

/*
* Make sure that manualModule is not returned
*/
assertNull(fTrace.getAnalysisModule(manualModule.getId()));
modules = fTrace.getAnalysisModules();
assertTrue(modules.iterator().hasNext());
foundModule = null;
for (IAnalysisModule module : modules) {
if (module.getId().equals(manualModule.getId())) {
foundModule = module;
break;
}
}
assertNull(foundModule);

// At this point only built-in analysis modules are available
// Take the first one in the list for the following tests
Iterator<IAnalysisModule> iter = fTrace.getAnalysisModules().iterator();
if (iter.hasNext()) {
IAnalysisModule builtinAnalysis = iter.next();
assertNotNull(builtinAnalysis);
try {
fTrace.addAnalysisModule(builtinAnalysis);
} catch (TmfTraceException e) {
// success
}

try {
fTrace.removeAnalysisModule(builtinAnalysis.getId());
} catch (TmfTraceException e) {
// success
}
}
}

// ------------------------------------------------------------------------
// seekEvent on location (note: does not reliably set the rank)
// ------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2013, 2014 École Polytechnique de Montréal
* Copyright (c) 2013, 2024 É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 2.0 which
Expand All @@ -15,6 +15,7 @@
package org.eclipse.tracecompass.tmf.tests.stubs.analysis;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
Expand All @@ -25,6 +26,33 @@
*/
public class TestAnalysis2 extends TmfAbstractAnalysisModule {

private String fName = null;

/**
* Default constructor
*/
public TestAnalysis2() {
super();
}
/**
* Name of analysis
*
* @param name
* the name of the analysis
*/
public TestAnalysis2(String name) {
super();
fName = name;
}

@Override
public @NonNull String getId() {
if (fName != null) {
return super.getId() + getName();
}
return super.getId();
}

@Override
public boolean canExecute(ITmfTrace trace) {
/* This just makes sure the trace is or contains a trace stub 2 */
Expand All @@ -33,7 +61,7 @@ public boolean canExecute(ITmfTrace trace) {
return true;
}
}
return false;
return fName != null;
}

@Override
Expand All @@ -46,4 +74,8 @@ protected boolean executeAnalysis(final IProgressMonitor monitor) {
return false;
}

@Override
public String getName() {
return fName == null ? super.getName() : fName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
package org.eclipse.tracecompass.tmf.tests.stubs.trace;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.tracecompass.internal.tmf.core.Activator;
import org.eclipse.tracecompass.internal.tmf.core.request.TmfCoalescedEventRequest;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
Expand All @@ -41,8 +38,6 @@
@SuppressWarnings("javadoc")
public class TmfExperimentStub extends TmfExperiment {

private final Collection<IAnalysisModule> fAdditionalModules = new HashSet<>();

/**
* Default constructor. Should not be called directly by the code, but
* needed for the extension point.
Expand Down Expand Up @@ -115,16 +110,6 @@ public void setTimerEnabledFlag(boolean enabled) throws Exception {
m.invoke(this, params);
}

/**
* Add an additional new module
*
* @param module
* The new module
*/
public void addAnalysisModule(IAnalysisModule module) {
fAdditionalModules.add(module);
}

/**
* Make this specific stub meant to support traces with at least one
* prefixed with "A-".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

/**
* An XML development trace using a custom XML trace definition and schema.
Expand Down Expand Up @@ -113,7 +112,6 @@ public abstract class TmfXmlTraceStub extends TmfTrace {

private Collection<ITmfEventAspect<?>> fAspects = TmfTrace.BASE_ASPECTS;
private final Collection<ITmfEventAspect<?>> fAdditionalAspects = new HashSet<>();
private final Collection<IAnalysisModule> fAdditionalModules = new HashSet<>();

/**
* Constructor. Constructs the custom XML trace with the appropriate
Expand Down Expand Up @@ -439,22 +437,6 @@ public void addEventAspect(ITmfEventAspect<?> aspect) {
fAspects = builder.build();
}

/**
* Add an additional new module
*
* @param module
* The new module
*/
public void addAnalysisModule(IAnalysisModule module) {
fAdditionalModules.add(module);
}

@Override
public Iterable<@NonNull IAnalysisModule> getAnalysisModules() {
@NonNull Iterable<IAnalysisModule> modules = super.getAnalysisModules();
return checkNotNull(Iterables.concat(modules, fAdditionalModules));
}

@Override
public @Nullable IAnalysisModule getAnalysisModule(@Nullable String analysisId) {
Iterable<@NonNull IAnalysisModule> modules = getAnalysisModules();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,47 @@ public interface ITmfTrace extends ITmfEventProvider {
*/
@NonNull Iterable<@NonNull IAnalysisModule> getAnalysisModules();


/**
* Add an analysis module.
*
* It will replace a previously added analysis module with the same ID which
* will be returned. Callers have to call {@link IAnalysisModule#dispose()}
* and {@link IAnalysisModule#clearPersistentData()}, if required.
*
* @param module
* the analysis module to add
* @return the replaced analysis module if it exists or null
* @throws TmfTraceException
* If analysis module cannot be added, for example, a module
* with same ID already exists as built-in analysis
* @since 9.5
*/
default @Nullable IAnalysisModule addAnalysisModule(@NonNull IAnalysisModule module) throws TmfTraceException {
throw new TmfTraceException("Not Implemented"); //$NON-NLS-1$
}

/**
* Remove an analysis module that was previously added by calling
* ({@link #addAnalysisModule(IAnalysisModule)}.
*
* It will return the removed analysis module with the given ID if it
* exists. Callers have to call {@link IAnalysisModule#dispose()} and
* {@link IAnalysisModule#clearPersistentData()}, if required.
*
* @param id
* the ID of the analysis module to remove
* @return the removed analysis module with the given ID or null if
* it doesn't exist.
* @throws TmfTraceException
* If analysis module cannot be removed, for example, a module
* with same ID already exists as built-in analysis
* @since 9.5
*/
default @Nullable IAnalysisModule removeAnalysisModule(@NonNull String id) throws TmfTraceException {
throw new TmfTraceException("Not Implemented"); //$NON-NLS-1$
}

/**
* Refresh the analysis modules for this traces
*
Expand Down
Loading

0 comments on commit bd3d20f

Please sign in to comment.