TMF: Specify if an analysis applies differently to an experiment
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Fri, 13 Jun 2014 19:11:56 +0000 (15:11 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Tue, 10 Mar 2015 18:28:02 +0000 (14:28 -0400)
Add a 'apply_experiment' to analysis extension for analysis who have different
results for experiments containing their trace types than for the individual
traces. The result of the experiment analysis is more than the aggregation of
the traces' analyses.

Change-Id: I18122a26bb680fb2b240c98a4757f1bcce71b525
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/38446
Reviewed-by: Hudson CI
12 files changed:
org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/module/TmfAnalysisModuleHelperXml.java
org.eclipse.tracecompass.tmf.core.tests/plugin.xml
org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisModuleHelperTest.java
org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/AnalysisModuleTestHelper.java
org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/analysis/TestAnalysis2.java
org.eclipse.tracecompass.tmf.core/schema/org.eclipse.linuxtools.tmf.core.analysis.exsd
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisModuleSourceConfigElement.java
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/IAnalysisModuleHelper.java
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisModuleHelperConfigElement.java
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java
org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/project/model/TmfExperimentElement.java

index 66120c398b0ab1201c8141a863e65accf1470268..e2936ce4be87cb650b9ef637620bd7f456335041 100644 (file)
@@ -102,6 +102,14 @@ public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper {
         return false;
     }
 
+    /**
+     * @since 1.0
+     */
+    @Override
+    public boolean appliesToExperiment() {
+        return false;
+    }
+
     @Override
     public String getHelpText() {
         return new String();
index 077c0ec294067afa72b8f1ec4855c58f8e81a866..e91409d034dfe16d528723750bfd63644b419115 100644 (file)
          </tracetype>
       </module>
       <module
-         id="org.eclipse.linuxtools.tmf.core.tests.analysis.testother"
-         name="Test other analysis"
-         analysis_module="org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis2"
-         automatic="true">
+            analysis_module="org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis2"
+            automatic="true"
+            id="org.eclipse.linuxtools.tmf.core.tests.analysis.testother"
+            name="Test other analysis"
+            applies_experiment="true">
          <tracetype
                applies="true"
                class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub3">
index 2cfad46f660c6085c103d1b9d313fda145d07262..3aa4840c4c74f9451aabf534e5b87d561610fc35 100644 (file)
@@ -37,6 +37,7 @@ import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
 import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
 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.analysis.TestRequirementAnalysis;
@@ -128,12 +129,14 @@ public class AnalysisModuleHelperTest {
         assertTrue(fModule.appliesToTraceType(TmfTraceStub.class));
         assertTrue(fModule.appliesToTraceType(TmfTraceStub2.class));
         assertFalse(fModule.appliesToTraceType(TmfTraceStub3.class));
+        assertFalse(fModule.appliesToTraceType(TmfExperiment.class));
 
         /* stub module 2 */
         assertFalse(fModuleOther.appliesToTraceType(TmfTrace.class));
         assertFalse(fModuleOther.appliesToTraceType(TmfTraceStub.class));
         assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub2.class));
         assertTrue(fModuleOther.appliesToTraceType(TmfTraceStub3.class));
+        assertFalse(fModuleOther.appliesToTraceType(TmfExperiment.class));
     }
 
     /**
@@ -190,6 +193,87 @@ public class AnalysisModuleHelperTest {
         assertNull(exception);
     }
 
+
+    /**
+     * Test the analysis modules with a differing result for experiments
+     */
+    @Test
+    public void testAppliesToExperiment() {
+        ITmfTrace trace1 = TmfTestTrace.A_TEST_10K.getTrace();
+        ITmfTrace trace2 = TmfTestTrace.A_TEST_10K2.getTrace();
+        ITmfTrace trace3 = TmfTestTrace.A_TEST_10K2.getTraceAsStub2();
+
+        /* Create an experiment with TmfTraceStub */
+        ITmfTrace[] tracesExp1 = { trace1, trace2 };
+        TmfExperiment exp1 = new TmfExperiment(tracesExp1[0].getEventType(), "Experiment 1", tracesExp1, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null);
+
+        /* Create an experiment containing some TmfTraceStub2 */
+        ITmfTrace[] tracesExp2 = { trace1, trace3 };
+        TmfExperiment exp2 = new TmfExperiment(tracesExp2[0].getEventType(), "Experiment 1", tracesExp2, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null);
+
+        try {
+
+            /* fModule should throw exception for both experiments */
+            Exception exception = null;
+            IAnalysisModule module = null;
+            try {
+                module = fModule.newModule(exp1);
+            } catch (TmfAnalysisException e) {
+                exception = e;
+            } finally {
+                if (module != null) {
+                    module.dispose();
+                }
+            }
+            assertNotNull(exception);
+            assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModule.getName()), exception.getMessage());
+
+            exception = null;
+            try {
+                module = fModule.newModule(exp2);
+            } catch (TmfAnalysisException e) {
+                exception = e;
+            } finally {
+                if (module != null) {
+                    module.dispose();
+                }
+            }
+            assertNotNull(exception);
+            assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModule.getName()), exception.getMessage());
+
+            /* fModuleOther should throw exception for exp1, but not exp2 */
+            exception = null;
+            try {
+                module = fModuleOther.newModule(exp1);
+            } catch (TmfAnalysisException e) {
+                exception = e;
+            } finally {
+                if (module != null) {
+                    module.dispose();
+                }
+            }
+            assertNotNull(exception);
+            assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModuleOther.getName()), exception.getMessage());
+
+            exception = null;
+            try {
+                module = fModuleOther.newModule(exp2);
+                assertNotNull(module);
+            } catch (TmfAnalysisException e) {
+                exception = e;
+            } finally {
+                if (module != null) {
+                    module.dispose();
+                }
+            }
+            assertNull(exception);
+
+        } finally {
+            exp2.dispose();
+            exp1.dispose();
+        }
+    }
+
     /**
      * Test for the initialization of parameters from the extension points
      */
index 01a329002c9b07f60d284e7820ee97dbe0594901..511653069acd95ab9d96256f1262d972f4dbb88d 100644 (file)
@@ -74,6 +74,11 @@ public class AnalysisModuleTestHelper implements IAnalysisModuleHelper {
         return false;
     }
 
+    @Override
+    public boolean appliesToExperiment() {
+        return false;
+    }
+
     @Override
     public String getHelpText() {
         return "";
@@ -153,4 +158,5 @@ public class AnalysisModuleTestHelper implements IAnalysisModuleHelper {
             return Collections.EMPTY_SET;
         }
     }
+
 }
index 3c32fffdfe4bac52b199f3119d8d4e9540723e47..30c9ec6b62812f8d6a366f3f5ad24578d5e64487 100644 (file)
@@ -15,6 +15,7 @@ package org.eclipse.tracecompass.tmf.tests.stubs.analysis;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub2;
 
 /**
@@ -24,8 +25,13 @@ public class TestAnalysis2 extends TmfAbstractAnalysisModule {
 
     @Override
     public boolean canExecute(ITmfTrace trace) {
-        /* This just makes sure the trace is a trace stub 2 */
-        return (TmfTraceStub2.class.isAssignableFrom(trace.getClass()));
+        /* This just makes sure the trace is or contains a trace stub 2 */
+        for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
+            if (TmfTraceStub2.class.isAssignableFrom(aTrace.getClass())) {
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
index 776c5e03beb6f52f7de184f601468aa5edc1e6f4..cac141633e5843c0bdc7f96c5b62fb137afc557d 100644 (file)
                </documentation>
             </annotation>
          </attribute>
+         <attribute name="applies_experiment" type="boolean">
+            <annotation>
+               <documentation>
+                  If true, indicate that an instance of this analysis will also be added to an experiment containing one or more trace(s) it applies to. In this case, the analysis will be run on the full experiment and the result is more than just the aggregation of each trace's analysis (default false).
+               </documentation>
+            </annotation>
+         </attribute>
       </complexType>
    </element>
 
index 640c67e426d15eb44c554e80d1175332040f47a1..52a10b64c38cc39d88b83eb5cccfbda08752d3df 100644 (file)
@@ -53,6 +53,9 @@ public final class TmfAnalysisModuleSourceConfigElement implements IAnalysisModu
     /** Extension point attribute 'automatic' */
     public static final String AUTOMATIC_ATTR = "automatic"; //$NON-NLS-1$
 
+    /** Extension point attribute 'applies_experiment' */
+    public static final String APPLIES_EXP_ATTR = "applies_experiment"; //$NON-NLS-1$
+
     /** Extension point attribute 'icon' */
     public static final String ICON_ATTR = "icon"; //$NON-NLS-1$
 
index 6e4a0f9602aa83c60a5f2ed769d8f3131ea1d6e8..1e3eb16ae5a839a62d02a0bc18234113d82c58e8 100644 (file)
@@ -113,6 +113,19 @@ public interface IAnalysisModuleHelper extends IAnalysisRequirementProvider {
      */
     Iterable<Class<? extends ITmfTrace>> getValidTraceTypes();
 
+    /**
+     * Determine if an analysis should be run on an experiment if it applies to
+     * at least one of its traces. It means that an instance of the analysis
+     * module will be created specifically for the experiment and the result
+     * will be more than a simple aggregation of the results of each trace's
+     * module. This method does not actually do the check, it just returns
+     * whether it should apply.
+     *
+     * @return whether this analysis should be run on an experiment
+     * @since 1.0
+     */
+    boolean appliesToExperiment();
+
     // ---------------------------------------
     // Functionalities
     // ---------------------------------------
index 7406aa058712b8789095784e92e42cb089885438..e7299f7fa022c5404a65c915a2141c278329f25a 100644 (file)
@@ -128,6 +128,12 @@ public class TmfAnalysisManager {
      *
      * This map is read-only
      *
+     * TODO: This method is only used to populate the project view in the UI. It
+     * should be deprecated eventually, after some UI rework, so that the trace
+     * type does not drive whether the analysis module applies or not to a
+     * trace, but rather the content of the trace or experiment (once it is
+     * opened)
+     *
      * @param traceclass
      *            The trace class to get modules for
      * @return The map of available {@link IAnalysisModuleHelper}
index a8ac22c03112328ef97033d19f9c67265f1b7530..fc1fc09fb61dd79cede2d4468389e018fae0ebfa 100644 (file)
@@ -29,6 +29,8 @@ import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
 import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
 import org.osgi.framework.Bundle;
 
 /**
@@ -78,6 +80,14 @@ public class TmfAnalysisModuleHelperConfigElement implements IAnalysisModuleHelp
         return Boolean.parseBoolean(fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.AUTOMATIC_ATTR));
     }
 
+    /**
+     * @since 1.0
+     */
+    @Override
+    public boolean appliesToExperiment() {
+        return Boolean.parseBoolean(fCe.getAttribute(TmfAnalysisModuleSourceConfigElement.APPLIES_EXP_ATTR));
+    }
+
     @Override
     public String getHelpText() {
         /*
@@ -115,14 +125,15 @@ public class TmfAnalysisModuleHelperConfigElement implements IAnalysisModuleHelp
                 if (classApplies) {
                     applies |= applyclass.isAssignableFrom(traceclass);
                 } else {
-                    /* If the trace type does not apply, reset the applies variable to false */
+                    /*
+                     * If the trace type does not apply, reset the applies
+                     * variable to false
+                     */
                     if (applyclass.isAssignableFrom(traceclass)) {
                         applies = false;
                     }
                 }
-            } catch (ClassNotFoundException e) {
-                Activator.logError("Error in applies to trace", e); //$NON-NLS-1$
-            } catch (InvalidRegistryObjectException e) {
+            } catch (ClassNotFoundException | InvalidRegistryObjectException e) {
                 Activator.logError("Error in applies to trace", e); //$NON-NLS-1$
             }
         }
@@ -171,8 +182,23 @@ public class TmfAnalysisModuleHelperConfigElement implements IAnalysisModuleHelp
     @Override
     public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException {
 
+        /* Check if it applies to trace itself */
+        boolean applies = appliesToTraceType(trace.getClass());
+        /*
+         * If the trace is an experiment, check if this module would apply to an
+         * experiment should it apply to one of its traces.
+         */
+        if (!applies && (trace instanceof TmfExperiment) && appliesToExperiment()) {
+            for (ITmfTrace expTrace : TmfTraceManager.getTraceSet(trace)) {
+                if (appliesToTraceType(expTrace.getClass())) {
+                    applies = true;
+                    break;
+                }
+            }
+        }
+
         /* Check that analysis can be executed */
-        if (!appliesToTraceType(trace.getClass())) {
+        if (!applies) {
             throw new TmfAnalysisException(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, getName()));
         }
 
index 16f60f00a3b4e8e8da598346432141dada0cc14c..f46183858ef461baf7bd200d9153d15fa3cc1b11 100644 (file)
@@ -59,6 +59,7 @@ import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointI
 import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
 
 /**
  * Abstract implementation of ITmfTrace.
@@ -284,8 +285,7 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, IT
     protected IStatus executeAnalysis() {
         MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
 
-        Class<? extends TmfTrace> className = checkNotNull(this.getClass());
-        Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(className);
+        Multimap<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules();
         for (IAnalysisModuleHelper helper : modules.values()) {
             try {
                 IAnalysisModule module = helper.newModule(this);
index aa3cf798a19636b398a6cd4e0a7a0c574b3f9456..df44b6e21b92c5b626e7745ced6353925b74899e 100644 (file)
@@ -42,8 +42,11 @@ import org.eclipse.osgi.util.NLS;
 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
 import org.eclipse.tracecompass.internal.tmf.ui.editors.ITmfEventsEditorConstants;
 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
 import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
 import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
 import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor;
@@ -180,6 +183,27 @@ public class TmfExperimentElement extends TmfCommonProjectElement implements IPr
 
         /* Update the analysis under this experiment */
         super.refreshChildren();
+
+        /*
+         * If the experiment is opened, add any analysis that was not added by
+         * the parent if it is available with the experiment
+         */
+        ITmfTrace experiment = getTrace();
+        if (experiment == null) {
+            return;
+        }
+        Map<String, TmfAnalysisElement> analysisMap = new HashMap<>();
+        for (TmfAnalysisElement analysis : getAvailableAnalysis()) {
+            analysisMap.put(analysis.getAnalysisId(), analysis);
+        }
+        for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules().values()) {
+            if (!analysisMap.containsKey(module.getId()) && module.appliesToExperiment() && (experiment.getAnalysisModule(module.getId()) != null)) {
+                IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(fResource.getFullPath().append(module.getId()));
+                TmfAnalysisElement analysis = new TmfAnalysisElement(module.getName(), newresource, this, module);
+                analysis.refreshChildren();
+                analysisMap.put(module.getId(), analysis);
+            }
+        }
     }
 
     private List<IResource> getTraceResources() {
This page took 0.032848 seconds and 5 git commands to generate.