GP-0 Moved most graph tests into integration tests. Corrected failing

graph tests
This commit is contained in:
ghidra1 2021-05-20 16:21:24 -04:00
parent 70675fce99
commit 7c11bb5751
15 changed files with 132 additions and 392 deletions

View File

@ -182,18 +182,45 @@ public class AttributedGraphExportersTest extends AbstractGenericTest {
List<String> lines = doExport(exporter, graph);
assertOutput(lines,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
" <key id=\"key11\" for=\"node\" attr.name=\"Type\" attr.type=\"string\"/>",
" <key id=\"key1\" for=\"node\" attr.name=\"Inverted\" attr.type=\"string\"/>",
" <key id=\"key12\" for=\"node\" attr.name=\"Name\" attr.type=\"string\"/>",
" <key id=\"key17\" for=\"edge\" attr.name=\"EType\" attr.type=\"string\"/>",
" <graph edgedefault=\"directed\">",
" <node id=\"A\"/>",
" <node id=\"B\"/>",
" <node id=\"C\"/>",
" <node id=\"D\"/>",
" <node id=\"E\"/>",
" <node id=\"F\"/>",
" <edge id=\"1\" source=\"A\" target=\"B\"/>",
" <edge id=\"2\" source=\"B\" target=\"C\"/>",
" <edge id=\"3\" source=\"B\" target=\"D\"/>",
" <edge id=\"4\" source=\"C\" target=\"E\"/>",
" <edge id=\"5\" source=\"D\" target=\"E\"/>",
" <node id=\"A\">",
" <data key=\"key11\">X</data>",
" <data key=\"key1\">true</data>",
" <data key=\"key12\">A</data>",
" </node>",
" <node id=\"B\">",
" <data key=\"key11\">Y</data>", " <data key=\"key12\">B</data>",
" </node>",
" <node id=\"C\">",
" <data key=\"key11\">Y</data>", " <data key=\"key12\">C</data>",
" </node>",
" <node id=\"D\">",
" <data key=\"key11\">Y</data>", " <data key=\"key12\">D</data>",
" </node>",
" <node id=\"E\">",
" <data key=\"key11\">Z</data>", " <data key=\"key12\">E</data>",
" </node>", " <node id=\"F\">",
" <data key=\"key11\">T</data>", " <data key=\"key12\">F</data>",
" </node>",
" <edge id=\"1\" source=\"A\" target=\"B\">",
" <data key=\"key17\">Fall</data>",
" </edge>",
" <edge id=\"2\" source=\"B\" target=\"C\">",
" <data key=\"key17\">JMP</data>",
" </edge>",
" <edge id=\"3\" source=\"B\" target=\"D\">",
" <data key=\"key17\">Fall</data>",
" </edge>",
" <edge id=\"4\" source=\"C\" target=\"E\">",
" <data key=\"key17\">Fall</data>",
" </edge>",
" <edge id=\"5\" source=\"D\" target=\"E\">",
" <data key=\"key17\">Call</data>",
" </edge>",
" </graph>",
"</graphml>");

View File

@ -193,22 +193,53 @@ public class GraphExportTest extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testGRAPHML() throws Exception {
List<String> lines = processDialog(new GraphMlGraphExporter());
// @formatter:off
assertOutput(lines,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
" <key id=\"key9\" for=\"node\" attr.name=\"Type\" attr.type=\"string\"/>",
" <key id=\"key1\" for=\"node\" attr.name=\"Inverted\" attr.type=\"string\"/>",
" <key id=\"key10\" for=\"node\" attr.name=\"Name\" attr.type=\"string\"/>",
" <key id=\"key15\" for=\"edge\" attr.name=\"EType\" attr.type=\"string\"/>",
" <graph edgedefault=\"directed\">",
" <node id=\"A\"/>",
" <node id=\"B\"/>",
" <node id=\"C\"/>",
" <node id=\"D\"/>",
" <node id=\"E\"/>",
" <edge id=\"1\" source=\"A\" target=\"B\"/>",
" <edge id=\"2\" source=\"B\" target=\"C\"/>",
" <edge id=\"3\" source=\"B\" target=\"D\"/>",
" <edge id=\"4\" source=\"C\" target=\"E\"/>",
" <edge id=\"5\" source=\"D\" target=\"E\"/>",
" <node id=\"A\">",
" <data key=\"key9\">X</data>",
" <data key=\"key1\">true</data>",
" <data key=\"key10\">A</data>",
" </node>",
" <node id=\"B\">",
" <data key=\"key9\">Y</data>",
" <data key=\"key10\">B</data>",
" </node>",
" <node id=\"C\">",
" <data key=\"key9\">Y</data>",
" <data key=\"key10\">C</data>",
" </node>",
" <node id=\"D\">",
" <data key=\"key9\">Y</data>",
" <data key=\"key10\">D</data>",
" </node>",
" <node id=\"E\">",
" <data key=\"key9\">Z</data>",
" <data key=\"key10\">E</data>",
" </node>",
" <edge id=\"1\" source=\"A\" target=\"B\">",
" <data key=\"key15\">Fall</data>",
" </edge>",
" <edge id=\"2\" source=\"B\" target=\"C\">",
" <data key=\"key15\">JMP</data>",
" </edge>",
" <edge id=\"3\" source=\"B\" target=\"D\">",
" <data key=\"key15\">Fall</data>",
" </edge>",
" <edge id=\"4\" source=\"C\" target=\"E\">",
" <data key=\"key15\">Fall</data>",
" </edge>",
" <edge id=\"5\" source=\"D\" target=\"E\">",
" <data key=\"key15\">Call</data>",
" </edge>",
" </graph>",
"</graphml>");
// @formatter:on
}
@Test

View File

@ -26,9 +26,6 @@ eclipse.project.name = 'Features Graph ProgramGraph'
dependencies {
api project(":Base")
// some tests use classes in SoftwareModeling
testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
helpPath project(path: ":Base", configuration: 'helpPath')
helpPath project(path: ":GraphServices", configuration: 'helpPath')

View File

@ -31,9 +31,11 @@ import ghidra.util.task.TaskMonitor;
*/
public class DataReferenceGraph extends AttributedGraph {
public static final String REF_SOURCE_ATTRIBUTE = "Source";
// TODO: ref/flow type attribute should be consistent with other program graphs
// so that they can be mixed (waiting for standardization)
public static final String REF_TYPE_ATTRIBUTE = "Type";
public static final String REF_SYMBOL_ATTRIBUTE = "Symbol";
public static final String DATA_ATTRIBUTE = "Data Type";
public static final String DATA_ATTRIBUTE = "DataType";
public static final String ADDRESS_ATTRIBUTE = "Address";
public static final String LABEL_ATTRIBUTE = "Label";

View File

@ -1,348 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.graph.export;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.junit.*;
import ghidra.app.plugin.core.blockmodel.BlockModelServicePlugin;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.plugin.core.graph.GraphDisplayBrokerPlugin;
import ghidra.app.services.BlockModelService;
import ghidra.app.services.GraphDisplayBroker;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.PluginException;
import ghidra.graph.exporter.*;
import ghidra.program.database.ProgramDB;
import ghidra.service.graph.*;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import utilities.util.FileUtilities;
public class GraphExportTest extends AbstractGhidraHeadedIntegrationTest {
protected PluginTool tool;
protected ProgramDB program;
protected TestEnv env;
protected BlockModelService blockModelService;
protected CodeBrowserPlugin codeBrowser;
private GraphExporterDialog dialog;
@Before
public void setUp() throws Exception {
setErrorGUIEnabled(false);
env = new TestEnv();
tool = env.getTool();
initializeTool();
GraphDisplayBroker broker = tool.getService(GraphDisplayBroker.class);
GraphDisplayProvider exportProvider = broker.getGraphDisplayProvider("Graph Export");
AttributedGraph graph = createGraph();
GraphDisplay exporter = exportProvider.getGraphDisplay(false, TaskMonitor.DUMMY);
// run in swing so the test is not blocked when we mess with the dialog.
runSwing(() -> setGraph(graph, exporter), false);
waitForSwing();
}
private void setGraph(AttributedGraph graph, GraphDisplay exporter) {
try {
exporter.setGraph(graph, "Test", false, TaskMonitor.DUMMY);
}
catch (CancelledException e) {
// can't happen with dummy
}
}
@After
public void tearDown() {
env.dispose();
}
@Test
public void testCSV() throws Exception {
List<String> lines = processDialog(new CsvEdgeListGraphExporter());
assertOutput(lines,
"A,B",
"B,C",
"B,D",
"C,E",
"D,E");
}
@Test
public void testDIMACS() throws Exception {
List<String> lines = processDialog(new DimacsGraphExporter());
assertOutput(lines,
"c",
"c SOURCE: Generated using the JGraphT library",
"c",
"p edge 5 5",
"e A B",
"e B C",
"e B D",
"e C E",
"e D E");
}
@Test
public void testDOT() throws Exception {
List<String> lines = processDialog(new DotGraphExporter());
assertOutput(lines,
"digraph Ghidra {",
" \"A\" [ Type=\"X\" Inverted=\"true\" Name=\"A\" ];",
" \"B\" [ Type=\"Y\" Name=\"B\" ];",
" \"C\" [ Type=\"Y\" Name=\"C\" ];",
" \"D\" [ Type=\"Y\" Name=\"D\" ];",
" \"E\" [ Type=\"Z\" Name=\"E\" ];",
" \"A\" -> \"B\" [ EType=\"Fall\" ];",
" \"B\" -> \"C\" [ EType=\"JMP\" ];",
" \"B\" -> \"D\" [ EType=\"Fall\" ];",
" \"C\" -> \"E\" [ EType=\"Fall\" ];",
" \"D\" -> \"E\" [ EType=\"Call\" ];",
"}");
}
@Test
public void testGML() throws Exception {
List<String> lines = processDialog(new GmlGraphExporter());
assertOutput(lines,
"Creator \"JGraphT GML Exporter\"",
"Version 1",
"graph",
"[",
" label \"\"",
" directed 1",
" node",
" [",
" id A",
" ]",
" node",
" [",
" id B",
" ]",
" node",
" [",
" id C",
" ]",
" node",
" [",
" id D",
" ]",
" node",
" [",
" id E",
" ]",
" edge",
" [",
" id 1",
" source A",
" target B",
" ]",
" edge",
" [",
" id 2",
" source B",
" target C",
" ]",
" edge",
" [",
" id 3",
" source B",
" target D",
" ]",
" edge",
" [",
" id 4",
" source C",
" target E",
" ]",
" edge",
" [",
" id 5",
" source D",
" target E",
" ]",
"]");
}
@Test
public void testGRAPHML() throws Exception {
List<String> lines = processDialog(new GraphMlGraphExporter());
assertOutput(lines,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
" <graph edgedefault=\"directed\">",
" <node id=\"A\"/>",
" <node id=\"B\"/>",
" <node id=\"C\"/>",
" <node id=\"D\"/>",
" <node id=\"E\"/>",
" <edge id=\"1\" source=\"A\" target=\"B\"/>",
" <edge id=\"2\" source=\"B\" target=\"C\"/>",
" <edge id=\"3\" source=\"B\" target=\"D\"/>",
" <edge id=\"4\" source=\"C\" target=\"E\"/>",
" <edge id=\"5\" source=\"D\" target=\"E\"/>",
" </graph>",
"</graphml>");
}
@Test
public void testJSON() throws Exception {
List<String> lines = processDialog(new JsonGraphExporter());
assertOutput(lines,
"{\"creator\":\"JGraphT JSON Exporter\",\"version\":\"1\",\"nodes\":" +
"[{\"id\":\"A\",\"Type\":\"X\",\"Inverted\":\"true\",\"Name\":\"A\"}," +
"{\"id\":\"B\",\"Type\":\"Y\",\"Name\":\"B\"}," +
"{\"id\":\"C\",\"Type\":\"Y\",\"Name\":\"C\"}," +
"{\"id\":\"D\",\"Type\":\"Y\",\"Name\":\"D\"}," +
"{\"id\":\"E\",\"Type\":\"Z\",\"Name\":\"E\"}]," +
"\"edges\":[{\"id\":\"1\",\"source\":\"A\",\"target\":\"B\",\"EType\":\"Fall\"}," +
"{\"id\":\"2\",\"source\":\"B\",\"target\":\"C\",\"EType\":\"JMP\"}," +
"{\"id\":\"3\",\"source\":\"B\",\"target\":\"D\",\"EType\":\"Fall\"}," +
"{\"id\":\"4\",\"source\":\"C\",\"target\":\"E\",\"EType\":\"Fall\"}," +
"{\"id\":\"5\",\"source\":\"D\",\"target\":\"E\",\"EType\":\"Call\"}]}");
}
@Test
public void testMATRIX() throws Exception {
List<String> lines = processDialog(new MatrixGraphExporter());
assertOutput(lines,
"A B 1",
"B C 1",
"B D 1",
"C E 1",
"D E 1");
}
@Test
public void testVISIO() throws Exception {
List<String> lines = processDialog(new VisioGraphExporter());
assertOutput(lines,
"Shape,A,,A",
"Shape,B,,B",
"Shape,C,,C",
"Shape,D,,D",
"Shape,E,,E",
"Link,A-->B,,,A,B",
"Link,B-->C,,,B,C",
"Link,B-->D,,,B,D",
"Link,C-->E,,,C,E",
"Link,D-->E,,,D,E");
}
protected void initializeTool() throws Exception {
installPlugins();
showTool(tool);
}
protected void installPlugins() throws PluginException {
tool.addPlugin(BlockModelServicePlugin.class.getName());
tool.addPlugin(GraphDisplayBrokerPlugin.class.getName());
}
private List<String> processDialog(AttributedGraphExporter exporter) throws IOException {
dialog = getDialogComponent(GraphExporterDialog.class);
String filePath =
createTempFilePath("GraphExportTest", "." + exporter.getFileExtension());
runSwing(() -> dialog.setOutputFile(filePath));
dialog.setExporter(exporter);
pressButtonByText(dialog, "OK");
List<String> lines = FileUtilities.getLines(new File(filePath));
return lines;
}
private AttributedGraph createGraph() {
AttributedGraph graph = new AttributedGraph();
AttributedVertex vA = graph.addVertex("A");
AttributedVertex vB = graph.addVertex("B");
AttributedVertex vC = graph.addVertex("C");
AttributedVertex vD = graph.addVertex("D");
AttributedVertex vE = graph.addVertex("E");
// A
// |
// B
// / \
// C D
// \ /
// E
AttributedEdge e1 = graph.addEdge(vA, vB);
AttributedEdge e2 = graph.addEdge(vB, vC);
AttributedEdge e3 = graph.addEdge(vB, vD);
AttributedEdge e4 = graph.addEdge(vC, vE);
AttributedEdge e5 = graph.addEdge(vD, vE);
vA.setAttribute("Type", "X");
vB.setAttribute("Type", "Y");
vC.setAttribute("Type", "Y");
vD.setAttribute("Type", "Y");
vE.setAttribute("Type", "Z");
e1.setAttribute("EType", "Fall");
e2.setAttribute("EType", "JMP");
e3.setAttribute("EType", "Fall");
e4.setAttribute("EType", "Fall");
e5.setAttribute("EType", "Call");
vA.setAttribute("Inverted", "true");
return graph;
}
private void printLines(List<String> lines) {
Msg.debug(this, "\n" + testName.getMethodName());
for (String line : lines) {
Msg.debug(this, "\"" + line + "\",");
}
}
private void assertOutput(List<String> actual, String... expected) {
try {
for (int i = 0; i < expected.length; i++) {
if (i >= actual.size()) {
fail(testName.getMethodName() + ": output line " + (i + 1) + ": expected :\"" +
expected[i] +
"\", got: EOF");
}
assertEquals(testName.getMethodName() + ": output line " + (i + 1) + ": ",
expected[i],
actual.get(i));
}
}
catch (Throwable e) {
printLines(actual);
throw e;
}
}
}

View File

@ -20,8 +20,8 @@ import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import ghidra.graph.program.TestGraphDisplay;
import ghidra.graph.program.TestGraphService;
import ghidra.graph.TestGraphDisplay;
import ghidra.graph.TestGraphService;
import ghidra.program.model.data.*;
import ghidra.service.graph.*;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;

View File

@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.graph.program;
package ghidra.graph;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import docking.action.DockingActionIf;
import docking.widgets.EventTrigger;
@ -84,7 +83,12 @@ public class TestGraphDisplay implements GraphDisplay {
public void setGraph(AttributedGraph graph, String title, boolean append,
TaskMonitor monitor)
throws CancelledException {
if (append) {
this.graph = mergeGraphs(graph, this.graph);
}
else {
this.graph = graph;
}
this.title = title;
}
@ -120,4 +124,20 @@ public class TestGraphDisplay implements GraphDisplay {
public void addAction(DockingActionIf action) {
// do nothing, actions are not supported by this display
}
private AttributedGraph mergeGraphs(AttributedGraph newGraph, AttributedGraph oldGraph) {
for (AttributedVertex vertex : oldGraph.vertexSet()) {
newGraph.addVertex(vertex);
}
for (AttributedEdge edge : oldGraph.edgeSet()) {
AttributedVertex from = oldGraph.getEdgeSource(edge);
AttributedVertex to = oldGraph.getEdgeTarget(edge);
AttributedEdge newEdge = newGraph.addEdge(from, to);
Map<String, String> attributeMap = edge.getAttributeMap();
for (String key : attributeMap.keySet()) {
newEdge.setAttribute(key, edge.getAttribute(key));
}
}
return newGraph;
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.graph.program;
package ghidra.graph;
import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool;

View File

@ -23,6 +23,8 @@ import java.util.Set;
import org.junit.Test;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.graph.TestGraphDisplay;
import ghidra.graph.TestGraphService;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.block.CodeBlockModel;
import ghidra.program.util.ProgramLocation;

View File

@ -21,6 +21,8 @@ import java.util.Map;
import org.junit.Test;
import ghidra.graph.TestGraphDisplay;
import ghidra.graph.TestGraphService;
import ghidra.program.model.block.CodeBlockModel;
import ghidra.program.util.ProgramSelection;
import ghidra.service.graph.*;

View File

@ -22,6 +22,8 @@ import java.util.Set;
import org.junit.Test;
import ghidra.graph.TestGraphDisplay;
import ghidra.graph.TestGraphService;
import ghidra.program.model.address.AddressSet;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
@ -38,6 +40,9 @@ public class DataReferenceGraphEventTest extends AbstractDataReferenceGraphTest
super.setUp();
TestGraphService graphService = new TestGraphService();
ProgramLocation location = new ProgramLocation(program, addr(0x01000000));
// env.showTool(program);
DataReferenceGraphTask task = new DataReferenceGraphTask(false, false, tool, null, location,
graphService, 0, 10, DataReferenceGraph.Directions.BOTH_WAYS);

View File

@ -19,6 +19,8 @@ import static org.junit.Assert.*;
import org.junit.Test;
import ghidra.graph.TestGraphDisplay;
import ghidra.graph.TestGraphService;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.service.graph.AttributedEdge;
@ -202,8 +204,8 @@ public class DataReferenceGraphTaskTest extends AbstractDataReferenceGraphTest {
AttributedVertex vertex = graph.getVertex(graph.makeName(addr(0x0100001d)));
assertEquals("pointer_thing", vertex.getAttribute(DataReferenceGraph.DATA_ATTRIBUTE));
assertEquals("0100001d\npointer_thing",
vertex.getAttribute(DataReferenceGraph.LABEL_ATTRIBUTE));
assertEquals("0100001d", vertex.getAttribute(DataReferenceGraph.ADDRESS_ATTRIBUTE));
assertNull(vertex.getAttribute(DataReferenceGraph.LABEL_ATTRIBUTE)); // no label at address
}
@Test