mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 14:54:29 +08:00
Merge remote-tracking branch 'origin/GP-5907-5908_ghidra1_ProjectTreeUpdateAndDelete--SQUASHED'
This commit is contained in:
+1
-2
@@ -526,7 +526,6 @@ public class ProjectCopyPasteFromRepositoryTest extends AbstractGhidraHeadedInte
|
||||
// of folder or another folder-link-file at the referenced location
|
||||
//
|
||||
String urlPath = sharedFolderURL.toExternalForm(); // will end with '/'
|
||||
urlPath = urlPath.substring(0, urlPath.length() - 1); // strip trailing '/'
|
||||
|
||||
assertEquals(urlPath, linkInfo.getLinkPath());
|
||||
|
||||
@@ -593,7 +592,7 @@ public class ProjectCopyPasteFromRepositoryTest extends AbstractGhidraHeadedInte
|
||||
viewTreeHelper.getDomainFileActionContext(f1LinkFile);
|
||||
|
||||
URL sharedFolderURL = GhidraURL.makeURL("localhost", ServerTestUtil.GHIDRA_TEST_SERVER_PORT,
|
||||
"Test", "/f1Link", null);
|
||||
"Test", "/f1Link/", null);
|
||||
|
||||
DockingActionIf copyAction = getAction(env.getFrontEndTool(), "Copy");
|
||||
assertNotNull("Copy action not found", copyAction);
|
||||
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
/* ###
|
||||
* 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.framework.main.datatree;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.framework.data.FolderLinkContentHandler;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.program.database.ProgramLinkContentHandler;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.*;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class ProjectDataTreeTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
private FrontEndTestEnv env;
|
||||
|
||||
private DomainFile programAFile;
|
||||
|
||||
private Program program;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
env = new FrontEndTestEnv();
|
||||
program = ToyProgramBuilder.buildSimpleProgram("foo", this);
|
||||
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
programAFile = rootFolder.getFile("Program_A");
|
||||
assertNotNull(programAFile);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (program != null) {
|
||||
program.release(this);
|
||||
}
|
||||
env.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkFileUpdate() throws Exception {
|
||||
|
||||
GTree tree = env.getTree();
|
||||
GTreeNode modelRoot = tree.getModelRoot();
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
|
||||
DomainFolder aFolder = rootFolder.createFolder("A");
|
||||
|
||||
// file link created before referenced file
|
||||
aFolder.createLinkFile(rootFolder.getProjectData(), "/A/x", true, "y",
|
||||
ProgramLinkContentHandler.INSTANCE);
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/A", false, "B",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("A")));
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("B")));
|
||||
env.waitForTree();
|
||||
|
||||
// Add file 'x' while folder A and linked-folder B are both expanded
|
||||
aFolder.createFile("x", program, TaskMonitor.DUMMY);
|
||||
program.release(this);
|
||||
program = null;
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
//
|
||||
// Verify good state after everything created
|
||||
//
|
||||
// /A
|
||||
// x
|
||||
// y -> x
|
||||
// /B -> /A (linked-folder)
|
||||
// x
|
||||
// y -> x
|
||||
//
|
||||
|
||||
DomainFolderNode aFolderNode = (DomainFolderNode) modelRoot.getChild("A");
|
||||
DomainFileNode xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
DomainFileNode yNode = (DomainFileNode) aFolderNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
String tip = yNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
DomainFileNode bFolderLinkNode = (DomainFileNode) modelRoot.getChild("B");
|
||||
yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
// Remove 'x' file and verify broken links are reflected
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
xNode.getDomainFile().delete();
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
assertNull(aFolderNode.getChild("x"));
|
||||
|
||||
yNode = (DomainFileNode) aFolderNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNull(xNode);
|
||||
|
||||
yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkFileUpdate1() throws Exception {
|
||||
|
||||
GTree tree = env.getTree();
|
||||
GTreeNode modelRoot = tree.getModelRoot();
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
|
||||
DomainFolder aFolder = rootFolder.createFolder("A");
|
||||
|
||||
// file link created before referenced file
|
||||
aFolder.createLinkFile(rootFolder.getProjectData(), "/A/x", true, "y",
|
||||
ProgramLinkContentHandler.INSTANCE);
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("A")));
|
||||
env.waitForTree();
|
||||
|
||||
// Add file 'x' before folder A and is expanded and linked-folder B is not
|
||||
aFolder.createFile("x", program, TaskMonitor.DUMMY);
|
||||
program.release(this);
|
||||
program = null;
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/A", false, "B",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
env.waitForTree();
|
||||
|
||||
DomainFileNode bFolderLinkNode = (DomainFileNode) modelRoot.getChild("B");
|
||||
Swing.runNow(() -> tree.expandPath(bFolderLinkNode));
|
||||
env.waitForTree();
|
||||
|
||||
//
|
||||
// Verify good state after everything created
|
||||
//
|
||||
// /A
|
||||
// x
|
||||
// y -> x
|
||||
// /B -> /A (linked-folder)
|
||||
// x
|
||||
// y -> x
|
||||
//
|
||||
|
||||
DomainFolderNode aFolderNode = (DomainFolderNode) modelRoot.getChild("A");
|
||||
DomainFileNode xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
DomainFileNode yNode = (DomainFileNode) aFolderNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
String tip = yNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
// Remove 'x' file and verify broken links are reflected
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
xNode.getDomainFile().delete();
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
assertNull(aFolderNode.getChild("x"));
|
||||
|
||||
yNode = (DomainFileNode) aFolderNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
xNode = (DomainFileNode) aFolderNode.getChild("x");
|
||||
assertNull(xNode);
|
||||
|
||||
yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkFileUpdate2() throws Exception {
|
||||
|
||||
GTree tree = env.getTree();
|
||||
GTreeNode modelRoot = tree.getModelRoot();
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
|
||||
DomainFolder aFolder = rootFolder.createFolder("A");
|
||||
|
||||
// file link created before referenced file
|
||||
aFolder.createLinkFile(rootFolder.getProjectData(), "/A/x", true, "y",
|
||||
ProgramLinkContentHandler.INSTANCE);
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/A", false, "B",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
env.waitForTree();
|
||||
|
||||
DomainFileNode bFolderLinkNode = (DomainFileNode) modelRoot.getChild("B");
|
||||
Swing.runNow(() -> tree.expandPath(bFolderLinkNode));
|
||||
env.waitForTree();
|
||||
|
||||
// Add file 'x' while linked-folder B is expanded and folder A is not
|
||||
DomainFile xFile = aFolder.createFile("x", program, TaskMonitor.DUMMY);
|
||||
program.release(this);
|
||||
program = null;
|
||||
env.waitForTree();
|
||||
|
||||
//// Verify good state after everything created (leave A collapsed)
|
||||
|
||||
DomainFileNode xNode = (DomainFileNode) bFolderLinkNode.getChild("x");
|
||||
assertNotNull(xNode);
|
||||
|
||||
DomainFileNode yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
String tip = yNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
//// Remove 'x' file
|
||||
|
||||
xFile.delete();
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
assertNull(bFolderLinkNode.getChild("x"));
|
||||
|
||||
yNode = (DomainFileNode) bFolderLinkNode.getChild("y");
|
||||
assertNotNull(yNode);
|
||||
waitForRefresh(yNode);
|
||||
|
||||
tip = yNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkFileUpdate3() throws Exception {
|
||||
|
||||
GTree tree = env.getTree();
|
||||
GTreeNode modelRoot = tree.getModelRoot();
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/usr/bin", false, "bin",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
|
||||
DomainFolder usrBinFolder = rootFolder.createFolder("usr").createFolder("bin");
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("usr")));
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("usr").getChild("bin")));
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("bin")));
|
||||
env.waitForTree();
|
||||
|
||||
// Add file 'bash'
|
||||
DomainFile bashFile = usrBinFolder.createFile("bash", program, TaskMonitor.DUMMY);
|
||||
program.release(this);
|
||||
program = null;
|
||||
env.waitForTree();
|
||||
|
||||
DomainFileNode binFolderLinkNode = (DomainFileNode) modelRoot.getChild("bin");
|
||||
assertNotNull(binFolderLinkNode.getChild("bash"));
|
||||
|
||||
//
|
||||
// /bin -> /usr/bin (linked folder)
|
||||
// bash
|
||||
// /usr
|
||||
// /bin
|
||||
// bash
|
||||
//
|
||||
|
||||
// Delete real folders and content
|
||||
bashFile.delete();
|
||||
usrBinFolder.delete(); // /usr/bin
|
||||
rootFolder.getFolder("usr").delete();
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
assertNull(binFolderLinkNode.getChild("bash"));
|
||||
|
||||
waitForRefresh(binFolderLinkNode);
|
||||
env.waitForTree();
|
||||
|
||||
String tip = binFolderLinkNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
|
||||
// binLinkFile.delete();
|
||||
env.waitForTree();
|
||||
|
||||
// Re-create content
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/usr/bin", false, "bin",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
|
||||
usrBinFolder = rootFolder.createFolder("usr").createFolder("bin");
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("usr")));
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("usr").getChild("bin")));
|
||||
env.waitForTree();
|
||||
|
||||
Swing.runNow(() -> tree.expandPath(modelRoot.getChild("bin")));
|
||||
env.waitForTree();
|
||||
|
||||
program = (Program) programAFile.getDomainObject(this, false, false, TaskMonitor.DUMMY);
|
||||
assertNotNull(program);
|
||||
usrBinFolder.createFile("bash", program, TaskMonitor.DUMMY);
|
||||
program.release(this);
|
||||
program = null;
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
DomainFileNode xLinkedFileNode = (DomainFileNode) binFolderLinkNode.getChild("bash");
|
||||
assertNotNull(xLinkedFileNode);
|
||||
|
||||
tip = binFolderLinkNode.getToolTip();
|
||||
assertFalse(tip.contains("Broken"));
|
||||
|
||||
// Repeat removal of folder A and its contents
|
||||
bashFile = usrBinFolder.getFile("bash");
|
||||
assertNotNull(bashFile);
|
||||
bashFile.delete();
|
||||
usrBinFolder.delete();
|
||||
rootFolder.getFolder("usr").delete();
|
||||
|
||||
env.waitForTree();
|
||||
|
||||
assertNull(binFolderLinkNode.getChild("bash"));
|
||||
|
||||
waitForRefresh(binFolderLinkNode);
|
||||
env.waitForTree();
|
||||
|
||||
tip = binFolderLinkNode.getToolTip();
|
||||
assertTrue(tip.contains("Broken"));
|
||||
}
|
||||
|
||||
private void waitForRefresh(DomainFileNode fileNode) {
|
||||
waitFor(new BooleanSupplier() {
|
||||
@Override
|
||||
public boolean getAsBoolean() {
|
||||
return !fileNode.hasPendingRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+158
-13
@@ -32,6 +32,7 @@ import ghidra.program.database.ProgramLinkContentHandler;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.server.remote.ServerTestUtil;
|
||||
import ghidra.test.*;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.DuplicateFileException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@@ -50,13 +51,16 @@ public class ProjectLinkFileStatusTest extends AbstractGhidraHeadedIntegrationTe
|
||||
|
||||
/**
|
||||
/abc/ (folder)
|
||||
abc -> /xyz/abc (circular)
|
||||
abc -> /xyz/abc (circular folder allowed as internal)
|
||||
foo (program file)
|
||||
/xyz/
|
||||
abc -> /abc (folder link)
|
||||
abc -> (circular)
|
||||
abc -> /xyz/abc (circular folder allowed as internal)
|
||||
foo
|
||||
foo -> /abc/foo (program link)
|
||||
/e -> f (circular folder link path)
|
||||
/f -> g (circular folder link path)
|
||||
/g -> e (circular folder link path)
|
||||
**/
|
||||
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
@@ -72,6 +76,18 @@ public class ProjectLinkFileStatusTest extends AbstractGhidraHeadedIntegrationTe
|
||||
|
||||
programFile.copyToAsLink(xyzFolder, false);
|
||||
|
||||
// Circular folder-link path without real folder
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/f", true, "e",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/g", true, "f",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(), "/e", true, "g",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
|
||||
rootFolder.createLinkFile(rootFolder.getProjectData(),
|
||||
"/home/tsharr2/Examples/linktest/usr/lib64/../lib64", true, "nested2lib64",
|
||||
FolderLinkContentHandler.INSTANCE);
|
||||
|
||||
env.waitForTree();
|
||||
}
|
||||
|
||||
@@ -257,23 +273,154 @@ public class ProjectLinkFileStatusTest extends AbstractGhidraHeadedIntegrationTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenFolderLink() throws Exception {
|
||||
public void testCircularFolderLink1() throws Exception {
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /abc/abc which has circular reference
|
||||
// Verify broken folder-link status for /e which has circular reference
|
||||
//
|
||||
DomainFileNode eLinkNode = waitForFileNode("/e");
|
||||
assertTrue(eLinkNode.isFolderLink());
|
||||
String displayName = runSwing(() -> eLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" f"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(eLinkNode.getDomainFile(), null));
|
||||
String tooltip = eLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /g which has circular reference
|
||||
//
|
||||
DomainFileNode gLinkNode = waitForFileNode("/g");
|
||||
assertTrue(gLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> gLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" e"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(gLinkNode.getDomainFile(), null));
|
||||
tooltip = gLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /f which has circular reference
|
||||
//
|
||||
DomainFileNode fLinkNode = waitForFileNode("/f");
|
||||
assertTrue(fLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> fLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" g"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(fLinkNode.getDomainFile(), null));
|
||||
tooltip = fLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Rename folder /e to /ABC causing folder-links to have broken path
|
||||
//
|
||||
Swing.runNow(() -> eLinkNode.setName("ABC"));
|
||||
|
||||
env.waitForTree(); // give time for ChangeManager to update
|
||||
|
||||
// Verify /e node not found
|
||||
assertNull(env.getRootNode().getChild("e"));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /ABC (final folder /e not found)
|
||||
//
|
||||
DomainFileNode abcLinkNode = waitForFileNode("/ABC");
|
||||
assertTrue(abcLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> abcLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" f"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(abcLinkNode.getDomainFile(), null));
|
||||
tooltip = abcLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("folder not found: /e"));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /g (final folder /e not found)
|
||||
//
|
||||
waitForFileNode("/g");
|
||||
assertTrue(gLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> gLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" e"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(gLinkNode.getDomainFile(), null));
|
||||
tooltip = gLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("folder not found: /e"));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /f (final folder /e not found)
|
||||
//
|
||||
waitForFileNode("/f");
|
||||
assertTrue(fLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> fLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" g"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(fLinkNode.getDomainFile(), null));
|
||||
tooltip = fLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("folder not found: /e"));
|
||||
|
||||
//
|
||||
// Create folder /e
|
||||
//
|
||||
DomainFolder rootFolder = env.getRootFolder();
|
||||
rootFolder.createFolder("e");
|
||||
|
||||
env.waitForTree(); // give time for ChangeManager to update
|
||||
|
||||
//
|
||||
// Verify good folder-link status for /ABC
|
||||
//
|
||||
waitForFileNode("/ABC");
|
||||
assertTrue(abcLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> abcLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" f"));
|
||||
assertEquals(LinkStatus.INTERNAL,
|
||||
LinkHandler.getLinkFileStatus(abcLinkNode.getDomainFile(), null));
|
||||
tooltip = gLinkNode.getToolTip().replace(" ", " ");
|
||||
assertFalse(tooltip.contains("folder not found"));
|
||||
assertFalse(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Verify good folder-link status for /g
|
||||
//
|
||||
waitForFileNode("/g");
|
||||
assertTrue(gLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> gLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" e"));
|
||||
assertEquals(LinkStatus.INTERNAL,
|
||||
LinkHandler.getLinkFileStatus(gLinkNode.getDomainFile(), null));
|
||||
tooltip = gLinkNode.getToolTip().replace(" ", " ");
|
||||
assertFalse(tooltip.contains("folder not found"));
|
||||
assertFalse(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Verify good folder-link status for /f
|
||||
//
|
||||
waitForFileNode("/f");
|
||||
assertTrue(fLinkNode.isFolderLink());
|
||||
displayName = runSwing(() -> fLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName, displayName.endsWith(" g"));
|
||||
assertEquals(LinkStatus.INTERNAL,
|
||||
LinkHandler.getLinkFileStatus(fLinkNode.getDomainFile(), null));
|
||||
tooltip = fLinkNode.getToolTip().replace(" ", " ");
|
||||
assertFalse(tooltip.contains("folder not found"));
|
||||
assertFalse(tooltip.contains("circular"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCircularFolderLink2() throws Exception {
|
||||
|
||||
//
|
||||
// Verify good folder-link internal status for /abc/abc which has allowed circular reference
|
||||
//
|
||||
DomainFileNode abcAbcLinkNode = waitForFileNode("/abc/abc");
|
||||
assertTrue(abcAbcLinkNode.isFolderLink());
|
||||
String displayName = runSwing(() -> abcAbcLinkNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName,
|
||||
displayName.endsWith(" /xyz/abc"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
assertEquals(LinkStatus.INTERNAL,
|
||||
LinkHandler.getLinkFileStatus(abcAbcLinkNode.getDomainFile(), null));
|
||||
String tooltip = abcAbcLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Verify good folder-link internal status for /xyz/abc which has circular reference
|
||||
// Verify good folder-link internal status for /xyz/abc which has allowed circular reference
|
||||
//
|
||||
DomainFileNode xyzAbcLinkNode = waitForFileNode("/xyz/abc");
|
||||
assertTrue(xyzAbcLinkNode.isFolderLink());
|
||||
@@ -283,17 +430,15 @@ public class ProjectLinkFileStatusTest extends AbstractGhidraHeadedIntegrationTe
|
||||
LinkHandler.getLinkFileStatus(xyzAbcLinkNode.getDomainFile(), null));
|
||||
|
||||
//
|
||||
// Verify broken folder-link status for /xyz/abc/abc which has circular reference
|
||||
// Verify good folder-link internal status for /xyz/abc/abc which has allowed circular reference
|
||||
//
|
||||
DomainFileNode abcLinkedNode = waitForFileNode("/xyz/abc/abc");
|
||||
assertTrue(abcLinkedNode.isFolderLink());
|
||||
displayName = runSwing(() -> abcLinkedNode.getDisplayText());
|
||||
assertTrue("Unexpected node display name: " + displayName,
|
||||
displayName.endsWith(" /xyz/abc"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
assertEquals(LinkStatus.INTERNAL,
|
||||
LinkHandler.getLinkFileStatus(abcLinkedNode.getDomainFile(), null));
|
||||
tooltip = abcLinkedNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("circular"));
|
||||
|
||||
//
|
||||
// Rename folder /abc to /ABC causing folder-link /xyz/abc to become broken
|
||||
@@ -315,7 +460,7 @@ public class ProjectLinkFileStatusTest extends AbstractGhidraHeadedIntegrationTe
|
||||
displayName.endsWith(" /xyz/abc"));
|
||||
assertEquals(LinkStatus.BROKEN,
|
||||
LinkHandler.getLinkFileStatus(ABCAbcLinkNode.getDomainFile(), null));
|
||||
tooltip = ABCAbcLinkNode.getToolTip().replace(" ", " ");
|
||||
String tooltip = ABCAbcLinkNode.getToolTip().replace(" ", " ");
|
||||
assertTrue(tooltip.contains("folder not found: /abc"));
|
||||
|
||||
env.waitForTree(); // give time for ChangeManager to update
|
||||
|
||||
Reference in New Issue
Block a user