blob: 31bd9124d46829858e77131d623278f67415f426 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2015 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson AB - Initial implementation of Test cases
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
import static org.junit.Assert.fail;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
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.concurrent.Sequence.Step;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseParametrizedTestCase;
import org.eclipse.cdt.tests.dsf.gdb.framework.ServiceEventWaitor;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
/**
* Tests MIRunControl class for for the execWhileTargetAvailable() method.
*/
@RunWith(Parameterized.class)
public class MIRunControlTargetAvailableTest extends BaseParametrizedTestCase {
private static final String TIMEOUT_MESSAGE = "Timeout";
private DsfServicesTracker fServicesTracker;
private IGDBControl fGDBCtrl;
private IMIRunControl fRunCtrl;
private IContainerDMContext fContainerDmc;
/*
* Name of the executable
*/
private static final String EXEC_NAME = "TargetAvail.exe";
@Override
public void doBeforeTest() throws Exception {
super.doBeforeTest();
final DsfSession session = getGDBLaunch().getSession();
Runnable runnable = new Runnable() {
@Override
public void run() {
fServicesTracker =
new DsfServicesTracker(TestsPlugin.getBundleContext(),
session.getId());
fGDBCtrl = fServicesTracker.getService(IGDBControl.class);
fRunCtrl = fServicesTracker.getService(IMIRunControl.class);
}
};
session.getExecutor().submit(runnable).get();
fContainerDmc = SyncUtil.getContainerContext();
}
@Override
public void doAfterTest() throws Exception {
super.doAfterTest();
if (fServicesTracker!=null) fServicesTracker.dispose();
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
EXEC_PATH + EXEC_NAME);
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with a single step when the target is stopped.
*/
@Test
public void executeSingleStepSingleOpWhileTargetStopped() throws Throwable {
// The target is currently stopped.
// A single step that will set a breakpoint at PrintHello, which we will then make sure hits
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
// Now resume the target and check that we stop at the breakpoint.
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
// Wait up to 3 second for the target to suspend. Should happen within 2 second.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with a single step when the target is running.
*/
@Test
public void executeSingleStepSingleOpWhileTargetRunning() throws Throwable {
// A single step that will set a breakpoint at PrintHello, which we will then make sure hits
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
// Now check that the target is stopped at the breakpoint.
// Wait up to 3 second for the target to suspend. Should happen at most in 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with multiple steps when the target is stopped.
*/
@Test
public void executeMultiStepSingleOpWhileTargetStopped() throws Throwable {
// The target is currently stopped.
// Multiple steps that will set three temp breakpoints at three different lines
// We then check that the target will stop three times
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHi", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintBonjour", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
// Now resume the target three times and check that we stop three times.
for (int i=0; i<steps.length; i++) {
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with multiple steps when the target is stopped
* and one of the steps fails.
*/
@Test
public void executeMultiStepSingleOpWhileTargetStoppedWithError() throws Throwable {
// The target is currently stopped.
// Multiple steps that will set three temp breakpoints at three different lines
// We then check that the target will stop three times
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, "invalid condition", 0, "PrintHi", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintBonjour", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
// We want to detect the error, so this is success
return;
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
fail("Did not detect the error of the step");
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with multiple steps when the target is running.
*/
@Test
public void executeMultiStepSingleOpWhileTargetRunning() throws Throwable {
// Multiple steps that will set three temp breakpoints at three different lines
// We then check that the target will stop three times
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHi", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintBonjour", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
// Now resume the target three times and check that we stop three times.
for (int i=0; i<steps.length; i++) {
// Wait up to 3 second for the target to suspend. Should happen within two seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for a single operation with multiple steps when the target is running
* and one of the steps fails.
*/
@Test
public void executeMultiStepSingleOpWhileTargetRunningWithError() throws Throwable {
// Multiple steps that will set three temp breakpoints at three different lines
// We then check that the target will stop three times
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, "invalid condition", 0, "PrintHi", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}},
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintBonjour", "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
boolean caughtError = false;
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
caughtError = true;
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
Assert.assertTrue("Did not catch the error of the step", caughtError);
// Now make sure the target stop of the first breakpoint
// Wait up to 3 second for the target to suspend. Should happen within two seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is stopped.
*/
@Test
public void executeSingleStepConcurrentOpWhileTargetStopped() throws Throwable {
// The target is currently stopped.
final int NUM_CONCURRENT = 3;
String[] locations = { "PrintHello", "PrintHi", "PrintBonjour" };
final Step[][] steps = new Step[NUM_CONCURRENT][1]; // one step for each concurrent operation
for (int i=0; i<steps.length; i++) {
final String location = locations[i];
steps[i] = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
}
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
CountingRequestMonitor crm = new CountingRequestMonitor(fGDBCtrl.getExecutor(), null) {
@Override
protected void handleCompleted() {
rm.done();
};
};
int index;
for (index=0; index<steps.length; index++) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps[index], crm);
}
crm.setDoneCount(index);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<steps.length; i++) {
// Now resume the target and check that we stop at all the breakpoints.
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
// Wait up to 3 second for the target to suspend. Should happen within 2 second.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is running.
*/
@Test
public void executeSingleStepConcurrentOpWhileTargetRunning() throws Throwable {
final int NUM_CONCURRENT = 3;
String[] locations = { "PrintHello", "PrintHi", "PrintBonjour" };
final Step[][] steps = new Step[NUM_CONCURRENT][1]; // one step for each concurrent operation
for (int i=0; i<steps.length; i++) {
final String location = locations[i];
steps[i] = new Step[] {
new Step() {
@Override
public void execute(RequestMonitor rm) {
IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm));
}}
};
}
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
CountingRequestMonitor crm = new CountingRequestMonitor(fGDBCtrl.getExecutor(), null) {
@Override
protected void handleCompleted() {
rm.done();
};
};
int index;
for (index=0; index<steps.length; index++) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps[index], crm);
}
crm.setDoneCount(index);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<steps.length; i++) {
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
// Now resume the target and check that we stop at all the breakpoints.
suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is stopped.
* This tests verifies that we properly handle concurrent operations that are sent
* while other operations are already being run.
*/
@Test
public void executeSingleStepConcurrentButDelayedOpWhileTargetStopped() throws Throwable {
// The target is currently stopped.
final String location = "PrintHello";
final String location2 = "PrintHi";
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor rm) {
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Now that time has elapsed, send another command
fRunCtrl.executeWithTargetAvailable(fContainerDmc, new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor rm) {
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location2, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), null));
}}}, new RequestMonitor(fGDBCtrl.getExecutor(), null));
// Complete the first operation because the two are supposed to be independent
rm.done();
}});
}}
};
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<2; i++) {
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is running.
* This tests verifies that we properly handle concurrent operations that are sent
* while other operations are already being run.
*/
@Test
public void executeSingleStepConcurrentButDelayedOpWhileTargetRunning() throws Throwable {
final String location = "PrintHello";
final String location2 = "PrintHi";
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor rm) {
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Now that time has elapsed, send another command
fRunCtrl.executeWithTargetAvailable(fContainerDmc, new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor otherRm) {
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location2, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), otherRm));
}}}, new RequestMonitor(fGDBCtrl.getExecutor(), null));
// Complete the first operation because the two are supposed to be independent
rm.done();
}});
}}
};
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<2; i++) {
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
// Now resume the target and check that we stop at all the breakpoints.
suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is stopped.
* This tests verifies that we properly handle concurrent operations that are
* dependent on each other; this means that the second operation needs to complete
* for the second one to complete.
*/
@Test
public void executeSingleStepConcurrentAndDependentOpWhileTargetStopped() throws Throwable {
// The target is currently stopped.
final String location = "PrintHello";
final String location2 = "PrintHi";
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor rm) {
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Send another such operation and wait for it to complete to mark the original one as completed
fRunCtrl.executeWithTargetAvailable(fContainerDmc, new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor otherRm) {
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location2, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), otherRm));
}}}, rm);
}});
}}
};
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<2; i++) {
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
}
}
/**
* Test that the executeWhileTargetAvailale interface works properly
* for concurrent operations with a single step when the target is running.
* This tests verifies that we properly handle concurrent operations that are
* dependent on each other; this means that the second operation needs to complete
* for the second one to complete.
*/
@Test
public void executeSingleStepConcurrentAndDependentOpWhileTargetRunning() throws Throwable {
final String location = "PrintHello";
final String location2 = "PrintHi";
final Step[] steps = new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor rm) {
final IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Send another such operation and wait for it to complete to mark the original one as completed
fRunCtrl.executeWithTargetAvailable(fContainerDmc, new Step[] {
new Step() {
@Override
public void execute(final RequestMonitor otherRm) {
fGDBCtrl.queueCommand(
fGDBCtrl.getCommandFactory().createMIBreakInsert(bpTargetDmc, true, false, null, 0, location2, "0"),
new DataRequestMonitor<MIBreakInsertInfo> (fGDBCtrl.getExecutor(), otherRm));
}}}, rm);
}});
}}
};
// The target is currently stopped so we resume it
ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
}
};
try {
fRunCtrl.getExecutor().execute(query);
query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
} catch (ExecutionException e) {
fail(e.getCause().getMessage());
} catch (TimeoutException e) {
fail(TIMEOUT_MESSAGE);
}
for (int i=0; i<2; i++) {
// Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
// Now resume the target and check that we stop at all the breakpoints.
suspendedEventWaitor = new ServiceEventWaitor<ISuspendedDMEvent>(
getGDBLaunch().getSession(),
ISuspendedDMEvent.class);
SyncUtil.resume();
}
}
}