GP-0: Fix tests

This commit is contained in:
Dan 2024-04-05 10:15:12 -04:00
parent c63be6d2c3
commit 53e4ce5c30
8 changed files with 59 additions and 17 deletions

View file

@ -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
*/ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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