mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-0: Fix tests
This commit is contained in:
parent
c63be6d2c3
commit
53e4ce5c30
8 changed files with 59 additions and 17 deletions
|
@ -250,6 +250,18 @@ public interface DebuggerTraceManagerService {
|
||||||
*/
|
*/
|
||||||
void closeTrace(Trace trace);
|
void closeTrace(Trace trace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the given trace without confirmation
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Ordinarily, {@link #closeTrace(Trace)} will prompt the user to confirm termination of live
|
||||||
|
* targets associated with traces to be closed. Such prompts can cause issues during automated
|
||||||
|
* tests.
|
||||||
|
*
|
||||||
|
* @param trace the trace to close
|
||||||
|
*/
|
||||||
|
void closeTraceNoConfirm(Trace trace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all traces
|
* Close all traces
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -546,7 +546,7 @@ public class DebuggerCoordinates {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
return path(object.getCanonicalPath());
|
return path(object.getCanonicalPath());
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("No such object at path" + path);
|
throw new IllegalArgumentException("No such object at path " + newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static TraceThread resolveThread(Target target, TraceObjectKeyPath objectPath) {
|
protected static TraceThread resolveThread(Target target, TraceObjectKeyPath objectPath) {
|
||||||
|
|
|
@ -551,7 +551,14 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||||
if (performElementCellDefaultAction(table)) {
|
if (performElementCellDefaultAction(table)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
performValueRowDefaultAction(elementsTablePanel.getSelectedItem());
|
ValueRow sel = elementsTablePanel.getSelectedItem();
|
||||||
|
if (performValueRowDefaultAction(sel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPath(sel.currentObject().getCanonicalPath(), table, EventOrigin.USER_GENERATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -610,7 +617,14 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||||
implements Adapters.FocusListener, CellActivationListener {
|
implements Adapters.FocusListener, CellActivationListener {
|
||||||
@Override
|
@Override
|
||||||
public void cellActivated(JTable table) {
|
public void cellActivated(JTable table) {
|
||||||
performPathRowDefaultAction(attributesTablePanel.getSelectedItem());
|
PathRow sel = attributesTablePanel.getSelectedItem();
|
||||||
|
if (performPathRowDefaultAction(sel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sel == null || !(sel.getValue() instanceof TraceObject obj)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPath(obj.getCanonicalPath(), table, EventOrigin.USER_GENERATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -449,12 +449,12 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeAllTraces() {
|
public void closeAllTraces() {
|
||||||
checkCloseTraces(getOpenTraces());
|
checkCloseTraces(getOpenTraces(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeOtherTraces(Trace keep) {
|
public void closeOtherTraces(Trace keep) {
|
||||||
checkCloseTraces(getOpenTraces().stream().filter(t -> t != keep).toList());
|
checkCloseTraces(getOpenTraces().stream().filter(t -> t != keep).toList(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -463,7 +463,8 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
? getOpenTraces()
|
? getOpenTraces()
|
||||||
: getOpenTraces().stream()
|
: getOpenTraces().stream()
|
||||||
.filter(t -> targetService.getTarget(t) == null)
|
.filter(t -> targetService.getTarget(t) == null)
|
||||||
.toList());
|
.toList(),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoServiceConsumed
|
@AutoServiceConsumed
|
||||||
|
@ -1026,7 +1027,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkCloseTraces(Collection<Trace> traces) {
|
protected void checkCloseTraces(Collection<Trace> traces, boolean noConfirm) {
|
||||||
List<Target> live =
|
List<Target> live =
|
||||||
traces.stream()
|
traces.stream()
|
||||||
.map(t -> targetService.getTarget(t))
|
.map(t -> targetService.getTarget(t))
|
||||||
|
@ -1037,7 +1038,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
* same thread to avoid a ClosedException.
|
* same thread to avoid a ClosedException.
|
||||||
*/
|
*/
|
||||||
Swing.runIfSwingOrRunLater(() -> {
|
Swing.runIfSwingOrRunLater(() -> {
|
||||||
if (live.isEmpty()) {
|
if (live.isEmpty() || noConfirm) {
|
||||||
doCloseTraces(traces, live);
|
doCloseTraces(traces, live);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1053,12 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeTrace(Trace trace) {
|
public void closeTrace(Trace trace) {
|
||||||
checkCloseTraces(List.of(trace));
|
checkCloseTraces(List.of(trace), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeTraceNoConfirm(Trace trace) {
|
||||||
|
checkCloseTraces(List.of(trace), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -67,6 +67,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
<element schema='Process' />
|
<element schema='Process' />
|
||||||
</schema>
|
</schema>
|
||||||
<schema name='Process' elementResync='NEVER' attributeResync='ONCE'>
|
<schema name='Process' elementResync='NEVER' attributeResync='ONCE'>
|
||||||
|
<interface name='Process' />
|
||||||
|
<interface name='Activatable' />
|
||||||
<attribute name='Threads' schema='ThreadContainer' />
|
<attribute name='Threads' schema='ThreadContainer' />
|
||||||
<attribute name='Handles' schema='HandleContainer' />
|
<attribute name='Handles' schema='HandleContainer' />
|
||||||
</schema>
|
</schema>
|
||||||
|
@ -76,6 +78,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
</schema>
|
</schema>
|
||||||
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
|
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
|
||||||
<interface name='Thread' />
|
<interface name='Thread' />
|
||||||
|
<interface name='Activatable' />
|
||||||
<attribute name='_display' schema='STRING' />
|
<attribute name='_display' schema='STRING' />
|
||||||
<attribute name='_self' schema='Thread' />
|
<attribute name='_self' schema='Thread' />
|
||||||
<attribute name='Stack' schema='Stack' />
|
<attribute name='Stack' schema='Stack' />
|
||||||
|
@ -87,6 +90,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
</schema>
|
</schema>
|
||||||
<schema name='Frame' elementResync='NEVER' attributeResync='NEVER'>
|
<schema name='Frame' elementResync='NEVER' attributeResync='NEVER'>
|
||||||
<interface name='StackFrame' />
|
<interface name='StackFrame' />
|
||||||
|
<interface name='Activatable' />
|
||||||
</schema>
|
</schema>
|
||||||
<schema name='HandleContainer' canonical='yes' elementResync='NEVER'
|
<schema name='HandleContainer' canonical='yes' elementResync='NEVER'
|
||||||
attributeResync='ONCE'>
|
attributeResync='ONCE'>
|
||||||
|
@ -409,26 +413,26 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
|
|
||||||
TraceObjectManager objects = tb.trace.getObjectManager();
|
TraceObjectManager objects = tb.trace.getObjectManager();
|
||||||
TraceObject root = objects.getRootObject();
|
TraceObject root = objects.getRootObject();
|
||||||
TraceObjectKeyPath processesPath = TraceObjectKeyPath.parse("Processes");
|
TraceObjectKeyPath process0Path = TraceObjectKeyPath.parse("Processes[0]");
|
||||||
TraceObject processes = objects.getObjectByCanonicalPath(processesPath);
|
TraceObject process0 = objects.getObjectByCanonicalPath(process0Path);
|
||||||
traceManager.activateObject(root);
|
traceManager.activateObject(root);
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
|
|
||||||
modelProvider.setTreeSelection(processesPath, EventOrigin.USER_GENERATED);
|
modelProvider.setTreeSelection(process0Path, EventOrigin.USER_GENERATED);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
GTree tree = modelProvider.objectsTreePanel.tree;
|
GTree tree = modelProvider.objectsTreePanel.tree;
|
||||||
GTreeNode node = waitForPass(() -> {
|
GTreeNode node = waitForPass(() -> {
|
||||||
GTreeNode n = Unique.assertOne(tree.getSelectedNodes());
|
GTreeNode n = Unique.assertOne(tree.getSelectedNodes());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"Processes@%d".formatted(System.identityHashCode(processes.getCanonicalParent(0))),
|
"[0]@%d".formatted(System.identityHashCode(process0.getCanonicalParent(0))),
|
||||||
n.getName());
|
n.getName());
|
||||||
return n;
|
return n;
|
||||||
});
|
});
|
||||||
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
||||||
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
waitForPass(() -> assertEquals(processes, traceManager.getCurrentObject()));
|
waitForPass(() -> assertEquals(process0, traceManager.getCurrentObject()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -569,8 +573,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
});
|
});
|
||||||
clickTableCell(modelProvider.attributesTablePanel.table, rowIndex, 0, 2);
|
clickTableCell(modelProvider.attributesTablePanel.table, rowIndex, 0, 2);
|
||||||
|
|
||||||
assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads"),
|
// ThreadContainer is not activatable, so only changes provider's path
|
||||||
traceManager.getCurrentObject().getCanonicalPath());
|
assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads"), modelProvider.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -88,6 +88,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
|
||||||
</schema>
|
</schema>
|
||||||
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
|
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
|
||||||
<interface name='Thread' />
|
<interface name='Thread' />
|
||||||
|
<interface name='Activatable' />
|
||||||
</schema>
|
</schema>
|
||||||
</context>""");
|
</context>""");
|
||||||
|
|
||||||
|
|
|
@ -1330,7 +1330,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||||
});
|
});
|
||||||
|
|
||||||
// NOTE: Still recording in the background
|
// NOTE: Still recording in the background
|
||||||
traceManager.closeTrace(trace);
|
traceManager.closeTraceNoConfirm(trace);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(0, breakpointService.getAllBreakpoints().size());
|
assertEquals(0, breakpointService.getAllBreakpoints().size());
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import db.Transaction;
|
import db.Transaction;
|
||||||
import generic.Unique;
|
import generic.Unique;
|
||||||
|
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
|
||||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TestTraceRmiLaunchOpinion.TestTraceRmiLaunchOffer;
|
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TestTraceRmiLaunchOpinion.TestTraceRmiLaunchOffer;
|
||||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin;
|
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin;
|
||||||
import ghidra.app.plugin.core.debug.service.tracermi.TestTraceRmiConnection.TestRemoteMethod;
|
import ghidra.app.plugin.core.debug.service.tracermi.TestTraceRmiConnection.TestRemoteMethod;
|
||||||
|
@ -48,6 +49,10 @@ public class FlatDebuggerRmiAPITest extends AbstractLiveFlatDebuggerAPITest<Flat
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUpRmiTest() throws Throwable {
|
public void setUpRmiTest() throws Throwable {
|
||||||
|
DebuggerListingProvider listingProvider =
|
||||||
|
waitForComponentProvider(DebuggerListingProvider.class);
|
||||||
|
// Auto-reads hang the TaskManager because readMem calls are not expected or answered
|
||||||
|
listingProvider.setAutoReadMemorySpec(readNone);
|
||||||
rmiLaunchPlugin = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
rmiLaunchPlugin = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue