--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Abstract class to test custom traces
+ *
+ * @author Geneviève Bastien
+ */
+public abstract class AbstractCustomTraceDataTest {
+
+ /**
+ * Time format use for event creation
+ */
+ protected static final String TIMESTAMP_FORMAT = "dd/MM/yyyy HH:mm:ss:SSS";
+
+ /**
+ * Block size used for the indexer
+ */
+ protected static final int BLOCK_SIZE = 100;
+
+ /** The trace directory */
+ protected static final String TRACE_DIRECTORY = TmfTraceManager.getTemporaryDirPath() + File.separator + "dummyTrace";
+
+
+ /**
+ * Interface to be implemented by concrete test cases to get the necessary
+ * test data
+ *
+ * @author Geneviève Bastien
+ */
+ protected static interface ICustomTestData {
+ /**
+ * Get the trace for this test case
+ *
+ * @return The initialized trace
+ * @throws IOException
+ * If an exception occurred while getting the trace
+ * @throws TmfTraceException
+ * If an exception occurred while getting the trace
+ */
+ public ITmfTrace getTrace() throws IOException, TmfTraceException;
+
+ /**
+ * Validate the event for this test case. This method should contain the
+ * necessary asserts.
+ *
+ * @param event
+ * The event to validate
+ */
+ public void validateEvent(ITmfEvent event);
+
+ /**
+ * Validate the event count. This method will be called after reading
+ * the whole trace.
+ *
+ * @param eventCount
+ * The event count to validate
+ */
+ public void validateEventCount(int eventCount);
+ }
+
+ private final @NonNull ICustomTestData fTestData;
+ private ITmfTrace fTrace;
+
+ /**
+ * Constructor
+ *
+ * @param data
+ * The custom trace test data
+ */
+ public AbstractCustomTraceDataTest(@NonNull ICustomTestData data) {
+ fTestData = data;
+ }
+
+ /**
+ * Setup the test
+ * @throws Exception Exceptions that occurred during setup
+ */
+ @Before
+ public void setUp() throws Exception {
+ setupTrace();
+ }
+
+ private synchronized void setupTrace() throws Exception {
+ File traceDirectory = new File(TRACE_DIRECTORY);
+ if (traceDirectory.exists()) {
+ traceDirectory.delete();
+ }
+ traceDirectory.mkdir();
+ if (fTrace == null) {
+ fTrace = fTestData.getTrace();
+ }
+ }
+
+ /**
+ * Tear down the test
+ */
+ @After
+ public void tearDown() {
+ String directory = TmfTraceManager.getSupplementaryFileDir(fTrace);
+ try {
+ fTrace.dispose();
+ fTrace = null;
+ } finally {
+ File dir = new File(directory);
+ if (dir.exists()) {
+ File[] files = dir.listFiles();
+ for (File file : files) {
+ file.delete();
+ }
+ dir.delete();
+ }
+
+ File trace = new File(TRACE_DIRECTORY);
+ if (trace.exists()) {
+ trace.delete();
+ }
+ }
+
+ }
+
+ /**
+ * Test reading the events of the trace
+ */
+ @Test
+ public void testReadingEvents() {
+ ITmfTrace trace = fTrace;
+
+ ITmfContext ctx = trace.seekEvent(0L);
+ int eventCount = 0;
+ ITmfEvent event = trace.getNext(ctx);
+ while (event != null) {
+ fTestData.validateEvent(event);
+ eventCount++;
+ event = trace.getNext(ctx);
+ }
+ fTestData.validateEventCount(eventCount);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtEvent;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Test the events parsed by a custom txt trace
+ *
+ * @author Geneviève Bastien
+ */
+@RunWith(Parameterized.class)
+public class CustomTxtTraceDataTest extends AbstractCustomTraceDataTest {
+
+ private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.txt";
+ private static final String DEFINITION_PATH = "testfiles" + File.separator + "txt" + File.separator + "testTxtDefinition.xml";
+
+ /**
+ * Constructor
+ *
+ * @param name The name of the test
+ * @param data The test data
+ */
+ public CustomTxtTraceDataTest(String name, @NonNull ICustomTestData data) {
+ super(data);
+ }
+
+
+ private static CustomTxtTraceDefinition getDefinition(int index) {
+ CustomTxtTraceDefinition[] definitions = CustomTxtTraceDefinition.loadAll(new File(DEFINITION_PATH).toString());
+ return definitions[index];
+ }
+
+ private static final ICustomTestData CUSTOM_TXT = new ICustomTestData() {
+
+ private static final int NB_EVENTS = 10;
+ private CustomTxtTraceDefinition fDefinition;
+
+ @Override
+ public ITmfTrace getTrace() throws IOException, TmfTraceException {
+ fDefinition = getDefinition(0);
+ final File file = new File(TRACE_PATH);
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) {
+ for (int i = 0; i < NB_EVENTS; ++i) {
+ String eventStr = i + " hello world\n";
+ writer.write(eventStr);
+ int extra = i % 3;
+ for (int j = 0; j < extra; j++) {
+ writer.write("extra line\n");
+ }
+ }
+ }
+ return new CustomTxtTrace(null, fDefinition, file.getPath(), BLOCK_SIZE);
+ }
+
+ @Override
+ public void validateEvent(ITmfEvent event) {
+ assertTrue(event instanceof CustomTxtEvent);
+ String name = fDefinition.definitionName;
+ assertEquals("Event name", name, event.getName());
+ assertEquals("Event name and type", event.getType().getName(), event.getName());
+ }
+
+ @Override
+ public void validateEventCount(int eventCount) {
+ assertEquals("Event count", NB_EVENTS, eventCount);
+ }
+
+ };
+
+ private static final ICustomTestData CUSTOM_TXT_EVENT_NAME = new ICustomTestData() {
+
+ private static final int NB_EVENTS = 10;
+ private static final String ODD_EVENT = "OddName";
+ private static final String EVEN_EVENT = "EvenName";
+ private CustomTxtTraceDefinition fDefinition;
+
+ @Override
+ public ITmfTrace getTrace() throws IOException, TmfTraceException {
+ fDefinition = getDefinition(1);
+ final File file = new File(TRACE_PATH);
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) {
+ for (int i = 1; i <= NB_EVENTS; ++i) {
+ String evName = ((i % 2) == 0) ? EVEN_EVENT : ODD_EVENT;
+ String eventStr = i + " " + evName + "\n";
+ writer.write(eventStr);
+ int extra = i % 3;
+ for (int j = 0; j < extra; j++) {
+ writer.write("extra line\n");
+ }
+ }
+ }
+ return new CustomTxtTrace(null, fDefinition, file.getPath(), BLOCK_SIZE);
+ }
+
+ @Override
+ public void validateEvent(ITmfEvent event) {
+ assertTrue(event instanceof CustomTxtEvent);
+ long ts = event.getTimestamp().getValue();
+ if (ts % 2 == 0) {
+ assertEquals("Event name", EVEN_EVENT, event.getName());
+ } else {
+ assertEquals("Event name", ODD_EVENT, event.getName());
+ }
+ assertEquals("Event name and type", event.getType().getName(), event.getName());
+ }
+
+ @Override
+ public void validateEventCount(int eventCount) {
+ assertEquals("Event count", NB_EVENTS, eventCount);
+ }
+
+ };
+
+ /**
+ * @return The arrays of parameters
+ */
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { "Base parser", CUSTOM_TXT },
+ { "Parse with event name", CUSTOM_TXT_EVENT_NAME }
+ });
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlEvent;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Test the events parsed by a custom XML trace
+ *
+ * @author Geneviève Bastien
+ */
+@RunWith(Parameterized.class)
+public class CustomXmlTraceDataTest extends AbstractCustomTraceDataTest {
+
+ private static final String TRACE_PATH = TRACE_DIRECTORY + File.separator + "test.xml";
+ private static final String DEFINITION_PATH = "testfiles" + File.separator + "xml" + File.separator + "testDefinition.xml";
+
+ /**
+ * Constructor
+ *
+ * @param name
+ * The name of this test
+ * @param data
+ * The custom test data for this test case
+ */
+ public CustomXmlTraceDataTest(String name, @NonNull ICustomTestData data) {
+ super(data);
+ }
+
+ private static CustomXmlTraceDefinition getDefinition(int index) {
+ CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(new File(DEFINITION_PATH).toString());
+ return definitions[index];
+ }
+
+ private static final ICustomTestData CUSTOM_XML = new ICustomTestData() {
+
+ private static final int NB_EVENTS = 10;
+ private CustomXmlTraceDefinition fDefinition;
+
+ @Override
+ public ITmfTrace getTrace() throws IOException, TmfTraceException {
+ fDefinition = getDefinition(0);
+ final File file = new File(TRACE_PATH);
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) {
+ writer.write("<trace>");
+ for (int i = 0; i < NB_EVENTS; ++i) {
+ SimpleDateFormat f = new SimpleDateFormat(TIMESTAMP_FORMAT);
+ String eventStr = "<element time=\"" + f.format(new Date(i)) + "\">message</element>\n";
+ writer.write(eventStr);
+ }
+ writer.write("</trace>");
+ }
+ return new CustomXmlTrace(null, fDefinition, file.getPath(), BLOCK_SIZE);
+ }
+
+ @Override
+ public void validateEvent(ITmfEvent event) {
+ assertTrue(event instanceof CustomXmlEvent);
+ String name = fDefinition.definitionName;
+ assertEquals("Event name", name, event.getName());
+ assertEquals("Event name and type", event.getType().getName(), event.getName());
+ }
+
+ @Override
+ public void validateEventCount(int eventCount) {
+ assertEquals("Event count", NB_EVENTS, eventCount);
+ }
+
+ };
+
+ private static final ICustomTestData CUSTOM_XML_EVENT_NAME = new ICustomTestData() {
+
+ private static final int NB_EVENTS = 10;
+ private static final String ODD_EVENT = "OddName";
+ private static final String EVEN_EVENT = "EvenName";
+ private CustomXmlTraceDefinition fDefinition;
+
+ @Override
+ public ITmfTrace getTrace() throws IOException, TmfTraceException {
+ fDefinition = getDefinition(1);
+ final File file = new File(TRACE_PATH);
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(file));) {
+ writer.write("<trace>");
+ for (int i = 0; i < NB_EVENTS; ++i) {
+ String msg = (i % 2 == 0) ? EVEN_EVENT : ODD_EVENT;
+ String eventStr = "<element time=\"" + i + "\">" + msg + "</element>\n";
+ writer.write(eventStr);
+ }
+ writer.write("</trace>");
+ }
+ return new CustomXmlTrace(null, fDefinition, file.getPath(), BLOCK_SIZE);
+ }
+
+ @Override
+ public void validateEvent(ITmfEvent event) {
+ assertTrue(event instanceof CustomXmlEvent);
+ long ts = event.getTimestamp().getValue();
+ if (ts % 2 == 0) {
+ assertEquals("Event name", EVEN_EVENT, event.getName());
+ } else {
+ assertEquals("Event name", ODD_EVENT, event.getName());
+ }
+ assertEquals("Event name and type", event.getType().getName(), event.getName());
+ }
+
+ @Override
+ public void validateEventCount(int eventCount) {
+ assertEquals("Event count", NB_EVENTS, eventCount);
+ }
+
+ };
+
+ /**
+ * @return The arrays of parameters
+ */
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { "Base parser", CUSTOM_XML },
+ { "Parse with event name", CUSTOM_XML_EVENT_NAME }
+ });
+ }
+
+}
<OutputColumn name="Time Stamp"/>
<OutputColumn name="Message"/>
</Definition>
+<Definition name="testtxtevname">
+<TimeStampOutputFormat>dd/MM/yyyy HH:mm:ss:SSS</TimeStampOutputFormat>
+<InputLine>
+<Cardinality max="2147483647" min="0"/>
+<RegEx>(\d*) (.*\S)</RegEx>
+<InputData action="0" format="Tn" name="Time Stamp"/>
+<InputData action="0" format="" name="Event type"/>
+<InputLine>
+<Cardinality max="2147483647" min="0"/>
+<RegEx>(.*\S)</RegEx>
+<InputData action="2" name="Message"/>
+</InputLine>
+</InputLine>
+<OutputColumn name="Time Stamp"/>
+<OutputColumn name="Event type"/>
+</Definition>
</CustomTxtTraceDefinitionList>
<OutputColumn name="Time Stamp"/>
<OutputColumn name="Message"/>
</Definition>
+<Definition name="xmlevname">
+<TimeStampOutputFormat>HH:mm:ss:SSS</TimeStampOutputFormat>
+<InputElement name="trace">
+<InputElement logentry="true" name="element">
+<InputData action="0" format="" name="Event type"/>
+<Attribute name="time">
+<InputData action="0" format="Tn" name="Time Stamp"/>
+</Attribute>
+</InputElement>
+</InputElement>
+<OutputColumn name="Time Stamp"/>
+<OutputColumn name="Event type"/>
+</Definition>
</CustomXMLTraceDefinitionList>