linux/lttng: Add a swtbot test for UI responsiveness of kernel views
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Tue, 19 Jul 2016 14:30:30 +0000 (10:30 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Thu, 8 Sep 2016 20:56:39 +0000 (16:56 -0400)
This adds abstract swtbot classes to open a trace, then navigate it
(full range, zooms, scroll, zoom back out) while some views are opened. This
test is not meant to be run in the performance test suite, but enabling JUL
logging with it allows to have a reproducible series of UI operations and
analyze the so-obtained traces.

Change-Id: Ia43c6b1244b989a6888547b43247bc9b30435dee
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/78271
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Hudson CI
15 files changed:
analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/.classpath
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/perf/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/perf/views/UiResponseTest.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageView.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/kernelmemoryusage/KernelMemoryUsageView.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java
lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/.classpath
lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/META-INF/MANIFEST.MF
lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/perf/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/perf/LttngUiResponseTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/.classpath
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/perf/org/eclipse/tracecompass/tmf/ui/swtbot/tests/perf/views/ViewsResponseTest.java [new file with mode: 0644]

index 577ece4e6fb8506ff90ddeb076a86109e5af59fe..3a05843db1b277c00f6590cb89856fc3305ea18e 100644 (file)
@@ -22,7 +22,7 @@ Import-Package: com.google.common.base,
 Export-Package: org.eclipse.tracecompass.analysis.os.linux.core.contextswitch,
  org.eclipse.tracecompass.analysis.os.linux.core.cpuusage,
  org.eclipse.tracecompass.analysis.os.linux.core.event.aspect,
- org.eclipse.tracecompass.analysis.os.linux.core.inputoutput;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui,org.eclipse.tracecompass.analysis.os.linux.core.tests",
+ org.eclipse.tracecompass.analysis.os.linux.core.inputoutput;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui,org.eclipse.tracecompass.analysis.os.linux.core.tests,org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
  org.eclipse.tracecompass.analysis.os.linux.core.kernel,
  org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage,
  org.eclipse.tracecompass.analysis.os.linux.core.model,
index 53e1048342e3a10ddbf95e5de99e12a89233eb24..aab7650a24e8414d5ee1078ef1772eba592c1017 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="perf"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
                <attributes>
                        <attribute name="annotationpath" value="/org.eclipse.tracecompass.common.core/annotations"/>
index 6da8c08d5e470fe90c1fb1b2bc662752afdc005d..14edf821cac9c46d4043422236df3a97226029ad 100644 (file)
@@ -7,7 +7,8 @@ Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests;singleton:=true
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.latency
+Export-Package: org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.latency,
+ org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.perf.views
 Require-Bundle: org.apache.log4j,
  org.eclipse.core.resources,
  org.eclipse.core.runtime,
@@ -30,5 +31,6 @@ Require-Bundle: org.apache.log4j,
  org.eclipse.tracecompass.analysis.os.linux.core,
  org.eclipse.tracecompass.segmentstore.core,
  org.eclipse.tracecompass.lttng2.kernel.core
-Import-Package: org.eclipse.tracecompass.testtraces.ctf,
+Import-Package: com.google.common.collect;version="15.0.0",
+ org.eclipse.tracecompass.testtraces.ctf,
  org.swtchart
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/perf/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/perf/views/UiResponseTest.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/perf/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/perf/views/UiResponseTest.java
new file mode 100644 (file)
index 0000000..fea9975
--- /dev/null
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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.analysis.os.linux.ui.swtbot.tests.perf.views;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.tracecompass.analysis.os.linux.core.cpuusage.KernelCpuUsageAnalysis;
+import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.InputOutputAnalysisModule;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.ControlFlowView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage.CpuUsageView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.io.diskioactivity.DiskIOActivityView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage.KernelMemoryUsageView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.perf.views.ViewsResponseTest;
+import org.junit.runner.RunWith;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test the responsiveness of Control Flow View and Resources View for different
+ * traces and scenarios. Ideally, when running this test, JUL logging should be
+ * enabled using a logger.properties file. LTTng JUL handler is advised since it
+ * works better with multi-threaded applications than other log handlers
+ *
+ * @author Geneviève Bastien
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public abstract class UiResponseTest extends ViewsResponseTest {
+
+    /**
+     * An enumeration of the views available to test
+     */
+    protected enum OsLinuxViews {
+        /**
+         * The Control Flow View
+         */
+        CONTROL_FLOW,
+        /**
+         * The Resources View
+         */
+        RESOURCES,
+        /**
+         * The CPU Usage View
+         */
+        CPU_USAGE,
+        /**
+         * The Disk IO Activity View
+         */
+        DISK_IO_ACTIVITY,
+        /**
+         * The Kernel Memory Usage View
+         */
+        KERNEL_MEMORY_USAGE
+    }
+
+    private static final @NonNull Map<OsLinuxViews, String> VIEW_IDS = ImmutableMap.of(OsLinuxViews.CONTROL_FLOW, ControlFlowView.ID,
+            OsLinuxViews.RESOURCES, ResourcesView.ID,
+            OsLinuxViews.CPU_USAGE, CpuUsageView.ID,
+            OsLinuxViews.DISK_IO_ACTIVITY, DiskIOActivityView.ID,
+            OsLinuxViews.KERNEL_MEMORY_USAGE, KernelMemoryUsageView.ID);
+
+    @Override
+    protected void beforeRunningTest(ITmfTrace trace) {
+        List<IAnalysisModule> modules = new ArrayList<>(3);
+        modules.add(trace.getAnalysisModule(KernelCpuUsageAnalysis.ID));
+        modules.add(trace.getAnalysisModule(KernelAnalysisModule.ID));
+        modules.add(trace.getAnalysisModule(InputOutputAnalysisModule.ID));
+        for (IAnalysisModule module : modules) {
+            if (module != null) {
+                module.schedule();
+            }
+        }
+        for (IAnalysisModule module : modules) {
+            if (module != null) {
+                assertTrue(module.waitForCompletion());
+            }
+        }
+    }
+
+    /**
+     * Run this swtbot with the trace specified at the specified path. The trace
+     * will be navigate for each view ID separately, then, after renaming the
+     * trace, with all the views opened. After this test, all views will be
+     * closed.
+     *
+     * @param tracePath
+     *            The full path of the trace to open
+     * @param traceType
+     *            The trace type of the trace to open
+     * @param views
+     *            The os linux specific views to test
+     */
+    protected void runTestWithTrace(String tracePath, String traceType, EnumSet<OsLinuxViews> views) {
+        List<String> viewIDs = new ArrayList<>();
+        for (OsLinuxViews view : views) {
+            viewIDs.add(VIEW_IDS.get(view));
+        }
+        runTestWithTrace(tracePath, traceType, viewIDs);
+    }
+
+}
index 7c4c4d6228afcb66261351159ce3b38fa5af4fcd..9b6b94a8a80aeeaec974f2b46ce73b8bae4b7c4a 100644 (file)
@@ -31,9 +31,9 @@ Export-Package: org.eclipse.tracecompass.internal.analysis.os.linux.ui;x-friends
    org.eclipse.tracecompass.analysis.os.linux.ui.tests,
    org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests,
    org.eclipse.tracecompass.lttng2.kernel.ui",
- org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage;x-friends:="org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests",
- org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.io.diskioactivity;x-internal:=true,
- org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage;x-internal:=true,
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests,org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests",
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.io.diskioactivity;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
  org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
  org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.statistics;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
  org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
index 1b3f0f519835924faa5931e1c5e60bdc15b015ad..22abb0fa007a09e47e041224fb1472f7648bab91 100644 (file)
@@ -100,7 +100,7 @@ public class ControlFlowView extends AbstractStateSystemTimeGraphView {
     /**
      * View ID.
      */
-    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.controlflow"; //$NON-NLS-1$
+    public static final @NonNull String ID = "org.eclipse.tracecompass.analysis.os.linux.views.controlflow"; //$NON-NLS-1$
 
     private static final String ICONS_PATH = "icons/"; //$NON-NLS-1$
     private static final String OPTIMIZE_ICON = ICONS_PATH + "elcl16/Optimization.png"; //$NON-NLS-1$
index d1ac399c17cddaa832b88e26cb4374d635279dcd..85202c459650e09db858a8d71a8cae10b89cf7d9 100644 (file)
@@ -51,7 +51,7 @@ import com.google.common.collect.Iterables;
 public class CpuUsageView extends TmfChartView {
 
     /** ID string */
-    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.cpuusage"; //$NON-NLS-1$
+    public static final @NonNull String ID = "org.eclipse.tracecompass.analysis.os.linux.views.cpuusage"; //$NON-NLS-1$
 
     /** ID of the selected thread in the map of data in {@link TmfTraceContext} */
     public static final @NonNull String CPU_USAGE_SELECTED_THREAD = ID + ".CPU_USAGE_SELECTED_TRHEAD"; //$NON-NLS-1$
index 0e9a83b2b19e2b47b52e9aadbc0b3d08fc288ffb..53cea00d8463c5d056791e7d7a5341a4a48be616 100644 (file)
@@ -36,7 +36,7 @@ import org.eclipse.tracecompass.tmf.ui.views.TmfChartView;
 public class KernelMemoryUsageView extends TmfChartView {
 
     /** ID string */
-    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.ui.kernelmemoryusageview"; //$NON-NLS-1$
+    public static final @NonNull String ID = "org.eclipse.tracecompass.analysis.os.linux.ui.kernelmemoryusageview"; //$NON-NLS-1$
     /** ID of the Kernel Memory Usage view data in the data map of {@link TmfTraceContext} */
     public static final @NonNull String KERNEL_MEMORY = ID + ".KERNEL_MEMORY"; //$NON-NLS-1$
 
index 7a24ddc67ba03930b5d4e7d29ca2b265063a7147..23ca9beb04e496a817335456bdadc5111da271c5 100644 (file)
@@ -58,7 +58,7 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 public class ResourcesView extends AbstractStateSystemTimeGraphView {
 
     /** View ID. */
-    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.resources"; //$NON-NLS-1$
+    public static final @NonNull String ID = "org.eclipse.tracecompass.analysis.os.linux.views.resources"; //$NON-NLS-1$
 
     /** ID of the followed CPU in the map data in {@link TmfTraceContext} */
     public static final @NonNull String RESOURCES_FOLLOW_CPU = ID + ".FOLLOW_CPU"; //$NON-NLS-1$
index 53e1048342e3a10ddbf95e5de99e12a89233eb24..aab7650a24e8414d5ee1078ef1772eba592c1017 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="perf"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
                <attributes>
                        <attribute name="annotationpath" value="/org.eclipse.tracecompass.common.core/annotations"/>
index f5a183df633d827370290461abf1aeb48eb63d9a..52675b72e2f48e3d4e47915e55837d544dec2fda 100644 (file)
@@ -29,6 +29,7 @@ Require-Bundle: org.apache.log4j,
  org.eclipse.ui.ide,
  org.eclipse.ui.views,
  org.junit,
- org.eclipse.tracecompass.analysis.graph.ui
+ org.eclipse.tracecompass.analysis.graph.ui,
+ org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests
 Import-Package: org.eclipse.tracecompass.testtraces.ctf,
  org.swtchart;version="0.7.0"
diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/perf/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/perf/LttngUiResponseTest.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/perf/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/perf/LttngUiResponseTest.java
new file mode 100644 (file)
index 0000000..a67341a
--- /dev/null
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.lttng2.kernel.ui.swtbot.tests.perf;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.perf.views.UiResponseTest;
+import org.eclipse.tracecompass.internal.lttng2.kernel.ui.views.PerspectiveFactory;
+import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test the responsiveness of Control Flow View and Resources View for different
+ * traces and scenarios. Ideally, when running this test, JUL logging should be
+ * enabled using a logger.properties file. LTTng JUL handler is advised since it
+ * works better with multi-threaded applications than other log handlers
+ *
+ * @author Geneviève Bastien
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public class LttngUiResponseTest extends UiResponseTest {
+
+    private static final String TRACE_TYPE = "org.eclipse.linuxtools.lttng2.kernel.tracetype";
+
+    @Override
+    protected void prepareWorkspace() {
+        /* Switch to kernel perspective */
+        SWTBotUtils.switchToPerspective(PerspectiveFactory.ID);
+    }
+
+    /**
+     * Test with the django trace
+     *
+     * @throws SecurityException
+     *             If a security manager is present and any the wrong class is
+     *             loaded or the class loader is not the same as its ancestor's
+     *             loader.
+     * @throws IllegalArgumentException
+     *             the object is not the correct class type
+     * @throws IOException
+     *             Exceptions with the trace file
+     */
+    @Test
+    public void testWithDjango() throws SecurityException, IllegalArgumentException, IOException {
+        runTestWithTrace(FileLocator.toFileURL(CtfTestTrace.DJANGO_CLIENT.getTraceURL()).getPath(), TRACE_TYPE, EnumSet.allOf(OsLinuxViews.class));
+    }
+
+    /**
+     * Test with the many-threads trace
+     *
+     * @throws SecurityException
+     *             If a security manager is present and any the wrong class is
+     *             loaded or the class loader is not the same as its ancestor's
+     *             loader.
+     * @throws IllegalArgumentException
+     *             the object is not the correct class type
+     * @throws IOException
+     *             Exceptions with the trace file
+     *
+     */
+    @Test
+    public void testWithManyThreads() throws SecurityException, IllegalArgumentException, IOException {
+        runTestWithTrace(FileLocator.toFileURL(CtfTestTrace.MANY_THREADS.getTraceURL()).getPath(), TRACE_TYPE, EnumSet.of(OsLinuxViews.CONTROL_FLOW, OsLinuxViews.RESOURCES, OsLinuxViews.CPU_USAGE, OsLinuxViews.DISK_IO_ACTIVITY));
+    }
+
+}
index 20df5fc0e818e03e4b79a23d8726aaafbda70791..3ca0c28ec95a2c18590680c6375e46f466496cd5 100644 (file)
@@ -12,5 +12,6 @@
        </classpathentry>
        <classpathentry kind="src" path="src"/>
        <classpathentry kind="src" path="shared"/>
+       <classpathentry kind="src" path="perf"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index f4f683abb9d26cd0c2b03f1bd4126fec861ef2d1..c11c36663cfaf23a070e88354b8a40c9f8f88b09 100644 (file)
@@ -35,6 +35,7 @@ Import-Package: com.google.common.collect,
  org.eclipse.swtbot.swt.finder.widgets,
  org.swtchart
 Export-Package: org.eclipse.tracecompass.tmf.ui.swtbot.tests.parsers.custom;x-internal:=true,
+ org.eclipse.tracecompass.tmf.ui.swtbot.tests.perf.views,
  org.eclipse.tracecompass.tmf.ui.swtbot.tests.perspectives;x-internal:=true,
  org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared,
  org.eclipse.tracecompass.tmf.ui.swtbot.tests.viewers.events;x-internal:=true,
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/perf/org/eclipse/tracecompass/tmf/ui/swtbot/tests/perf/views/ViewsResponseTest.java b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/perf/org/eclipse/tracecompass/tmf/ui/swtbot/tests/perf/views/ViewsResponseTest.java
new file mode 100644 (file)
index 0000000..3f83949
--- /dev/null
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * 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.ui.swtbot.tests.perf.views;
+
+import java.io.File;
+import java.util.Collection;
+
+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.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
+import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
+import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+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.views.timegraph.AbstractTimeGraphView;
+import org.eclipse.ui.IWorkbenchPart;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+/**
+ * Base class to test the responsiveness of any views. The main method of this
+ * class, {@link #runTestWithTrace(String, String, Collection)}, will receive a
+ * collection of view IDs. For each view, the trace under test will be navigated
+ * when only the view is opened (closing all other listed views, all other
+ * opened views will remain opened) and also when all the views are opened
+ * simultaneously. In this last case, it will rename the trace so that events
+ * from when all the views are opened can be listed separately.
+ *
+ * @author Geneviève Bastien
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public abstract class ViewsResponseTest {
+
+    private static final String PROJECT_NAME = "test";
+
+    private final @NonNull SWTWorkbenchBot fBot = new SWTWorkbenchBot();
+
+    /**
+     * Specific tests will prepare the workspace for the run. For example,
+     * concrete classes can open perspectives, open views, prepare the layout,
+     * etc.
+     */
+    protected abstract void prepareWorkspace();
+
+    /**
+     * Things to setup
+     */
+    @Before
+    public void beforeClass() {
+
+        SWTBotUtils.initialize();
+        Thread.currentThread().setName("SWTBotTest");
+        /* set up for swtbot */
+        SWTBotPreferences.TIMEOUT = 60000; /* 60 second timeout */
+        SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
+        SWTWorkbenchBot bot = new SWTWorkbenchBot();
+        SWTBotUtils.closeView("welcome", bot);
+        /* Prepare the workspace */
+        prepareWorkspace();
+        /* Finish waiting for eclipse to load */
+        SWTBotUtils.waitForJobs();
+
+        /* Create project */
+        SWTBotUtils.createProject(PROJECT_NAME);
+    }
+
+    /**
+     * Deletes the project from the workspace
+     */
+    @After
+    public void cleanUp() {
+        /* Close editors and delete project */
+        fBot.closeAllEditors();
+        SWTBotUtils.deleteProject(PROJECT_NAME, fBot);
+    }
+
+    private void closeAllViews(Collection<String> viewIDs) {
+        viewIDs.stream().forEach(id -> {
+            SWTBotUtils.openView(id);
+            SWTBotUtils.closeViewById(id, fBot);
+        });
+    }
+
+    /**
+     * This method will be run when all views are still close, but the trace has
+     * been opened. For instance, if any analysis module need to have completed
+     * before the test, it can wait for completion here.
+     *
+     * @param trace
+     *            The trace used for this test
+     */
+    protected abstract void beforeRunningTest(ITmfTrace trace);
+
+    /**
+     * Run this swtbot with the trace specified at the specified path. The trace
+     * will be navigate for each view ID separately, then, after renaming the
+     * trace, with all the views opened. After this test, all views will be
+     * closed.
+     *
+     * @param tracePath
+     *            The full path of the trace to open
+     * @param traceType
+     *            The trace type of the trace to open
+     * @param viewIDs
+     *            The IDs of the views to test.
+     */
+    protected void runTestWithTrace(String tracePath, String traceType, Collection<String> viewIDs) {
+        closeAllViews(viewIDs);
+        /* Open the trace */
+        String traceName = tracePath.substring(tracePath.lastIndexOf(File.separator, tracePath.length() - 2) + 1, tracePath.length() - 1);
+        SWTBotUtils.openTrace(PROJECT_NAME, tracePath, traceType);
+
+        // Make sure all the analyses we'll need are done
+        ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
+        beforeRunningTest(trace);
+        SWTBotUtils.waitForJobs();
+
+        SWTBotView view;
+
+        for (String viewID : viewIDs) {
+            SWTBotUtils.openView(viewID);
+            view = fBot.viewById(viewID);
+            navigateTrace(view);
+            SWTBotUtils.closeViewById(viewID, fBot);
+        }
+
+        // Close the trace
+        fBot.closeAllEditors();
+
+        // If there is only 1 view to test, return
+        if (viewIDs.size() <= 1) {
+            // Close the views
+            closeAllViews(viewIDs);
+            return;
+        }
+
+        // Open all the views
+        view = null;
+        for (String viewID : viewIDs) {
+            SWTBotUtils.openView(viewID);
+            if (view == null) {
+                view = fBot.viewById(viewID);
+            }
+        }
+
+        // Rename the trace, so the results appear under another trace and
+        // navigate it
+        renameTrace(traceName, traceName + " full");
+        navigateTrace(view);
+
+        // Close the trace
+        fBot.closeAllEditors();
+
+        // Close the views
+        closeAllViews(viewIDs);
+    }
+
+    private void renameTrace(String oldName, String newName) {
+
+        SWTBotTreeItem traceItem = SWTBotUtils.getTraceProjectItem(fBot, SWTBotUtils.selectTracesFolder(fBot, PROJECT_NAME), oldName);
+
+        traceItem.contextMenu().menu("Rename...").click();
+        final String RENAME_TRACE_DIALOG_TITLE = "Rename Trace";
+        fBot.waitUntil(Conditions.shellIsActive(RENAME_TRACE_DIALOG_TITLE));
+        SWTBotShell shell = fBot.shell(RENAME_TRACE_DIALOG_TITLE);
+        SWTBotText text = shell.bot().textWithLabel("New Trace name:");
+        text.setText(newName);
+        shell.bot().button("OK").click();
+        fBot.waitUntil(Conditions.shellCloses(shell));
+        fBot.waitWhile(new ConditionHelpers.ActiveEventsEditor(fBot, null));
+
+        SWTBotTreeItem copiedItem = SWTBotUtils.getTraceProjectItem(fBot, SWTBotUtils.selectTracesFolder(fBot, PROJECT_NAME), newName);
+        copiedItem.contextMenu().menu("Open").click();
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+        }
+        SWTBotUtils.waitForJobs();
+    }
+
+    // TODO: Add some vertical scrollings. With eventual 2D queries, that will
+    // be something to test as well
+    private void navigateTrace(SWTBotView view) {
+        TmfTimeRange originalWindowRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange();
+        TmfTimeRange selectionRange = TmfTraceManager.getInstance().getCurrentTraceContext().getSelectionRange();
+        IWorkbenchPart part = view.getViewReference().getPart(false);
+
+        // Set the time range to the full trace range
+        ITmfTrace activeTrace = TmfTraceManager.getInstance().getActiveTrace();
+        TmfTimeRange fullRange = new TmfTimeRange(activeTrace.getStartTime(), activeTrace.getEndTime());
+        TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, fullRange));
+        waitViewReady(part, selectionRange, fullRange.getEndTime());
+        TmfTimeRange windowRange = fullRange;
+
+        // Zoom in 10 times 15 percent of the range and wait for the view to be
+        // ready
+        for (int i = 0; i < 10; i++) {
+            double delta = (windowRange.getEndTime().getValue() - windowRange.getStartTime().getValue()) * 0.15;
+            TmfTimeRange newWindowRange = new TmfTimeRange(TmfTimestamp.fromNanos((long) (windowRange.getStartTime().toNanos() + delta)), TmfTimestamp.fromNanos((long) (windowRange.getEndTime().toNanos() - delta)));
+            TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, newWindowRange));
+            windowRange = newWindowRange;
+            waitViewReady(part, selectionRange, newWindowRange.getEndTime());
+        }
+
+        // At this zoom level, go to the end
+        long scrollTime = (windowRange.getEndTime().toNanos() - windowRange.getStartTime().toNanos()) / 2;
+        windowRange = new TmfTimeRange(TmfTimestamp.fromNanos(fullRange.getEndTime().toNanos() - (2 * scrollTime)), fullRange.getEndTime());
+        TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, windowRange));
+        waitViewReady(part, selectionRange, windowRange.getEndTime());
+
+        // Scroll back horizontally half the range at a time
+        for (int i = 0; i < 10; i++) {
+            TmfTimeRange newWindowRange = new TmfTimeRange(TmfTimestamp.fromNanos(windowRange.getStartTime().toNanos() - scrollTime), TmfTimestamp.fromNanos(windowRange.getEndTime().toNanos() - scrollTime));
+            TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, newWindowRange));
+            windowRange = newWindowRange;
+            waitViewReady(part, selectionRange, newWindowRange.getEndTime());
+        }
+
+        // then go all the way back to the beginning
+        windowRange = new TmfTimeRange(fullRange.getStartTime(), TmfTimestamp.fromNanos(fullRange.getStartTime().toNanos() + scrollTime));
+        TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, windowRange));
+        waitViewReady(part, selectionRange, windowRange.getEndTime());
+
+        // and zoom out again
+        TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, fullRange));
+        waitViewReady(part, selectionRange, fullRange.getEndTime());
+
+        // Reset the original window range
+        TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, originalWindowRange));
+        waitViewReady(part, selectionRange, originalWindowRange.getEndTime());
+    }
+
+    private void waitViewReady(IWorkbenchPart part, @NonNull TmfTimeRange selectionRange, @NonNull ITmfTimestamp visibleTime) {
+        if (part instanceof AbstractTimeGraphView) {
+            fBot.waitUntil(ConditionHelpers.timeGraphIsReadyCondition((AbstractTimeGraphView) part, selectionRange, visibleTime));
+        }
+        // TODO Add conditions for other kind of views
+    }
+
+}
This page took 0.035547 seconds and 5 git commands to generate.