Skip to content

Commit

Permalink
devonfw#139: fixed toAbsolute, which was wrong, more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MattesMrzik committed Dec 11, 2023
1 parent 304c48c commit f8dfe79
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,13 @@ private Path adaptPath(Path source, Path targetLink, boolean relative) {
return (source.toString().isEmpty()) ? Paths.get(".") : source;
}
if (!relative && !source.isAbsolute()) {
return source.toAbsolutePath();
try {
source = targetLink.resolveSibling(source).toRealPath();
} catch (IOException e) {
throw new IllegalStateException(
"Failed to create fallback symlink from " + source + " with target link " + targetLink, e);
}
// TODO maybe in the two off cases also call toRealPath to collapse paths like ../d1/../d2

}
return source;
Expand Down
82 changes: 77 additions & 5 deletions cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ private boolean windowsJunctionsAreUsed(IdeContext context, Path dir) {
}

/**
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = false".
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = false". Passing absolute paths as
* source
*/
@Test
public void testSymlinkNotRelative(@TempDir Path tempDir) {
Expand All @@ -57,6 +58,31 @@ public void testSymlinkNotRelative(@TempDir Path tempDir) {
assertSymlinksWork(dir, readLinks);
}

/**
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = false". Passing relative paths as
* source
*/
@Test
public void testSymlinkNotRelativeWithRelativeSource(@TempDir Path tempDir) {

// relative links are checked in testRelativeLinksWorkAfterMoving

// arrange
IdeContext context = IdeTestContextMock.get();
FileAccess fileAccess = new FileAccessImpl(context);
Path dir = tempDir.resolve("parent");
createDirs(fileAccess, dir);
boolean readLinks = !windowsJunctionsAreUsed(context, tempDir);
boolean relative = false;

// act
createSymlinksByPassingRelativeSource(fileAccess, dir, relative);

// assert
assertSymlinksExist(dir);
assertSymlinksWork(dir, readLinks);
}

/**
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = true". But Windows junctions are used
* and therefore the fallback from relative to absolute paths is tested.
Expand Down Expand Up @@ -111,6 +137,35 @@ public void testAbsoluteLinksBreakAfterMoving(@TempDir Path tempDir) throws IOEx
assertSymlinksAreBroken(sibling, readLinks);
}

/**
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = true". Furthermore, it is tested that
* the links still work after moving them. Passing relative paths as source.
*/
@Test
public void testRelativeLinksWorkAfterMovingWithRelativeSource(@TempDir Path tempDir) {

// arrange
IdeContext context = IdeTestContextMock.get();
if (windowsJunctionsAreUsed(context, tempDir)) {
context.info("Can not check the Test: testRelativeLinksWorkAfterMoving since windows junctions are used.");
return;
}
FileAccess fileAccess = new FileAccessImpl(context);
Path dir = tempDir.resolve("parent");
createDirs(fileAccess, dir);
boolean relative = true;
createSymlinksByPassingRelativeSource(fileAccess, dir, relative);
boolean readLinks = true; // junctions are not used, so links can be read with Files.readSymbolicLink(link);

// act
Path sibling = dir.resolveSibling("parent2");
fileAccess.move(dir, sibling);

// assert
assertSymlinksExist(sibling);
assertSymlinksWork(sibling, readLinks);
}

/**
* Test of {@link FileAccessImpl#symlink(Path, Path, boolean)} with "relative = true". Furthermore, it is tested that
* the links still work after moving them.
Expand Down Expand Up @@ -150,8 +205,8 @@ public void testWindowsJunctionsCanNotPointToFiles(@TempDir Path tempDir) throws
// arrange
IdeContext context = IdeTestContextMock.get();
if (!windowsJunctionsAreUsed(context, tempDir)) {
context.info(
"Can not check the Test: testWindowsJunctionsCanNotPointToFiles since windows junctions are not used.");
context
.info("Can not check the Test: testWindowsJunctionsCanNotPointToFiles since windows junctions are not used.");
return;
}
Path file = tempDir.resolve("file");
Expand All @@ -171,6 +226,24 @@ private void createDirs(FileAccess fileAccess, Path dir) {
fileAccess.mkdirs(dir.resolve("d2/d22/d222"));
}

private void createSymlinksByPassingRelativeSource(FileAccess fa, Path dir, boolean relative) {

fa.symlink(Path.of("."), dir.resolve("d1/d11/link1"), relative);
// test if symbolic links or junctions can be overwritten with symlink()
fa.symlink(Path.of(".."), dir.resolve("d1/d11/link1"), relative);

fa.symlink(Path.of("."), dir.resolve("d1/d11/link2"), relative);
fa.symlink(Path.of("d111"), dir.resolve("d1/d11/link3"), relative);
fa.symlink(Path.of("d111/d1111"), dir.resolve("d1/d11/link4"), relative);
fa.symlink(Path.of("../../d2"), dir.resolve("d1/d11/link5"), relative);
fa.symlink(Path.of("../../d2/d22"), dir.resolve("d1/d11/link6"), relative);
fa.symlink(Path.of("../../d2/d22/d222"), dir.resolve("d1/d11/link7"), relative);

fa.symlink(Path.of("../../d1/d11/link1"), dir.resolve("d2/d22/link8"), relative);
fa.symlink(Path.of("../d1/d11/link1"), dir.resolve("d2/link9"), relative);
fa.symlink(Path.of("d2/link9"), dir.resolve("link10"), relative);
}

private void createSymlinks(FileAccess fa, Path dir, boolean relative) {

fa.symlink(dir.resolve("d1/d11"), dir.resolve("d1/d11/link1"), relative);
Expand Down Expand Up @@ -235,8 +308,7 @@ private void assertSymlinkIsBroken(Path link, boolean readLinks) throws IOExcept
}
}


// only pass readLinks = true when junctions are not used.
// only pass readLinks = true when junctions are not used.
private void assertSymlinksWork(Path dir, boolean readLinks) {

assertSymlinkToRealPath(dir.resolve("d1/d11/link1"), dir.resolve("d1"));
Expand Down

0 comments on commit f8dfe79

Please sign in to comment.