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);
/**
* 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
*/

View file

@ -546,7 +546,7 @@ public class DebuggerCoordinates {
if (object != null) {
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) {

View file

@ -551,7 +551,14 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
if (performElementCellDefaultAction(table)) {
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
@ -610,7 +617,14 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
implements Adapters.FocusListener, CellActivationListener {
@Override
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

View file

@ -449,12 +449,12 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
@Override
public void closeAllTraces() {
checkCloseTraces(getOpenTraces());
checkCloseTraces(getOpenTraces(), false);
}
@Override
public void closeOtherTraces(Trace keep) {
checkCloseTraces(getOpenTraces().stream().filter(t -> t != keep).toList());
checkCloseTraces(getOpenTraces().stream().filter(t -> t != keep).toList(), false);
}
@Override
@ -463,7 +463,8 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
? getOpenTraces()
: getOpenTraces().stream()
.filter(t -> targetService.getTarget(t) == null)
.toList());
.toList(),
false);
}
@AutoServiceConsumed
@ -1026,7 +1027,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
.collect(Collectors.joining("\n"));
}
protected void checkCloseTraces(Collection<Trace> traces) {
protected void checkCloseTraces(Collection<Trace> traces, boolean noConfirm) {
List<Target> live =
traces.stream()
.map(t -> targetService.getTarget(t))
@ -1037,7 +1038,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
* same thread to avoid a ClosedException.
*/
Swing.runIfSwingOrRunLater(() -> {
if (live.isEmpty()) {
if (live.isEmpty() || noConfirm) {
doCloseTraces(traces, live);
return;
}
@ -1052,7 +1053,12 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
@Override
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

View file

@ -67,6 +67,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
<element schema='Process' />
</schema>
<schema name='Process' elementResync='NEVER' attributeResync='ONCE'>
<interface name='Process' />
<interface name='Activatable' />
<attribute name='Threads' schema='ThreadContainer' />
<attribute name='Handles' schema='HandleContainer' />
</schema>
@ -76,6 +78,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
</schema>
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
<interface name='Thread' />
<interface name='Activatable' />
<attribute name='_display' schema='STRING' />
<attribute name='_self' schema='Thread' />
<attribute name='Stack' schema='Stack' />
@ -87,6 +90,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
</schema>
<schema name='Frame' elementResync='NEVER' attributeResync='NEVER'>
<interface name='StackFrame' />
<interface name='Activatable' />
</schema>
<schema name='HandleContainer' canonical='yes' elementResync='NEVER'
attributeResync='ONCE'>
@ -409,26 +413,26 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
TraceObjectManager objects = tb.trace.getObjectManager();
TraceObject root = objects.getRootObject();
TraceObjectKeyPath processesPath = TraceObjectKeyPath.parse("Processes");
TraceObject processes = objects.getObjectByCanonicalPath(processesPath);
TraceObjectKeyPath process0Path = TraceObjectKeyPath.parse("Processes[0]");
TraceObject process0 = objects.getObjectByCanonicalPath(process0Path);
traceManager.activateObject(root);
waitForTasks();
modelProvider.setTreeSelection(processesPath, EventOrigin.USER_GENERATED);
modelProvider.setTreeSelection(process0Path, EventOrigin.USER_GENERATED);
waitForSwing();
GTree tree = modelProvider.objectsTreePanel.tree;
GTreeNode node = waitForPass(() -> {
GTreeNode n = Unique.assertOne(tree.getSelectedNodes());
assertEquals(
"Processes@%d".formatted(System.identityHashCode(processes.getCanonicalParent(0))),
"[0]@%d".formatted(System.identityHashCode(process0.getCanonicalParent(0))),
n.getName());
return n;
});
clickTreeNode(tree, node, MouseEvent.BUTTON1);
clickTreeNode(tree, node, MouseEvent.BUTTON1);
waitForSwing();
waitForPass(() -> assertEquals(processes, traceManager.getCurrentObject()));
waitForPass(() -> assertEquals(process0, traceManager.getCurrentObject()));
}
@Test
@ -569,8 +573,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
});
clickTableCell(modelProvider.attributesTablePanel.table, rowIndex, 0, 2);
assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads"),
traceManager.getCurrentObject().getCanonicalPath());
// ThreadContainer is not activatable, so only changes provider's path
assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads"), modelProvider.getPath());
}
@Test

View file

@ -88,6 +88,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
</schema>
<schema name='Thread' elementResync='NEVER' attributeResync='NEVER'>
<interface name='Thread' />
<interface name='Activatable' />
</schema>
</context>""");

View file

@ -1330,7 +1330,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
});
// NOTE: Still recording in the background
traceManager.closeTrace(trace);
traceManager.closeTraceNoConfirm(trace);
waitForSwing();
assertEquals(0, breakpointService.getAllBreakpoints().size());

View file

@ -26,6 +26,7 @@ import org.junit.Test;
import db.Transaction;
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.TraceRmiLauncherServicePlugin;
import ghidra.app.plugin.core.debug.service.tracermi.TestTraceRmiConnection.TestRemoteMethod;
@ -48,6 +49,10 @@ public class FlatDebuggerRmiAPITest extends AbstractLiveFlatDebuggerAPITest<Flat
@Before
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);
}