/******************************************************************************* * Copyright (c) 2014, 2015 École Polytechnique de Montréal and others * * 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 * * Contributors: * Geneviève Bastien - Initial API and implementation *******************************************************************************/ package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; 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.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; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; 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.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.Activator; import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub; import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStubNs; import org.junit.After; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * Tests for the {@link XmlUtils} class * * @author Geneviève Bastien */ public class XmlUtilsTest { private static final Path PATH_INVALID = new Path("test_xml_files/test_invalid"); private static final Path PATH_VALID = new Path("test_xml_files/test_valid"); /** * Empty the XML directory after the test */ @After public void emptyXmlFolder() { File fFolder = XmlUtils.getXmlFilesPath().toFile(); if (!(fFolder.isDirectory() && fFolder.exists())) { return; } for (File xmlFile : fFolder.listFiles()) { xmlFile.delete(); } } /** * Test the {@link XmlUtils#getXmlFilesPath()} method */ @Test public void testXmlPath() { IPath xmlPath = XmlUtils.getXmlFilesPath(); IWorkspace workspace = ResourcesPlugin.getWorkspace(); IPath workspacePath = workspace.getRoot().getRawLocation(); workspacePath = workspacePath.addTrailingSeparator() .append(".metadata").addTrailingSeparator().append(".plugins") .addTrailingSeparator() .append("org.eclipse.tracecompass.tmf.analysis.xml.core") .addTrailingSeparator().append("xml_files"); assertEquals(xmlPath, workspacePath); } /** * test the {@link XmlUtils#xmlValidate(File)} method */ @Test public void testXmlValidate() { File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); if ((testXmlFile == null) || !testXmlFile.exists()) { fail("XML test file does not exist"); } IStatus status = XmlUtils.xmlValidate(testXmlFile); if (!status.isOK()) { fail(status.getMessage()); } testXmlFile = TmfXmlTestFiles.INVALID_FILE.getFile(); if ((testXmlFile == null) || !testXmlFile.exists()) { fail("XML test file does not exist"); } assertFalse(XmlUtils.xmlValidate(testXmlFile).isOK()); } /** * Test various invalid files and make sure they are invalid */ @Test public void testXmlValidateInvalid() { IPath path = Activator.getAbsolutePath(PATH_INVALID); File file = path.toFile(); File[] invalidFiles = file.listFiles(); assertTrue(invalidFiles.length > 0); for (File f : invalidFiles) { assertFalse("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); } } /** * Test various valid files and make sure they are valid */ @Test public void testXmlValidateValid() { IPath path = Activator.getAbsolutePath(PATH_VALID); File file = path.toFile(); File[] validFiles = file.listFiles(); assertTrue(validFiles.length > 0); for (File f : validFiles) { assertTrue("File " + f.getName(), XmlUtils.xmlValidate(f).isOK()); } } /** * test the {@link XmlUtils#addXmlFile(File)} method */ @Test public void testXmlAddFile() { /* Check the file does not exist */ IPath xmlPath = XmlUtils.getXmlFilesPath().addTrailingSeparator().append("test_valid.xml"); File destFile = xmlPath.toFile(); assertFalse(destFile.exists()); /* Add test_valid.xml file */ File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); if ((testXmlFile == null) || !testXmlFile.exists()) { fail("XML test file does not exist"); } XmlUtils.addXmlFile(testXmlFile); assertTrue(destFile.exists()); } private static final @NonNull String ANALYSIS_ID = "kernel.linux.sp"; /** * Test the {@link XmlUtils#getElementInFile(String, String, String)} method */ @Test public void testGetElementInFile() { File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); assertNotNull("XML test file does not exist", testXmlFile); assertTrue("XML test file does not exist", testXmlFile.exists()); Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); assertNotNull(analysis); } /** * Test the {@link XmlUtils#getChildElements(Element)} and * {@link XmlUtils#getChildElements(Element, String)} methods */ @Test public void testGetChildElements() { File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile(); if ((testXmlFile == null) || !testXmlFile.exists()) { fail("XML test file does not exist"); } /* * This sounds useless, but I get a potential null pointer warning * otherwise */ if (testXmlFile == null) { return; } Element analysis = XmlUtils.getElementInFile(testXmlFile.getAbsolutePath(), TmfXmlStrings.STATE_PROVIDER, ANALYSIS_ID); List<Element> values = XmlUtils.getChildElements(analysis, TmfXmlStrings.LOCATION); assertEquals(5, values.size()); Element aLocation = values.get(0); List<Element> attributes = XmlUtils.getChildElements(aLocation, TmfXmlStrings.STATE_ATTRIBUTE); assertEquals(2, attributes.size()); values = XmlUtils.getChildElements(analysis, TmfXmlStrings.HEAD); assertEquals(1, values.size()); Element head = values.get(0); values = XmlUtils.getChildElements(head); assertEquals(2, values.size()); } /** * Initialize a new trace based using the input file path * * @param traceFile * The trace file * @return The trace */ public static @NonNull ITmfTrace initializeTrace(String traceFile) { /* Initialize the trace */ TmfXmlTraceStub trace = TmfXmlTraceStubNs.setupTrace(Activator.getAbsolutePath(new Path(traceFile))); return trace; } /** * Initialize a new module using the xml file * * @param xmlAnalysisFile * The xml file used to initialize the module * @return The module */ public static @NonNull XmlStateSystemModule initializeModule(TmfXmlTestFiles xmlAnalysisFile) { /* Initialize the state provider module */ Document doc = xmlAnalysisFile.getXmlDocument(); assertNotNull(doc); /* get State Providers modules */ NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); assertFalse(stateproviderNodes.getLength() == 0); Element node = (Element) stateproviderNodes.item(0); XmlStateSystemModule module = new XmlStateSystemModule(); String moduleId = node.getAttribute(TmfXmlStrings.ID); assertNotNull(moduleId); module.setId(moduleId); module.setXmlFile(xmlAnalysisFile.getPath()); 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 * * @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 verifyStateIntervals(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()); assertEquals(testId + ": Expected value of interval " + i, expectedValues[i], interval.getStateValue()); } } /** * 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 * * @param expected * The expected pattern segment * @param actual * The actual pattern segment */ public static void testPatternSegmentData(TmfXmlPatternSegment expected, TmfXmlPatternSegment actual) { assertEquals("getStart", expected.getStart(), actual.getStart()); assertEquals("getEnd", expected.getEnd(), actual.getEnd()); assertEquals("getScale", expected.getScale(), actual.getScale()); assertEquals("getName", expected.getName(), actual.getName()); assertNotNull("getContent", actual.getContent()); // Test the content of the pattern segment assertEquals("content size", expected.getContent().size(), actual.getContent().size()); Iterator<Map.Entry<String, @NonNull ITmfStateValue>> it2 = expected.getContent().entrySet().iterator(); for (int i = 0; i < expected.getContent().size(); i++) { Map.Entry<String, @NonNull ITmfStateValue> expectedContent = it2.next(); ITmfStateValue actualValue = actual.getContent().get(expectedContent.getKey()); assertNotNull("Content " + expectedContent.getKey() + " exists", actualValue); assertEquals("Content value comparison " + i, 0, expectedContent.getValue().compareTo(actualValue)); } } }