/*******************************************************************************
* 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.model;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.eclipse.core.runtime.NullProgressMonitor;
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.model.TmfXmlPatternSegmentBuilder;
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.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
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.interval.ITmfStateInterval;
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.analysis.xml.core.tests.stateprovider.XmlModuleTestBase;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Test the pattern analysis fsm
*
* @author Jean-Christian Kouame
*/
public class FsmTest {
private static final int END_TIME = 7;
private static final @NonNull String TEST_TRACE = "test_traces/testTrace4.xml";
private static final String TEST_SEGMENT_NEW = TmfXmlPatternSegmentBuilder.PATTERN_SEGMENT_NAME_PREFIX + "NEW";
private static final TmfXmlTestFiles TEST_FILE_1 = TmfXmlTestFiles.INITIAL_STATE_ELEMENT_TEST_FILE_1;
private static final TmfXmlTestFiles TEST_FILE_2 = TmfXmlTestFiles.INITIAL_STATE_ELEMENT_TEST_FILE_2;
private static XmlPatternAnalysis fModule;
private static XmlPatternAnalysis fModule2;
private static ITmfTrace fTrace;
private static XmlPatternAnalysis createModule(@NonNull Element element, TmfXmlTestFiles file) {
XmlPatternAnalysis module = new XmlPatternAnalysis();
module.setXmlFile(new Path(file.getFile().getAbsolutePath()));
module.setName(XmlModuleTestBase.getName(element));
return module;
}
private static XmlPatternAnalysis initModule(TmfXmlTestFiles file) {
Document doc = file.getXmlDocument();
assertNotNull(doc);
/* get State Providers modules */
NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.PATTERN);
Element node = (Element) stateproviderNodes.item(0);
assertNotNull(node);
XmlPatternAnalysis module = createModule(node, file);
String moduleId = node.getAttribute(TmfXmlStrings.ID);
assertNotNull(moduleId);
module.setId(moduleId);
return module;
}
/**
* End the test suite
*/
@AfterClass
public static void tearDown() {
fModule.dispose();
fModule2.dispose();
fTrace.dispose();
}
/**
* Before the test suite
*/
@BeforeClass
public static void before() {
ITmfTrace trace = XmlUtilsTest.initializeTrace(TEST_TRACE);
//Create first module
fModule = initModule(TEST_FILE_1);
try {
fModule.setTrace(trace);
fModule.schedule();
assertTrue(fModule.waitForCompletion(new NullProgressMonitor()));
} catch (TmfAnalysisException e) {
fail("Cannot execute analyses " + e.getMessage());
}
//Create second module
fModule2 = initModule(TEST_FILE_2);
try {
fModule2.setTrace(trace);
fModule2.schedule();
assertTrue(fModule2.waitForCompletion(new NullProgressMonitor()));
} catch (TmfAnalysisException e) {
fail("Cannot execute analyses " + e.getMessage());
}
fTrace = trace;
}
/**
* Compare the execution of two state machines that do the same job, one
* using the initial element, the second one using the initialState element.
* The result should be the same for both state machines
*/
@Test
public void testInitialStateDeclaration() {
ITmfStateSystem stateSystem = fModule.getStateSystem(fModule.getId());
assertNotNull("state system exist", stateSystem);
try {
int quark = stateSystem.getQuarkAbsolute("fsm1");
@NonNull ITmfStateInterval interval = stateSystem.querySingleState(END_TIME, quark);
long count1 = interval.getStateValue().unboxLong();
quark = stateSystem.getQuarkAbsolute("fsm2");
interval = stateSystem.querySingleState(END_TIME, quark);
long count2 = interval.getStateValue().unboxLong();
assertTrue("Test the count value", count1 == count2);
} catch (AttributeNotFoundException | StateSystemDisposedException e) {
fail("Failed to query the state system");
}
}
/**
* Compare the execution of two state machines doing the same job, the tid
* condition is ignored with the initial element and used with the
* initialState element. The result should be different.
*/
@Test
public void testInitialStateWithCondition() {
ITmfStateSystem stateSystem = fModule.getStateSystem(fModule.getId());
assertNotNull("state system exist", stateSystem);
try {
int quark = stateSystem.getQuarkAbsolute("fsm1");
@NonNull ITmfStateInterval interval = stateSystem.querySingleState(END_TIME, quark);
long count1 = interval.getStateValue().unboxLong();
quark = stateSystem.getQuarkAbsolute("fsm3");
interval = stateSystem.querySingleState(END_TIME, quark);
long count3 = interval.getStateValue().unboxLong();
assertTrue("Test the count value", count1 > count3);
} catch (AttributeNotFoundException | StateSystemDisposedException e) {
fail("Failed to query the state system");
}
}
/**
* Execute one pattern, with the two types of initial state initialization,
* then test that the new behavior is prioritized and that preconditions are
* ignored with initialState element
*/
@Test
public void testTwoInitialStates() {
//Test segment store
@Nullable ISegmentStore<@NonNull ISegment> ss = fModule2.getSegmentStore();
assertNotNull("segment store exist", ss);
assertTrue("Segment store not empty", ss.size() == 1);
Object item = ss.toArray()[0];
assertTrue(item instanceof TmfXmlPatternSegment);
assertTrue(((TmfXmlPatternSegment) item).getName().equals(TEST_SEGMENT_NEW));
//Test state system
ITmfStateSystem stateSystem = fModule2.getStateSystem(fModule2.getId());
assertNotNull("state system exist", stateSystem);
int quark;
try {
quark = stateSystem.getQuarkAbsolute("count_new");
@NonNull ITmfStateInterval interval = stateSystem.querySingleState(END_TIME, quark);
int count = interval.getStateValue().unboxInt();
assertTrue("Test the count value", count > 0);
} catch (AttributeNotFoundException | StateSystemDisposedException e) {
fail("Failed to query the state system");
}
try {
quark = stateSystem.getQuarkAbsolute("precond");
} catch (AttributeNotFoundException e) {
return;
}
fail();
}
}