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 514bc795cb9..fda09dbd9f0 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 @@ -12,11 +12,16 @@ package org.eclipse.cdt.tests.dsf.gdb.framework; import java.io.BufferedReader; +import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.dsf.datamodel.IDMEvent; @@ -66,6 +71,12 @@ import org.junit.rules.Timeout; */ @SuppressWarnings("restriction") public class BaseTestCase { + /* + * Path to executable + */ + protected static final String EXEC_PATH = "data/launch/bin/"; + protected static final String SOURCE_PATH = "data/launch/src/"; + // Timeout value for each individual test private final static int TEST_TIMEOUT = 5 * 60 * 1000; // 5 minutes in milliseconds @@ -103,6 +114,8 @@ public class BaseTestCase { private static boolean fgStatusHandlersEnabled = true; + private static HashMap fTagLocations = new HashMap<>(); + public GdbLaunch getGDBLaunch() { return fLaunch; } public void setLaunchAttribute(String key, Object value) { @@ -197,8 +210,8 @@ public class BaseTestCase { setLaunchAttributes(); doLaunch(); } - - protected void setLaunchAttributes() { + + protected void setLaunchAttributes() { // Clear all launch attributes before starting a new test launchAttributes = new HashMap(); @@ -225,6 +238,64 @@ public class BaseTestCase { launchAttributes.putAll(globalLaunchAttributes); } + /** + * Given a set of tags (strings) to find in sourceFile, populate the + * fTagLocations map with the line numbers where they are found. + * + * @param sourceName The path of the source file, relative to {@link #SOURCE_PATH}. + * @param tags Strings to find in sourceFile. + * @throws IOException If sourceFile is not found or can't be read. + * @throws RuntimeException If one or more tags are not found in sourceFile. + */ + protected void resolveLineTagLocations(String sourceName, + String... tags) throws IOException { + try (BufferedReader reader = + new BufferedReader(new FileReader(SOURCE_PATH + sourceName))) { + Set tagsToFind = new HashSet<>(Arrays.asList(tags)); + String line; + int lineNumber = 1; + + fTagLocations.clear(); + + line = reader.readLine(); + while (line != null) { + for (String tag : tagsToFind) { + if (line.contains(tag)) { + fTagLocations.put(tag, lineNumber); + tagsToFind.remove(tag); + break; + } + } + + lineNumber++; + line = reader.readLine(); + } + + /* Make sure all tags have been found */ + if (tagsToFind.size() > 0) { + throw new RuntimeException( + "Some tags were not found in " + sourceName); + } + } + } + + /** + * Get the source line number that contains the specified tag. In order to + * get an interesting result, {@link #resolveLineTagLocations} must be + * called prior to calling this function. + * + * @param tag Tag for which to get the source line. + * @return The line number corresponding to tag. + * @throws NoSuchElementException if the tag does not exist. + */ + protected int getLineForTag(String tag) { + if (!fTagLocations.containsKey(tag)) { + throw new NoSuchElementException("tag " + tag); + } + + return fTagLocations.get(tag); + } + /** * Launch GDB. The launch attributes must have been set already. */ diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBProcessesTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBProcessesTest.java index 43f045ef65e..70638b0df3a 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBProcessesTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBProcessesTest.java @@ -40,10 +40,6 @@ import org.junit.runner.RunWith; @RunWith(BackgroundRunner.class) public class GDBProcessesTest extends BaseTestCase { - /* - * Path to executable - */ - private static final String EXEC_PATH = "data/launch/bin/"; /* * Name of the executable */ @@ -64,7 +60,9 @@ public class GDBProcessesTest extends BaseTestCase { @Override public void doBeforeTest() throws Exception { super.doBeforeTest(); - + + resolveLineTagLocations(SOURCE_NAME, MIRunControlTest.LINE_TAGS); + fSession = getGDBLaunch().getSession(); Runnable runnable = new Runnable() { @Override @@ -153,7 +151,7 @@ public class GDBProcessesTest extends BaseTestCase { @Test public void getThreadData() throws Throwable { // Start all threads, stop when they are all started - SyncUtil.runToLine(SOURCE_NAME, MIRunControlTest.LINE_MAIN_ALL_THREADS_STARTED); + SyncUtil.runToLine(SOURCE_NAME, getLineForTag("LINE_MAIN_ALL_THREADS_STARTED")); IThreadDMData mainThreadData = SyncUtil.getThreadData(1); diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java index 1230a7a6f90..f11f359070f 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java @@ -79,7 +79,6 @@ public class MIBreakpointsTest extends BaseTestCase { // Global constants public static final String PLUGIN_ID = "org.eclipse.cdt.debug.core" ; //$NON-NLS-1$ public static final String TEST_APPL = "data/launch/bin/BreakpointTestApp.exe"; //$NON-NLS-1$ - public static final String SOURCE_PATH = "data/launch/src"; //$NON-NLS-1$ public static final String SOURCE_PROJECT = "MIBreakpointsTest"; public static final String SOURCE_FOLDER = "src"; diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRegistersTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRegistersTest.java index 7e154f2ddd7..533ea0328e2 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRegistersTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIRegistersTest.java @@ -116,16 +116,11 @@ public class MIRegistersTest extends BaseTestCase { return fRegisterNames; } - /* - * Path to executable - */ - private static final String EXEC_PATH = "data/launch/bin/"; - /* * Name of the executable */ private static final String EXEC_NAME = "MultiThread.exe"; - private static final String SRC_NAME = "MultiThread.cc"; + private static final String SOURCE_NAME = "MultiThread.cc"; private static final String GROUP_X = "GroupX"; private static final String GROUP_Y = "GroupY"; @@ -143,6 +138,7 @@ public class MIRegistersTest extends BaseTestCase { super.doBeforeTest(); fSession = getGDBLaunch().getSession(); + resolveLineTagLocations(SOURCE_NAME, MIRunControlTest.LINE_TAGS); Runnable runnable = new Runnable() { @Override @@ -368,7 +364,8 @@ public class MIRegistersTest extends BaseTestCase { @Test public void compareRegisterForMultipleExecutionContexts() throws Throwable { - MIStoppedEvent stoppedEvent = SyncUtil.runToLine(SRC_NAME, MIRunControlTest.LINE_MAIN_ALL_THREADS_STARTED); + MIStoppedEvent stoppedEvent = SyncUtil.runToLine(SOURCE_NAME, + getLineForTag("LINE_MAIN_ALL_THREADS_STARTED")); // Get the thread IDs final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(stoppedEvent.getDMContext(), IContainerDMContext.class); 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 ba46f42319c..2a1f439915b 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 @@ -85,15 +85,12 @@ public class MIRunControlTest extends BaseTestCase { private IContainerDMContext fContainerDmc; private IExecutionDMContext fThreadExecDmc; - // line numbers in MultiThread.cc - static final int LINE_MAIN_BEFORE_THREAD_START = 75; // Just before StartThread - static final int LINE_MAIN_AFTER_THREAD_START = 86; // Just after StartThread, where the thread is guaranteed to be started. - static final int LINE_MAIN_ALL_THREADS_STARTED = 92; // Where all threads are guaranteed to be started. - - /* - * Path to executable - */ - private static final String EXEC_PATH = "data/launch/bin/"; + // Breakpoint tags in MultiThread.cc + public static final String[] LINE_TAGS = new String[] { + "LINE_MAIN_BEFORE_THREAD_START", // Just before StartThread + "LINE_MAIN_AFTER_THREAD_START", // Just after StartThread + "LINE_MAIN_ALL_THREADS_STARTED", // Where all threads are guaranteed to be started. + }; /* * Name of the executable @@ -104,7 +101,9 @@ public class MIRunControlTest extends BaseTestCase { @Override public void doBeforeTest() throws Exception { super.doBeforeTest(); - + + resolveLineTagLocations(SOURCE_NAME, LINE_TAGS); + final DsfSession session = getGDBLaunch().getSession(); Runnable runnable = new Runnable() { @@ -275,7 +274,11 @@ public class MIRunControlTest extends BaseTestCase { getGDBLaunch().getSession(), IStartedDMEvent.class); - SyncUtil.runToLine(fContainerDmc, SOURCE_NAME, LINE_MAIN_AFTER_THREAD_START, true); + SyncUtil.runToLine( + fContainerDmc, + SOURCE_NAME, + getLineForTag("LINE_MAIN_AFTER_THREAD_START"), + true); final IContainerDMContext containerDmc = SyncUtil.getContainerContext(); @@ -426,7 +429,8 @@ public class MIRunControlTest extends BaseTestCase { /* * Add a breakpoint */ - SyncUtil.addBreakpoint(SOURCE_NAME + ":" + LINE_MAIN_BEFORE_THREAD_START, false); + SyncUtil.addBreakpoint(SOURCE_NAME + ":" + + getLineForTag("LINE_MAIN_BEFORE_THREAD_START"), false); /* * Resume till the breakpoint is hit @@ -681,7 +685,7 @@ public class MIRunControlTest extends BaseTestCase { @Override public void run() { fRunCtrl.runToLine(fThreadExecDmc, SOURCE_NAME, - LINE_MAIN_ALL_THREADS_STARTED, true, + getLineForTag("LINE_MAIN_ALL_THREADS_STARTED"), true, new RequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() {