tmf: add events field analysis requirement class and test
authorBernd Hufmann <Bernd.Hufmann@ericsson.com>
Fri, 11 Mar 2016 18:27:04 +0000 (13:27 -0500)
committerBernd Hufmann <bernd.hufmann@ericsson.com>
Tue, 19 Apr 2016 10:02:59 +0000 (06:02 -0400)
This class allows to specify required events fields for one given event
type.

This class is useful for CTF, where optional event contexts are provided
as event fields.

Moreover, this will be useful for custom txt and xml trace types, where
for each event the event type is the same but the event fields might
be different.

Change-Id: I445976ea7b93ee95be887504bc223912c2cab298
Signed-off-by: Bernd Hufmann <Bernd.Hufmann@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/68233
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/AnalysisEventFieldRequirementTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfAnalysisEventFieldRequirement.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfEventTypeCollectionHelper.java

diff --git a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/AnalysisEventFieldRequirementTest.java b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/AnalysisEventFieldRequirementTest.java
new file mode 100644 (file)
index 0000000..f03e42c
--- /dev/null
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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.tmf.core.tests.analysis.requirements;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisEventFieldRequirement;
+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.event.ITmfEventField;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test the {@link TmfAnalysisEventFieldRequirement} class
+ *
+ * @author Bernd Hufmann
+ */
+public class AnalysisEventFieldRequirementTest {
+
+    private static final @NonNull String EVENT1 = "abc";
+    private static final @NonNull String EVENT2 = "def";
+    private static final @NonNull String EVENT3 = "ghi";
+
+    private static final @NonNull String EVENT1_FIELD1 = "mno";
+    private static final @NonNull String EVENT1_FIELD2 = "pqr";
+
+    private static final @NonNull String EVENT2_FIELD1 = "stu";
+    private static final @NonNull String EVENT2_FIELD2 = "vwx";
+    private static final @NonNull String EVENT_FIELD = "bla";
+
+    /* A trace class with pre-defined events */
+    private static class TraceWithEvents extends TmfTraceStub implements ITmfTraceWithPreDefinedEvents {
+
+        @Override
+        public @NonNull Set<? extends @NonNull ITmfEventType> getContainedEventTypes() {
+            return ImmutableSet.of(
+                    new ITmfEventType() {
+
+                        @Override
+                        public @NonNull String getName() {
+                            return EVENT1;
+                        }
+
+                        @Override
+                        public ITmfEventField getRootField() {
+                            return null;
+                        }
+
+                        @Override
+                        public Collection<String> getFieldNames() {
+                            return ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2);
+                        }
+                    },
+                    new ITmfEventType() {
+                        @Override
+                        public @NonNull String getName() {
+                            return EVENT2;
+                        }
+
+                        @Override
+                        public ITmfEventField getRootField() {
+                            return null;
+                        }
+
+                        @Override
+                        public Collection<String> getFieldNames() {
+                            return ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2);
+                        }
+                    },
+                    new ITmfEventType() {
+                        @Override
+                        public @NonNull String getName() {
+                            return EVENT2;
+                        }
+
+                        @Override
+                        public ITmfEventField getRootField() {
+                            return null;
+                        }
+
+                        @Override
+                        public Collection<String> getFieldNames() {
+                            return ImmutableSet.of(EVENT2_FIELD1, EVENT2_FIELD2);
+                        }
+                    });
+        }
+
+    }
+
+    private final @NonNull TmfTrace trace = new TraceWithEvents();
+
+    /**
+     * Test with optional requirements
+     */
+    @Test
+    public void testOptionalRequirements() {
+        /* Test optional requirement */
+        TmfAnalysisRequirement req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1));
+        assertTrue(req.test(trace));
+
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2));
+        assertTrue(req.test(trace));
+
+        req = new TmfAnalysisEventFieldRequirement("", ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2));
+        assertTrue(req.test(trace));
+
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, checkNotNull(Collections.EMPTY_LIST));
+        assertTrue(req.test(trace));
+
+        req = new TmfAnalysisEventFieldRequirement("", checkNotNull(Collections.EMPTY_LIST));
+        assertTrue(req.test(trace));
+    }
+
+    /**
+     * Test with mandatory requirements
+     */
+    @Test
+    public void testMandatoryRequirements() {
+        /* Test mandatory requirement */
+        TmfAnalysisRequirement req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1), ValuePriorityLevel.MANDATORY);
+        assertTrue(req.test(trace));
+
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2), ValuePriorityLevel.MANDATORY);
+        assertTrue(req.test(trace));
+
+        /* EVENT3 is not part of the trace. Test case that one of the events is part of the trace */
+        req = new TmfAnalysisEventFieldRequirement(EVENT3, ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2), ValuePriorityLevel.MANDATORY);
+        assertFalse(req.test(trace));
+
+        /* EVENT_FIELD is not an event field of the trace */
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2, EVENT_FIELD), ValuePriorityLevel.MANDATORY);
+        assertFalse(req.test(trace));
+
+        /* Test case that all events need to have the given fields */
+        req = new TmfAnalysisEventFieldRequirement("", ImmutableSet.of(EVENT1_FIELD1, EVENT1_FIELD2));
+        assertTrue(req.test(trace));
+
+        /* Test case that empty list of event fields behaves like Event Requirements */
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, checkNotNull(Collections.EMPTY_LIST));
+        assertTrue(req.test(trace));
+    }
+
+    /**
+     * Test event requirements on a trace with no pre-defined events. They
+     * should all pass
+     */
+    @Test
+    public void testNoPreDefinedEvents() {
+        /* A simple trace with no pre-defined events */
+        TmfTrace traceNoEvents = new TmfTraceStub();
+
+        TmfAnalysisRequirement req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1), ValuePriorityLevel.MANDATORY);
+        assertTrue(req.test(traceNoEvents));
+
+        req = new TmfAnalysisEventFieldRequirement(EVENT1, ImmutableSet.of(EVENT1_FIELD1), ValuePriorityLevel.OPTIONAL);
+        assertTrue(req.test(traceNoEvents));
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfAnalysisEventFieldRequirement.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfAnalysisEventFieldRequirement.java
new file mode 100644 (file)
index 0000000..3e2973e
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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.tmf.core.analysis.requirements;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
+import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * An analysis requirement for event fields of a given event name.
+ *
+ * @author Bernd Hufmann
+ * @since 2.0
+ */
+public class TmfAnalysisEventFieldRequirement extends TmfAnalysisRequirement {
+
+    /** The type of requirement */
+    private static final String TYPE_EVENT_FIELD = "field"; //$NON-NLS-1$
+
+    /** The event name of the event containing the mandatory fields */
+    private String fEventName;
+
+    /**
+     * Constructor
+     *
+     * @param eventName
+     *            The event name of the event containing the mandatory fields.
+     *            Empty string will indicate that all events need to have the
+     *            fields.
+     * @param fields
+     *            The list of event field names the trace must have
+     */
+    public TmfAnalysisEventFieldRequirement(String eventName, Collection<String> fields) {
+        this(eventName, fields, ValuePriorityLevel.OPTIONAL);
+    }
+
+    /**
+     * Constructor. Instantiate a requirement object with a list of values of
+     * the same level
+     *
+     * @param eventName
+     *            The event name of the event containing the mandatory fields.
+     *            Empty string will indicate that all events need to have the
+     *            fields.
+     * @param fields
+     *            The list of event field names the trace must have
+     * @param level
+     *            A level associated with all the values
+     * @throws IllegalArgumentException if no event names are provided
+     */
+    public TmfAnalysisEventFieldRequirement(String eventName, Collection<String> fields, ValuePriorityLevel level) {
+        super(TYPE_EVENT_FIELD, fields, level);
+        fEventName = eventName;
+    }
+
+    @Override
+    public boolean test(ITmfTrace trace) {
+        if ((trace instanceof ITmfTraceWithPreDefinedEvents)) {
+            Set<String> mandatoryValues = getValues(ValuePriorityLevel.MANDATORY);
+            if (mandatoryValues.isEmpty()) {
+                return true;
+            }
+            Multimap<@NonNull String, @NonNull String> traceEvents =
+                    TmfEventTypeCollectionHelper.getEventFieldNames((((ITmfTraceWithPreDefinedEvents) trace).getContainedEventTypes()));
+
+            if (fEventName.isEmpty()) {
+                return traceEvents.keys().stream().allMatch(eventName -> {
+                    Collection<@NonNull String> fields = traceEvents.get(fEventName);
+                    return fields.containsAll(mandatoryValues);
+                });
+            }
+            Collection<@NonNull String> fields = traceEvents.get(fEventName);
+            return fields.containsAll(mandatoryValues);
+        }
+        return true;
+    }
+
+}
index 029151210deb53b73a90575b30667680a6e9b191..fe5ca4cc9dfefd1c0b1013644055652793f9d40c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 Ericsson
+ * Copyright (c) 2014, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
 
 package org.eclipse.tracecompass.tmf.core.trace;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
 
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
 /**
  * Set Helper for sets of ITmfTraceType
  *
@@ -45,4 +49,30 @@ public final class TmfEventTypeCollectionHelper {
         }
         return retSet;
     }
+
+    /**
+     * Gets a map from event name to a collection of field names from a
+     * collection of event types
+     *
+     * @param eventTypes
+     *            an iterable collection of ITmfEventTypes
+     * @return a set of the names of these events, if some event names are
+     *         clashing they will only appear once
+     * @since 2.0
+     */
+    public static Multimap<@NonNull String, @NonNull String> getEventFieldNames(Iterable<@NonNull ? extends ITmfEventType> eventTypes) {
+        Multimap<@NonNull String, @NonNull String> retMap = HashMultimap.create();
+        eventTypes.forEach(eventType -> {
+            Collection<String> collection = eventType.getFieldNames();
+            if (collection != null) {
+                collection.forEach(field -> {
+                    if (field != null) {
+                        retMap.put(eventType.getName(), field);
+                    }
+                });
+            }
+        });
+        return retMap;
+    }
+
 }
This page took 0.028566 seconds and 5 git commands to generate.