lttng: add some stress test for opening and closing of traces
authorBernd Hufmann <Bernd.Hufmann@ericsson.com>
Sat, 25 Oct 2014 00:41:32 +0000 (20:41 -0400)
committerBernd Hufmann <bernd.hufmann@ericsson.com>
Tue, 28 Oct 2014 23:35:45 +0000 (19:35 -0400)
This will trigger concurrent starting and cancelling of analyses.
After fixing bug 447434 (commit e1c415) this test should run without
exceptions.

Change-Id: I9c7a35d29e0c4a406511ec1e8032b3d818498b94
Signed-off-by: Bernd Hufmann <Bernd.Hufmann@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/35508
Tested-by: Hudson CI
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/AllTests.java
org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/OpenTraceStressTest.java [new file with mode: 0644]
org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/SWTBotUtil.java

index 321898014c6c48c269d197748a9f1c12749ede86..26c37091c64844cc68f85a331bf5ecdcd94263f7 100644 (file)
@@ -21,7 +21,8 @@ import org.junit.runners.Suite;
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
     ImportAndReadKernelSmokeTest.class,
-    KernelPerspectiveChecker.class
+    KernelPerspectiveChecker.class,
+    OpenTraceStressTest.class
 })
 public class AllTests {
 
diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/OpenTraceStressTest.java b/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/OpenTraceStressTest.java
new file mode 100644 (file)
index 0000000..af84f28
--- /dev/null
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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
+ *
+ * Contributors:
+ *   Bernd Hufmann - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.tracecompass.tmf.core.analysis.Messages;
+import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.SWTBotUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * SWTBot stress test for opening and closing of traces.
+ *
+ * @author Bernd Hufmann
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public class OpenTraceStressTest {
+
+    private static final String TRACE_TYPE = "org.eclipse.linuxtools.lttng2.kernel.tracetype";
+    private static final String KERNEL_PERSPECTIVE_ID = "org.eclipse.linuxtools.lttng2.kernel.ui.perspective";
+    private static final CtfTmfTestTrace CTF_TRACE = CtfTmfTestTrace.SYNC_DEST;
+    private static final String TRACE_PROJECT_NAME = "test";
+
+    private static SWTWorkbenchBot workbenchbot;
+
+    /**
+     * Test Class setup
+     */
+    @BeforeClass
+    public static void init() {
+        SWTBotUtil.failIfUIThread();
+
+        /* Set up for swtbot */
+        SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
+
+        workbenchbot = new SWTWorkbenchBot();
+
+        /* Close welcome view */
+        SWTBotUtil.closeView("Welcome", workbenchbot);
+
+        /* Switch perspectives */
+        SWTBotUtil.switchToPerspective(KERNEL_PERSPECTIVE_ID);
+
+        /* Finish waiting for eclipse to load */
+        SWTBotUtil.waitForJobs();
+    }
+
+    /**
+     * Main test case to test opening and closing of traces concurrently.
+     */
+    @Test
+    public void testOpenAndCloseConcurrency() {
+        SWTBotUtil.createProject(TRACE_PROJECT_NAME);
+
+        File fTestFile = new File(CTF_TRACE.getPath());
+
+        String path = fTestFile.getAbsolutePath();
+
+        assertNotNull(fTestFile);
+        assumeTrue(fTestFile.exists());
+
+        /*
+         *  This opening and closing of traces will trigger several threads for analysis which
+         *  will be closed concurrently. There used to be a concurrency bug (447434) which should
+         *  be fixed by now and this test should run without any exceptions.
+         *
+         *  Since the failure depends on timing it only happened sometimes before the bug fix
+         *  using this test.
+         */
+        final MultiStatus status = new MultiStatus("lttn2.kernel.ui.swtbot.tests", IStatus.OK, null, null);
+        IJobManager mgr = Job.getJobManager();
+        JobChangeAdapter changeListener = new JobChangeAdapter() {
+            @Override
+            public void done(IJobChangeEvent event) {
+                Job job = event.getJob();
+                // Check for analysis failure
+                String jobNamePrefix = NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, "");
+                if ((job.getName().startsWith(jobNamePrefix)) && (job.getResult().getSeverity() == IStatus.ERROR)) {
+                    status.add(job.getResult());
+                }
+            }
+        };
+        mgr.addJobChangeListener(changeListener);
+        for (int i = 0; i < 10; i++) {
+            SWTBotUtil.openTrace(TRACE_PROJECT_NAME, path, TRACE_TYPE, false);
+            SWTBotUtil.openTrace(TRACE_PROJECT_NAME, path, TRACE_TYPE, false);
+            SWTBotUtil.openTrace(TRACE_PROJECT_NAME, path, TRACE_TYPE, false);
+            SWTBotUtil.openTrace(TRACE_PROJECT_NAME, path, TRACE_TYPE, false);
+            SWTBotUtil.openTrace(TRACE_PROJECT_NAME, path, TRACE_TYPE, false);
+            // Add little delay so that treads have a chance to start
+            SWTBotUtil.delay(1000);
+            workbenchbot.closeAllEditors();
+
+            if (!status.isOK()) {
+                SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, workbenchbot);
+                fail(handleErrorStatus(status));
+            }
+        }
+        SWTBotUtil.deleteProject(TRACE_PROJECT_NAME, workbenchbot);
+    }
+
+    private static String handleErrorStatus(MultiStatus status) {
+
+        // Build a string with all the children status messages, exception
+        // messages and stack traces
+        StringBuilder sb = new StringBuilder();
+        for (IStatus childStatus : status.getChildren()) {
+            StringBuilder childSb = new StringBuilder();
+            if (!childStatus.getMessage().isEmpty()) {
+                childSb.append(childStatus.getMessage() + '\n');
+            }
+
+            Throwable childException = childStatus.getException();
+            if (childException != null) {
+                String reason = childException.getMessage();
+                // Some system exceptions have no message
+                if (reason == null) {
+                    reason = childException.toString();
+                }
+
+                String stackMessage = getExceptionStackMessage(childException);
+                if (stackMessage == null) {
+                    stackMessage = reason;
+                }
+
+                childSb.append(stackMessage);
+            }
+
+            if (childSb.length() > 0) {
+                childSb.insert(0, '\n');
+                sb.append(childSb.toString());
+            }
+        }
+        return sb.toString();
+    }
+
+    private static String getExceptionStackMessage(Throwable exception) {
+        String stackMessage = null;
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        exception.printStackTrace(ps);
+        ps.flush();
+        try {
+            baos.flush();
+            stackMessage = baos.toString();
+        } catch (IOException e) {
+        }
+
+        return stackMessage;
+    }
+}
\ No newline at end of file
index fab54d6e64b9a3210e8c38e0e8e594d8473dd897..7ce4c6468a46d6c408fff8ce50287b55001ba97d 100644 (file)
@@ -223,6 +223,23 @@ public abstract class SWTBotUtil {
      *            org.eclipse.linuxtools.btf.trace)
      */
     public static void openTrace(final String projectName, final String tracePath, final String traceType) {
+        openTrace(projectName, tracePath, traceType, true);
+    }
+
+    /**
+     * Open a trace, this does not perform any validation though
+     *
+     * @param projectName
+     *            The project name
+     * @param tracePath
+     *            the path of the trace file (absolute or relative)
+     * @param traceType
+     *            the trace canonical string (eg:
+     *            org.eclipse.linuxtools.btf.trace)
+     * @param delay
+     *            delay and wait for jobs
+     */
+    public static void openTrace(final String projectName, final String tracePath, final String traceType, boolean delay) {
         final Exception exception[] = new Exception[1];
         exception[0] = null;
         UIThreadRunnable.syncExec(new VoidResult() {
@@ -241,8 +258,10 @@ public abstract class SWTBotUtil {
             fail(exception[0].getMessage());
         }
 
-        delay(1000);
-        waitForJobs();
+        if (delay) {
+            delay(1000);
+            waitForJobs();
+        }
     }
 
     /**
This page took 0.028687 seconds and 5 git commands to generate.