From d571b6e48a360fc3110e0acd55a3072419272f02 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 28 Mar 2008 15:18:45 +0000 Subject: [PATCH] Fix for the JUnit test due to Bug 223969. The JUnit launch now re-uses (without any changes) the standard DSF launch sequence. The problem then became that the tests would start too fast, before the suspend event was received. To address this, I added a wait for the Suspend event in the BaseTestCase.baseBeforeMethod() which runs before every test. --- .../dd/tests/gdb/framework/BaseTestCase.java | 11 + .../tests/gdb/launching/LaunchSequence.java | 267 ------------------ .../tests/gdb/launching/ShutdownSequence.java | 108 ------- .../gdb/launching/TestLaunchDelegate.java | 28 +- 4 files changed, 33 insertions(+), 381 deletions(-) delete mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java delete mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index 7e86c586dec..9bb59f00fbb 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -16,6 +16,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; @@ -81,6 +82,16 @@ public class BaseTestCase { // Now initialize our SyncUtility, since we have the launcher SyncUtil.initialize(fLaunch.getSession()); + + try { + // Also wait for the program to stop before allowing tests to start + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + fLaunch.getSession(), + MIStoppedEvent.class); + eventWaitor.waitForEvent(10000); + } catch (Exception e) {} + } @After diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java deleted file mode 100644 index ba0357795b6..00000000000 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.tests.gdb.launching; - -import java.util.concurrent.TimeUnit; - -import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; -import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.debug.service.StepQueueManager; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; -import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; -import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; -import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; -import org.eclipse.dd.mi.service.command.output.MIInfo; -import org.eclipse.debug.core.DebugException; - -public class LaunchSequence extends Sequence { - - public class EntryPointHitEventListener { - boolean fAborted = false; - boolean fFinished = false; - final RequestMonitor fRequestMonitor; - - EntryPointHitEventListener(RequestMonitor requestMonitor) { - fRequestMonitor = requestMonitor; - } - - @DsfServiceEventHandler - public void eventDispatched(@SuppressWarnings("unused") - MIStoppedEvent e) { - fFinished = true; - if (!fAborted) { - fSession.removeServiceEventListener(this); - fRequestMonitor.done(); - } - } - } - - - Step[] fSteps = new Step[] { - // Create and initialize the Connection service. - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - // - // Create the connection. - // - fCommandControl = new GDBControl( - fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); - fCommandControl.initialize(requestMonitor); - } - }, - /* - * If needed, insert breakpoint at main and run to it. - */ - new Step() { - private boolean fStopInMain = false; - private String fStopSymbol = null; - - /** - * @return The return value actually indicates whether the get operation succeeded, - * not whether to stop. - */ - private boolean readStopAtMain(RequestMonitor requestMonitor) { - try { - fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - private boolean readStopSymbol(RequestMonitor requestMonitor) { - try { - fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - @Override - public void execute(final RequestMonitor requestMonitor) { - if (!readStopAtMain(requestMonitor)) return; - if (!fStopInMain) { - requestMonitor.done(); - return; - } - - if (!readStopSymbol(requestMonitor)) return; - - // Create a listener to wait for the stopped event, and register as even handler. - // This handler will execute the requestMonitor. - final EntryPointHitEventListener entryPointHitListener = new EntryPointHitEventListener(requestMonitor); - fSession.addServiceEventListener(entryPointHitListener, null); - - // Create a time-out, to abort if breakpoint not hit. - fSession.getExecutor().schedule( - new Runnable() { public void run() { - // Only process the event if we have not finished yet (hit the breakpoint). - if (!entryPointHitListener.fFinished) { - // Mark the listener as aborted, and unregister it as event listener. - entryPointHitListener.fAborted = true; - fSession.removeServiceEventListener(entryPointHitListener); - - // Submit the error result for the step. - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out running to entry point.", null)); //$NON-NLS-1$ - requestMonitor.done(); - } - }}, - 60, TimeUnit.SECONDS); - - // Insert a breakpoint at the requested stop symbol. - fCommandControl.queueCommand( - new MIBreakInsert(fCommandControl.getGDBDMContext(), true, false, null, 0, fStopSymbol, 0), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - - // After the break-insert is done, execute the -exec-run command. - fCommandControl.queueCommand( - new MIExecRun(fCommandControl.getGDBDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - // Note : Do we not need to do something with the original requestMonitor? - // Do nothing. Execution was resumed and the EntryPointHitEventListener - // will resume execution - } - } - ); - } - }); - } - }, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new GDBRunControl(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new StepQueueManager(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIStack(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new ExpressionService(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup = new CSourceLookup(fSession); - fSourceLookup.initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup.setSourceLookupDirector( - fCommandControl.getGDBDMContext(), - ((CSourceLookupDirector)fLaunch.getSourceLocator())); - requestMonitor.done(); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create the low-level breakpoint service - final MIBreakpoints bpService = new MIBreakpoints(fSession); - bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - requestMonitor.done(); - } - }); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create high-level breakpoint service and install breakpoints - // for the GDB debug context. - final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); - bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); - } - }); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIRegisters(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIDisassembly(fSession).initialize(requestMonitor); - }}, - /*new Step() { public void execute(RequestMonitor requestMonitor) { - new GDBVariables(fSession).initialize(requestMonitor); - }},*/ - }; - - final DsfSession fSession; - final GdbLaunch fLaunch; - final IPath fExecPath; - - GDBControl fCommandControl; - CSourceLookup fSourceLookup; - - public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { - super(session.getExecutor()); - fSession = session; - fLaunch = launch; - fExecPath = execPath; - } - - @Override - public Step[] getSteps() { - return fSteps; - } - - private IPath getGDBPath() { - IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ - try { - retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); - } catch (CoreException e) { - } - return retVal; - } - -} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java deleted file mode 100644 index 14357c73502..00000000000 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.tests.gdb.launching; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; - - -public class ShutdownSequence extends Sequence { - - String fSessionId; - String fApplicationName; - String fDebugModelId; - DsfServicesTracker fTracker; - - - public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { - super(executor, requestMonitor); - fSessionId = sessionId; - } - - @Override - public Step[] getSteps() { return fSteps; } - - private final Step[] fSteps = new Step[] { - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - fTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSessionId); - requestMonitor.done(); - } - - @Override - public void rollBack(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - }, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIDisassembly.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }}, - new Step() { - // Uninstall the breakpoints before the service is shut down. - @Override - public void execute(RequestMonitor requestMonitor) { - MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); - GDBControl commandControl = fTracker.getService(GDBControl.class); - if (bpm != null && commandControl != null) { - bpm.stopTrackingBreakpoints(commandControl.getGDBDMContext(), requestMonitor); - } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, - "Needed services not found.", null)); //$NON-NLS-1$ - requestMonitor.done(); - } - } - }, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpointsManager.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpoints.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(CSourceLookup.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(ExpressionService.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIStack.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIMemory.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBRunControl.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBControl.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - }} - }; - - @SuppressWarnings("unchecked") - private void shutdownService(Class clazz, RequestMonitor requestMonitor) { - IDsfService service = fTracker.getService(clazz); - if (service != null) { - service.shutdown(requestMonitor); - } - else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, - "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ - requestMonitor.done(); - } - } -} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 114ee8324c7..aca586a6e29 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -34,9 +34,13 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.launching.FinalLaunchSequence; import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.ServicesLaunchSequence; import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; @@ -104,15 +108,16 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate monitor.worked( 1 ); // Create and invoke the launch sequence to create the debug control and services - final LaunchSequence launchSequence = - new LaunchSequence(launch.getSession(), launch, exePath); - launch.getSession().getExecutor().execute(launchSequence); + // Create and invoke the launch sequence to create the debug control and services + final ServicesLaunchSequence servicesLaunchSequence = + new ServicesLaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(servicesLaunchSequence); try { - launchSequence.get(); + servicesLaunchSequence.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ } launch.initializeControl(); @@ -143,6 +148,17 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ } + // Create and invoke the final launch sequence to setup GDB + final FinalLaunchSequence finalLaunchSequence = + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.RUN); + launch.getSession().getExecutor().execute(finalLaunchSequence); + try { + finalLaunchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ + } // Create a memory retrieval and register it with session try { launch.getDsfExecutor().submit( new Callable() { @@ -151,7 +167,7 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, gdbControl.getGDBDMContext()); + GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); }