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);
+ }
}
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;
}
}
+ /**
+ * 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
*
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;
/* 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:
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:
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