timing.swtbot: add Generic SegmentTable tests
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Thu, 27 Oct 2016 00:35:25 +0000 (20:35 -0400)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Tue, 8 Nov 2016 00:22:14 +0000 (19:22 -0500)
This makes table tests truly extendible. In order to implement
custom tests, one must override getSegmentStoreProvider with the
analysis to test, createSegment to return the right type of
segment and the test validation they want.

The System Call table view is an example implementation.

Change-Id: Id77c8afce3a5296d066d94885e8f54ddcf719de0
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/84446
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Reviewed-by: Hudson CI
analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/latency/SystemCallLatencyTableAnalysisTest.java
analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/build.properties
analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/plugin.xml [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/timing/ui/swtbot/tests/table/SegmentTableTest.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/table/AbstractSegmentStoreTableViewer.java

index 3a05843db1b277c00f6590cb89856fc3305ea18e..4945e61630e6a271e3a20ad7f11acc46b3f75115 100644 (file)
@@ -34,5 +34,9 @@ Export-Package: org.eclipse.tracecompass.analysis.os.linux.core.contextswitch,
  org.eclipse.tracecompass.internal.analysis.os.linux.core.inputoutput.handlers;x-internal:=true,
  org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel;x-friends:="org.eclipse.tracecompass.analysis.os.linux.core.tests,org.eclipse.tracecompass.analysis.os.linux.ui,org.eclipse.tracecompass.lttng2.kernel.core.tests",
  org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers;x-friends:="org.eclipse.tracecompass.analysis.os.linux.core.tests",
- org.eclipse.tracecompass.internal.analysis.os.linux.core.latency;x-friends:="org.eclipse.tracecompass.analysis.os.linux.core.tests,org.eclipse.tracecompass.analysis.os.linux.ui,org.eclipse.tracecompass.lttng2.kernel.core.tests",
+ org.eclipse.tracecompass.internal.analysis.os.linux.core.latency;
+  x-friends:="org.eclipse.tracecompass.analysis.os.linux.core.tests,
+   org.eclipse.tracecompass.analysis.os.linux.ui,
+   org.eclipse.tracecompass.lttng2.kernel.core.tests,
+   org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
  org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.statistics;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui,org.eclipse.tracecompass.analysis.os.linux.core.tests"
index ea9974e502449ad2450d762e194d456aea02681c..7cf4e261ffe1d730c1cbc44048519f9dc3ec0f05 100644 (file)
@@ -31,7 +31,8 @@ Require-Bundle: org.apache.log4j,
  org.eclipse.tracecompass.analysis.os.linux.core,
  org.eclipse.tracecompass.segmentstore.core,
  org.eclipse.tracecompass.lttng2.kernel.core,
- org.eclipse.tracecompass.tmf.ui.tests
+ org.eclipse.tracecompass.tmf.ui.tests,
+ org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests
 Import-Package: com.google.common.collect;version="15.0.0",
  org.eclipse.tracecompass.testtraces.ctf,
  org.swtchart
index b1ac1070d1f7cbddfe321c244c19d92deb0d98c0..358d252e856889d243384c9a304d30dacb0e95db 100644 (file)
@@ -14,110 +14,66 @@ package org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.latency;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.stream.Collectors;
 
-import org.apache.log4j.ConsoleAppender;
-import org.apache.log4j.Logger;
-import org.apache.log4j.SimpleLayout;
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
-import org.eclipse.swtbot.swt.finder.SWTBot;
 import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
 import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
-import org.eclipse.swtbot.swt.finder.results.BoolResult;
 import org.eclipse.swtbot.swt.finder.results.Result;
-import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
-import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table.SegmentTableTest;
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableView;
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer;
+import org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.SystemCall;
+import org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.SystemCallLatencyAnalysis;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.SystemCallLatencyView;
-import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
-import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
-import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
 import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IViewReference;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.WorkbenchException;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 /**
- * Tests of the latency table
+ * SystemCall Latency Table Test. This adds specific tests for the system call
+ * name for the TSV export and adds a column test.
  *
  * @author Matthew Khouzam
  */
 @RunWith(SWTBotJunit4ClassRunner.class)
-public class SystemCallLatencyTableAnalysisTest {
+public class SystemCallLatencyTableAnalysisTest extends SegmentTableTest {
 
     private static final String TRACE_TYPE = "org.eclipse.linuxtools.lttng2.kernel.tracetype";
     private static final String PROJECT_NAME = "test";
-    private static final String VIEW_ID = SystemCallLatencyView.ID;
-    private static final String TRACING_PERSPECTIVE_ID = "org.eclipse.linuxtools.tmf.ui.perspective";
+    static final String VIEW_ID = SystemCallLatencyView.ID;
+    private static final SystemCallLatencyAnalysis fSystemCallLatencyAnalysis = new SystemCallLatencyAnalysis();
 
-    /** The Log4j logger instance. */
-    private static final Logger fLogger = Logger.getRootLogger();
-    private SystemCallLatencyView fLatencyView;
-    private AbstractSegmentStoreTableViewer fTable;
+    @Override
+    protected ISegmentStoreProvider getSegStoreProvider() {
+        return fSystemCallLatencyAnalysis;
+    }
 
     /**
      * Things to setup
      */
     @BeforeClass
     public static void beforeClass() {
-
-        SWTBotUtils.initialize();
-        Thread.currentThread().setName("SWTBotTest");
-        /* set up for swtbot */
-        SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
-        SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
-        fLogger.removeAllAppenders();
-        fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
-        SWTWorkbenchBot bot = new SWTWorkbenchBot();
-        final List<SWTBotView> openViews = bot.views();
-        for (SWTBotView view : openViews) {
-            if (view.getTitle().equals("Welcome")) {
-                view.close();
-                bot.waitUntil(ConditionHelpers.ViewIsClosed(view));
-            }
-        }
-        /* Switch perspectives */
-        switchTracingPerspective();
-        /* Finish waiting for eclipse to load */
-        WaitUtils.waitForJobs();
-
+        SegmentTableTest.beforeClass();
     }
 
-    /**
-     * Opens a latency table
-     */
-    @Before
-    public void createTable() {
+    @Override
+    protected AbstractSegmentStoreTableView openTable() {
         /*
          * Open latency view
          */
@@ -135,261 +91,35 @@ public class SystemCallLatencyTableAnalysisTest {
         if (!(viewPart instanceof SystemCallLatencyView)) {
             fail("Could not instanciate view");
         }
-        fLatencyView = (SystemCallLatencyView) viewPart;
-        fTable = fLatencyView.getSegmentStoreViewer();
-        assertNotNull(fTable);
+        return (SystemCallLatencyView) viewPart;
     }
 
-    /**
-     * Closes the view
-     */
-    @After
-    public void closeTable() {
-        final SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
-        SWTBotView viewBot = swtWorkbenchBot.viewById(VIEW_ID);
-        viewBot.close();
+    @Override
+    protected @NonNull ISegment createSegment(long start, long end) {
+        // Notice the string is interned, that saves a lot of ram.
+        return new SystemCall(new SystemCall.InitialInfo(start, start % 3 == 0 ? "rightpad" : "leftpad"), end);
     }
 
-    private static void switchTracingPerspective() {
-        final Exception retE[] = new Exception[1];
-        if (!UIThreadRunnable.syncExec(new BoolResult() {
-            @Override
-            public Boolean run() {
-                try {
-                    PlatformUI.getWorkbench().showPerspective(TRACING_PERSPECTIVE_ID,
-                            PlatformUI.getWorkbench().getActiveWorkbenchWindow());
-                } catch (WorkbenchException e) {
-                    retE[0] = e;
-                    return false;
-                }
-                return true;
-            }
-        })) {
-            fail(retE[0].getMessage());
-        }
-
-    }
-
-    /**
-     * Test incrementing
-     */
     @Test
+    @Override
     public void climbTest() {
-        List<@NonNull BasicSegment> fixture = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            fixture.add(new BasicSegment(i, 2 * i));
-        }
-
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        super.climbTest();
+        SWTWorkbenchBot bot = new SWTWorkbenchBot();
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        tableBot.header("System Call").click();
+        // this is an assert in the sense that it will timeout if it is not true
+        // FIXME: The first one should be leftpad, but because of preceding
+        // sorts, it first sort descending in this case
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "rightpad", 0, 3));
+        tableBot.header("System Call").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "leftpad", 0, 3));
+        // Test that duration still works after having tested System Call
         tableBot.header("Duration").click();
         bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
         tableBot.header("Duration").click();
         bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "99", 0, 2));
-    }
-
-    /**
-     * Test decrementing
-     */
-    @Test
-    public void decrementingTest() {
-        List<@NonNull BasicSegment> fixture = new ArrayList<>();
-        for (int i = 100; i >= 0; i--) {
-            fixture.add(new BasicSegment(i, 2 * i));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2));
-    }
-
-    /**
-     * Test small table
-     */
-    @Test
-    public void smallTest() {
-        List<@NonNull BasicSegment> fixture = new ArrayList<>();
-        for (int i = 1; i >= 0; i--) {
-            fixture.add(new BasicSegment(i, 2 * i));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
-    }
-
-    /**
-     * Test large
-     */
-    @Test
-    public void largeTest() {
-        final int size = 1000000;
-        BasicSegment[] fixture = new BasicSegment[size];
-        for (int i = 0; i < size; i++) {
-            fixture[i] = (new BasicSegment(i, 2 * i));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2));
-    }
-
-    /**
-     * Test noise
-     */
-    @Test
-    public void noiseTest() {
-        Random rnd = new Random();
-        rnd.setSeed(1234);
-        final int size = 1000000;
-        BasicSegment[] fixture = new BasicSegment[size];
-        for (int i = 0; i < size; i++) {
-            int start = Math.abs(rnd.nextInt(100000000));
-            int end = start + Math.abs(rnd.nextInt(1000000));
-            fixture[i] = (new BasicSegment(start, end));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "894,633", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2));
-    }
-
-    /**
-     * Test gaussian noise
-     */
-    @Test
-    public void gaussianNoiseTest() {
-        Random rnd = new Random();
-        rnd.setSeed(1234);
-        List<@NonNull BasicSegment> fixture = new ArrayList<>();
-        for (int i = 1; i <= 1000000; i++) {
-            int start = Math.abs(rnd.nextInt(100000000));
-            final int delta = Math.abs(rnd.nextInt(1000));
-            int end = start + delta * delta;
-            fixture.add(new BasicSegment(start, end));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "400,689", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
-        tableBot.header("Duration").click();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "998,001", 0, 2));
-    }
-
-    /**
-     * Test creating a tsv
-     *
-     * @throws NoSuchMethodException
-     *             Error creating the tsv
-     * @throws IOException
-     *             no such file or the file is locked.
-     */
-    @Ignore
-    @Test
-    public void testWriteToTsv() throws NoSuchMethodException, IOException {
-
-        List<@NonNull BasicSegment> fixture = new ArrayList<>();
-        for (int i = 1; i <= 20; i++) {
-            int start = i;
-            final int delta = i;
-            int end = start + delta * delta;
-            fixture.add(new BasicSegment(start, end));
-        }
-        assertNotNull(fTable);
-        fTable.updateModel(fixture);
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
-        SWTBot bot = new SWTBot();
-        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
-        SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
-        SWTBotView viewBot = swtWorkbenchBot.viewById(VIEW_ID);
-        List<String> actionResult = Arrays.asList(testToTsv(viewBot));
-        String absolutePath = TmfTraceManager.getTemporaryDirPath() + File.separator + "syscallLatencyTest.testWriteToTsv.tsv";
-        TmfFileDialogFactory.setOverrideFiles(absolutePath);
-        SWTBotMenu menuBot = viewBot.viewMenu().menu("Export to TSV");
-        try {
-            assertTrue(menuBot.isEnabled());
-            assertTrue(menuBot.isVisible());
-            menuBot.click();
-
-            try (BufferedReader br = new BufferedReader(new FileReader(absolutePath))) {
-                List<String> lines = br.lines().collect(Collectors.toList());
-                assertEquals("Both reads", actionResult, lines);
-            }
-        } finally {
-            new File(absolutePath).delete();
-        }
-
-    }
-
-    private String[] testToTsv(SWTBotView view) throws NoSuchMethodException {
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        assertNotNull(os);
-        Class<@NonNull AbstractSegmentStoreTableView> clazz = AbstractSegmentStoreTableView.class;
-        Method method = clazz.getDeclaredMethod("exportToTsv", java.io.OutputStream.class);
-        method.setAccessible(true);
-        final Exception[] except = new Exception[1];
-        UIThreadRunnable.syncExec(() -> {
-            try {
-                method.invoke(fLatencyView, os);
-            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                except[0] = e;
-            }
-        });
-        assertNull(except[0]);
-        @SuppressWarnings("null")
-        String[] lines = String.valueOf(os).split(System.getProperty("line.separator"));
-        assertNotNull(lines);
-        assertEquals("number of lines", 21, lines.length);
-        assertEquals("header", "Start Time\tEnd Time\tDuration", lines[0]);
-        // not a straight up string compare due to time zones. Kathmandu and
-        // Eucla have 15 minute time zones.
-        assertTrue("line 1", lines[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
-        assertTrue("line 2", lines[2].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s002\\t\\d\\d:\\d\\d:00.000 000 006\\t4"));
-        assertTrue("line 3", lines[3].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s003\\t\\d\\d:\\d\\d:00.000 000 012\\t9"));
-        assertTrue("line 4", lines[4].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s004\\t\\d\\d:\\d\\d:00.000 000 020\\t16"));
-        assertTrue("line 5", lines[5].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s005\\t\\d\\d:\\d\\d:00.000 000 030\\t25"));
-        assertTrue("line 6", lines[6].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s006\\t\\d\\d:\\d\\d:00.000 000 042\\t36"));
-        assertTrue("line 7", lines[7].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s007\\t\\d\\d:\\d\\d:00.000 000 056\\t49"));
-        assertTrue("line 8", lines[8].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s008\\t\\d\\d:\\d\\d:00.000 000 072\\t64"));
-        assertTrue("line 9", lines[9].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s009\\t\\d\\d:\\d\\d:00.000 000 090\\t81"));
-        assertTrue("line 10", lines[10].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s010\\t\\d\\d:\\d\\d:00.000 000 110\\t100"));
-        assertTrue("line 11", lines[11].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s011\\t\\d\\d:\\d\\d:00.000 000 132\\t121"));
-        assertTrue("line 12", lines[12].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s012\\t\\d\\d:\\d\\d:00.000 000 156\\t144"));
-        assertTrue("line 13", lines[13].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s013\\t\\d\\d:\\d\\d:00.000 000 182\\t169"));
-        assertTrue("line 14", lines[14].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s014\\t\\d\\d:\\d\\d:00.000 000 210\\t196"));
-        assertTrue("line 15", lines[15].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s015\\t\\d\\d:\\d\\d:00.000 000 240\\t225"));
-        assertTrue("line 16", lines[16].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s016\\t\\d\\d:\\d\\d:00.000 000 272\\t256"));
-        assertTrue("line 17", lines[17].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s017\\t\\d\\d:\\d\\d:00.000 000 306\\t289"));
-        assertTrue("line 18", lines[18].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s018\\t\\d\\d:\\d\\d:00.000 000 342\\t324"));
-        assertTrue("line 19", lines[19].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s019\\t\\d\\d:\\d\\d:00.000 000 380\\t361"));
-        assertTrue("line 20", lines[20].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s020\\t\\d\\d:\\d\\d:00.000 000 420\\t400"));
-        return lines;
+        tableBot.header("Start Time").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "99", 0, 2));
     }
 
     /**
@@ -412,9 +142,13 @@ public class SystemCallLatencyTableAnalysisTest {
         SWTBotUtils.createProject(PROJECT_NAME);
         SWTBotUtils.openTrace(PROJECT_NAME, tracePath, TRACE_TYPE);
         WaitUtils.waitForJobs();
-        createTable();
+        AbstractSegmentStoreTableView tableView = openTable();
+        setTableView(tableView);
+        AbstractSegmentStoreTableViewer table = tableView.getSegmentStoreViewer();
+        assertNotNull(table);
+        setTable(table);
         WaitUtils.waitForJobs();
-        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
+        SWTBotTable tableBot = new SWTBotTable(table.getTableViewer().getTable());
         bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "24,100", 0, 2));
         tableBot.header("Duration").click();
         bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1,000", 0, 2));
@@ -423,4 +157,33 @@ public class SystemCallLatencyTableAnalysisTest {
         bot.closeAllEditors();
         SWTBotUtils.deleteProject(PROJECT_NAME, bot);
     }
+
+    @Override
+    protected void testTsv(String[] lines) {
+        assertNotNull(lines);
+        assertEquals("number of lines", 21, lines.length);
+        assertEquals("header", "Start Time\tEnd Time\tDuration\tSystem Call", lines[0]);
+        // not a straight up string compare due to time zones. Kathmandu and
+        // Eucla have 15 minute time zones.
+        assertTrue("line 1 : " + lines[1], lines[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1\\tleftpad"));
+        assertTrue("line 2 : " + lines[2], lines[2].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s002\\t\\d\\d:\\d\\d:00.000 000 006\\t4\\tleftpad"));
+        assertTrue("line 3 : " + lines[3], lines[3].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s003\\t\\d\\d:\\d\\d:00.000 000 012\\t9\\trightpad"));
+        assertTrue("line 4 : " + lines[4], lines[4].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s004\\t\\d\\d:\\d\\d:00.000 000 020\\t16\\tleftpad"));
+        assertTrue("line 5 : " + lines[5], lines[5].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s005\\t\\d\\d:\\d\\d:00.000 000 030\\t25\\tleftpad"));
+        assertTrue("line 6 : " + lines[6], lines[6].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s006\\t\\d\\d:\\d\\d:00.000 000 042\\t36\\trightpad"));
+        assertTrue("line 7 : " + lines[7], lines[7].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s007\\t\\d\\d:\\d\\d:00.000 000 056\\t49\\tleftpad"));
+        assertTrue("line 8 : " + lines[8], lines[8].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s008\\t\\d\\d:\\d\\d:00.000 000 072\\t64\\tleftpad"));
+        assertTrue("line 9 : " + lines[9], lines[9].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s009\\t\\d\\d:\\d\\d:00.000 000 090\\t81\\trightpad"));
+        assertTrue("line 10 : " + lines[10], lines[10].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s010\\t\\d\\d:\\d\\d:00.000 000 110\\t100\\tleftpad"));
+        assertTrue("line 11 : " + lines[11], lines[11].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s011\\t\\d\\d:\\d\\d:00.000 000 132\\t121\\tleftpad"));
+        assertTrue("line 12 : " + lines[12], lines[12].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s012\\t\\d\\d:\\d\\d:00.000 000 156\\t144\\trightpad"));
+        assertTrue("line 13 : " + lines[13], lines[13].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s013\\t\\d\\d:\\d\\d:00.000 000 182\\t169\\tleftpad"));
+        assertTrue("line 14 : " + lines[14], lines[14].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s014\\t\\d\\d:\\d\\d:00.000 000 210\\t196\\tleftpad"));
+        assertTrue("line 15 : " + lines[15], lines[15].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s015\\t\\d\\d:\\d\\d:00.000 000 240\\t225\\trightpad"));
+        assertTrue("line 16 : " + lines[16], lines[16].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s016\\t\\d\\d:\\d\\d:00.000 000 272\\t256\\tleftpad"));
+        assertTrue("line 17 : " + lines[17], lines[17].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s017\\t\\d\\d:\\d\\d:00.000 000 306\\t289\\tleftpad"));
+        assertTrue("line 18 : " + lines[18], lines[18].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s018\\t\\d\\d:\\d\\d:00.000 000 342\\t324\\trightpad"));
+        assertTrue("line 19 : " + lines[19], lines[19].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s019\\t\\d\\d:\\d\\d:00.000 000 380\\t361\\tleftpad"));
+        assertTrue("line 20 : " + lines[20], lines[20].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s020\\t\\d\\d:\\d\\d:00.000 000 420\\t400\\tleftpad"));
+    }
 }
index b328f0550b666302c9bc417e39525bb8eb5a0d2e..605890831440bd2e75004a3eefd7d2b25c613d9a 100644 (file)
@@ -7,7 +7,8 @@ Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests;singleton:=true
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.flamegraph;x-internal:=true
+Export-Package: org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.flamegraph;x-internal:=true,
+ org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table
 Require-Bundle: org.apache.log4j,
  org.eclipse.core.resources,
  org.eclipse.core.runtime,
@@ -27,6 +28,7 @@ Require-Bundle: org.apache.log4j,
  org.eclipse.ui.views,
  org.junit,
  org.eclipse.tracecompass.analysis.timing.core.tests,
- org.eclipse.tracecompass.tmf.ui.tests
+ org.eclipse.tracecompass.tmf.ui.tests,
+ org.eclipse.tracecompass.segmentstore.core
 Import-Package: com.google.common.collect,
  org.swtchart
index 3f7a01bf09101eb16c87823a42f008f59d2c0895..d2c81f59259b8b7907b39f2e65df24a9ccf68eed 100644 (file)
@@ -14,6 +14,7 @@ source.. = src/
 bin.includes = META-INF/,\
                .,\
                plugin.properties,\
-               about.html
+               about.html,\
+               plugin.xml
 additional.bundles = org.eclipse.jdt.annotation
 jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/plugin.xml b/analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/plugin.xml
new file mode 100644 (file)
index 0000000..6d23f44
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            class="org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table.SegmentTableTest$TestSegmentStoreTableView"
+            id="org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table.TestSegmentStoreTableView"
+            name="Table"
+            restorable="true">
+      </view>
+   </extension>
+
+</plugin>
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/timing/ui/swtbot/tests/table/SegmentTableTest.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/timing/ui/swtbot/tests/table/SegmentTableTest.java
new file mode 100644 (file)
index 0000000..57df8f2
--- /dev/null
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * 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.analysis.timing.ui.swtbot.tests.table;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Logger;
+import org.apache.log4j.SimpleLayout;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableView;
+import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer;
+import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory;
+import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory.SegmentStoreType;
+import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
+import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests of the latency table to extend it to custom tables, 4 steps are needed.
+ * <ol>
+ * <li>Override {@link #createSegment(long, long)}</li>
+ * <li>Override {@link #openTable()} to open the desired table view</li>
+ * <li>Override {@link #getSegStoreProvider()} to retrieve the segment store
+ * provider with the desirable aspects</li>
+ * <li>Override {@link #testTsv(String[])} to test the content of the output to
+ * TSV</li>
+ * </ol>
+ *
+ * Feel free to override any test and add additional tests but remember to call
+ * <code>super.test()</code> before.
+ *
+ * @author Matthew Khouzam
+ */
+public class SegmentTableTest {
+
+    /**
+     * Test table
+     *
+     * @author Matthew Khouzam
+     */
+    public static final class TestSegmentStoreTableView extends AbstractSegmentStoreTableView {
+        /**
+         * ID of this view
+         */
+        public static final String ID = "org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table.TestSegmentStoreTableView"; //$NON-NLS-1$
+
+        /**
+         * Constructor
+         */
+        public TestSegmentStoreTableView() {
+        }
+
+        SegmentTableTest fTest;
+
+        /**
+         * Set the parent test
+         *
+         * @param test
+         *            the test
+         */
+        public void setTest(SegmentTableTest test) {
+            fTest = test;
+        }
+
+        @Override
+        protected @NonNull AbstractSegmentStoreTableViewer createSegmentStoreViewer(@NonNull TableViewer tableViewer) {
+            return new AbstractSegmentStoreTableViewer(tableViewer) {
+
+                @Override
+                protected @Nullable ISegmentStoreProvider getSegmentStoreProvider(@NonNull ITmfTrace trace) {
+                    return fTest.getSegStoreProvider();
+                }
+            };
+        }
+    }
+
+    private final class SimpleSegmentStoreProvider implements ISegmentStoreProvider {
+        @Override
+        public void removeListener(@NonNull IAnalysisProgressListener listener) {
+            // do nothing
+        }
+
+        @Override
+        public @Nullable ISegmentStore<@NonNull ISegment> getSegmentStore() {
+            return fSs;
+        }
+
+        @Override
+        public @NonNull Iterable<@NonNull ISegmentAspect> getSegmentAspects() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public void addListener(@NonNull IAnalysisProgressListener listener) {
+            // do nothing
+        }
+    }
+
+    private AbstractSegmentStoreTableView fTableView;
+    private AbstractSegmentStoreTableViewer fTable;
+    private ISegmentStoreProvider fSsp;
+    private final ISegmentStore<@NonNull ISegment> fSs = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast);
+
+    /** The Log4j logger instance. */
+    private static final Logger fLogger = Logger.getRootLogger();
+
+    /**
+     * Before class, call by all subclassed
+     */
+    @BeforeClass
+    public static void beforeClass() {
+
+        SWTBotUtils.initialize();
+        Thread.currentThread().setName("SWTBotTest");
+        /* set up for swtbot */
+        SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
+        SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
+        fLogger.removeAllAppenders();
+        fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
+        SWTWorkbenchBot bot = new SWTWorkbenchBot();
+        final List<SWTBotView> openViews = bot.views();
+        for (SWTBotView view : openViews) {
+            if (view.getTitle().equals("Welcome")) {
+                view.close();
+                bot.waitUntil(ConditionHelpers.ViewIsClosed(view));
+            }
+        }
+        /* Switch perspectives */
+        SWTBotUtils.switchToTracingPerspective();
+        /* Finish waiting for eclipse to load */
+        WaitUtils.waitForJobs();
+    }
+
+    /**
+     * Opens a latency table
+     */
+    @Before
+    public void init() {
+        setTableView(openTable());
+        assertNotNull(getTableView());
+        setTable(getTableView().getSegmentStoreViewer());
+        assertNotNull(getTable());
+        ISegmentStoreProvider segStoreProvider = getSegStoreProvider();
+        assertNotNull(segStoreProvider);
+        UIThreadRunnable.syncExec(() -> getTable().setSegmentProvider(segStoreProvider));
+    }
+
+    /**
+     * Close the table
+     */
+    @After
+    public void finish() {
+        new SWTWorkbenchBot().viewById(getTableView().getSite().getId()).close();
+    }
+
+    /**
+     * Create the table viewer to test
+     *
+     * @return the table viewer bot
+     */
+    protected AbstractSegmentStoreTableView openTable() {
+        AbstractSegmentStoreTableView tableView = getTableView();
+        if (tableView != null) {
+            return tableView;
+        }
+        IViewPart vp = null;
+        final IWorkbench workbench = PlatformUI.getWorkbench();
+        vp = UIThreadRunnable.syncExec((Result<IViewPart>) () -> {
+            try {
+                return workbench.getActiveWorkbenchWindow().getActivePage().showView(TestSegmentStoreTableView.ID);
+            } catch (PartInitException e) {
+                return null;
+            }
+        });
+        assertNotNull(vp);
+        assertTrue(vp instanceof TestSegmentStoreTableView);
+        TestSegmentStoreTableView testSegmentStoreTableView = (TestSegmentStoreTableView) vp;
+        testSegmentStoreTableView.setTest(this);
+        fTableView = testSegmentStoreTableView;
+
+        return fTableView;
+    }
+
+    /**
+     * Create a segment of the type supported by the table under test, with the
+     * requested start and end time
+     *
+     * @param start
+     *            start time
+     * @param end
+     *            end time
+     * @return the segment
+     */
+    protected @NonNull ISegment createSegment(long start, long end) {
+        return new BasicSegment(start, end);
+    }
+
+    /**
+     * Test a climbing data structure.
+     * <p>
+     * Create segments that are progressively larger and start later. Test that
+     * the "duration" column sorts well
+     */
+    @Test
+    public void climbTest() {
+        List<@NonNull ISegment> fixture = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            fixture.add(createSegment(i, 2 * i));
+        }
+
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "99", 0, 2));
+    }
+
+    /**
+     * Test a decrementing data structure.
+     * <p>
+     * Create segments that are progressively shorter and start sooner,
+     * effectively the inverse sorted {@link #climbTest()} datastructure. Test
+     * that the "duration" column sorts well
+     */
+    @Test
+    public void decrementingTest() {
+        List<@NonNull ISegment> fixture = new ArrayList<>();
+        for (int i = 100; i >= 0; i--) {
+            fixture.add(createSegment(i, 2 * i));
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2));
+    }
+
+    /**
+     * Test small table
+     * <p>
+     * Test table with 2 segments. Duration sort is tested.
+     */
+    @Test
+    public void smallTest() {
+        List<@NonNull ISegment> fixture = new ArrayList<>();
+        for (int i = 1; i >= 0; i--) {
+            fixture.add(createSegment(i, 2 * i));
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
+    }
+
+    /**
+     * Test large table
+     * <p>
+     * Test table with over 9000 segments. Duration sort is tested.
+     */
+    @Test
+    public void largeTest() {
+        final int size = 1000000;
+        ISegment[] fixture = new ISegment[size];
+        for (int i = 0; i < size; i++) {
+            fixture[i] = createSegment(i, 2 * i);
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2));
+    }
+
+    /**
+     * Test table with segments that have durations spread into a random (white
+     * noise) distribution
+     * <p>
+     * Test table with a random distribution of segments. Duration sort is
+     * tested.
+     */
+    @Test
+    public void noiseTest() {
+        Random rnd = new Random();
+        rnd.setSeed(1234);
+        final int size = 1000000;
+        ISegment[] fixture = new ISegment[size];
+        for (int i = 0; i < size; i++) {
+            int start = Math.abs(rnd.nextInt(100000000));
+            int end = start + Math.abs(rnd.nextInt(1000000));
+            fixture[i] = (createSegment(start, end));
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "894,633", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2));
+    }
+
+    /**
+     * Test table with segments that have durations spread into a gaussian
+     * (normal) distribution
+     * <p>
+     * Test table with a gaussian distribution of segments. Duration sort is
+     * tested.
+     */
+    @Test
+    public void gaussianNoiseTest() {
+        Random rnd = new Random();
+        rnd.setSeed(1234);
+        List<@NonNull ISegment> fixture = new ArrayList<>();
+        for (int i = 1; i <= 1000000; i++) {
+            int start = Math.abs(rnd.nextInt(100000000));
+            final int delta = Math.abs(rnd.nextInt(1000));
+            int end = start + delta * delta;
+            fixture.add(createSegment(start, end));
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "400,689", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2));
+        tableBot.header("Duration").click();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "998,001", 0, 2));
+    }
+
+    /**
+     * Test creating a tsv
+     *
+     * @throws NoSuchMethodException
+     *             Error creating the tsv
+     * @throws IOException
+     *             no such file or the file is locked.
+     */
+    @Test
+    public void testWriteToTsv() throws NoSuchMethodException, IOException {
+
+        List<@NonNull ISegment> fixture = new ArrayList<>();
+        for (int i = 1; i <= 20; i++) {
+            int start = i;
+            final int delta = i;
+            int end = start + delta * delta;
+            fixture.add(createSegment(start, end));
+        }
+        assertNotNull(getTable());
+        getTable().updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
+        SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+        SWTBotView viewBot = swtWorkbenchBot.viewById(getTableView().getSite().getId());
+        String[] lines = extractTsv(viewBot);
+        testTsv(lines);
+        List<String> actionResult = Arrays.asList(lines);
+        String absolutePath = TmfTraceManager.getTemporaryDirPath() + File.separator + "syscallLatencyTest.testWriteToTsv.tsv";
+        TmfFileDialogFactory.setOverrideFiles(absolutePath);
+        SWTBotMenu menuBot = viewBot.viewMenu().menu("Export to TSV");
+        try {
+            assertTrue(menuBot.isEnabled());
+            assertTrue(menuBot.isVisible());
+            menuBot.click();
+
+            try (BufferedReader br = new BufferedReader(new FileReader(absolutePath))) {
+                List<String> actual = br.lines().collect(Collectors.toList());
+                assertEquals("Both reads", actionResult, actual);
+            }
+        } finally {
+            new File(absolutePath).delete();
+        }
+
+    }
+
+    private String[] extractTsv(SWTBotView viewBot) throws NoSuchMethodException, SecurityException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        assertNotNull(os);
+        Class<@NonNull AbstractSegmentStoreTableView> clazz = AbstractSegmentStoreTableView.class;
+        Method method = clazz.getDeclaredMethod("exportToTsv", java.io.OutputStream.class);
+        method.setAccessible(true);
+        final Exception[] except = new Exception[1];
+        UIThreadRunnable.syncExec(() -> {
+            try {
+                method.invoke(getTableView(), os);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                except[0] = e;
+            }
+        });
+        assertNull(except[0]);
+        @SuppressWarnings("null")
+        String[] lines = String.valueOf(os).split(System.getProperty("line.separator"));
+        return lines;
+    }
+
+    /**
+     * Test the TSV generated. For each line, including the header, it should be
+     * asserted that it is equal to the expected line
+     *
+     * @param lines
+     *            every entry, starting with the header
+     */
+    protected void testTsv(String[] lines) {
+        assertNotNull(lines);
+        assertEquals("number of lines", 21, lines.length);
+        assertEquals("header", "Start Time\tEnd Time\tDuration", lines[0]);
+        // not a straight up string compare due to time zones. Kathmandu and
+        // Eucla have 15 minute time zones.
+        assertTrue("line 1", lines[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
+        assertTrue("line 2", lines[2].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s002\\t\\d\\d:\\d\\d:00.000 000 006\\t4"));
+        assertTrue("line 3", lines[3].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s003\\t\\d\\d:\\d\\d:00.000 000 012\\t9"));
+        assertTrue("line 4", lines[4].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s004\\t\\d\\d:\\d\\d:00.000 000 020\\t16"));
+        assertTrue("line 5", lines[5].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s005\\t\\d\\d:\\d\\d:00.000 000 030\\t25"));
+        assertTrue("line 6", lines[6].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s006\\t\\d\\d:\\d\\d:00.000 000 042\\t36"));
+        assertTrue("line 7", lines[7].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s007\\t\\d\\d:\\d\\d:00.000 000 056\\t49"));
+        assertTrue("line 8", lines[8].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s008\\t\\d\\d:\\d\\d:00.000 000 072\\t64"));
+        assertTrue("line 9", lines[9].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s009\\t\\d\\d:\\d\\d:00.000 000 090\\t81"));
+        assertTrue("line 10", lines[10].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s010\\t\\d\\d:\\d\\d:00.000 000 110\\t100"));
+        assertTrue("line 11", lines[11].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s011\\t\\d\\d:\\d\\d:00.000 000 132\\t121"));
+        assertTrue("line 12", lines[12].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s012\\t\\d\\d:\\d\\d:00.000 000 156\\t144"));
+        assertTrue("line 13", lines[13].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s013\\t\\d\\d:\\d\\d:00.000 000 182\\t169"));
+        assertTrue("line 14", lines[14].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s014\\t\\d\\d:\\d\\d:00.000 000 210\\t196"));
+        assertTrue("line 15", lines[15].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s015\\t\\d\\d:\\d\\d:00.000 000 240\\t225"));
+        assertTrue("line 16", lines[16].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s016\\t\\d\\d:\\d\\d:00.000 000 272\\t256"));
+        assertTrue("line 17", lines[17].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s017\\t\\d\\d:\\d\\d:00.000 000 306\\t289"));
+        assertTrue("line 18", lines[18].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s018\\t\\d\\d:\\d\\d:00.000 000 342\\t324"));
+        assertTrue("line 19", lines[19].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s019\\t\\d\\d:\\d\\d:00.000 000 380\\t361"));
+        assertTrue("line 20", lines[20].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s020\\t\\d\\d:\\d\\d:00.000 000 420\\t400"));
+    }
+
+    /**
+     * Gets the table view
+     *
+     * @return the table view
+     */
+    protected AbstractSegmentStoreTableView getTableView() {
+        return fTableView;
+    }
+
+    /**
+     * Sets the table view
+     *
+     * @param tableView
+     *            the table view
+     */
+    protected void setTableView(AbstractSegmentStoreTableView tableView) {
+        fTableView = tableView;
+    }
+
+    /**
+     * Gets the table viewer
+     *
+     * @return the table viewer
+     */
+    protected AbstractSegmentStoreTableViewer getTable() {
+        return fTable;
+    }
+
+    /**
+     * Set the table viewer
+     *
+     * @param table
+     *            the table viewer
+     */
+    protected void setTable(AbstractSegmentStoreTableViewer table) {
+        fTable = table;
+    }
+
+    /**
+     * get the segment store provider
+     *
+     * @return the segment store provider
+     */
+    protected ISegmentStoreProvider getSegStoreProvider() {
+        ISegmentStoreProvider ssp = fSsp;
+        if (ssp == null) {
+            ssp = new SimpleSegmentStoreProvider();
+            fSsp = ssp;
+        }
+        return ssp;
+    }
+}
\ No newline at end of file
index a3484bbcdef16d04463b57978e9df979d74e7b34..75df3d42dbf15ab1bd1a71854c2d57472cfa0249 100644 (file)
@@ -30,6 +30,7 @@ import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
@@ -54,6 +55,8 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
 
+import com.google.common.annotations.VisibleForTesting;
+
 /**
  * Displays the segment store provider data in a column table
  *
@@ -154,6 +157,32 @@ public abstract class AbstractSegmentStoreTableViewer extends TmfSimpleTableView
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * Sets the segment provider, use only in test, only run in display thread
+     *
+     * @param segmentProvider
+     *            the segment provider
+     * @since 1.2
+     */
+    @VisibleForTesting
+    public void setSegmentProvider(ISegmentStoreProvider segmentProvider) {
+        fSegmentProvider = segmentProvider;
+        // Sort order of the content provider is by start time by default
+        getTableViewer().setContentProvider(new SegmentStoreContentProvider());
+
+        Table table = getTableViewer().getTable();
+        table.setRedraw(false);
+        while (table.getColumnCount() > 0) {
+            table.getColumn(0).dispose();
+        }
+        createColumns();
+        createProviderColumns();
+        getTableViewer().getTable().addSelectionListener(new TableSelectionListener());
+        addPackListener();
+        fListener = new SegmentStoreProviderProgressListener();
+        table.setRedraw(true);
+    }
+
     /**
      * Create default columns for start time, end time and duration
      */
This page took 0.038872 seconds and 5 git commands to generate.