From f8b8d1ca9b03201e9c8adfa16bc3183e46abc3b0 Mon Sep 17 00:00:00 2001 From: ghidraffe <108089404+ghidraffe@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:47:41 +0000 Subject: [PATCH] GP-4433 add unit tests for project URL --- .../plugin/core/go/GhidraGoPluginTest.java | 163 +++++++++++++++--- 1 file changed, 143 insertions(+), 20 deletions(-) diff --git a/Ghidra/Features/GhidraGo/src/test.slow/java/ghidra/app/plugin/core/go/GhidraGoPluginTest.java b/Ghidra/Features/GhidraGo/src/test.slow/java/ghidra/app/plugin/core/go/GhidraGoPluginTest.java index b05357e063..9ec72834a8 100644 --- a/Ghidra/Features/GhidraGo/src/test.slow/java/ghidra/app/plugin/core/go/GhidraGoPluginTest.java +++ b/Ghidra/Features/GhidraGo/src/test.slow/java/ghidra/app/plugin/core/go/GhidraGoPluginTest.java @@ -29,8 +29,7 @@ import ghidra.GhidraApplicationLayout; import ghidra.GhidraGo; import ghidra.app.plugin.core.go.ipc.CheckForFileProcessedRunnable; import ghidra.app.plugin.core.go.ipc.CheckForListenerRunnable; -import ghidra.framework.model.DomainFile; -import ghidra.framework.model.DomainFolder; +import ghidra.framework.model.*; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.protocol.ghidra.GhidraURL; import ghidra.program.model.listing.Program; @@ -40,33 +39,40 @@ import ghidra.util.task.TaskMonitor; public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { + private final static String DIRECTORY_NAME = getTestDirectoryPath(); + private final static String ACTIVE_PROJECT = "active"; + private final static String INACTIVE_PROJECT = "inactive"; private TestEnv env; private PluginTool tool; private GhidraGo ghidraGo; - private URL url; + private Project inactiveProject; private GhidraApplicationLayout layout; @Before public void setUp() throws Exception { - env = new TestEnv(); + // clean up projects + ProjectTestUtils.deleteProject(DIRECTORY_NAME, ACTIVE_PROJECT); + ProjectTestUtils.deleteProject(DIRECTORY_NAME, INACTIVE_PROJECT); + + // create inactive project if it doesn't exist + ProjectTestUtils.getProject(DIRECTORY_NAME, INACTIVE_PROJECT).close(); + + // add program and folder to inactive project + inactiveProject = ProjectTestUtils.getProject(DIRECTORY_NAME, INACTIVE_PROJECT); + addProgramAndFolderToProject(inactiveProject); + inactiveProject.close(); + + // set up test env and add GhidraGoPlugin to the front end tool. + env = new TestEnv(ACTIVE_PROJECT); tool = env.getFrontEndTool(); tool.addPlugin(GhidraGoPlugin.class.getName()); showTool(tool); - - DomainFolder rootFolder = env.getProject().getProjectData().getRootFolder(); - - Program p = createNotepadProgram(); - - rootFolder.createFile("notepad", p, TaskMonitor.DUMMY); - - env.release(p); - - url = GhidraURL.makeURL(env.getProjectManager().getActiveProject().getProjectLocator(), - "/notepad", null); - layout = (GhidraApplicationLayout) createApplicationLayout(); + addProgramAndFolderToProject(env.getProject()); + + // initialize GhidraGo client ghidraGo = new GhidraGo(); CheckForFileProcessedRunnable.WAIT_FOR_PROCESSING_DELAY_MS = 1000; @@ -78,6 +84,14 @@ public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { CheckForListenerRunnable.WAIT_FOR_LISTENER_PERIOD_MS = 10; } + private void addProgramAndFolderToProject(Project p) throws Exception { + Program program = createNotepadProgram(); + DomainFolder rootFolder = p.getProjectData().getRootFolder(); + rootFolder.createFile("notepad", program, TaskMonitor.DUMMY); + rootFolder.createFolder("testFolder"); + + } + private Program createNotepadProgram() throws Exception { ClassicSampleX86ProgramBuilder builder = new ClassicSampleX86ProgramBuilder("notepad", false, this); @@ -87,11 +101,18 @@ public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { @After public void tearDown() { + ProjectTestUtils.deleteProject(DIRECTORY_NAME, ACTIVE_PROJECT); + ProjectTestUtils.deleteProject(DIRECTORY_NAME, INACTIVE_PROJECT); env.dispose(); } @Test - public void testProcessingUrl() throws Exception { + public void testLaunchingWithProgramUrl() throws Exception { + // given a valid local GhidraURL pointing to a program + URL url = GhidraURL.makeURL(env.getProjectManager().getActiveProject().getProjectLocator(), + "/notepad", null); + + // when ghidraGo is launched with the url Swing.runLater(() -> { try { ghidraGo.launch(layout, new String[] { url.toString() }); @@ -100,6 +121,8 @@ public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { // empty } }); + + // then the code browser should be launched waitForSwing(); waitFor(() -> Arrays.asList(tool.getToolServices().getRunningTools()) .stream() @@ -109,8 +132,9 @@ public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { .stream() .filter(p -> p.getName().equals("CodeBrowser")) .findFirst(); - assertTrue(cb.isPresent()); + + // and the domain file should be open in the code browser assertTrue(Arrays.asList(cb.get().getDomainFiles()) .stream() .map(DomainFile::getName) @@ -118,15 +142,114 @@ public class GhidraGoPluginTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testLaunchingWithInvalidUrl() throws Exception { + public void testLaunchingWithProgramUrlForInactiveProject() throws Exception { + // given a valid local GhidraURL pointing to a program contained within the inactive project + URL url = GhidraURL.makeURL(inactiveProject.getProjectLocator(), "/notepad", null); + + try { + // when ghidraGo is launched with the url + Swing.runLater(() -> { + try { + ghidraGo.launch(layout, new String[] { url.toString() }); + } + catch (Exception e) { + // empty + } + }); + + // then the code browser should be launched + waitForSwing(); + waitFor(() -> Arrays.asList(tool.getToolServices().getRunningTools()) + .stream() + .map(PluginTool::getName) + .anyMatch(Predicate.isEqual("CodeBrowser"))); + Optional cb = Arrays.asList(tool.getToolServices().getRunningTools()) + .stream() + .filter(p -> p.getName().equals("CodeBrowser")) + .findFirst(); + assertTrue(cb.isPresent()); + + // and the domain file should be open in the code browser + assertTrue(Arrays.asList(cb.get().getDomainFiles()) + .stream() + .map(DomainFile::getName) + .anyMatch(Predicate.isEqual("notepad"))); + } + finally { + inactiveProject.close(); + } + + } + + @Test + public void testLaunchingWithFolderUrl() throws Exception { + // given a valid local GhidraURL pointing to a folder within the active project + URL url = GhidraURL.makeURL(env.getProjectManager().getActiveProject().getProjectLocator(), + "/testFolder", null); + + // when ghidraGo is launched with the url Swing.runLater(() -> { try { - ghidraGo.launch(layout, new String[] { "ghidra:/test" }); + ghidraGo.launch(layout, new String[] { url.toString() }); } catch (Exception e) { // empty } }); + + // then the project window should select the folder within the active project data panel + waitForSwing(); + + ProjectLocator[] projViews = env.getProject().getProjectViews(); + Assert.assertEquals(0, projViews.length); + } + + @Test + public void testLaunchingWithFolderUrlForInactiveProject() throws Exception { + // given a valid local GhidraURL pointing to a folder within an in-active project + URL url = + GhidraURL.makeURL(inactiveProject.getProjectLocator(), + "/testFolder", null); + + try { + // when ghidraGo is launched with the url + Swing.runLater(() -> { + try { + ghidraGo.launch(layout, new String[] { url.toString() }); + } + catch (Exception e) { + // empty + } + }); + + // then the project window should select the folder within the viewed project data panel + waitForSwing(); + ProjectLocator[] projViews = env.getProject().getProjectViews(); + Assert.assertEquals(1, projViews.length); + } + finally { + inactiveProject.close(); + } + + } + + @Test + public void testLaunchingWithResourceThatDoesNotExist() throws Exception { + // given a valid local GhidraURL pointing to a program that does not exist + URL url = GhidraURL.makeURL(env.getProjectManager().getActiveProject().getProjectLocator(), + "/test", null); + + // when ghidraGo is launched with the url + Swing.runLater(() -> { + try { + ghidraGo.launch(layout, new String[] { url.toString() }); + } + catch (Exception e) { + // empty + } + }); + + // then an error dialog should be displayed AbstractErrDialog err = waitForErrorDialog(); assertEquals("Content Not Found", err.getTitle()); }