tmf.xml: Add support for peek() stack operation
authorJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Wed, 13 Jul 2016 17:38:49 +0000 (13:38 -0400)
committerJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Wed, 24 Aug 2016 02:57:50 +0000 (22:57 -0400)
This implements the peek operation for a stack of state value. On a
condition, the peek operation read the value at the top without
removing. On a state change, the peek operation will do nothing. A test
for a stack state value is provided.

Change-Id: I2192ee41171a7c6eabce2941466edbc168c1fa82
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/77274
Reviewed-by: Hudson CI
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlUtilsTest.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteStateValue.java

index d6489d51b6514a92b16018d4f36d77a98a37dfdb..e9a53fae5df16616abc2e2c1cf2020febb8a0349 100644 (file)
@@ -117,4 +117,30 @@ public class TmfStateValueTest {
         XmlUtilsTest.verifyStateIntervals("testStateValueModify", ss, quark, expectedStarts, expectedValues);
 
     }
+
+    /**
+     *
+     * it tests that a state change on stack, with a peek() condition. This test
+     * verifies the value on the top of the stack and verifies that the peek
+     * operation do not remove the value on the top of the stack.
+     *
+     * @throws StateSystemDisposedException
+     *             Exceptions thrown during state system verification
+     * @throws AttributeNotFoundException
+     *             Exceptions thrown during state system verification
+     */
+    @Test
+    public void testStateValuePeek() throws AttributeNotFoundException, StateSystemDisposedException {
+        XmlStateSystemModule module = fModule;
+        assertNotNull(module);
+
+        ITmfStateSystem ss = module.getStateSystem();
+        assertNotNull(ss);
+
+        int quark = ss.getQuarkAbsolute("stack");
+
+        final int[] expectedStarts = { 1, 5, 7, 7 };
+        ITmfStateValue[] expectedValues = { TmfStateValue.newValueLong(1l), TmfStateValue.newValueLong(5l), TmfStateValue.newValueLong(1l) };
+        XmlUtilsTest.verifyStackStateIntervals("testStateValueModify", ss, quark, expectedStarts, expectedValues);
+    }
 }
index 1d1fb801c92f09254e300efb963cb3681ec74ef3..e57794c3fbf952cef223fa9bd4e90cf04ca62df5 100644 (file)
@@ -29,6 +29,7 @@ import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
@@ -293,6 +294,41 @@ public class XmlUtilsTest {
         }
     }
 
+    /**
+     * This function test the data provided by the state intervals queried on a stack
+     *
+     * @param testId
+     *            The id of the test
+     * @param ss
+     *            The state system associated to this test
+     * @param quark
+     *            The quark we want to query
+     * @param expectedStarts
+     *            The expected start timestamps for the intervals generated for
+     *            this quark
+     * @param expectedValues
+     *            The expected content values for this quark
+     * @throws AttributeNotFoundException
+     *             If the quark we want to query is invalid
+     * @throws StateSystemDisposedException
+     *             If the state system has been disposed before the end of the
+     *             queries
+     */
+    public static void verifyStackStateIntervals(String testId, @NonNull ITmfStateSystem ss, Integer quark, int[] expectedStarts, ITmfStateValue[] expectedValues) throws AttributeNotFoundException, StateSystemDisposedException {
+        int expectedCount = expectedStarts.length - 1;
+        List<ITmfStateInterval> intervals = StateSystemUtils.queryHistoryRange(ss, quark, expectedStarts[0], expectedStarts[expectedCount]);
+        assertEquals(testId + ": Interval count", expectedCount, intervals.size());
+        for (int i = 0; i < expectedCount; i++) {
+            ITmfStateInterval interval = intervals.get(i);
+            assertEquals(testId + ": Start time of interval " + i, expectedStarts[i], interval.getStartTime());
+            long actualEnd = (i == expectedCount - 1) ? (expectedStarts[i + 1]) : (expectedStarts[i + 1]) - 1;
+            assertEquals(testId + ": End time of interval " + i, actualEnd, interval.getEndTime());
+            @Nullable ITmfStateInterval stackValueInterval = StateSystemUtils.querySingleStackTop(ss, interval.getStartTime(), quark);
+            assertNotNull(stackValueInterval);
+            assertEquals(testId + ": Expected value of interval " + i, expectedValues[i], stackValueInterval.getStateValue());
+        }
+    }
+
     /**
      * Test a pattern segment against what is expected
      *
index 2326f6ce23cf37a10ff1e07229b272d26c5aba1e..72b1b090c9b8de513e2bd2c6afebe551b43442a7 100644 (file)
                                <stateAttribute type="eventField" value="cpu" />
                                <stateValue type="string" value="UNKNOWN" />
                        </stateChange>
+                       <stateChange>
+                               <stateAttribute type="constant" value="stack"/>
+                               <stateValue stack="push" type="eventField" value="timestamp" />
+                       </stateChange>
                </eventHandler>
                <eventHandler eventName="exit">
                        <stateChange>
                                <stateAttribute type="eventField" value="cpu" />
                                <stateValue type="eventField" value="curState" />
                        </stateChange>
+                       <stateChange>
+                               <if>
+                                       <condition>
+                                               <stateValue type="long" stack="peek" >
+                                                       <stateAttribute type="constant" value="stack" />
+                                               </stateValue>
+                                               <stateValue type="long" value="5" />
+                                       </condition>
+                               </if>
+                               <then>
+                                       <stateAttribute type="constant" value="stack"/>
+                                       <stateValue stack="pop" type="long"/>
+                               </then>
+                       </stateChange>
                </eventHandler>
        </stateProvider>
 </tmfxml>
\ No newline at end of file
index 5192cf79cc862488db8d7a73db6f0e11f8c1fa55..8125afc9f7f605b17cde3d79d91af75ed7e31239 100644 (file)
@@ -28,9 +28,12 @@ import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.Tmf
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
 import org.eclipse.tracecompass.statesystem.core.StateSystemBuilderUtils;
+import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
@@ -96,37 +99,54 @@ public class TmfXmlReadWriteStateValue extends TmfXmlStateValue {
         /* Process the XML Element state value */
         String type = node.getAttribute(TmfXmlStrings.TYPE);
         String value = getSsContainer().getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE));
-        if (value == null) {
+
+        if (value == null && getStackType().equals(ValueTypeStack.NULL)) {
             throw new IllegalStateException();
         }
 
+        List<@Nullable Element> children = XmlUtils.getChildElements(node);
+        List<ITmfXmlStateAttribute> childAttributes = new ArrayList<>();
+        for (Element child : children) {
+            if (child == null) {
+                continue;
+            }
+            ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer());
+            childAttributes.add(queryAttribute);
+        }
+
         switch (type) {
         case TmfXmlStrings.TYPE_INT: {
             /* Integer value */
-            ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value));
-            stateValueType = new TmfXmlStateValueTmf(stateValue);
+            ITmfStateValue stateValue = value != null && !value.isEmpty() ?
+                    TmfStateValue.newValueInt(Integer.parseInt(value)) : TmfStateValue.nullValue();
+            stateValueType = new TmfXmlStateValueTmf(stateValue, childAttributes);
             break;
         }
         case TmfXmlStrings.TYPE_LONG: {
             /* Long value */
-            ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value));
-            stateValueType = new TmfXmlStateValueTmf(stateValue);
+            ITmfStateValue stateValue = value != null && !value.isEmpty() ?
+                    TmfStateValue.newValueLong(Long.parseLong(value)) : TmfStateValue.nullValue();
+            stateValueType = new TmfXmlStateValueTmf(stateValue, childAttributes);
             break;
         }
         case TmfXmlStrings.TYPE_STRING: {
             /* String value */
-            ITmfStateValue stateValue = TmfStateValue.newValueString(value);
-            stateValueType = new TmfXmlStateValueTmf(stateValue);
+            ITmfStateValue stateValue = value != null ?
+                    TmfStateValue.newValueString(value) : TmfStateValue.nullValue();
+            stateValueType = new TmfXmlStateValueTmf(stateValue, childAttributes);
             break;
         }
         case TmfXmlStrings.TYPE_NULL: {
             /* Null value */
             ITmfStateValue stateValue = TmfStateValue.nullValue();
-            stateValueType = new TmfXmlStateValueTmf(stateValue);
+            stateValueType = new TmfXmlStateValueTmf(stateValue, childAttributes);
             break;
         }
         case TmfXmlStrings.EVENT_FIELD:
             /* Event field */
+            if (value == null) {
+                throw new IllegalStateException("Event field name cannot be null"); //$NON-NLS-1$
+            }
             stateValueType = new TmfXmlStateValueEventField(value);
             break;
         case TmfXmlStrings.TYPE_EVENT_NAME:
@@ -139,15 +159,6 @@ public class TmfXmlReadWriteStateValue extends TmfXmlStateValue {
             break;
         case TmfXmlStrings.TYPE_QUERY:
             /* Value is the result of a query */
-            List<@Nullable Element> children = XmlUtils.getChildElements(node);
-            List<ITmfXmlStateAttribute> childAttributes = new ArrayList<>();
-            for (Element child : children) {
-                if (child == null) {
-                    continue;
-                }
-                ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer());
-                childAttributes.add(queryAttribute);
-            }
             stateValueType = new TmfXmlStateValueQuery(childAttributes);
             break;
         default:
@@ -241,14 +252,68 @@ public class TmfXmlReadWriteStateValue extends TmfXmlStateValue {
     private class TmfXmlStateValueTmf extends TmfXmlStateValueTypeReadWrite {
 
         private final ITmfStateValue fValue;
+        private final List<ITmfXmlStateAttribute> fAttributesValue;
 
-        public TmfXmlStateValueTmf(ITmfStateValue value) {
+        public TmfXmlStateValueTmf(ITmfStateValue value, List<ITmfXmlStateAttribute> attributes) {
             fValue = value;
+            fAttributesValue = attributes;
         }
 
         @Override
         public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) {
-            return fValue;
+            try {
+                switch (getStackType()) {
+                case PEEK:
+                    return peek(event, scenarioInfo);
+                case PUSH:
+                case NULL:
+                case POP:
+                default:
+                    return fValue;
+                }
+            } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+                Activator.logError("Query stack failed"); //$NON-NLS-1$
+                return TmfStateValue.nullValue();
+            }
+        }
+
+        /**
+         * @param event
+         *            The ongoing event
+         * @param scenarioInfo
+         *            The active scenario details. The value should be null if
+         *            there no scenario.
+         * @return The value value at the top of the stack without removing it
+         * @throws AttributeNotFoundException
+         *             If the do not exist
+         * @throws StateSystemDisposedException
+         *             If the state system is disposed
+         */
+        private ITmfStateValue peek(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateSystemDisposedException {
+            int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK;
+            ITmfStateSystemBuilder ss = getStateSystem();
+            if (ss == null) {
+                throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
+            }
+
+            if (event == null) {
+                throw new IllegalStateException("The event should not be null at this point."); //$NON-NLS-1$
+            }
+
+            for (ITmfXmlStateAttribute attribute : fAttributesValue) {
+                quarkQuery = attribute.getAttributeQuark(event, quarkQuery, scenarioInfo);
+                if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) {
+                    /*
+                     * the query is not valid, we stop the state change
+                     */
+                    return TmfStateValue.nullValue();
+                }
+            }
+
+            final long ts = event.getTimestamp().toNanos();
+            @Nullable ITmfStateInterval stackTopInterval = StateSystemUtils.querySingleStackTop(ss, ts, quarkQuery);
+            final ITmfStateValue value = stackTopInterval != null ? stackTopInterval.getStateValue() : null;
+            return value != null ? value : TmfStateValue.nullValue();
         }
 
         @Override
This page took 0.032474 seconds and 5 git commands to generate.