mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-0: Fix timing issues in 2 tests:
BreakpointProviderTest.testActionFilter, ModelProviderTest.testActionShowPrimitives
This commit is contained in:
parent
3aac7dae75
commit
fbd177941e
7 changed files with 83 additions and 35 deletions
|
@ -1060,6 +1060,11 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
changeListeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> changesSettled() {
|
||||
return CompletableFuture.supplyAsync(() -> null, executor);
|
||||
}
|
||||
|
||||
protected MappedLogicalBreakpoint synthesizeLogicalBreakpoint(Program program, Address address,
|
||||
long length, Collection<TraceBreakpointKind> kinds) {
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.service.modules;
|
|||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
@ -596,6 +597,11 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
|||
changeListeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> changesSettled() {
|
||||
return changeDebouncer.settled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEvent(PluginEvent event) {
|
||||
if (event instanceof ProgramOpenedPluginEvent) {
|
||||
|
|
|
@ -147,6 +147,16 @@ public interface DebuggerLogicalBreakpointService {
|
|||
*/
|
||||
void removeChangeListener(LogicalBreakpointsChangeListener l);
|
||||
|
||||
/**
|
||||
* Get a future which completes after pending changes have been processed
|
||||
*
|
||||
* <p>
|
||||
* The returned future completes after all change listeners have been invoked
|
||||
*
|
||||
* @return the future
|
||||
*/
|
||||
CompletableFuture<Void> changesSettled();
|
||||
|
||||
static <T> T programOrTrace(ProgramLocation loc,
|
||||
BiFunction<? super Program, ? super Address, ? extends T> progFunc,
|
||||
BiFunction<? super Trace, ? super Address, ? extends T> traceFunc) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.app.services;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
|
@ -400,6 +401,16 @@ public interface DebuggerStaticMappingService {
|
|||
*/
|
||||
void removeChangeListener(DebuggerStaticMappingChangeListener l);
|
||||
|
||||
/**
|
||||
* Get a future which completes when pending changes have all settled
|
||||
*
|
||||
* <p>
|
||||
* The returned future completes after all change listeners have been invoked.
|
||||
*
|
||||
* @return the future
|
||||
*/
|
||||
CompletableFuture<Void> changesSettled();
|
||||
|
||||
/**
|
||||
* Collect likely matches for destination programs for the given trace module
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@ import static org.junit.Assert.*;
|
|||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -63,12 +64,14 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
protected DebuggerBreakpointsPlugin breakpointsPlugin;
|
||||
protected DebuggerBreakpointsProvider breakpointsProvider;
|
||||
protected DebuggerStaticMappingService mappingService;
|
||||
protected DebuggerLogicalBreakpointService breakpointService;
|
||||
|
||||
@Before
|
||||
public void setUpBreakpointsProviderTest() throws Exception {
|
||||
breakpointsPlugin = addPlugin(tool, DebuggerBreakpointsPlugin.class);
|
||||
breakpointsProvider = waitForComponentProvider(DebuggerBreakpointsProvider.class);
|
||||
mappingService = tool.getService(DebuggerStaticMappingService.class);
|
||||
breakpointService = tool.getService(DebuggerLogicalBreakpointService.class);
|
||||
}
|
||||
|
||||
protected void waitAndFlush(TraceRecorder recorder) throws Throwable {
|
||||
|
@ -538,7 +541,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testActionFilters() throws Exception {
|
||||
public void testActionFilters() throws Throwable {
|
||||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
|
||||
|
@ -561,42 +564,49 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
addLiveBreakpoint(recorder1, 0x55550321);
|
||||
addLiveMemoryAndBreakpoint(mb.testProcess3, recorder3);
|
||||
addLiveBreakpoint(recorder3, 0x55550321);
|
||||
waitRecorder(recorder1);
|
||||
waitRecorder(recorder3);
|
||||
addStaticMemoryAndBreakpoint();
|
||||
// Note, no program breakpoint for 0321...
|
||||
|
||||
programManager.openProgram(program);
|
||||
traceManager.openTrace(trace1);
|
||||
CompletableFuture<Void> mappingsSettled = mappingService.changesSettled();
|
||||
CompletableFuture<Void> breakpointsSettled = breakpointService.changesSettled();
|
||||
traceManager.openTrace(trace3);
|
||||
// Because mapping service debounces, wait for breakpoints to be reconciled
|
||||
waitForSwing();
|
||||
waitOn(mappingsSettled);
|
||||
waitOn(breakpointsSettled);
|
||||
waitForSwing();
|
||||
|
||||
LogicalBreakpointTableModel bptModel = breakpointsProvider.breakpointTableModel;
|
||||
waitForPass(() -> {
|
||||
List<LogicalBreakpointRow> data = copyModelData(bptModel);
|
||||
assertEquals(2, data.size());
|
||||
LogicalBreakpointRow row1 = data.get(0);
|
||||
LogicalBreakpointRow row2 = data.get(1);
|
||||
LogicalBreakpoint lb1 = row1.getLogicalBreakpoint();
|
||||
LogicalBreakpoint lb2 = row2.getLogicalBreakpoint();
|
||||
assertEquals(program, lb1.getProgram());
|
||||
assertEquals(program, lb2.getProgram());
|
||||
assertEquals(addr(program, 0x00400123), lb1.getAddress());
|
||||
assertEquals(addr(program, 0x00400321), lb2.getAddress());
|
||||
assertEquals(Set.of(trace1, trace3), lb1.getParticipatingTraces());
|
||||
assertEquals(Set.of(trace1, trace3), lb2.getParticipatingTraces());
|
||||
|
||||
// Sanity check / experiment: Equal fields, but from different traces
|
||||
TraceBreakpoint bl1t1 = Unique.assertOne(lb1.getTraceBreakpoints(trace1));
|
||||
TraceBreakpoint bl1t3 = Unique.assertOne(lb1.getTraceBreakpoints(trace3));
|
||||
assertNotEquals(bl1t1, bl1t3);
|
||||
List<LogicalBreakpointRow> data = copyModelData(bptModel);
|
||||
assertEquals(2, data.size());
|
||||
LogicalBreakpointRow row1 = data.get(0);
|
||||
LogicalBreakpointRow row2 = data.get(1);
|
||||
LogicalBreakpoint lb1 = row1.getLogicalBreakpoint();
|
||||
LogicalBreakpoint lb2 = row2.getLogicalBreakpoint();
|
||||
assertEquals(program, lb1.getProgram());
|
||||
assertEquals(program, lb2.getProgram());
|
||||
assertEquals(addr(program, 0x00400123), lb1.getAddress());
|
||||
assertEquals(addr(program, 0x00400321), lb2.getAddress());
|
||||
assertEquals(Set.of(trace1, trace3), lb1.getParticipatingTraces());
|
||||
assertEquals(Set.of(trace1, trace3), lb2.getParticipatingTraces());
|
||||
|
||||
// OK, back to work
|
||||
assertEquals(2, lb1.getTraceBreakpoints().size());
|
||||
assertEquals(2, lb2.getTraceBreakpoints().size());
|
||||
});
|
||||
// Sanity check / experiment: Equal fields, but from different traces
|
||||
TraceBreakpoint bl1t1 = Unique.assertOne(lb1.getTraceBreakpoints(trace1));
|
||||
TraceBreakpoint bl1t3 = Unique.assertOne(lb1.getTraceBreakpoints(trace3));
|
||||
assertNotEquals(bl1t1, bl1t3);
|
||||
|
||||
// OK, back to work
|
||||
assertEquals(2, lb1.getTraceBreakpoints().size());
|
||||
assertEquals(2, lb2.getTraceBreakpoints().size());
|
||||
|
||||
List<LogicalBreakpointRow> breakData = copyModelData(bptModel);
|
||||
List<BreakpointLocationRow> filtLocs =
|
||||
breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
|
||||
for (LogicalBreakpointRow breakRow : breakData) {
|
||||
for (LogicalBreakpointRow breakRow : data) {
|
||||
assertEquals(2, breakRow.getLocationCount());
|
||||
}
|
||||
assertEquals(4, filtLocs.size());
|
||||
|
@ -605,9 +615,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
||||
|
||||
// No trace active, so empty :)
|
||||
breakData = bptModel.getModelData();
|
||||
data = copyModelData(bptModel);
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
for (LogicalBreakpointRow breakRow : breakData) {
|
||||
for (LogicalBreakpointRow breakRow : data) {
|
||||
assertEquals(0, breakRow.getLocationCount());
|
||||
}
|
||||
assertEquals(0, filtLocs.size());
|
||||
|
@ -615,9 +625,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
traceManager.activateTrace(trace1);
|
||||
waitForSwing();
|
||||
|
||||
breakData = bptModel.getModelData();
|
||||
data = copyModelData(bptModel);
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
for (LogicalBreakpointRow breakRow : breakData) {
|
||||
for (LogicalBreakpointRow breakRow : data) {
|
||||
assertEquals(1, breakRow.getLocationCount());
|
||||
}
|
||||
assertEquals(2, filtLocs.size());
|
||||
|
@ -626,14 +636,14 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
performAction(breakpointsProvider.actionFilterLocationsByBreakpoints);
|
||||
|
||||
// No breakpoint selected, so no change, yet.
|
||||
breakData = bptModel.getModelData();
|
||||
data = copyModelData(bptModel);
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
for (LogicalBreakpointRow breakRow : breakData) {
|
||||
for (LogicalBreakpointRow breakRow : data) {
|
||||
assertEquals(1, breakRow.getLocationCount());
|
||||
}
|
||||
assertEquals(2, filtLocs.size());
|
||||
|
||||
breakpointsProvider.setSelectedBreakpoints(Set.of(breakData.get(0).getLogicalBreakpoint()));
|
||||
breakpointsProvider.setSelectedBreakpoints(Set.of(data.get(0).getLogicalBreakpoint()));
|
||||
waitForSwing();
|
||||
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
|
@ -642,9 +652,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
assertTrue(breakpointsProvider.actionFilterByCurrentTrace.isEnabled());
|
||||
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
||||
|
||||
breakData = bptModel.getModelData();
|
||||
data = copyModelData(bptModel);
|
||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||
for (LogicalBreakpointRow breakRow : breakData) {
|
||||
for (LogicalBreakpointRow breakRow : data) {
|
||||
assertEquals(2, breakRow.getLocationCount());
|
||||
}
|
||||
assertEquals(2, filtLocs.size());
|
||||
|
|
|
@ -547,16 +547,19 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
|
||||
waitForSwing();
|
||||
|
||||
AbstractNode nodeThread2 = modelProvider.objectsTreePanel.getSelectedItem();
|
||||
AbstractNode nodeThread2 =
|
||||
waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||
assertEquals(1, nodeThread2.getChildren().size());
|
||||
|
||||
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
||||
assertTrue(modelProvider.isShowPrimitivesInTree());
|
||||
nodeThread2 = waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||
assertEquals(3, nodeThread2.getChildren().size());
|
||||
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
||||
|
||||
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
||||
assertFalse(modelProvider.isShowPrimitivesInTree());
|
||||
nodeThread2 = waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||
assertEquals(1, nodeThread2.getChildren().size());
|
||||
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue