Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.OpenOption;
Expand Down Expand Up @@ -351,6 +352,15 @@ public boolean deleteIfExists(Path path) throws IOException {
initStorage();
CloudStoragePath cloudPath = CloudStorageUtil.checkPath(path);
if (cloudPath.seemsLikeADirectoryAndUsePseudoDirectories()) {
// if the "folder" is empty then we're fine, otherwise complain
// that we cannot act on folders.
try (DirectoryStream<Path> paths = Files.newDirectoryStream(path)) {
if (!paths.iterator().hasNext()) {
// "folder" isn't actually there in the first place, so: success!
// (we must return true so delete doesn't freak out)
return true;
}
}
throw new CloudStoragePseudoDirectoryException(cloudPath);
}
return storage.delete(cloudPath.getBlobId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,6 @@ public void testDelete_dotDirNotNormalized_throwsIae() throws IOException {

@Test
public void testDelete_trailingSlash() throws IOException {
thrown.expect(CloudStoragePseudoDirectoryException.class);
Files.delete(Paths.get(URI.create("gs://love/passion/")));
}

Expand Down Expand Up @@ -442,7 +441,6 @@ public void testDeleteIfExists() throws IOException {

@Test
public void testDeleteIfExists_trailingSlash() throws IOException {
thrown.expect(CloudStoragePseudoDirectoryException.class);
Files.deleteIfExists(Paths.get(URI.create("gs://love/passion/")));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import com.google.common.testing.NullPointerTester;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

Expand All @@ -38,6 +40,9 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.FileVisitResult;
import java.nio.file.attribute.BasicFileAttributes;

/**
* Unit tests for {@link CloudStorageFileSystem}.
Expand All @@ -55,6 +60,9 @@ public class CloudStorageFileSystemTest {
+ "The Heart-ache, and the thousand Natural shocks\n"
+ "That Flesh is heir to? 'Tis a consummation\n";

@Rule
public ExpectedException thrown = ExpectedException.none();

@Before
public void before() {
CloudStorageFileSystemProvider.setStorageOptions(LocalStorageHelper.getOptions());
Expand Down Expand Up @@ -180,6 +188,117 @@ public void testMatcher() throws IOException {
}
}

@Test
public void testDeleteEmptyFolder() throws IOException {
try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) {
List<Path> paths = new ArrayList<>();
paths.add(fs.getPath("dir/angel"));
paths.add(fs.getPath("dir/dir2/another_angel"));
paths.add(fs.getPath("atroot"));
for (Path path : paths) {
Files.write(path, ALONE.getBytes(UTF_8));
}
// we can delete non-existent folders, because they are not represented on disk anyways.
Files.delete(fs.getPath("ghost/"));
Files.delete(fs.getPath("dir/ghost/"));
Files.delete(fs.getPath("dir/dir2/ghost/"));
// likewise, deleteIfExists works.
Files.deleteIfExists(fs.getPath("ghost/"));
Files.deleteIfExists(fs.getPath("dir/ghost/"));
Files.deleteIfExists(fs.getPath("dir/dir2/ghost/"));
}
}

@Test
public void testDeleteFullFolder() throws IOException {
thrown.expect(CloudStoragePseudoDirectoryException.class);
try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) {
Files.write(fs.getPath("dir/angel"), ALONE.getBytes(UTF_8));
// we cannot delete existing folders if they contain something
Files.delete(fs.getPath("dir/"));
}
}

@Test
public void testDelete() throws IOException {
try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) {
List<Path> paths = new ArrayList<>();
paths.add(fs.getPath("dir/angel"));
paths.add(fs.getPath("dir/dir2/another_angel"));
paths.add(fs.getPath("atroot"));
for (Path path : paths) {
Files.write(path, ALONE.getBytes(UTF_8));
}
Files.delete(fs.getPath("atroot"));
Files.delete(fs.getPath("dir/angel"));
Files.deleteIfExists(fs.getPath("dir/dir2/another_angel"));

for (Path path : paths) {
assertThat(Files.exists(path)).isFalse();
}
}
}

@Test
public void testDeleteEmptiedFolder() throws IOException {
try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) {
List<Path> paths = new ArrayList<>();
paths.add(fs.getPath("dir/angel"));
paths.add(fs.getPath("dir/dir2/another_angel"));
for (Path path : paths) {
Files.write(path, ALONE.getBytes(UTF_8));
}
Files.delete(fs.getPath("dir/angel"));
Files.deleteIfExists(fs.getPath("dir/dir2/another_angel"));
// delete folder (trailing slash is required)
Path dir2 = fs.getPath("dir/dir2/");
Files.deleteIfExists(dir2);
Path dir = fs.getPath("dir/");
Files.deleteIfExists(dir);
// We can't check Files.exists on a folder (since GCS fakes folders)
}
}

@Test
public void testDeleteRecursive() throws IOException {
try (FileSystem fs = CloudStorageFileSystem.forBucket("bucket")) {
List<Path> paths = new ArrayList<>();
paths.add(fs.getPath("atroot"));
paths.add(fs.getPath("dir/angel"));
paths.add(fs.getPath("dir/dir2/another_angel"));
paths.add(fs.getPath("dir/dir2/angel3"));
paths.add(fs.getPath("dir/dir3/cloud"));
for (Path path : paths) {
Files.write(path, ALONE.getBytes(UTF_8));
}

deleteRecursive(fs.getPath("dir/"));
assertThat(Files.exists(fs.getPath("dir/angel"))).isFalse();
assertThat(Files.exists(fs.getPath("dir/dir3/cloud"))).isFalse();
assertThat(Files.exists(fs.getPath("atroot"))).isTrue();
}
}

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.


/**
* Delete the given directory and all of its contents if non-empty.
* @param directory the directory to delete
* @throws IOException
*/
private static void deleteRecursive(Path directory) throws IOException {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}

private void assertMatches(FileSystem fs, PathMatcher matcher, String toMatch, boolean expected) {
assertThat(matcher.matches(fs.getPath(toMatch).getFileName())).isEqualTo(expected);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.FileSystem;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -354,6 +357,46 @@ public void testListFiles() throws IOException {
}
}


@Test
public void testDeleteRecursive() throws IOException {
try (FileSystem fs = getTestBucket()) {
List<Path> paths = new ArrayList<>();
paths.add(fs.getPath("Racine"));
paths.add(fs.getPath("playwrights/Moliere"));
paths.add(fs.getPath("playwrights/French/Corneille"));
for (Path path : paths) {
Files.write(path, FILE_CONTENTS, UTF_8);
}
deleteRecursive(fs.getPath("playwrights/"));
assertThat(Files.exists(fs.getPath("playwrights/Moliere"))).isFalse();
assertThat(Files.exists(fs.getPath("playwrights/French/Corneille"))).isFalse();
assertThat(Files.exists(fs.getPath("Racine"))).isTrue();
Files.deleteIfExists(fs.getPath("Racine"));
assertThat(Files.exists(fs.getPath("Racine"))).isFalse();
}
}

/**
* Delete the given directory and all of its contents if non-empty.
* @param directory the directory to delete
* @throws IOException
*/
private static void deleteRecursive(Path directory) throws IOException {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}

private int readFully(ReadableByteChannel chan, byte[] outputBuf) throws IOException {
ByteBuffer buf = ByteBuffer.wrap(outputBuf);
int sofar = 0;
Expand Down