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 <[email protected]>
  • Loading branch information
bhufmann committed Oct 15, 2024
1 parent 9fb2174 commit 570a7f2
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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 +49,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 +452,55 @@ public void testGetModules() {
assertTrue(count >= 2);
}

@Test
public void testGetManualModules() throws TmfAnalysisException {
/* 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);
}

// ------------------------------------------------------------------------
// seekEvent on location (note: does not reliably set the rank)
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -725,7 +776,7 @@ public void testSeekEventOnTimestampOutOfScope() {

// ------------------------------------------------------------------------
// seekEvent on rank
// ------------------------------------------------------------------------
// ------------------------------------------------------------------`------

@Test
public void testSeekEventOnNegativeRank() {
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,37 @@ public interface ITmfTrace extends ITmfEventProvider {
*/
@NonNull Iterable<@NonNull IAnalysisModule> getAnalysisModules();


/**
* Add an analysis module. It will return an existing analysis module with
* the same ID. Caller have to call {@link IAnalysisModule#dispose()} and
* {@link IAnalysisModule#clearPersistentData()} if required.
*
* @param module
* the analysis module to add
* @return It will return an existing analysis module with the same ID or
* null.
* @since 9.5
*/
default @Nullable IAnalysisModule addAnalysisModule(@NonNull IAnalysisModule module) {
return null;
}

/**
* Remove an analysis module. It will return the existing analysis module with
* the same ID if it exists. Caller have to call {@link IAnalysisModule#dispose()}
* and {@link IAnalysisModule#clearPersistentData()} if required.
*
* @param id
* the ID of the analysis module
* @return It will return an existing analysis module with the same ID or
* null.
* @since 9.5
*/
default @Nullable IAnalysisModule removeAnalysisModule(@NonNull String id) {
return null;
}

/**
* Refresh the analysis modules for this traces
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, IT
private final Map<String, IAnalysisModule> fAnalysisModules =
Collections.synchronizedMap(new LinkedHashMap<String, IAnalysisModule>());

private final Map<String, IAnalysisModule> fAddedAnalysisModules =
Collections.synchronizedMap(new LinkedHashMap<String, IAnalysisModule>());

// Analysis modules that were removed during lifecycle of the trace that need to be disposed
private final Set<IAnalysisModule> fToBeDisposedAnalysisModules =
Collections.synchronizedSet(new HashSet<IAnalysisModule>());
Expand Down Expand Up @@ -304,14 +307,34 @@ public IStatus refreshAnalysisModules() {

@Override
public IAnalysisModule getAnalysisModule(String analysisId) {
return fAnalysisModules.get(analysisId);
IAnalysisModule module = fAnalysisModules.get(analysisId);
if (module != null) {
return module;
}
return fAddedAnalysisModules.get(analysisId);
}


@Override
public Iterable<IAnalysisModule> getAnalysisModules() {
synchronized (fAnalysisModules) {
return new HashSet<>(fAnalysisModules.values());
HashSet<IAnalysisModule> modules = new HashSet<>(fAnalysisModules.values());
modules.addAll(fAddedAnalysisModules.values());
return modules;
}
}

@Override
public IAnalysisModule addAnalysisModule(@NonNull IAnalysisModule module) {
synchronized (fAnalysisModules) {
return fAddedAnalysisModules.put(module.getId(), module);
}
}

@Override
public IAnalysisModule removeAnalysisModule(@NonNull String id) {
synchronized (fAnalysisModules) {
return fAddedAnalysisModules.remove(id);
}
}

Expand All @@ -337,6 +360,7 @@ public synchronized void dispose() {
module.dispose();
}
fAnalysisModules.clear();
fAddedAnalysisModules.clear();

/* Clean up the analysis modules removed during lifecycle of trace */
analysisModules = fToBeDisposedAnalysisModules;
Expand Down

0 comments on commit 570a7f2

Please sign in to comment.