blob: c64b22280d33d10fda7d6063e7acaad509f7c9b2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.fsm.compile;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile.AnalysisCompilationData;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile.TmfXmlActionCu;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile.TmfXmlConditionCu;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile.TmfXmlFsmStateCu;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile.TmfXmlFsmStateCu.TmfXmlFsmCu;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenAction;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenActionResetStoredFields;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenActionSegment;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenActionUpdateStoredFields;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenCondition;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenCondition.ConditionOperator;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenFsm;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenFsmSimpleState;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenFsmStateTransition;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.values.DataDrivenValueConstant;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.values.DataDrivenValueEventField;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.values.DataDrivenValueEventName;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* Test the DataDrivenAction compilation from XML
*
* @author Geneviève Bastien
*/
@RunWith(Parameterized.class)
public class TmfXmlFsmCuTest {
// String names for actions, tests and states
private static final @NonNull String STATE1_NAME = "state1";
private static final @NonNull String STATE2_NAME = "state2";
private static final @NonNull String STATE_FINAL_NAME = "final";
private static final @NonNull String ACTION1_NAME = "action1";
private static final @NonNull String ACTION2_NAME = "action2";
private static final @NonNull String TEST1_NAME = "test1";
private static final @NonNull String TEST2_NAME = "test2";
private static final @NonNull String FSM_START = "<fsm id=\"%s\" %s>";
private static final @NonNull String FSM_END = "</fsm>";
private static final @NonNull String STATE_START = "<state id=\"%s\">";
private static final @NonNull String STATE_END = "</state>";
private static final @NonNull String TRANSITION_STRING = "<transition %s %s %s %s %s %s/>";
private static final @NonNull String SAVE_STORED_FIELDS = TmfXmlStrings.SAVE_STORED_FIELDS + "=\"true\"";
private static final @NonNull String CLEAR_STORED_FIELDS = TmfXmlStrings.CLEAR_STORED_FIELDS + "=\"true\"";
private static final @NonNull String EVENTS_STRING = TmfXmlStrings.EVENT + "=\"sys*\"";
private static final @NonNull String ACTION_STRING = TmfXmlStrings.ACTION + "=\"%s\"";
private static final @NonNull String TARGET_STRING = TmfXmlStrings.TARGET + "=\"%s\"";
private static final @NonNull String TEST_STRING = TmfXmlStrings.COND + "=\"%s\"";
private static final @NonNull String WRAPPER_STRING = "<doc>%s</doc>";
// Dummy actions and conditions to use in the FSM strings
private static final @NonNull String ACTION1 = "<action id=\"" + ACTION1_NAME + "\"><segment><segType segName=\"test\"/></segment></action>";
private static final @NonNull String ACTION2 = "<action id=\"" + ACTION2_NAME + "\"><segment><segType segName=\"hello\"/></segment></action>";
private static final @NonNull String TEST1 = "<test id=\"" + TEST1_NAME + "\"><if><condition><stateValue type=\"int\" value=\"2\"/><stateValue type=\"eventField\" value=\"cpu\" /></condition></if></test>";
private static final @NonNull String TEST2 = "<test id=\"" + TEST2_NAME + "\"><if><condition><stateValue type=\"int\" value=\"0\"/><stateValue type=\"eventField\" value=\"cpu\" /></condition></if></test>";
// Their generated values
private static final @NonNull DataDrivenAction ACTION1_DD = new DataDrivenActionSegment(new DataDrivenValueConstant(null, ITmfStateValue.Type.NULL, "test"),
null, null, null, Collections.emptyMap());
private static final @NonNull DataDrivenAction ACTION2_DD = new DataDrivenActionSegment(new DataDrivenValueConstant(null, ITmfStateValue.Type.NULL, "hello"),
null, null, null, Collections.emptyMap());
private static final @NonNull DataDrivenCondition EVENT_CONDITION = new DataDrivenCondition.DataDrivenRegexCondition(Pattern.compile("sys.*"),
new DataDrivenValueEventName(null));
private static final @NonNull DataDrivenCondition TEST1_DD = new DataDrivenCondition.DataDrivenComparisonCondition(new DataDrivenValueConstant(null, ITmfStateValue.Type.NULL, 2),
new DataDrivenValueEventField(null, ITmfStateValue.Type.NULL, "cpu"), ConditionOperator.EQ);
private static final @NonNull DataDrivenCondition TEST2_DD = new DataDrivenCondition.DataDrivenComparisonCondition(new DataDrivenValueConstant(null, ITmfStateValue.Type.NULL, 0),
new DataDrivenValueEventField(null, ITmfStateValue.Type.NULL, "cpu"), ConditionOperator.EQ);
// Describe some test cases of valid actions
private static abstract class CompilationResult {
public abstract @NonNull String getName();
public abstract @NonNull String getXmlString();
public abstract @Nullable DataDrivenFsm getResult();
@Override
public String toString() {
return getName();
}
}
private static final @NonNull CompilationResult VALID_ONE_STATE_FINAL = new CompilationResult() {
@Override
public String getName() {
return "one_state_final";
}
@Override
public String getXmlString() {
return String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
STATE_END +
FSM_END;
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME, Collections.emptyList(), DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_ONE_STATE_LOOP = new CompilationResult() {
@Override
public String getName() {
return "one_state_loop";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + ACTION1 + String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE1_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE1_NAME,
Collections.singletonList(ACTION1_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_SAVE_CLEAR_FIELDS = new CompilationResult() {
@Override
public String getName() {
return "save_and_clear_fields";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + ACTION1 + String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE1_NAME), SAVE_STORED_FIELDS, CLEAR_STORED_FIELDS) +
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE1_NAME,
ImmutableList.of(ACTION1_DD, DataDrivenActionUpdateStoredFields.getInstance(), DataDrivenActionResetStoredFields.getInstance()))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_MULTIPLE_ACTIONS_TESTS = new CompilationResult() {
@Override
public String getName() {
return "multiple_actions_and_tests";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + TEST2 + ACTION1 + ACTION2 +
String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME + ':' + ACTION2_NAME), String.format(TEST_STRING, TEST1_NAME + ':' + TEST2_NAME), String.format(TARGET_STRING, STATE1_NAME),
StringUtils.EMPTY, StringUtils.EMPTY)
+
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(TEST1_DD, TEST2_DD)),
STATE1_NAME,
ImmutableList.of(ACTION1_DD, ACTION2_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_MULTIPLE_STATES_TRANSITIONS = new CompilationResult() {
@Override
public String getName() {
return "multiple_states_and_transitions";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + TEST2 + ACTION1 + ACTION2 +
String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION2_NAME), String.format(TEST_STRING, TEST1_NAME + ':' + TEST2_NAME), String.format(TARGET_STRING, STATE1_NAME), StringUtils.EMPTY,
StringUtils.EMPTY)
+
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE2_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
String.format(STATE_START, STATE2_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, StringUtils.EMPTY, String.format(TEST_STRING, TEST1_NAME + ':' + TEST2_NAME), String.format(TARGET_STRING, STATE_FINAL_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST2_NAME), String.format(TARGET_STRING, STATE1_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
"<final id=\"" + STATE_FINAL_NAME + "\"/>" +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
ImmutableList.of(
new DataDrivenFsmStateTransition(EVENT_CONDITION,
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(TEST1_DD, TEST2_DD)),
STATE1_NAME,
Collections.singletonList(ACTION2_DD)),
new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE2_NAME,
Collections.singletonList(ACTION1_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
DataDrivenFsmSimpleState state2 = new DataDrivenFsmSimpleState(STATE2_NAME,
ImmutableList.of(
new DataDrivenFsmStateTransition(EVENT_CONDITION,
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(TEST1_DD, TEST2_DD)),
STATE_FINAL_NAME,
Collections.emptyList()),
new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST2_DD,
STATE1_NAME,
Collections.singletonList(ACTION1_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
DataDrivenFsmSimpleState finalState = new DataDrivenFsmSimpleState(STATE_FINAL_NAME, Collections.emptyList(), DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state, STATE2_NAME, state2, STATE_FINAL_NAME, finalState), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_ON_ENTRY_EXIT = new CompilationResult() {
@Override
public String getName() {
return "on_entry_exit";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + TEST2 + ACTION1 + ACTION2 +
String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
"<onentry action=\"" + ACTION1_NAME + "\"/>" +
"<onexit action=\"" + ACTION2_NAME + "\"/>" +
String.format(TRANSITION_STRING, EVENTS_STRING, StringUtils.EMPTY, String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE_FINAL_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
"<final id=\"" + STATE_FINAL_NAME + "\"/>" +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE_FINAL_NAME,
Collections.emptyList())),
ACTION1_DD, ACTION2_DD);
DataDrivenFsmSimpleState finalState = new DataDrivenFsmSimpleState(STATE_FINAL_NAME, Collections.emptyList(), DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state, STATE_FINAL_NAME, finalState), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_PRECONDITION = new CompilationResult() {
@Override
public String getName() {
return "with_precondition";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + TEST2 + ACTION1 + ACTION2 +
String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
"<" + TmfXmlStrings.PRECONDITION + " " + EVENTS_STRING + " " + String.format(TEST_STRING, TEST1_NAME) + "/>" +
"<" + TmfXmlStrings.PRECONDITION + " " + TmfXmlStrings.EVENT + "=\"test\" " + String.format(TEST_STRING, TEST1_NAME) + " " + String.format(ACTION_STRING, ACTION1_NAME) + "/>" +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME + ':' + ACTION2_NAME), String.format(TEST_STRING, TEST1_NAME + ':' + TEST2_NAME), String.format(TARGET_STRING, STATE1_NAME),
StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(TEST1_DD, TEST2_DD)),
STATE1_NAME,
ImmutableList.of(ACTION1_DD, ACTION2_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
DataDrivenCondition preCond = new DataDrivenCondition.DataDrivenOrCondition(
ImmutableList.of(
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(EVENT_CONDITION, TEST1_DD)),
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(
new DataDrivenCondition.DataDrivenRegexCondition(Pattern.compile("test"),
new DataDrivenValueEventName(null)), TEST1_DD))
));
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), preCond, true, true);
}
};
private static final @NonNull CompilationResult VALID_INITIAL_STATE = new CompilationResult() {
@Override
public String getName() {
return "initial state";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + TEST2 + ACTION1 + ACTION2 +
String.format(FSM_START, getName(), StringUtils.EMPTY) +
"<initialState>" +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE1_NAME),
StringUtils.EMPTY, StringUtils.EMPTY) +
"</initialState>" +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME + ':' + ACTION2_NAME), String.format(TEST_STRING, TEST1_NAME + ':' + TEST2_NAME), String.format(TARGET_STRING, STATE1_NAME),
StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState initial = new DataDrivenFsmSimpleState(TmfXmlStrings.INITIAL_STATE,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE1_NAME,
Collections.singletonList(ACTION1_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
new DataDrivenCondition.DataDrivenAndCondition(ImmutableList.of(TEST1_DD, TEST2_DD)),
STATE1_NAME,
ImmutableList.of(ACTION1_DD, ACTION2_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), initial,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_INITIAL = new CompilationResult() {
@Override
public String getName() {
return "initial_element";
}
@Override
public String getXmlString() {
return String.format(WRAPPER_STRING,
TEST1 + ACTION1 + String.format(FSM_START, getName(), StringUtils.EMPTY) +
"<initial>" +
String.format(TRANSITION_STRING, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, String.format(TARGET_STRING, STATE1_NAME),
StringUtils.EMPTY, StringUtils.EMPTY) +
"</initial>" +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, ACTION1_NAME), String.format(TEST_STRING, TEST1_NAME), String.format(TARGET_STRING, STATE1_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END);
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME,
Collections.singletonList(new DataDrivenFsmStateTransition(EVENT_CONDITION,
TEST1_DD,
STATE1_NAME,
Collections.singletonList(ACTION1_DD))),
DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult VALID_NO_INITIAL = new CompilationResult() {
@Override
public String getName() {
return "valid_no_initial";
}
@Override
public String getXmlString() {
return String.format(FSM_START, getName(), StringUtils.EMPTY) +
String.format(STATE_START, STATE1_NAME) +
STATE_END +
FSM_END;
}
@Override
public DataDrivenFsm getResult() {
DataDrivenFsmSimpleState state = new DataDrivenFsmSimpleState(STATE1_NAME, Collections.emptyList(), DataDrivenAction.NO_ACTION, DataDrivenAction.NO_ACTION);
return new DataDrivenFsm(getName(), state,
ImmutableMap.of(STATE1_NAME, state), DataDrivenCondition.TRUE_CONDITION, true, true);
}
};
private static final @NonNull CompilationResult INVALID_UNDEFINED_ACTION = new CompilationResult() {
@Override
public String getName() {
return "undefined_action";
}
@Override
public String getXmlString() {
return String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(ACTION_STRING, "action1"), StringUtils.EMPTY, String.format(TARGET_STRING, "state1"), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END;
}
@Override
public DataDrivenFsm getResult() {
return null;
}
};
private static final @NonNull CompilationResult INVALID_UNDEFINED_CONDITION = new CompilationResult() {
@Override
public String getName() {
return "undefined_condition";
}
@Override
public String getXmlString() {
return String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(TEST_STRING, TEST1_NAME), StringUtils.EMPTY, String.format(TARGET_STRING, STATE1_NAME), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END;
}
@Override
public DataDrivenFsm getResult() {
return null;
}
};
private static final @NonNull CompilationResult INVALID_UNDEFINED_TARGET = new CompilationResult() {
@Override
public String getName() {
return "undefined_target";
}
@Override
public String getXmlString() {
return String.format(FSM_START, getName(), "initial=\"" + STATE1_NAME + "\"") +
String.format(STATE_START, STATE1_NAME) +
String.format(TRANSITION_STRING, EVENTS_STRING, String.format(TEST_STRING, TEST1_NAME), StringUtils.EMPTY, String.format(TARGET_STRING, "state2"), StringUtils.EMPTY, StringUtils.EMPTY) +
STATE_END +
FSM_END;
}
@Override
public DataDrivenFsm getResult() {
return null;
}
};
/**
* @return The arrays of parameters
*/
@Parameters(name = "{index}: {0}")
public static Iterable<Object[]> getParameters() {
return Arrays.asList(new Object[][] {
{ VALID_ONE_STATE_FINAL },
{ VALID_ONE_STATE_LOOP },
{ VALID_SAVE_CLEAR_FIELDS },
{ VALID_MULTIPLE_ACTIONS_TESTS },
{ VALID_MULTIPLE_STATES_TRANSITIONS },
{ VALID_ON_ENTRY_EXIT },
{ VALID_PRECONDITION },
{ VALID_INITIAL_STATE },
{ VALID_INITIAL },
{ INVALID_UNDEFINED_ACTION },
{ INVALID_UNDEFINED_CONDITION },
{ INVALID_UNDEFINED_TARGET },
{ VALID_NO_INITIAL },
});
}
private final CompilationResult fExpected;
/**
* Constructor
*
* @param expected
* The expected result
*/
public TmfXmlFsmCuTest(CompilationResult expected) {
fExpected = expected;
}
/**
* Test the compilation of a valid action strings
*
* @throws SAXException
* Exception thrown by parser
* @throws IOException
* Exception thrown by parser
* @throws ParserConfigurationException
* Exception thrown by parser
*/
@Test
public void testFsm() throws SAXException, IOException, ParserConfigurationException {
AnalysisCompilationData data = new AnalysisCompilationData();
compileActionsAndTests(fExpected.getXmlString(), data);
Element xmlElement = TmfXmlTestUtils.getXmlElement(TmfXmlStrings.FSM, fExpected.getXmlString());
assertNotNull(xmlElement);
TmfXmlFsmCu compiledFsm = TmfXmlFsmStateCu.compileFsm(data, xmlElement);
if (fExpected.getResult() == null) {
assertNull("Expected null action" + fExpected.getName(), compiledFsm);
} else {
assertNotNull("Expected non null " + fExpected.getName(), compiledFsm);
assertEquals(fExpected.getName() + " generated", fExpected.getResult(), compiledFsm.generate());
}
}
private static void compileActionsAndTests(@NonNull String xmlString, @NonNull AnalysisCompilationData data) throws SAXException, IOException, ParserConfigurationException {
List<@NonNull Element> xmlElements = TmfXmlTestUtils.getXmlElements(TmfXmlStrings.ACTION, xmlString);
for (Element xmlElement : xmlElements) {
assertNotNull(TmfXmlActionCu.compileNamedAction(data, xmlElement));
}
xmlElements = TmfXmlTestUtils.getXmlElements(TmfXmlStrings.TEST, xmlString);
for (Element xmlElement : xmlElements) {
assertNotNull(TmfXmlConditionCu.compileNamedCondition(data, xmlElement));
}
}
}