1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

debug tests: Introduce line "tags" to avoid hardcoding line numbers

Hardcoding line numbers in tests make it a pain to modify the test sources.
The approach adopted in the gdb testsuite is to look for a specific string
in the source file and return the line number where it is found. I made a
similar system for the CDT debug tests.

I dubbed this system breakpoint tags, a tag being the string we look for in
the source file.

I modified the MIRunControlTest as an example, as well as GDBProcessesTest
and MIRegistersTest because they are re-using the same breakpoints.

SOURCE_PATH and EXEC_PATH were duplicated in many test cases, so I factored
them in BaseTestCase.

Change-Id: Id1e64b2064914005ab1d87e16704866aa1c8b9ec
Signed-off-by: Simon Marchi <simon.marchi@polymtl.ca>
Reviewed-on: https://git.eclipse.org/r/36872
Tested-by: Hudson CI
Reviewed-by: Elena Laskavaia <elaskavaia.cdt@gmail.com>
This commit is contained in:
Simon Marchi 2014-11-21 17:28:19 -05:00 committed by Elena Laskavaia
parent c0590c67c1
commit d0e93b665b
5 changed files with 98 additions and 29 deletions

View file

@ -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<String, Integer> 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<String, Object>();
@ -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<String> 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.
*/

View file

@ -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);

View file

@ -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";

View file

@ -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);

View file

@ -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() {