diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseParametrizedTestCase.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseParametrizedTestCase.java index 2a78f0a1a53..7c4da86abd4 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseParametrizedTestCase.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseParametrizedTestCase.java @@ -127,6 +127,22 @@ public abstract class BaseParametrizedTestCase extends BaseTestCase { return getGdbVersion(gdbPath); } + public boolean isGdbVersionAtLeast(String checkVersion) { + String gdbVersion = getGdbVersion(); + if (gdbVersion == GDB_NOT_FOUND) { + return false; + } + + if (checkVersion == null || checkVersion.isEmpty() || checkVersion.equals("default")) + return false; + + if (checkVersion.equals(gdbVersion)) + return true; + + // return if it has to be same of higher + return LaunchUtils.compareVersions(checkVersion, gdbVersion) <= 0; + } + public void assumeGdbVersionAtLeast(String checkVersion) { String gdbVersion = getGdbVersion(); if (gdbVersion == GDB_NOT_FOUND) { 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 47c45b92880..850459b6628 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 @@ -134,6 +134,10 @@ public class BaseTestCase { private HashMap fTagLocations = new HashMap<>(); + // Provides the possibility to override the Debug Services factory and + // override specific service(s) + private static ServiceFactoriesManager fTestDebugServiceFactoriesMgr = new ServiceFactoriesManager(); + /** * Return the launch created when {@link #doLaunch()} was called. */ @@ -740,5 +744,13 @@ public class BaseTestCase { protected void waitUntil(String message, Callable callable) throws Exception { waitUntil(message, callable, TestsPlugin.massageTimeout(2000)); } - + + /** + * @return A Test Debug Service Factories manager which allow individual tests to register + * a specific service factory which can then provide mocked/extended instances of Test Services + */ + public static ServiceFactoriesManager getServiceFactoriesManager() { + return fTestDebugServiceFactoriesMgr; + } + } diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/ServiceFactoriesManager.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/ServiceFactoriesManager.java new file mode 100644 index 00000000000..4874173333f --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/ServiceFactoriesManager.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2017 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 + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.gdb.framework; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory; +import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * This is a Debug Service Factories Manager which keeps track of the factories provided by specific test cases. + * This allow individual tests to override DSF-GDB Services which is sometimes needed to validate different + * code paths. + * + * The test is in charge of providing a unique id for the given factory, however this class will trigger an + * exception if a duplicate id is detected. + * + * This id can then be shared via launch attributes, since each individual test method has its + * own launch configuration there is no possibility to override the launch attributes by other tests + * + * Users can then retrieve/remove the registered factory via the unique factory id provided by the test + */ +public class ServiceFactoriesManager { + public final static String DEBUG_SERVICES_FACTORY_KEY = TestsPlugin.PLUGIN_ID + ".DEBUG_SERVICES_FACTORY"; + + private final Map fTestServiceFactoriesMap = new HashMap<>(); + + public void addTestServicesFactory(String id, GdbDebugServicesFactory servicesFactory) + throws CoreException { + if (fTestServiceFactoriesMap.containsKey(id)) { + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.getUniqueIdentifier(), + "A factory with this id already exists " + id)); + } + + fTestServiceFactoriesMap.put(id, servicesFactory); + } + + public GdbDebugServicesFactory removeTestServicesFactory(String id) { + return fTestServiceFactoriesMap.remove(id); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/launching/TestLaunchDelegate.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/launching/TestLaunchDelegate.java index fcc984254d9..c874ec09f70 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/launching/TestLaunchDelegate.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/launching/TestLaunchDelegate.java @@ -11,7 +11,10 @@ package org.eclipse.cdt.tests.dsf.gdb.launching; import org.eclipse.cdt.dsf.concurrent.ThreadSafe; +import org.eclipse.cdt.dsf.debug.service.IDsfDebugServicesFactory; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; +import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase; +import org.eclipse.cdt.tests.dsf.gdb.framework.ServiceFactoriesManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -62,4 +65,22 @@ public class TestLaunchDelegate extends GdbLaunchDelegate return super.checkBinaryDetails(config); } + @Override + protected IDsfDebugServicesFactory newServiceFactory(ILaunchConfiguration config, String version) { + // Check if this test has registered a services factory for this launch + String servicesFactoryId = null; + try { + servicesFactoryId = config.getAttribute(ServiceFactoriesManager.DEBUG_SERVICES_FACTORY_KEY, ""); + } catch (CoreException e) { + } + + if (servicesFactoryId != null && servicesFactoryId.length() > 0) { + // A services factory has been registered, so lets resolve it and use it + return BaseTestCase.getServiceFactoriesManager() + .removeTestServicesFactory(servicesFactoryId); + } + + // Use the original services factory + return super.newServiceFactory(config, version); + } } \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIModifiedServicesTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIModifiedServicesTest.java new file mode 100644 index 00000000000..c310ce6efc0 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIModifiedServicesTest.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * Copyright (c) 2017 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 + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.gdb.tests; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +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.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory; +import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; +import org.eclipse.cdt.dsf.gdb.service.extensions.GDBBackend_HEAD; +import org.eclipse.cdt.dsf.mi.service.IMIBackend; +import org.eclipse.cdt.dsf.mi.service.IMIProcesses; +import org.eclipse.cdt.dsf.mi.service.IMIRunControl; +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.BaseParametrizedTestCase; +import org.eclipse.cdt.tests.dsf.gdb.framework.ServiceEventWaitor; +import org.eclipse.cdt.tests.dsf.gdb.framework.ServiceFactoriesManager; +import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil; +import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** + * The tests of this class use special versions of services. + */ +@RunWith(Parameterized.class) +public class MIModifiedServicesTest extends BaseParametrizedTestCase { + + private IMIRunControl fRunCtrl; + + private IContainerDMContext fContainerDmc; + private IExecutionDMContext fThreadExecDmc; + private IGDBBackend fBackend; + + /* + * Name of the executable + */ + private static final String EXEC_NAME = "MultiThread.exe"; + private static final String SOURCE_NAME = "MultiThread.cc"; + + /** + * A backend class that disables the full GDB console and uses the basic console instead. + */ + private class TestBackendBasicConsole extends GDBBackend_HEAD { + public TestBackendBasicConsole(DsfSession session, ILaunchConfiguration lc) { + super(session, lc); + } + + @Override + public boolean isFullGdbConsoleSupported() { + return false; + } + } + + /** + * A services factory that uses the test backend service that instantiates + * a basic console instead of a full console. + */ + private class TestServicesFactoryBasicConsole extends GdbDebugServicesFactory { + public TestServicesFactoryBasicConsole(String version, ILaunchConfiguration config) { + super(version, config); + } + + @Override + protected IMIBackend createBackendGDBService(DsfSession session, ILaunchConfiguration lc) { + if (compareVersionWith(GDB_7_12_VERSION) >= 0) { + return new TestBackendBasicConsole(session, lc); + } + return super.createBackendGDBService(session, lc); + } + } + + + @Override + public void doBeforeTest() throws Exception { + removeTeminatedLaunchesBeforeTest(); + 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. + + // Looks up line tags in source file(s). + clearLineTags(); + resolveLineTagLocations(SOURCE_NAME, MIRunControlTest.LINE_TAGS); + } + + @Override + protected void setLaunchAttributes() { + super.setLaunchAttributes(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, EXEC_PATH + EXEC_NAME); + + // This is crude, but effective. We need to determine if the program was + // built with cygwin. The easiest way is to scan the binary file looking + // for 'cygwin1.dll'. In the real world, this wouldn't cut mustard, but + // since this is just testing code, and we control the programs, it's a + // no brainer. + if (runningOnWindows()) { + + // This is interesting. Our tests rely on the working directory. + // That is, we specify a program path in the launch configuration + // that is relative to the working directory. + File file = new File(EXEC_PATH + EXEC_NAME); + + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException e) { + Assert.fail(e.getLocalizedMessage()); + return; // needed to avoid warning at fis usage below + } + + final String MATCH = "cygwin1.dll"; + final int MATCH_LEN = MATCH.length(); + int i = 0; + int ch = 0; + while (true) { + try { + ch = fis.read(); + } catch (IOException e) { + Assert.fail("Problem inspecting file to see if it's a cygwin executable : " + + e.getLocalizedMessage()); + } + if (ch == -1) { // EOF + break; + } + if (ch == MATCH.charAt(i)) { + if (i == MATCH_LEN - 1) { + break; // found it! + } + i++; + } else { + i = 0; + } + } + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + } + } + } + } + + // This method cannot be tagged as @Before, because the launch is not + // running yet. We have to call this manually after all the proper + // parameters have been set for the launch + @Override + protected void doLaunch() throws Exception { + // perform the launch + super.doLaunch(); + + fContainerDmc = SyncUtil.getContainerContext(); + + final DsfSession session = getGDBLaunch().getSession(); + + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + DsfServicesTracker servicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), + session.getId()); + + IMIProcesses procService = servicesTracker.getService(IMIProcesses.class); + IProcessDMContext procDmc = DMContexts.getAncestorOfType(fContainerDmc, IProcessDMContext.class); + IThreadDMContext threadDmc = procService.createThreadContext(procDmc, "1"); + fThreadExecDmc = procService.createExecutionContext(fContainerDmc, threadDmc, "1"); + + fRunCtrl = servicesTracker.getService(IMIRunControl.class); + fBackend = servicesTracker.getService(IGDBBackend.class); + + servicesTracker.dispose(); + + rm.done(); + } + }; + session.getExecutor().execute(query); + query.get(TestsPlugin.massageTimeout(5000), TimeUnit.MILLISECONDS); + + } + + protected void registerServicesFactoryForBasicConsole() throws CoreException { + // Resolve a unique id for the Test Debug services factory + String servicesFactoryId = this.getClass().getName() + "#" + testName.getMethodName(); + + // Register this test case factory + getServiceFactoriesManager().addTestServicesFactory(servicesFactoryId, + new TestServicesFactoryBasicConsole(getGdbVersion(), getLaunchConfiguration())); + + // Register the factory id using a launch attribute, so it can be later resolved + // e.g. by a test launch delegate + setLaunchAttribute(ServiceFactoriesManager.DEBUG_SERVICES_FACTORY_KEY, servicesFactoryId); + } + + private void resumeContainerContextExe() + throws InterruptedException, ExecutionException, TimeoutException { + + final ServiceEventWaitor resumedWaitor = new ServiceEventWaitor( + getGDBLaunch().getSession(), IResumedDMEvent.class); + + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fRunCtrl.resume(fContainerDmc, rm); + } + }; + + fRunCtrl.getExecutor().execute(query); + query.get(TestsPlugin.massageTimeout(5000), TimeUnit.MILLISECONDS); + + try { + resumedWaitor.waitForEvent(TestsPlugin.massageTimeout(5000)); + } catch (Exception e) { + Assert.fail("Exception raised:: " + e.getMessage()); + e.printStackTrace(); + return; + } + + Query querySuspend = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + rm.done(fRunCtrl.isSuspended(fContainerDmc)); + } + }; + + fRunCtrl.getExecutor().execute(querySuspend); + Boolean suspended = querySuspend.get(TestsPlugin.massageTimeout(5000), TimeUnit.MILLISECONDS); + Assert.assertFalse("Target is suspended. It should have been running", suspended); + } + + /** + * Validate we can interrupt via the CLI, This would not be feasible to test in the traditional test + * environment e.g. Linux with GDB 7.12 This test case forces the use of the Basic console which triggers + * async mode off, and will cause the program interrupt via the CLI (rather than MI -exec-interrupt which + * is used with async mode) + * + * Note: This test case uses a modified Test Backend service which is instrumented before test execution, + * see initializeLaunchAttributes + */ + private void interruptRunningTargetExe() + throws InterruptedException, Exception, ExecutionException, TimeoutException { + ServiceEventWaitor suspendedEventWaitor = new ServiceEventWaitor( + getGDBLaunch().getSession(), ISuspendedDMEvent.class); + + Query requestSuspend = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fRunCtrl.suspend(fThreadExecDmc, rm); + } + }; + + fRunCtrl.getExecutor().execute(requestSuspend); + requestSuspend.get(TestsPlugin.massageTimeout(5000), TimeUnit.MILLISECONDS); + + // Wait up to 2 seconds for the target to suspend. Should happen immediately. + suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(2000)); + + // Double check that the target is in the suspended state + Query querySuspend = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + rm.done(fRunCtrl.isSuspended(fContainerDmc)); + } + }; + + fRunCtrl.getExecutor().execute(querySuspend); + Boolean suspended = querySuspend.get(TestsPlugin.massageTimeout(5000), TimeUnit.MILLISECONDS); + + Assert.assertTrue("Target is running. It should have been suspended", suspended); + } + + /** + * Validate that with the basic console, GDB will not accept commands while the target is running. + * This would not be feasible to test with our standard services. This test case forces the use of the Basic + * console by using a test IGDBBackEnd service. + */ + @Test + public void doNotAcceptCommandsWhenTargetRunning_BasicConsole() throws Throwable { + assumeGdbVersionAtLeast(ITestConstants.SUFFIX_GDB_7_12); + + registerServicesFactoryForBasicConsole(); + + doLaunch(); + + // Make sure we are using our test version of IGDBBackEnd + assertTrue("Not using the expected backend service", fBackend instanceof TestBackendBasicConsole); + + resumeContainerContextExe(); + + // Verify that with the basic console, we cannot accept commands when the target is running. + assertFalse("Target should be running with async off, and should NOT be accepting commands", + fRunCtrl.isTargetAcceptingCommands()); + } + + /** + * Validate that with the basic console, interrupting a running target does work. + * This would not be feasible to test with our standard services. + * This test case forces the use of the Basic console by using a test IGDBBackEnd service. + */ + @Test + public void interruptRunningTarget_BasicConsole() throws Throwable { + assumeGdbVersionAtLeast(ITestConstants.SUFFIX_GDB_7_12); + + registerServicesFactoryForBasicConsole(); + + doLaunch(); + + // Make sure we are using our test version of IGDBBackEnd + assertTrue("Not using the expected backend service", fBackend instanceof TestBackendBasicConsole); + + resumeContainerContextExe(); + + interruptRunningTargetExe(); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRunControlTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRunControlTest.java index 90785318395..23602e85bb1 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRunControlTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRunControlTest.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.tests.dsf.gdb.tests; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; @@ -39,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.mi.service.IMIProcesses; @@ -81,6 +83,7 @@ public class MIRunControlTest extends BaseParametrizedTestCase { private IGDBControl fGDBCtrl; private IMIRunControl fRunCtrl; + private IGDBBackend fBackEnd; private IContainerDMContext fContainerDmc; private IExecutionDMContext fThreadExecDmc; @@ -121,6 +124,7 @@ public class MIRunControlTest extends BaseParametrizedTestCase { fThreadExecDmc = procService.createExecutionContext(fContainerDmc, threadDmc, "1"); fRunCtrl = fServicesTracker.getService(IMIRunControl.class); + fBackEnd = fServicesTracker.getService(IGDBBackend.class); } }; session.getExecutor().submit(runnable).get(); @@ -185,6 +189,12 @@ public class MIRunControlTest extends BaseParametrizedTestCase { i = 0; } } + if (fis !=null) { + try { + fis.close(); + } catch (IOException e) { + } + } } } @@ -668,7 +678,17 @@ public class MIRunControlTest extends BaseParametrizedTestCase { Assert.assertFalse("Target is suspended. It should have been running", (Boolean)wait.getReturnInfo()); wait.waitReset(); - } + + // In all-stop mode, MI async is active when the Full GDB console is used + if (fBackEnd.isFullGdbConsoleSupported()) { + assertTrue("Target should be running with async on, and shall be accepting commands", + fRunCtrl.isTargetAcceptingCommands()); + return; + } + + assertFalse("Target should be running with async off, and shall NOT be accepting commands", + fRunCtrl.isTargetAcceptingCommands()); + } @Test public void runToLine() throws Throwable { diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SuiteGdb.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SuiteGdb.java index 1a0c5fd533c..3ff09ce9e8b 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SuiteGdb.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SuiteGdb.java @@ -41,6 +41,7 @@ import org.junit.runners.Suite; SourceLookupTest.class, StepIntoSelectionTest.class, OperationsWhileTargetIsRunningTest.class, + MIModifiedServicesTest.class, MIRunControlTest.class, MIRunControlTargetAvailableTest.class, MIRunControlReverseTest.class,