Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Khouzam2014-07-18 20:06:03 +0000
committerMarc Khouzam2014-07-21 20:26:52 +0000
commit90718216f11bf4b65cbbc5e6838966bbaa023a26 (patch)
tree2faaceb5f44e3cdbe06f86f2e54d3524db1e8cfc
parent947b25009ae9506e5c8c4f9b49b0b2f16ad5e3a4 (diff)
downloadorg.eclipse.cdt-90718216f11bf4b65cbbc5e6838966bbaa023a26.tar.gz
org.eclipse.cdt-90718216f11bf4b65cbbc5e6838966bbaa023a26.tar.xz
org.eclipse.cdt-90718216f11bf4b65cbbc5e6838966bbaa023a26.zip
Bug 439926 - CommandTimeout tests can fail on fast machines
Change-Id: I7bd4862cb8b3900a2fc41ad7476b2dff6f541009 Signed-off-by: Marc Khouzam <marc.khouzam@ericsson.com> Reviewed-on: https://git.eclipse.org/r/30144
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF2
-rw-r--r--dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java26
-rw-r--r--dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java130
-rw-r--r--dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/ITestConstants.java5
4 files changed, 101 insertions, 62 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
index 02ad924b5b..9629b8d2f9 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
@@ -20,7 +20,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: org.eclipse.cdt.dsf.gdb,
org.eclipse.cdt.dsf.gdb.actions,
org.eclipse.cdt.dsf.gdb.breakpoints,
- org.eclipse.cdt.dsf.gdb.internal;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.debug.gdbjtag.ui",
+ org.eclipse.cdt.dsf.gdb.internal;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.debug.gdbjtag.ui,org.eclipse.cdt.tests.dsf.gdb",
org.eclipse.cdt.dsf.gdb.internal.commands;x-friends:="org.eclipse.cdt.dsf.gdb.ui",
org.eclipse.cdt.dsf.gdb.internal.memory;x-internal:=true,
org.eclipse.cdt.dsf.gdb.internal.service.command.commands;x-internal:=true,
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java
index f98c8a268d..29b4a39f1a 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 Ericsson and others.
+ * Copyright (c) 2007, 2014 Ericsson and others.
* 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
@@ -31,6 +31,7 @@ import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.DsfSession.SessionStartedListener;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
+import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
@@ -215,7 +216,8 @@ public class BaseTestCase {
launchAttributes.put(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, true);
launchAttributes.put(IGDBLaunchConfigurationConstants.ATTR_HOST, "localhost");
launchAttributes.put(IGDBLaunchConfigurationConstants.ATTR_PORT, "9999");
-
+ launchAttributes.put(ITestConstants.LAUNCH_GDB_SERVER, true);
+
setGdbVersion();
// Set the global launch attributes
@@ -236,9 +238,7 @@ public class BaseTestCase {
boolean postMortemLaunch = launchAttributes.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE)
.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE);
- // First check if we should launch gdbserver in the case of a remote session
- if (reallyLaunchGDBServer())
- launchGdbServer();
+ launchGdbServer();
ILaunchManager launchMgr = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType lcType = launchMgr.getLaunchConfigurationType("org.eclipse.cdt.tests.dsf.gdb.TestLaunch");
@@ -315,6 +315,12 @@ public class BaseTestCase {
* If the user specified a different host, things won't work.
*/
private void launchGdbServer() {
+ // First check if we should not launch gdbserver even for a remote session
+ if (launchAttributes.get(ITestConstants.LAUNCH_GDB_SERVER).equals(false)) {
+ System.out.println("Forcing to not start gdbserver for this test");
+ return;
+ }
+
if (launchAttributes.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE)
.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) {
if (launchAttributes.get(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP).equals(Boolean.TRUE)) {
@@ -391,16 +397,6 @@ public class BaseTestCase {
Assume.assumeNoException(e);
}
}
-
- /**
- * In some tests we need to start a gdbserver session without starting gdbserver.
- * This method allows super classes of this class control the launch of gdbserver.
- *
- * @return whether gdbserver should be started
- */
- protected boolean reallyLaunchGDBServer() {
- return true;
- }
@BeforeClass
public static void setGlobalPreferences() {
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java
index 7f30d962e8..b3ff59cf35 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Mentor Graphics and others.
+ * Copyright (c) 2012, 2014 Mentor Graphics and others.
* 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
@@ -7,21 +7,32 @@
*
* Contributors:
* Mentor Graphics - Initial API and implementation
+ * Marc Khouzam (Ericsson) - Update tests to use long timeouts (Bug 439926)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
-import junit.framework.Assert;
-
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.Query;
+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
+import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelect;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
+import org.eclipse.cdt.dsf.service.DsfServicesTracker;
+import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
+import org.eclipse.cdt.tests.dsf.gdb.framework.ServiceEventWaitor;
+import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.debug.core.DebugException;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,9 +42,11 @@ public class CommandTimeoutTest extends BaseTestCase {
private static boolean fgTimeoutEnabled = false;
private static int fgTimeout = IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT;
+ private static boolean fgAutoTerminate;
@BeforeClass
public static void doBeforeClass() throws Exception {
+ // Save the original values of the timeout-related preferences
fgTimeoutEnabled = Platform.getPreferencesService().getBoolean(
GdbPlugin.PLUGIN_ID,
IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT,
@@ -44,99 +57,124 @@ public class CommandTimeoutTest extends BaseTestCase {
IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE,
IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT,
null );
+ fgAutoTerminate = Platform.getPreferencesService().getBoolean(
+ GdbPlugin.PLUGIN_ID,
+ IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB,
+ true,
+ null );
}
-
+
@Override
public void doBeforeTest() throws Exception {
setLaunchAttributes();
// Can't run the launch right away because each test needs to first set some
// parameters. The individual tests will be responsible for starting the launch.
- // Save the original values of the timeout-related preferences
}
@Override
public void doAfterTest() throws Exception {
- // Don't call super here, as the launch is already terminated
+ // Don't call super here, as each test needs to deal with the launch in its own way
- // Restore the timeout preferences
+ // Restore the different preferences we might have changed
IEclipsePreferences node = InstanceScope.INSTANCE.getNode( GdbPlugin.PLUGIN_ID );
node.putBoolean( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, fgTimeoutEnabled );
node.putInt( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, fgTimeout );
- }
-
- protected void performLaunchAndTerminate() throws Exception {
- // perform the launch
- doLaunch();
- // terminate the launch right away
- super.doAfterTest();
- }
-
- @Override
- protected boolean reallyLaunchGDBServer() {
- return false;
+ node.putBoolean( IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB, fgAutoTerminate );
}
/**
- * Enables the timeout support and sets the timeout value to minimal - 1.
- * Launch is expected to timeout on the first gdb command.
+ * Sends a command to which GDB will take a long time to reply, so as to generate a timeout.
+ * This is done after the launch has completed and while the debug session is ongoing.
*/
@Test
- public void firstCommandTimedOut() {
+ public void commandTimedOutDuringSession() throws Exception {
+ // Enable timeout
IEclipsePreferences node = InstanceScope.INSTANCE.getNode( GdbPlugin.PLUGIN_ID );
node.putBoolean( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, true );
- node.putInt( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, 1 );
-
+ node.putInt( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, 2000 );
+
+ // Note that sending a "target-select" command when a program is running will kill the program.
+ // If that triggers us to kill GDB, then our testcase won't have time to timeout.
+ // Therefore we set the preference to keep GDB alive even if the program is no longer running
+ node.putBoolean( IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB, false );
+
+ doLaunch();
+
+ final DsfSession session = getGDBLaunch().getSession();
+ ServiceEventWaitor<ICommandControlShutdownDMEvent> shutdownEventWaitor = new ServiceEventWaitor<ICommandControlShutdownDMEvent>(
+ session,
+ ICommandControlShutdownDMEvent.class);
+
+ // Send the command that will timeout
+ Query<MIInfo> query = new Query<MIInfo>() {
+ @Override
+ protected void execute( DataRequestMonitor<MIInfo> rm ) {
+ DsfServicesTracker tracker = new DsfServicesTracker( TestsPlugin.getBundleContext(), session.getId() );
+ ICommandControlService commandService = tracker.getService( ICommandControlService.class );
+ tracker.dispose();
+ commandService.queueCommand( new MITargetSelect( commandService.getContext(), "localhost", "1", false ), rm );
+ }
+ };
try {
- performLaunchAndTerminate();
- Assert.fail( "Launch is expected to fail" );
+ session.getExecutor().execute( query );
+ query.get();
+ // Cleanup in case the query does not throw the expected exception
+ super.doAfterTest();
+ Assert.fail( "Command is expected to timeout" );
}
catch( Exception e ) {
processException( e );
}
+
+ // Make sure we receive a shutdown event to confirm we have aborted the session
+ shutdownEventWaitor.waitForEvent(TestsPlugin.massageTimeout(5000));
}
/**
- * Tries to connect to gdbserver without starting it.
- * Launch is expected to timeout on "target-remote" command.
+ * Sends a command to which GDB will take a long time to reply, so as to generate a timeout.
+ * This is done during the launch to verify that we properly handle that case.
*/
@Test
- public void remoteConnectionTimedOut() {
- if ( !isRemoteSession() )
- return;
-
+ public void commandTimedOutDuringLaunch() {
+ // Enable timeout
IEclipsePreferences node = InstanceScope.INSTANCE.getNode( GdbPlugin.PLUGIN_ID );
node.putBoolean( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, true );
- node.putInt( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, 1000 );
-
+ node.putInt( IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, 2000 );
+
+ // Setup a remote launch so that it sends a "-target-remote" as part of the
+ // launch steps.
+ setLaunchAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
+ IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE );
+ // We won't start gdbserver, so the command will timeout
+ setLaunchAttribute( ITestConstants.LAUNCH_GDB_SERVER, false);
+
try {
- performLaunchAndTerminate();
+ doLaunch();
+
+ // Cleanup in case the launch does not throw the expected exception
+ super.doAfterTest();
Assert.fail( "Launch is expected to fail" );
}
catch( Exception e ) {
processException( e );
}
}
-
+
/**
* Checks whether the given exception is an instance of {@link CoreException}
* with the status code 20100 which indicates that a gdb command has been timed out.
*/
private void processException( Exception e ) {
- if ( e instanceof DebugException ) {
- Throwable t = getExceptionCause( e );
- Assert.assertTrue(
+ Throwable t = getExceptionCause( e );
+ Assert.assertTrue(
"Unexpected exception",
t instanceof CoreException && ((CoreException)t).getStatus().getCode() == 20100 );
- }
- else {
- Assert.fail( "Unexpected exception type" );
- }
}
private Throwable getExceptionCause(Throwable e) {
Throwable current = e;
- while ( current instanceof CoreException ) {
- Throwable t = ((CoreException)current).getCause();
+ while ( true ) {
+ Throwable t = (current).getCause();
if ( t == null )
break;
current = t;
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/ITestConstants.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/ITestConstants.java
index 679206620b..9470015225 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/ITestConstants.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/ITestConstants.java
@@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
+import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
+
public interface ITestConstants {
public static final String SUFFIX_GDB_6_6 = "6.6";
@@ -25,4 +27,7 @@ public interface ITestConstants {
public static final String SUFFIX_GDB_7_6 = "7.6";
public static final String SUFFIX_GDB_7_7 = "7.7";
public static final String SUFFIX_GDB_7_8 = "7.8";
+
+ // Attribute that allows a test to request not to start gdbserver even if the session is a remote one
+ public static final String LAUNCH_GDB_SERVER = TestsPlugin.PLUGIN_ID + ".launchGdbServer";
}

Back to the top