mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-856: Fixed tests for dbgeng, added tests for dbgmodel
This commit is contained in:
parent
a61c2e1400
commit
f077adfffb
76 changed files with 917 additions and 225 deletions
|
@ -218,7 +218,7 @@ public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectMo
|
|||
|
||||
public void removeExisting(List<String> path) {
|
||||
TargetObject existing = getModelObject(path);
|
||||
// It had better be. This also checks for null
|
||||
// It's best if the implementation has already removed it, but just in case....
|
||||
if (existing == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -230,15 +230,27 @@ public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectMo
|
|||
if (!path.equals(existing.getPath())) {
|
||||
return; // Is a link
|
||||
}
|
||||
if (parent instanceof DefaultTargetObject<?, ?>) { // It had better be
|
||||
DefaultTargetObject<?, ?> dtoParent = (DefaultTargetObject<?, ?>) parent;
|
||||
if (PathUtils.isIndex(path)) {
|
||||
dtoParent.changeElements(List.of(PathUtils.getIndex(path)), List.of(), "Replaced");
|
||||
}
|
||||
else {
|
||||
assert PathUtils.isName(path);
|
||||
dtoParent.changeAttributes(List.of(PathUtils.getKey(path)), Map.of(), "Replaced");
|
||||
}
|
||||
if (!(parent instanceof SpiTargetObject)) { // It had better be
|
||||
Msg.error(this, "Could not remove existing object " + existing +
|
||||
", because parent is not an SpiTargetObject");
|
||||
return;
|
||||
}
|
||||
SpiTargetObject spiParent = (SpiTargetObject) parent;
|
||||
SpiTargetObject delegate = spiParent.getDelegate();
|
||||
if (!(delegate instanceof DefaultTargetObject<?, ?>)) { // It had better be :)
|
||||
Msg.error(this, "Could not remove existing object " + existing +
|
||||
", because its parent's delegate is not a DefaultTargetObject");
|
||||
return;
|
||||
}
|
||||
DefaultTargetObject<?, ?> dtoParent = (DefaultTargetObject<?, ?>) delegate;
|
||||
if (PathUtils.isIndex(path)) {
|
||||
dtoParent.changeElements(List.of(PathUtils.getIndex(path)), List.of(),
|
||||
"Replaced");
|
||||
}
|
||||
else {
|
||||
assert PathUtils.isName(path);
|
||||
dtoParent.changeAttributes(List.of(PathUtils.getKey(path)), Map.of(),
|
||||
"Replaced");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -319,9 +319,9 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
Delta<E, E> delta;
|
||||
synchronized (model.lock) {
|
||||
delta = Delta.computeAndSet(this.elements, elements, Delta.SAME);
|
||||
getSchema().validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateElements(delta.removed, reason);
|
||||
}
|
||||
getSchema().validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateElements(delta.removed, reason);
|
||||
if (!delta.isEmpty()) {
|
||||
updateCallbackElements(delta);
|
||||
listeners.fire.elementsChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
|
@ -361,9 +361,9 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
Delta<E, E> delta;
|
||||
synchronized (model.lock) {
|
||||
delta = Delta.apply(this.elements, remove, add, Delta.SAME);
|
||||
getSchema().validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateElements(delta.removed, reason);
|
||||
}
|
||||
getSchema().validateElementDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateElements(delta.removed, reason);
|
||||
if (!delta.isEmpty()) {
|
||||
updateCallbackElements(delta);
|
||||
listeners.fire.elementsChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
|
@ -497,9 +497,9 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
Delta<Object, ?> delta;
|
||||
synchronized (model.lock) {
|
||||
delta = Delta.computeAndSet(this.attributes, attributes, Delta.EQUAL);
|
||||
getSchema().validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
}
|
||||
getSchema().validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (!delta.isEmpty()) {
|
||||
updateCallbackAttributes(delta);
|
||||
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
|
@ -556,9 +556,9 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
Delta<Object, ?> delta;
|
||||
synchronized (model.lock) {
|
||||
delta = Delta.apply(this.attributes, remove, add, Delta.EQUAL);
|
||||
getSchema().validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
}
|
||||
getSchema().validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (!delta.isEmpty()/* && !reason.equals("Default")*/) {
|
||||
updateCallbackAttributes(delta);
|
||||
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
|
|
|
@ -26,4 +26,13 @@ public interface SpiTargetObject extends TargetObject, InvalidatableTargetObject
|
|||
//Map<String, ? extends SpiTargetObject> getCachedElements();
|
||||
|
||||
boolean enforcesStrictSchema();
|
||||
|
||||
/**
|
||||
* If this internal implementation is a proxy, get its delegate
|
||||
*
|
||||
* @return the delegate, or this same object
|
||||
*/
|
||||
default SpiTargetObject getDelegate() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
package ghidra.dbg.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNotNull;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -150,6 +149,7 @@ public abstract class AbstractDebuggerModelActivationTest extends AbstractDebugg
|
|||
assertActiveViaInterpreter(obj, interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -185,8 +185,8 @@ public abstract class AbstractDebuggerModelActivationTest extends AbstractDebugg
|
|||
m.build();
|
||||
|
||||
TargetFocusScope focusScope = findFocusScope();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
Set<TargetObject> activatable = getActivatableThings();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
for (TargetObject obj : activatable) {
|
||||
activateViaInterpreter(obj, interpreter);
|
||||
retryVoid(() -> {
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
package ghidra.dbg.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNotNull;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -511,8 +510,8 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug
|
|||
assumeTrue(m.hasInterpreter());
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
Set<TargetBreakpointLocation> locs = createLocations();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runToggleTestViaInterpreter(locs.stream()
|
||||
.map(l -> l.getSpecification().as(TargetTogglable.class))
|
||||
.collect(Collectors.toSet()),
|
||||
|
@ -535,8 +534,8 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug
|
|||
assumeTrue(m.hasInterpreter());
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
Set<TargetBreakpointLocation> locs = createLocations();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runToggleTestViaInterpreter(
|
||||
locs.stream().map(l -> l.as(TargetTogglable.class)).collect(Collectors.toSet()),
|
||||
interpreter);
|
||||
|
@ -587,8 +586,8 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug
|
|||
assumeTrue(m.hasInterpreter());
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
Set<TargetBreakpointLocation> locs = createLocations();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runDeleteTestViaInterpreter(locs.stream()
|
||||
.map(l -> l.getSpecification().as(TargetDeletable.class))
|
||||
.collect(Collectors.toSet()),
|
||||
|
|
|
@ -92,13 +92,26 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
*/
|
||||
protected abstract String getKillCommand(TargetProcess process);
|
||||
|
||||
/**
|
||||
* Perform an pre-test actions to ensure an interpreter exists where expected
|
||||
*
|
||||
* <p>
|
||||
* The model will have been built already. This method is invoked immediately preceding
|
||||
* {@link #findInterpreter()}
|
||||
*
|
||||
* @throws Throwable if anything goes wrong
|
||||
*/
|
||||
protected void ensureInterpreterAvailable() throws Throwable {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterpreterIsWhereExpected() throws Throwable {
|
||||
List<String> expectedInterpreterPath = getExpectedInterpreterPath();
|
||||
assumeNotNull(expectedInterpreterPath);
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = m.find(TargetInterpreter.class, List.of());
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
assertEquals(expectedInterpreterPath, interpreter.getPath());
|
||||
}
|
||||
|
||||
|
@ -126,7 +139,8 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
assumeNotNull(cmd);
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = m.find(TargetInterpreter.class, List.of());
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runTestExecute(interpreter, cmd);
|
||||
}
|
||||
|
||||
|
@ -161,7 +175,8 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
assumeNotNull(cmd);
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = m.find(TargetInterpreter.class, List.of());
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runTestExecuteCapture(interpreter, cmd);
|
||||
}
|
||||
|
||||
|
@ -176,7 +191,8 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
assumeNotNull(cmd);
|
||||
m.build();
|
||||
|
||||
TargetInterpreter interpreter = m.find(TargetInterpreter.class, List.of());
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
runTestExecute(interpreter, cmd);
|
||||
}
|
||||
|
||||
|
@ -203,6 +219,7 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
assumeTrue(m.hasProcessContainer());
|
||||
m.build();
|
||||
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
TargetProcess process = runTestLaunchViaInterpreterShowsInProcessContainer(interpreter);
|
||||
|
||||
|
@ -233,6 +250,7 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug
|
|||
m.build();
|
||||
dummy = specimen.runDummy();
|
||||
|
||||
ensureInterpreterAvailable();
|
||||
TargetInterpreter interpreter = findInterpreter();
|
||||
TargetProcess process = runTestAttachViaInterpreterShowsInProcessContainer(interpreter);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package ghidra.dbg.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNotNull;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
@ -109,7 +109,7 @@ public abstract class AbstractDebuggerModelSteppableTest extends AbstractDebugge
|
|||
* @return the window in milliseconds
|
||||
*/
|
||||
protected long getDebounceWindowMs() {
|
||||
return 1000;
|
||||
return 5000;
|
||||
}
|
||||
|
||||
enum CallbackType {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue