/** A valid file for pattern tests */
VALID_PATTERN_FILE("test_xml_files/test_valid/test_valid_pattern.xml"),
/** A valid pattern file to test the pattern segment **/
- VALID_PATTERN_SEGMENT("test_xml_files/test_valid/test_pattern_segment.xml");
+ VALID_PATTERN_SEGMENT("test_xml_files/test_valid/test_pattern_segment.xml"),
+ /** A valid file for consuming fsm test */
+ CONSUMING_FSM_TEST("test_xml_files/test_valid/test_consuming_fsm.xml");
private final String fPath;
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.pattern.stateprovider.XmlPatternAnalysis;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule;
return module;
}
+ /**
+ * Initialize a new pattern analysis using the xml file
+ *
+ * @param xmlAnalysisFile
+ * The xml file used to initialize the pattern analysis
+ * @return The pattern analysis
+ */
+ public static @NonNull XmlPatternAnalysis initializePatternModule(TmfXmlTestFiles xmlAnalysisFile) {
+
+ /* Initialize the state provider module */
+ Document doc = xmlAnalysisFile.getXmlDocument();
+ assertNotNull(doc);
+
+ /* get State Providers modules */
+ NodeList patternNodes = doc.getElementsByTagName(TmfXmlStrings.PATTERN);
+ assertFalse(patternNodes.getLength() == 0);
+
+ Element node = (Element) patternNodes.item(0);
+ XmlPatternAnalysis analysis = new XmlPatternAnalysis();
+ String moduleId = node.getAttribute(TmfXmlStrings.ID);
+ assertNotNull(moduleId);
+ analysis.setId(moduleId);
+
+ analysis.setXmlFile(xmlAnalysisFile.getPath());
+
+ return analysis;
+ }
+
/**
* This function test the data provided by the state intervals queried
*
--- /dev/null
+/*******************************************************************************
+ * 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.analysis.xml.core.tests.stateprovider;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternAnalysis;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module.XmlUtilsTest;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test the consuming state of an fsm. This test creates a pattern with two fsm.
+ * One is consuming, the other is not. Each fsm will create three scenarios. We
+ * use a counter to verify if an event was consumed or not.
+ *
+ * @author Jean-Christian Kouame
+ */
+public class ConsumingFsmTest {
+
+ private static final @NonNull String TEST_TRACE = "test_traces/testTrace5.xml";
+
+ ITmfTrace fTrace;
+ XmlPatternAnalysis fModule;
+
+ /**
+ * Initializes the trace and the module for the tests
+ *
+ * @throws TmfAnalysisException
+ * Any exception thrown during module initialization
+ */
+ @Before
+ public void setUp() throws TmfAnalysisException {
+ ITmfTrace trace = XmlUtilsTest.initializeTrace(TEST_TRACE);
+ @NonNull XmlPatternAnalysis module = XmlUtilsTest.initializePatternModule(TmfXmlTestFiles.CONSUMING_FSM_TEST);
+
+ module.setTrace(trace);
+
+ module.schedule();
+ module.waitForCompletion();
+
+ fTrace = trace;
+ fModule = module;
+ }
+
+ /**
+ * Dispose the module and the trace
+ */
+ @After
+ public void cleanUp() {
+ fTrace.dispose();
+ fModule.dispose();
+ }
+
+ /**
+ * Test the consuming fsm counter
+ *
+ * @throws StateSystemDisposedException
+ * Exceptions thrown during state system verification
+ * @throws AttributeNotFoundException
+ * Exceptions thrown during state system verification
+ */
+ @Test
+ public void testConsumingFsm() throws AttributeNotFoundException, StateSystemDisposedException {
+ XmlPatternAnalysis module = fModule;
+ assertNotNull(module);
+
+ ITmfStateSystem ss = module.getStateSystem(module.getId());
+ assertNotNull(ss);
+
+ int quark = ss.getQuarkAbsolute("consuming");
+
+ final int[] expectedStarts = { 1, 7, 7 };
+ ITmfStateValue[] expectedValues = { TmfStateValue.nullValue(), TmfStateValue.newValueLong(1l)};
+ XmlUtilsTest.verifyStateIntervals("testConsuming", ss, quark, expectedStarts, expectedValues);
+
+ }
+
+ /**
+ * Test the non consuming fsm counter
+ *
+ * @throws StateSystemDisposedException
+ * Exceptions thrown during state system verification
+ * @throws AttributeNotFoundException
+ * Exceptions thrown during state system verification
+ */
+ @Test
+ public void testNonConsumingFsm() throws AttributeNotFoundException, StateSystemDisposedException {
+ XmlPatternAnalysis module = fModule;
+ assertNotNull(module);
+
+ ITmfStateSystem ss = module.getStateSystem(module.getId());
+ assertNotNull(ss);
+
+ int quark = ss.getQuarkAbsolute("non_consuming");
+
+ final int[] expectedStarts = { 1, 7, 7 };
+ ITmfStateValue[] expectedValues = { TmfStateValue.nullValue(), TmfStateValue.newValueLong(3l)};
+ XmlUtilsTest.verifyStateIntervals("testNonConsuming", ss, quark, expectedStarts, expectedValues);
+
+ }
+}
+
--- /dev/null
+<!-- ***************************************************************************
+* Copyright (c) 2014 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
+*************************************************************************** -->
+<trace>
+<event timestamp="1" name="entry" source="0">
+<field name="cpu" type="int" value="0" />
+</event>
+<event timestamp="3" name="entry" source="0">
+<field name="cpu" type="int" value="0" />
+</event>
+<event timestamp="5" name="entry" source="0">
+<field name="cpu" type="int" value="0" />
+</event>
+<event timestamp="7" name="exit" source="0">
+<field name="cpu" type="int" value="0" />
+</event>
+</trace>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<tmfxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="xmlDefinition.xsd">
+<!-- ***************************************************************************
+* 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
+*************************************************************************** -->
+<pattern version="0" id="syscall.analysis">
+ <patternHandler>
+ <action id="increment_counter_consuming">
+ <stateChange>
+ <stateAttribute type="constant" value="consuming" />
+ <stateValue increment="true" type="long" value="1"/>
+ </stateChange>
+ </action>
+
+ <fsm id="consuming">
+ <state id="start">
+ <transition event="entry" target="exit_state"/>
+ </state>
+ <state id="exit_state" >
+ <transition event="exit" target="end" action="increment_counter_consuming"/>
+ </state>
+ <final id="end"/>
+ </fsm>
+
+ <action id="increment_counter_non_consuming">
+ <stateChange>
+ <stateAttribute type="constant" value="non_consuming" />
+ <stateValue increment="true" type="long" value="1"/>
+ </stateChange>
+ </action>
+
+ <fsm id="non_consuming" consuming="false">
+ <state id="start">
+ <transition event="entry" target="exit_state"/>
+ </state>
+ <state id="exit_state" >
+ <transition event="exit" target="end" action="increment_counter_non_consuming"/>
+ </state>
+ <final id="end"/>
+ </fsm>
+ </patternHandler>
+</pattern>
+</tmfxml>
\ No newline at end of file
private final String fAbandonStateId;
private final boolean fInstanceMultipleEnabled;
private final String fInitialStateId;
+ private final boolean fConsuming;
+ private boolean fEventConsumed;
private int fTotalScenarios;
/**
*/
public static TmfXmlFsm create(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
String id = node.getAttribute(TmfXmlStrings.ID);
+ boolean consuming = node.getAttribute(TmfXmlStrings.CONSUMING).isEmpty() ? true : Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.CONSUMING));
boolean instanceMultipleEnabled = node.getAttribute(TmfXmlStrings.MULTIPLE).isEmpty() ? true : Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.MULTIPLE));
final List<@NonNull TmfXmlBasicTransition> preconditions = new ArrayList<>();
statesMap.put(abandonState.getId(), abandonState);
}
}
- return new TmfXmlFsm(modelFactory, container, id, instanceMultipleEnabled, initialState, finalStateId, abandonStateId, preconditions, statesMap);
+ return new TmfXmlFsm(modelFactory, container, id, consuming, instanceMultipleEnabled, initialState, finalStateId, abandonStateId, preconditions, statesMap);
}
- private TmfXmlFsm(ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, String id, boolean multiple,
- String initialState, String finalState, String abandonState, List<TmfXmlBasicTransition> preconditions,
+ private TmfXmlFsm(ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, String id, boolean consuming,
+ boolean multiple, String initialState, String finalState, String abandonState, List<TmfXmlBasicTransition> preconditions,
Map<String, TmfXmlState> states) {
fModelFactory = modelFactory;
fTotalScenarios = 0;
fContainer = container;
fId = id;
+ fConsuming = consuming;
fInstanceMultipleEnabled = multiple;
fInitialStateId = initialState;
fFinalStateId = finalState;
return Collections.unmodifiableMap(fStatesMap);
}
+ /**
+ * Set whether the ongoing was consumed by a scenario or not
+ *
+ * @param eventConsumed
+ * The consumed state
+ */
+ public void setEventConsumed(boolean eventConsumed) {
+ fEventConsumed = eventConsumed;
+ }
+
+ private boolean isEventConsumed() {
+ return fEventConsumed;
+ }
+
/**
* Process the active event and determine the next step of this fsm
*
* The transitions of the pattern
*/
public void handleEvent(ITmfEvent event, Map<String, TmfXmlTransitionValidator> transitionMap) {
+ setEventConsumed(false);
if (!validatePreconditions(event, transitionMap)) {
return;
}
currentItr.remove();
} else {
handleScenario(scenario, event);
+ if (fConsuming && isEventConsumed()) {
+ return;
+ }
}
}
}
return;
}
+ fFsm.setEventConsumed(true);
// Processing the actions in the transition
final List<String> actions = out.getAction();
for (String actionId : actions) {
<xs:attribute name="multiple" type="xs:boolean" use="optional" default="true">
<xs:annotation>
<xs:documentation>ONLY USE for fsm. Specifies if this FSM allows multiple instance or only one instance. If not specified, this attribute will be set to 'true' by default.</xs:documentation></xs:annotation></xs:attribute>
+ <xs:attribute name="consuming" type="xs:boolean" use="optional" default="true">
+ <xs:annotation>
+ <xs:documentation>ONLY USE for fsm. Specifies if this FSM is consuming or not. If the FSM is consuming the ongoing event can be used by only one scenario of the FSM, if not, the ongoing scenario can be used in one or several scenario of the FSM. If not specified, this attribute will be set to 'true' by default.</xs:documentation></xs:annotation></xs:attribute>
</xs:complexType>
<xs:complexType name="transition">
String AND_SEPARATOR = ":";
String ALIAS = "alias";
String ABANDON = "abandon";
+ String CONSUMING = "consuming";
}
\ No newline at end of file