Skip to content

Commit 9d9aae8

Browse files
committed
add edge case tests
1 parent 715c14a commit 9d9aae8

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpTransformerTest.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.salesforce.multicloudj.blob.driver.ObjectLockConfiguration;
2222
import com.salesforce.multicloudj.blob.driver.RetentionMode;
2323
import com.salesforce.multicloudj.common.exceptions.InvalidArgumentException;
24+
import com.salesforce.multicloudj.common.exceptions.SubstrateSdkException;
2425
import com.salesforce.multicloudj.common.retries.RetryConfig;
2526
import org.apache.commons.lang3.tuple.Pair;
2627
import org.junit.jupiter.api.BeforeEach;
@@ -1047,6 +1048,100 @@ public void testToFilePaths_FollowSymbolicLinks() throws IOException {
10471048
}
10481049
}
10491050

1051+
@Test
1052+
public void testToFilePaths_CircularSymbolicLinks() throws IOException {
1053+
Path tempDir = Files.createTempDirectory("test-circular-symlink");
1054+
try {
1055+
Files.write(tempDir.resolve("file.txt"), "content".getBytes());
1056+
Path dirA = Files.createDirectory(tempDir.resolve("dirA"));
1057+
Path dirB = Files.createDirectory(tempDir.resolve("dirB"));
1058+
Files.createSymbolicLink(dirA.resolve("link-to-b"), dirB);
1059+
Files.createSymbolicLink(dirB.resolve("link-to-a"), dirA);
1060+
1061+
DirectoryUploadRequest request = DirectoryUploadRequest.builder()
1062+
.localSourceDirectory(tempDir.toString())
1063+
.prefix("uploads/")
1064+
.includeSubFolders(true)
1065+
.followSymbolicLinks(true)
1066+
.build();
1067+
1068+
assertThrows(RuntimeException.class, () -> transformer.toFilePaths(request));
1069+
} finally {
1070+
// Manual cleanup since Files.walk with FOLLOW_LINKS would fail on circular links
1071+
Files.deleteIfExists(tempDir.resolve("dirA/link-to-b"));
1072+
Files.deleteIfExists(tempDir.resolve("dirB/link-to-a"));
1073+
Files.walk(tempDir)
1074+
.sorted(Comparator.reverseOrder())
1075+
.map(Path::toFile)
1076+
.forEach(File::delete);
1077+
}
1078+
}
1079+
1080+
@Test
1081+
public void testToFilePaths_BrokenSymbolicLinks() throws IOException {
1082+
Path tempDir = Files.createTempDirectory("test-broken-symlink");
1083+
try {
1084+
Path file1 = tempDir.resolve("file1.txt");
1085+
Files.write(file1, "content".getBytes());
1086+
Files.createSymbolicLink(tempDir.resolve("broken-link"), Paths.get("/non/existent/path"));
1087+
1088+
DirectoryUploadRequest request = DirectoryUploadRequest.builder()
1089+
.localSourceDirectory(tempDir.toString())
1090+
.prefix("uploads/")
1091+
.includeSubFolders(true)
1092+
.followSymbolicLinks(true)
1093+
.build();
1094+
1095+
List<Path> paths = transformer.toFilePaths(request);
1096+
assertEquals(1, paths.size());
1097+
assertTrue(paths.contains(file1));
1098+
} finally {
1099+
Files.walk(tempDir)
1100+
.sorted(Comparator.reverseOrder())
1101+
.map(Path::toFile)
1102+
.forEach(File::delete);
1103+
}
1104+
}
1105+
1106+
@Test
1107+
public void testToFilePaths_NestedSymbolicLinks() throws IOException {
1108+
Path tempDir = Files.createTempDirectory("test-nested-symlink");
1109+
Path externalDir1 = Files.createTempDirectory("test-nested-target1");
1110+
Path externalDir2 = Files.createTempDirectory("test-nested-target2");
1111+
try {
1112+
Files.write(tempDir.resolve("root.txt"), "root".getBytes());
1113+
Files.write(externalDir2.resolve("deep.txt"), "deep".getBytes());
1114+
// externalDir1 contains a symlink to externalDir2
1115+
Files.createSymbolicLink(externalDir1.resolve("link-to-dir2"), externalDir2);
1116+
// tempDir contains a symlink to externalDir1
1117+
Files.createSymbolicLink(tempDir.resolve("link-to-dir1"), externalDir1);
1118+
1119+
DirectoryUploadRequest request = DirectoryUploadRequest.builder()
1120+
.localSourceDirectory(tempDir.toString())
1121+
.prefix("uploads/")
1122+
.includeSubFolders(true)
1123+
.followSymbolicLinks(true)
1124+
.build();
1125+
1126+
List<Path> paths = transformer.toFilePaths(request);
1127+
assertEquals(2, paths.size());
1128+
assertTrue(paths.contains(tempDir.resolve("root.txt")));
1129+
} finally {
1130+
Files.walk(externalDir2)
1131+
.sorted(Comparator.reverseOrder())
1132+
.map(Path::toFile)
1133+
.forEach(File::delete);
1134+
Files.walk(externalDir1)
1135+
.sorted(Comparator.reverseOrder())
1136+
.map(Path::toFile)
1137+
.forEach(File::delete);
1138+
Files.walk(tempDir)
1139+
.sorted(Comparator.reverseOrder())
1140+
.map(Path::toFile)
1141+
.forEach(File::delete);
1142+
}
1143+
}
1144+
10501145
@Test
10511146
public void testToBlobKey() {
10521147
Path sourceDir = Paths.get("/source");

0 commit comments

Comments
 (0)