/******************************************************************************* | |
* Copyright (c) 2009, 2010 Nokia 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: | |
* Nokia - Initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.cdt.debug.edc.debugger.tests; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.concurrent.TimeUnit; | |
import junit.framework.Assert; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.eclipse.cdt.core.IAddress; | |
import org.eclipse.cdt.debug.edc.internal.EDCDebugger; | |
import org.eclipse.cdt.debug.edc.internal.services.dsf.Breakpoints; | |
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl; | |
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; | |
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; | |
import org.eclipse.cdt.debug.edc.services.Stack; | |
import org.eclipse.cdt.debug.edc.tests.EDCTestPlugin; | |
import org.eclipse.cdt.debug.edc.tests.TestReflectionHelper; | |
import org.eclipse.cdt.debug.edc.tests.TestUtils; | |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; | |
import org.eclipse.cdt.dsf.concurrent.Query; | |
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; | |
import org.eclipse.cdt.dsf.datamodel.DMContexts; | |
import org.eclipse.cdt.dsf.debug.service.IStack; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.tm.tcf.services.IRunControl; | |
public class RunControlDMCSubclass extends BaseLaunchTest { | |
private static final String bareDMC_id = "testBareDeviceExcecutionDMC"; //$NON-NLS-1$ | |
private static final String dbg_derived_types_cpp | |
= "C:\\myprog\\BlackFlagWascana\\src\\dbg_derived_types.cpp"; //$NON-NLS-1$ | |
private static final String unitTestRCExeDMCContextException | |
= "unitTestRunControlExecutionDMCContextException"; //$NON-NLS-1$ | |
private RunControl runControlService; | |
private Breakpoints breakpointsService; | |
private IStack stackService; | |
@Override | |
protected String getExeFileName() { | |
// This is the executable built by Cygwin gcc 3.4.4 | |
// All source files are built from this folder: | |
// "C:\\myprog\\BlackFlagWascana\\src\\" | |
// Note we don't need any source file to perform the test. | |
// | |
// used because the locations of certain line numbers are known, | |
// not because there's no hardcoded break | |
return "BlackFlagMinGW_NoHardcodedBreak.exe"; //$NON-NLS-1$ | |
} | |
@Override | |
protected IStack getStackService() { | |
return stackService; | |
} | |
@Override | |
protected boolean getStopAtMain() { | |
return true; | |
} | |
@Before | |
public void launch() throws Exception { | |
basicLaunch(); | |
EDCServicesTracker edcTracker | |
= new EDCServicesTracker(EDCDebugger.getBundleContext(), session.getId()); | |
Assert.assertNotNull(edcTracker); | |
runControlService = edcTracker.getService(RunControl.class); | |
Assert.assertNotNull(runControlService); | |
stackService = edcTracker.getService(Stack.class); | |
Assert.assertNotNull(stackService); | |
breakpointsService = edcTracker.getService(Breakpoints.class); | |
Assert.assertNotNull(breakpointsService); | |
} | |
@After | |
public void shutdown() { | |
threadDMC.purgeFromDebugger(); | |
TestUtils.shutdownDebugSession(launch, session); | |
session = null; | |
} | |
@Test | |
public void testBareDeviceExecutionDMC() throws Exception { | |
Map<String, Object> bdeDMCProps = new HashMap<String, Object>(); | |
bdeDMCProps.put(RunControl.PROP_IS_CONTAINER, false); | |
bdeDMCProps.put(RunControl.BareDeviceExecutionDMC.PROP_ID, bareDMC_id); | |
RunControl.BareDeviceExecutionDMC bdeDMC | |
= runControlService.new BareDeviceExecutionDMC(threadDMC, bdeDMCProps, threadDMC.getTCFContext()); | |
assertNotNull(bdeDMC); | |
assertTrue(bdeDMC.canDetach()); | |
// DMCSuspendedEvent createSuspendedEvent(StateChangeReason reason, Map<String, Object> properties) | |
Map<String, Object> cseProps = new HashMap<String, Object>(); | |
cseProps.put("cseKey1", "cseVal1"); | |
cseProps.put("cseKey2", "cseVal2"); | |
RunControl.StateChangeReason scr = RunControl.StateChangeReason.CONTAINER; | |
Object[] cseArgs = new Object[] {scr, cseProps}; | |
Class<?>[] cseArgClasses = new Class<?>[] {scr.getClass(), Map.class}; | |
RunControl.ContainerSuspendedEvent cse | |
= (RunControl.ContainerSuspendedEvent)TestReflectionHelper | |
.objectFromPrivateFunctionWithArgs(bdeDMC, "createSuspendedEvent", | |
cseArgs, cseArgClasses); | |
assertNotNull(cse); | |
Map<String, Object> cseParams = cse.getParams(); | |
assertNotNull(cseParams); | |
Assert.assertEquals(cseProps, cseParams); | |
RunControl.IExecutionDMContext[] dmc = cse.getTriggeringContexts(); | |
assertNotNull(dmc); | |
assertEquals(1, dmc.length); | |
Assert.assertEquals(bdeDMC, dmc[0]); | |
// protected DMCResumedEvent createResumedEvent() | |
RunControl.ContainerResumedEvent cre | |
= (RunControl.ContainerResumedEvent)TestReflectionHelper | |
.objectFromPrivateFunctionWithArgs(bdeDMC, "createResumedEvent", null); | |
assertNotNull(cre); | |
dmc = cre.getTriggeringContexts(); | |
assertNotNull(dmc); | |
assertEquals(1, dmc.length); | |
Assert.assertEquals(bdeDMC, dmc[0]); | |
} | |
@Test | |
public void testExecutionDMCStepOut() throws Exception { | |
waitRunToLine(runControlService, dbg_derived_types_cpp, 57); | |
// set this so it stops someplace, even if it's after the expected step out point | |
setTempBreakpoint(breakpointsService, dbg_derived_types_cpp, 288); | |
// public abstract class ExectionDMC { protected void stepOut(RequestMonitor) } | |
final Class<?>[] stepOutArgClasses = new Class<?>[] {RequestMonitor.class}; | |
Query<IStatus> query = new Query<IStatus>() { | |
@Override | |
protected void execute(final DataRequestMonitor<IStatus> drm) { | |
ExecutionDMC exeDMC = DMContexts.getAncestorOfType(threadDMC, ExecutionDMC.class); | |
Object[] stepOutArgs = new Object[] {drm}; | |
try { | |
TestReflectionHelper.objectFromPrivateFunctionWithArgs( | |
exeDMC, ExecutionDMC.class, "stepOut", stepOutArgs, stepOutArgClasses); | |
} catch (InvocationTargetException ite) { | |
Throwable t = ite.getTargetException(); | |
if ((t instanceof AssertionError) | |
&& t.getMessage().equals(RunControl.STEP_RETURN_NOT_SUPPORTED)) { | |
drm.setData(new Status(IStatus.INFO, EDCDebugger.PLUGIN_ID, | |
RunControl.STEP_RETURN_NOT_SUPPORTED)); | |
} else { | |
drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID, | |
"InvocationTargetException thrown invoking ExecutionDMC#stepOut() : "//$NON-NLS-1$ | |
+ ite.getLocalizedMessage())); | |
} | |
drm.done(); | |
} catch (Exception e) { | |
drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID, | |
"exception thrown invoking ExecutionDMC#stepOut() : "//$NON-NLS-1$ | |
+ e.getLocalizedMessage())); | |
drm.done(); | |
} | |
} | |
}; | |
try { | |
session.getExecutor().execute(query); | |
} catch (Exception e) { | |
Assert.fail(e.getLocalizedMessage()); | |
} | |
IStatus status = query.get(5, TimeUnit.SECONDS); | |
if (status != null) { | |
assertTrue(status.getSeverity() == IStatus.INFO); | |
assertEquals(RunControl.STEP_RETURN_NOT_SUPPORTED, status.getMessage()); | |
} else { | |
updateSuspendedFrame(200); | |
assertControlIsAt("dbg_derived_types.cpp", "dbg_derived_types", 286); | |
} | |
} | |
@Test | |
public void testRootDMC() { | |
RunControl.RootExecutionDMC rootDMC = runControlService.getRootDMC(); | |
assertNotNull(rootDMC); | |
assertNull(rootDMC.getSymbolDMContext()); | |
assertFalse(rootDMC.canDetach()); | |
assertFalse(rootDMC.canStep()); | |
} | |
@Test | |
public void testThreadDMC() { | |
assertFalse(threadDMC.canDetach()); | |
ExecutionDMC exeDMC = null; | |
try { | |
// first arg is a map of properties, but we expect an immediate assert | |
exeDMC = threadDMC.contextAdded(null, threadDMC.getTCFContext()); | |
} catch (AssertionError ae) { | |
// this is expected | |
} | |
assertNull(exeDMC); | |
} | |
@Test | |
public void unitTestRunControlGetModelData() throws Exception { | |
Query<Boolean> query = new Query<Boolean>() { | |
@Override | |
protected void execute(final DataRequestMonitor<Boolean> drm) { | |
runControlService.getModelData(threadDMC, drm); | |
} | |
}; | |
session.getExecutor().execute(query); | |
query.get(2, TimeUnit.SECONDS); | |
assertTrue(query.isDone()); | |
} | |
@Test | |
public void unitTestRunControlStepIntoOneInstruction() throws Exception { | |
waitRunToLine(runControlService, dbg_derived_types_cpp, 285); | |
// private void stepOverOneInstruction(ExecutionDMC, IAddress, RequestMonitor) | |
final Class<?>[] stepIntoArgClasses = new Class<?>[] {ExecutionDMC.class, RequestMonitor.class}; | |
Query<IStatus> query = new Query<IStatus>() { | |
@Override | |
protected void execute(final DataRequestMonitor<IStatus> drm) { | |
Object[] stepIntoArgs = new Object[] {threadDMC, drm}; | |
try { | |
TestReflectionHelper.objectFromPrivateFunctionWithArgs( | |
runControlService, "stepIntoOneInstruction", stepIntoArgs, stepIntoArgClasses); | |
} catch (Exception e) { | |
drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID, | |
"exception thrown invoking RunControl#stepIntoOneInstruction()"//$NON-NLS-1$ | |
+ e.getLocalizedMessage())); | |
drm.done(); | |
} | |
} | |
}; | |
session.getExecutor().execute(query); | |
query.get(5, TimeUnit.SECONDS); | |
assertTrue(query.isDone()); | |
updateSuspendedFrame(200); | |
assertControlIsAt("dbg_derived_types.cpp", "structs", 40); | |
} | |
@Test | |
public void unitTestRunControlStepOverOneInstruction() throws Exception { | |
waitRunToLine(runControlService, dbg_derived_types_cpp, 285); | |
final IAddress line285Addr = waitGetLineAddress(dbg_derived_types_cpp, 285); | |
final Class<?>[] stepOverArgClasses = new Class<?>[] {ExecutionDMC.class, IAddress.class, RequestMonitor.class}; | |
// private void stepOverOneInstruction(ExecutionDMC, IAddress pcAddress, RequestMonitor) | |
Query<Boolean> query = new Query<Boolean>() { | |
@Override | |
protected void execute(final DataRequestMonitor<Boolean> drm) { | |
Object[] stepOverArgs = new Object[] {threadDMC, line285Addr, drm}; | |
try { | |
TestReflectionHelper.objectFromPrivateFunctionWithArgs( | |
runControlService, "stepOverOneInstruction", stepOverArgs, stepOverArgClasses); | |
} catch (Exception e) { | |
drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID, | |
"exception thrown invoking RunControl#stepOverOneInstruction()"//$NON-NLS-1$ | |
+ e.getLocalizedMessage())); | |
drm.done(); | |
} | |
} | |
}; | |
session.getExecutor().execute(query); | |
query.get(5, TimeUnit.SECONDS); | |
assertTrue(query.isDone()); | |
updateSuspendedFrame(100); | |
assertControlIsAt("dbg_derived_types.cpp", "dbg_derived_types", 286); | |
} | |
@Test | |
public void coverageRunControlGetSteppingStartTime() { | |
long steppingStartTime = RunControl.getSteppingStartTime(); | |
if (RunControl.timeStepping()) { | |
} else { | |
assertEquals(0, steppingStartTime); | |
} | |
} | |
@Test | |
public void coverageRunControlRunListener() throws Exception { | |
IRunControl.RunControlListener runListener | |
= (IRunControl.RunControlListener) | |
TestReflectionHelper.getPrivateField("runListener", runControlService); | |
assertNotNull(runListener); | |
// the following will also test ExecutionDMC#contextException() | |
runListener.contextException(threadDMC.getID(), unitTestRCExeDMCContextException); | |
Thread.sleep(400); // wait a little for the exception to propagate | |
String propMessage = (String)threadDMC.getProperty(RunControl.PROP_MESSAGE); | |
assertEquals(unitTestRCExeDMCContextException, propMessage); | |
// the next 3 are empty and expected to do nothing | |
runListener.containerResumed(null); | |
runListener.containerSuspended(null, null, null, null, null); | |
runListener.contextChanged(null); | |
// resume our thread | |
assertTrue(threadDMC.isSuspended()); | |
runListener.contextResumed(threadDMC.getID()); | |
Thread.sleep(400); // wait a little for it to get re-started | |
assertFalse(threadDMC.isSuspended()); | |
} | |
} |