diff options
author | John Cortell | 2010-05-27 21:08:28 +0000 |
---|---|---|
committer | John Cortell | 2010-05-27 21:08:28 +0000 |
commit | 87aa0351e6a47969805d2ff8e27b9e14336bf086 (patch) | |
tree | 723840205dc752640cce3699ed9267ee488d5e88 /dsf-gdb | |
parent | c48835544de8e08e71cbdd9c19a1e35e3427b6fb (diff) | |
download | org.eclipse.cdt-87aa0351e6a47969805d2ff8e27b9e14336bf086.tar.gz org.eclipse.cdt-87aa0351e6a47969805d2ff8e27b9e14336bf086.tar.xz org.eclipse.cdt-87aa0351e6a47969805d2ff8e27b9e14336bf086.zip |
Bug 314174: Eliminate the 1s wait at start of each DSF-GDB test.
Diffstat (limited to 'dsf-gdb')
-rw-r--r-- | dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java | 91 |
1 files changed, 73 insertions, 18 deletions
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 cbcc95665f3..01387dc9d46 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 @@ -17,9 +17,14 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent; +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.utils.spawner.ProcessFactory; import org.eclipse.core.runtime.NullProgressMonitor; @@ -31,6 +36,7 @@ import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -51,7 +57,14 @@ public class BaseTestCase { private static Map<String, Object> attrs = new HashMap<String, Object>(); private static Process gdbserverProc = null; - private MIStoppedEvent fInitialStoppedEvent = null; + /** The MI event associated with the breakpoint at main() */ + private MIStoppedEvent fInitialStoppedEvent; + + /** Flag we set to true when the target has reached the breakpoint at main() */ + private boolean fTargetSuspended; + + /** Event semaphore we set when the target has reached the breakpoint at main() */ + final private String fTargetSuspendedSem = new String(); // just used as a semaphore public GdbLaunch getGDBLaunch() { return fLaunch; } @@ -59,7 +72,7 @@ public class BaseTestCase { attrs.put(key, value); } - public MIStoppedEvent getInitialStoppedEvent() { return fInitialStoppedEvent; } + public synchronized MIStoppedEvent getInitialStoppedEvent() { return fInitialStoppedEvent; } @BeforeClass public static void baseBeforeClassMethod() { @@ -96,29 +109,42 @@ public class BaseTestCase { ILaunchConfigurationWorkingCopy lcWorkingCopy = lcType.newInstance( null, - launchMgr.generateUniqueLaunchConfigurationNameFrom("Test Launch")); //$NON-NLS-1$ + launchMgr.generateLaunchConfigurationName("Test Launch")); //$NON-NLS-1$ assert lcWorkingCopy != null; lcWorkingCopy.setAttributes(attrs); final ILaunchConfiguration lc = lcWorkingCopy.doSave(); - assert lc != null; + + // Register ourselves as a listener for the new session so that we can + // register ourselves with that particular session before any events + // occur. We want to find out when the break on main() occurs. + SessionStartedListener sessionStartedListener = new SessionStartedListener() { + public void sessionStarted(DsfSession session) { + session.addServiceEventListener(BaseTestCase.this, null); + } + }; + // Launch the debug session. The session-started listener will be called + // before the launch() call returns (unless, of course, there was a + // problem launching and no session is created). + DsfSession.addSessionStartedListener(sessionStartedListener); fLaunch = (GdbLaunch)lc.launch(ILaunchManager.DEBUG_MODE, new NullProgressMonitor()); - assert fLaunch != null; - - try { - // Also wait for the program to stop before allowing tests to start - // This should be done as soon as we have the launch, to avoid missing the Stopped - // event. If we do miss it, we'll just have a 10 second delay. - final ServiceEventWaitor<MIStoppedEvent> eventWaitor = - new ServiceEventWaitor<MIStoppedEvent>( - fLaunch.getSession(), - MIStoppedEvent.class); - - // In practice, most launches happen within 100-300 milliseconds - fInitialStoppedEvent = eventWaitor.waitForEvent(TestsPlugin.massageTimeout(1000)); - } catch (Exception e) {} + DsfSession.removeSessionStartedListener(sessionStartedListener); + // Wait for the program to hit the breakpoint at main() before + // proceeding. All tests assume that stable initial state. Two + // seconds is plenty; we typically get to that state in a few + // hundred milliseconds with the tiny test programs we use. + synchronized (fTargetSuspendedSem) { + fTargetSuspendedSem.wait(TestsPlugin.massageTimeout(2000)); + Assert.assertTrue(fTargetSuspended); + } + + // This should be a given if the above check passes + synchronized(this) { + Assert.assertNotNull(fInitialStoppedEvent); + } + // If we started a gdbserver add it to the launch to make sure it is killed at the end if (gdbserverProc != null) { DebugPlugin.newProcess(fLaunch, gdbserverProc, "gdbserver"); @@ -129,6 +155,35 @@ public class BaseTestCase { } + /** + * We listen for the target to stop at the main breakpoint. This listener is + * installed when the session is created and we uninstall ourselves when we + * get to the breakpoint state, as we have no further need to monitor events + * beyond that point. + */ + @DsfServiceEventHandler + public void eventDispatched(IDMEvent<?> event) { + if (event instanceof MIStoppedEvent) { + // We get this low-level event first. Record the MI event; various + // tests use it for context + synchronized(this) { + fInitialStoppedEvent = (MIStoppedEvent)event; + } + } + else if (event instanceof ISuspendedDMEvent) { + // We get this higher level event shortly thereafter. We don't want + // to consider the session suspended until we get it. Set the event + // semaphore that will allow the test to proceed + synchronized (fTargetSuspendedSem) { + fTargetSuspended = true; + fTargetSuspendedSem.notify(); + } + + // no further need for this listener + fLaunch.getSession().removeServiceEventListener(BaseTestCase.this); + } + } + @After public void baseAfterMethod() throws Exception { if (fLaunch != null) { |