TMF: Add trace stub for TMF unit tests
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Mon, 31 Mar 2014 18:34:44 +0000 (14:34 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Mon, 22 Sep 2014 14:28:28 +0000 (10:28 -0400)
This new trace type uses a custom XML definition and converts custom XML
events to TmfEvents, where the fields and their values are defined through the
XML fields. To illustrate, here is the content of each type of event:

CustomXmlEvent: fields = "a | b", values = "1 | abd"

would transpose to this

Development trace: a = 1, b = "abd"

This type of trace will be useful to unit test analyses involving LTTng kernel
and UST traces for instance.

Change-Id: I41ac7206c1a54088c998d551a4174f2184b05f5b
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/21265
Tested-by: Hudson CI
13 files changed:
org.eclipse.linuxtools.tmf.core.tests/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/txtFile.txt [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/xmlFile.xml [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/valid/test.xml [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/parsers/custom/CustomXmlTraceDefinition.java

index 0495205c926509762454df9f4d891aa986c12c47..4e97842e687568a22a6d83663d1dfbd0970c1a02 100644 (file)
@@ -16,5 +16,6 @@ Require-Bundle: org.junit;bundle-version="4.0.0",
 Export-Package: org.eclipse.linuxtools.tmf.core.tests,
  org.eclipse.linuxtools.tmf.core.tests.perf,
  org.eclipse.linuxtools.tmf.core.tests.shared,
- org.eclipse.linuxtools.tmf.tests.stubs.trace
+ org.eclipse.linuxtools.tmf.tests.stubs.trace,
+ org.eclipse.linuxtools.tmf.tests.stubs.trace.xml
 Import-Package: com.google.common.collect
index 8344bd3e2d1591692804c6c094f58c9ef617f8f8..baa99960d7eb1d60143d41f89efe05d1b5f04046 100644 (file)
@@ -35,6 +35,7 @@ import org.junit.runners.Suite;
     org.eclipse.linuxtools.tmf.core.tests.trace.indexer.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.trace.location.AllTests.class,
+    org.eclipse.linuxtools.tmf.core.tests.trace.stub.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.trace.text.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.uml2sd.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.util.AllTests.class
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/AllTests.java
new file mode 100644 (file)
index 0000000..4ed2c6e
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2014 É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 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.linuxtools.tmf.core.tests.trace.stub;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Unit tests for the development trace package.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+        XmlStubTraceTest.class
+})
+public class AllTests {
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/stub/XmlStubTraceTest.java
new file mode 100644 (file)
index 0000000..2147a8d
--- /dev/null
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2014 É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 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.linuxtools.tmf.core.tests.trace.stub;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
+import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link TmfXmlTraceStub} class
+ *
+ * @author Geneviève Bastien
+ */
+public class XmlStubTraceTest {
+
+    private static final String VALID_FILE = "../org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/valid/test.xml";
+    private static final String VALID_PATH = "../org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/valid";
+    private static final String INVALID_PATH = "../org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid";
+
+    private static final String EVENT_A = "A";
+    private static final String EVENT_B = "B";
+    private static final String FIELD_A = "b";
+    private static final String FIELD_B = "f";
+
+    /**
+     * Test the
+     * {@link TmfXmlTraceStub#validate(org.eclipse.core.resources.IProject, String)}
+     * method
+     */
+    @Test
+    public void testValidate() {
+        TmfXmlTraceStub trace = new TmfXmlTraceStub();
+        File[] invalidFiles = (new File(INVALID_PATH)).listFiles();
+        assertTrue(invalidFiles.length > 0);
+        for (File f : invalidFiles) {
+            assertTrue(!trace.validate(null, f.getAbsolutePath()).isOK());
+        }
+
+        File[] validFiles = (new File(VALID_PATH)).listFiles();
+        assertTrue(validFiles.length > 0);
+        for (File f : validFiles) {
+            assertTrue(trace.validate(null, f.getAbsolutePath()).isOK());
+        }
+    }
+
+    /**
+     * Test the reading and querying the XML trace and make sure fields are
+     * present
+     */
+    @Test
+    public void testDevelopmentTrace() {
+        TmfXmlTraceStub trace = new TmfXmlTraceStub();
+        IStatus status = trace.validate(null, VALID_FILE);
+        if (!status.isOK()) {
+            fail(status.getException().getMessage());
+        }
+
+        try {
+            trace.initTrace(null, VALID_FILE, TmfEvent.class);
+        } catch (TmfTraceException e1) {
+            fail(e1.getMessage());
+        }
+
+        CustomEventRequest req = new CustomEventRequest(trace);
+        trace.sendRequest(req);
+        try {
+            req.waitForCompletion();
+            if (req.isCancelled()) {
+                fail(req.getStatus().getMessage());
+            }
+        } catch (InterruptedException e) {
+            fail(e.getMessage());
+        }
+        assertEquals(4, req.getCount());
+    }
+
+    private static IStatus testEvent(ITmfEvent event) {
+        switch (event.getType().getName()) {
+        case EVENT_A: {
+            ITmfEventField content = event.getContent();
+            if (!event.getSource().equals("1")) {
+                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Events of type A should have source 1 but was " + event.getSource());
+            }
+            if (content.getField(FIELD_A) == null) {
+                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_A, EVENT_A));
+            }
+            break;
+        }
+        case EVENT_B: {
+            ITmfEventField content = event.getContent();
+            if (!event.getSource().equals("2")) {
+                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Events of type B should have source 2 but was " + event.getSource());
+            }
+            if (content.getField(FIELD_B) == null) {
+                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("Field %s does not exist in event %s", FIELD_B, EVENT_B));
+            }
+            break;
+        }
+        default:
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unexpected event " + event.getType().getName());
+        }
+        return Status.OK_STATUS;
+    }
+
+    private class CustomEventRequest extends TmfEventRequest {
+        private final ITmfTrace fTrace;
+        private IStatus fResult = Status.OK_STATUS;
+        private int fCount = 0;
+
+        public CustomEventRequest(ITmfTrace trace) {
+            super(trace.getEventType(),
+                    TmfTimeRange.ETERNITY,
+                    0,
+                    ITmfEventRequest.ALL_DATA,
+                    ITmfEventRequest.ExecutionType.BACKGROUND);
+            this.fTrace = trace;
+        }
+
+        @Override
+        public void handleData(final ITmfEvent event) {
+            super.handleData(event);
+            if (event.getTrace() == fTrace) {
+                fCount++;
+                IStatus result = testEvent(event);
+                if (!result.isOK()) {
+                    fResult = result;
+                    this.cancel();
+                }
+            }
+        }
+
+        public IStatus getStatus() {
+            return fResult;
+        }
+
+        public int getCount() {
+            return fCount;
+        }
+
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/Messages.java
new file mode 100644 (file)
index 0000000..f0dba7e
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2014 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.trace.xml;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Externalized messages for the
+ * {@link org.eclipse.linuxtools.tmf.tests.stubs.trace.xml} package
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.messages"; //$NON-NLS-1$
+
+    public static String TmfDevelopmentTrace_FileNotFound;
+    public static String TmfDevelopmentTrace_IoError;
+    public static String TmfDevelopmentTrace_ValidationError;
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xml
new file mode 100644 (file)
index 0000000..96ec2b9
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<CustomXMLTraceDefinitionList>
+<Definition name="handmade">
+<TimeStampOutputFormat>T</TimeStampOutputFormat>
+<InputElement name="trace">
+<InputElement logentry="true" name="event">
+<InputData action="0" format="" name="Ignore"/>
+<Attribute name="name">
+<InputData action="0" format="" name="Message"/>
+</Attribute>
+<Attribute name="source">
+<InputData action="0" format="" name="source"/>
+</Attribute>
+<Attribute name="timestamp">
+<InputData action="0" format="T" name="Time Stamp"/>
+</Attribute>
+<InputElement name="field">
+<InputData action="0" format="" name="Ignore"/>
+<Attribute name="name">
+<InputData action="2" format="" name="fields"/>
+</Attribute>
+<Attribute name="type">
+<InputData action="2" format="" name="type"/>
+</Attribute>
+<Attribute name="value">
+<InputData action="2" format="" name="values"/>
+</Attribute>
+</InputElement>
+</InputElement>
+</InputElement>
+<OutputColumn name="Time Stamp"/>
+<OutputColumn name="Message"/>
+<OutputColumn name="source"/>
+<OutputColumn name="fields"/>
+<OutputColumn name="values"/>
+<OutputColumn name="type"/>
+</Definition>
+</CustomXMLTraceDefinitionList>
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlDevelopmentTrace.xsd
new file mode 100644 (file)
index 0000000..fe8abdf
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- ***************************************************************************
+ * Copyright (c) 2014 É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 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
+ *************************************************************************** -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+       attributeFormDefault="unqualified" elementFormDefault="qualified">
+
+       <xs:element name="trace">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element maxOccurs="unbounded" minOccurs="0" name="event" type="event" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+
+       <xs:complexType name="event">
+               <xs:sequence>
+                       <xs:element maxOccurs="unbounded" minOccurs="0" name="field" type="field" />
+               </xs:sequence>
+               <xs:attribute name="timestamp" type="xs:integer" use="required" />
+               <xs:attribute name="name" type="xs:string" use="required" />
+               <xs:attribute name="source" type="xs:integer" use="required" />
+       </xs:complexType>
+
+       <xs:complexType name="field">
+               <xs:attribute name="name" type="xs:string" use="required" />
+               <xs:attribute name="value" type="xs:string" use="required" />
+               <xs:attribute name="type" use="required" >
+                       <xs:simpleType>
+                               <xs:restriction base="xs:string">
+                                       <xs:enumeration value="int"/>
+                                       <xs:enumeration value="long"/>
+                                       <xs:enumeration value="string"/>
+                               </xs:restriction>
+                       </xs:simpleType>
+               </xs:attribute>
+       </xs:complexType>
+
+</xs:schema>
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java
new file mode 100644 (file)
index 0000000..d356e04
--- /dev/null
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2014 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.trace.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventType;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventType;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomEventContent;
+import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent;
+import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace;
+import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.SAXException;
+
+/**
+ * An XML development trace using a custom XML trace definition and schema.
+ *
+ * This class will typically be used to build custom traces to unit test more
+ * complex functionalities like analyzes or to develop and test data-driven
+ * analyzes.
+ *
+ * This class wraps a custom XML trace and rewrites the returned events in the
+ * getNext() method so that event's fields are the ones defined in <field ... />
+ * elements instead of those defined in the custom XML parser. This way, each
+ * event can have a different set of fields. This class can, for example, mimic
+ * a CTF trace.
+ *
+ * @author Geneviève Bastien
+ */
+public class TmfXmlTraceStub extends TmfTrace {
+
+    private static final String DEVELOPMENT_TRACE_PARSER_PATH = "TmfXmlDevelopmentTrace.xml"; //$NON-NLS-1$
+    private static final String DEVELOPMENT_TRACE_XSD = "TmfXmlDevelopmentTrace.xsd"; //$NON-NLS-1$
+    private static final String EMPTY = ""; //$NON-NLS-1$
+
+    /* XML elements and attributes names */
+    private static final String EVENT_NAME_FIELD = "Message"; //$NON-NLS-1$
+    private static final String FIELD_NAMES_FIELD = "fields"; //$NON-NLS-1$
+    private static final String SOURCE_FIELD = "source"; //$NON-NLS-1$
+    private static final String VALUES_FIELD = "values"; //$NON-NLS-1$
+    private static final String TYPES_FIELD = "type"; //$NON-NLS-1$
+    private static final String VALUES_SEPARATOR = " \\| "; //$NON-NLS-1$
+    private static final String TYPE_INTEGER = "int"; //$NON-NLS-1$
+    private static final String TYPE_LONG = "long"; //$NON-NLS-1$
+
+    private final CustomXmlTrace fTrace;
+
+    /**
+     * Constructor. Constructs the custom XML trace with the appropriate
+     * definition.
+     */
+    public TmfXmlTraceStub() {
+
+        /* Load custom XML definition */
+        try (InputStream in = TmfXmlTraceStub.class.getResourceAsStream(DEVELOPMENT_TRACE_PARSER_PATH);) {
+            CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(in);
+            if (definitions.length == 0) {
+                throw new IllegalStateException("The custom trace definition does not exist"); //$NON-NLS-1$
+            }
+            fTrace = new CustomXmlTrace(definitions[0]);
+            /* Deregister the custom XML trace */
+            TmfSignalManager.deregister(fTrace);
+            this.setParser(fTrace);
+        } catch (IOException e) {
+            throw new IllegalStateException("Cannot open the trace parser for development traces"); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException {
+        super.initTrace(resource, path, type);
+        fTrace.initTrace(resource, path, type);
+        ITmfContext ctx;
+        /* Set the start and (current) end times for this trace */
+        ctx = seekEvent(0L);
+        ITmfEvent event = getNext(ctx);
+        if (event != null) {
+            final ITmfTimestamp curTime = event.getTimestamp();
+            this.setStartTime(curTime);
+            this.setEndTime(curTime);
+        }
+    }
+
+    @Override
+    public ITmfLocation getCurrentLocation() {
+        return fTrace.getCurrentLocation();
+    }
+
+    @Override
+    public double getLocationRatio(ITmfLocation location) {
+        return fTrace.getLocationRatio(location);
+    }
+
+    @Override
+    public ITmfContext seekEvent(ITmfLocation location) {
+        return fTrace.seekEvent(location);
+    }
+
+    @Override
+    public ITmfContext seekEvent(double ratio) {
+        return fTrace.seekEvent(ratio);
+    }
+
+    @Override
+    public IStatus validate(IProject project, String path) {
+        File xmlFile = new File(path);
+        if (!xmlFile.exists() || !xmlFile.isFile() || !xmlFile.canRead()) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_FileNotFound, path));
+        }
+        /* Does the XML file validate with the XSD */
+        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        Source xmlSource = new StreamSource(xmlFile);
+
+        try {
+            URL url = TmfXmlTraceStub.class.getResource(DEVELOPMENT_TRACE_XSD);
+            Schema schema = schemaFactory.newSchema(url);
+
+            Validator validator = schema.newValidator();
+            validator.validate(xmlSource);
+        } catch (SAXException e) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_ValidationError, path), e);
+        } catch (IOException e) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_IoError, path), e);
+        }
+        return Status.OK_STATUS;
+    }
+
+    @Override
+    public synchronized ITmfEvent getNext(ITmfContext context) {
+        final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank());
+        CustomXmlEvent event = fTrace.getNext(context);
+        if (event == null) {
+            return null;
+        }
+
+        /* Translate the content of the event */
+        /* The "fields" field contains a | separated list of field names */
+        /* The "values" field contains a | separated list of field values */
+        /* the "type" field contains a | separated list of field types */
+        ITmfEventField content = event.getContent();
+        String fieldString = (String) content.getField(FIELD_NAMES_FIELD).getValue();
+        String valueString = (String) content.getField(VALUES_FIELD).getValue();
+        String typeString = (String) content.getField(TYPES_FIELD).getValue();
+
+        String[] fields = fieldString.split(VALUES_SEPARATOR);
+        String[] values = valueString.split(VALUES_SEPARATOR);
+        String[] types = typeString.split(VALUES_SEPARATOR);
+        ITmfEventField[] fieldsArray = new TmfEventField[fields.length];
+
+        for (int i = 0; i < fields.length; i++) {
+            String value = EMPTY;
+            if (values.length > i) {
+                value = values[i];
+            }
+            String type = null;
+            if (types.length > i) {
+                type = types[i];
+            }
+            Object val = value;
+            if (type != null) {
+                switch (type) {
+                case TYPE_INTEGER: {
+                    try {
+                        val = Integer.valueOf(value);
+                    } catch (NumberFormatException e) {
+                        Activator.logError(String.format("Get next XML event: cannot cast value %s to integer", value), e); //$NON-NLS-1$
+                        val = 0;
+                    }
+                    break;
+                }
+                case TYPE_LONG: {
+                    try {
+                        val = Long.valueOf(value);
+                    } catch (NumberFormatException e) {
+                        Activator.logError(String.format("Get next XML event: cannot cast value %s to long", value), e); //$NON-NLS-1$
+                        val = 0L;
+                    }
+                    break;
+                }
+                default:
+                    break;
+                }
+            }
+            fieldsArray[i] = new TmfEventField(fields[i], val, null);
+        }
+
+        /* Create a new event with new fields and name */
+        ITmfEventType customEventType = event.getType();
+        TmfEventType eventType = new TmfEventType(customEventType.getContext(), (String) content.getField(EVENT_NAME_FIELD).getValue(), customEventType.getRootField());
+        ITmfEventField eventFields = new CustomEventContent(content.getName(), content.getValue(), fieldsArray);
+        TmfEvent newEvent = new TmfEvent(this, event.getTimestamp(), (String) content.getField(SOURCE_FIELD).getValue(), eventType, eventFields, event.getReference());
+        updateAttributes(savedContext, event.getTimestamp());
+        context.increaseRank();
+
+        return newEvent;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/trace/xml/messages.properties
new file mode 100644 (file)
index 0000000..005b58e
--- /dev/null
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2014 É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 v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     École Polytechnique de Montréal - Initial API and implementation
+###############################################################################
+
+TmfDevelopmentTrace_FileNotFound=File not found: {0}
+TmfDevelopmentTrace_IoError=IOException validating file: {0}
+TmfDevelopmentTrace_ValidationError=Trace file does not validate: {0}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/txtFile.txt b/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/txtFile.txt
new file mode 100644 (file)
index 0000000..1643e89
--- /dev/null
@@ -0,0 +1 @@
+This is not an XML development trace
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/xmlFile.xml b/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/invalid/xmlFile.xml
new file mode 100644 (file)
index 0000000..c9c817a
--- /dev/null
@@ -0,0 +1,19 @@
+<!-- missing name attribute in first event -->
+<trace>
+<event timestamp="1" source="1">
+<field name="b" value="1" type="int" />
+<field name="d" value="3" type="int" />
+</event>
+<event timestamp="3" name="B" source="2">
+<field name="f" value="c" type="string" />
+<field name="g" value="e" type="string" />
+</event>
+<event timestamp="4" name="A" source="1">
+<field name="b" value="3" type="int" />
+<field name="d" value="7" type="int" />
+</event>
+<event timestamp="5" name="B" source="2">
+<field name="f" value="c" type="string" />
+<field name="g" value="e" type="string" />
+</event>
+</trace>
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/valid/test.xml b/org.eclipse.linuxtools.tmf.core.tests/testfiles/stub_xml_traces/valid/test.xml
new file mode 100644 (file)
index 0000000..2912f31
--- /dev/null
@@ -0,0 +1,18 @@
+<trace>
+<event timestamp="1" name="A" source="1">
+<field name="b" value="1" type="int" />
+<field name="d" value="3" type="int" />
+</event>
+<event timestamp="3" name="B" source="2">
+<field name="f" value="c" type="string" />
+<field name="g" value="e" type="string" />
+</event>
+<event timestamp="4" name="A" source="1">
+<field name="b" value="3" type="int" />
+<field name="d" value="7" type="int" />
+</event>
+<event timestamp="5" name="B" source="2">
+<field name="f" value="c" type="string" />
+<field name="g" value="e" type="string" />
+</event>
+</trace>
\ No newline at end of file
index 66bf880e9e7e000e2a39d40a6eedc256ab2d27c6..1e69549ed7fa051029ccc2061696ec99daeb8ce1 100644 (file)
@@ -15,8 +15,10 @@ package org.eclipse.linuxtools.tmf.core.parsers.custom;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -520,6 +522,27 @@ public class CustomXmlTraceDefinition extends CustomTraceDefinition {
      * @return The loaded trace definitions
      */
     public static CustomXmlTraceDefinition[] loadAll(String path) {
+        File file = new File(path);
+        if (!file.canRead()) {
+            return new CustomXmlTraceDefinition[0];
+        }
+        try (FileInputStream fis = new FileInputStream(file);) {
+            return loadAll(fis);
+        } catch (IOException e) {
+            Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
+        }
+        return new CustomXmlTraceDefinition[0];
+    }
+
+    /**
+     * Load all the XML trace definitions from the given stream
+     *
+     * @param stream
+     *            An input stream from which to read the definitions
+     * @return The loaded trace definitions
+     * @since 3.1
+     */
+    public static CustomXmlTraceDefinition[] loadAll(InputStream stream) {
         try {
             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
             DocumentBuilder db = dbf.newDocumentBuilder();
@@ -530,12 +553,7 @@ public class CustomXmlTraceDefinition extends CustomTraceDefinition {
             // The following catches xml parsing exceptions
             db.setErrorHandler(createErrorHandler());
 
-            File file = new File(path);
-            if (!file.canRead()) {
-                return new CustomXmlTraceDefinition[0];
-            }
-            Document doc = db.parse(file);
-
+            Document doc = db.parse(stream);
             Element root = doc.getDocumentElement();
             if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
                 return new CustomXmlTraceDefinition[0];
@@ -554,7 +572,7 @@ public class CustomXmlTraceDefinition extends CustomTraceDefinition {
             }
             return defList.toArray(new CustomXmlTraceDefinition[0]);
         } catch (ParserConfigurationException | SAXException | IOException e) {
-            Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
+            Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream, e); //$NON-NLS-1$
         }
         return new CustomXmlTraceDefinition[0];
     }
This page took 0.04253 seconds and 5 git commands to generate.