2424import com .google .common .testing .NullPointerTester ;
2525
2626import org .junit .Before ;
27+ import org .junit .Rule ;
2728import org .junit .Test ;
29+ import org .junit .rules .ExpectedException ;
2830import org .junit .runner .RunWith ;
2931import org .junit .runners .JUnit4 ;
3032
3840import java .nio .file .Paths ;
3941import java .util .ArrayList ;
4042import java .util .List ;
43+ import java .nio .file .SimpleFileVisitor ;
44+ import java .nio .file .FileVisitResult ;
45+ import java .nio .file .attribute .BasicFileAttributes ;
4146
4247/**
4348 * Unit tests for {@link CloudStorageFileSystem}.
@@ -55,6 +60,9 @@ public class CloudStorageFileSystemTest {
5560 + "The Heart-ache, and the thousand Natural shocks\n "
5661 + "That Flesh is heir to? 'Tis a consummation\n " ;
5762
63+ @ Rule
64+ public ExpectedException thrown = ExpectedException .none ();
65+
5866 @ Before
5967 public void before () {
6068 CloudStorageFileSystemProvider .setStorageOptions (LocalStorageHelper .getOptions ());
@@ -187,6 +195,117 @@ public void testMatcher() throws IOException {
187195 }
188196 }
189197
198+ @ Test
199+ public void testDeleteEmptyFolder () throws IOException {
200+ try (FileSystem fs = CloudStorageFileSystem .forBucket ("bucket" )) {
201+ List <Path > paths = new ArrayList <>();
202+ paths .add (fs .getPath ("dir/angel" ));
203+ paths .add (fs .getPath ("dir/dir2/another_angel" ));
204+ paths .add (fs .getPath ("atroot" ));
205+ for (Path path : paths ) {
206+ Files .write (path , ALONE .getBytes (UTF_8 ));
207+ }
208+ // we can delete non-existent folders, because they are not represented on disk anyways.
209+ Files .delete (fs .getPath ("ghost/" ));
210+ Files .delete (fs .getPath ("dir/ghost/" ));
211+ Files .delete (fs .getPath ("dir/dir2/ghost/" ));
212+ // likewise, deleteIfExists works.
213+ Files .deleteIfExists (fs .getPath ("ghost/" ));
214+ Files .deleteIfExists (fs .getPath ("dir/ghost/" ));
215+ Files .deleteIfExists (fs .getPath ("dir/dir2/ghost/" ));
216+ }
217+ }
218+
219+ @ Test
220+ public void testDeleteFullFolder () throws IOException {
221+ thrown .expect (CloudStoragePseudoDirectoryException .class );
222+ try (FileSystem fs = CloudStorageFileSystem .forBucket ("bucket" )) {
223+ Files .write (fs .getPath ("dir/angel" ), ALONE .getBytes (UTF_8 ));
224+ // we cannot delete existing folders if they contain something
225+ Files .delete (fs .getPath ("dir/" ));
226+ }
227+ }
228+
229+ @ Test
230+ public void testDelete () throws IOException {
231+ try (FileSystem fs = CloudStorageFileSystem .forBucket ("bucket" )) {
232+ List <Path > paths = new ArrayList <>();
233+ paths .add (fs .getPath ("dir/angel" ));
234+ paths .add (fs .getPath ("dir/dir2/another_angel" ));
235+ paths .add (fs .getPath ("atroot" ));
236+ for (Path path : paths ) {
237+ Files .write (path , ALONE .getBytes (UTF_8 ));
238+ }
239+ Files .delete (fs .getPath ("atroot" ));
240+ Files .delete (fs .getPath ("dir/angel" ));
241+ Files .deleteIfExists (fs .getPath ("dir/dir2/another_angel" ));
242+
243+ for (Path path : paths ) {
244+ assertThat (Files .exists (path )).isFalse ();
245+ }
246+ }
247+ }
248+
249+ @ Test
250+ public void testDeleteEmptiedFolder () throws IOException {
251+ try (FileSystem fs = CloudStorageFileSystem .forBucket ("bucket" )) {
252+ List <Path > paths = new ArrayList <>();
253+ paths .add (fs .getPath ("dir/angel" ));
254+ paths .add (fs .getPath ("dir/dir2/another_angel" ));
255+ for (Path path : paths ) {
256+ Files .write (path , ALONE .getBytes (UTF_8 ));
257+ }
258+ Files .delete (fs .getPath ("dir/angel" ));
259+ Files .deleteIfExists (fs .getPath ("dir/dir2/another_angel" ));
260+ // delete folder (trailing slash is required)
261+ Path dir2 = fs .getPath ("dir/dir2/" );
262+ Files .deleteIfExists (dir2 );
263+ Path dir = fs .getPath ("dir/" );
264+ Files .deleteIfExists (dir );
265+ // We can't check Files.exists on a folder (since GCS fakes folders)
266+ }
267+ }
268+
269+ @ Test
270+ public void testDeleteRecursive () throws IOException {
271+ try (FileSystem fs = CloudStorageFileSystem .forBucket ("bucket" )) {
272+ List <Path > paths = new ArrayList <>();
273+ paths .add (fs .getPath ("atroot" ));
274+ paths .add (fs .getPath ("dir/angel" ));
275+ paths .add (fs .getPath ("dir/dir2/another_angel" ));
276+ paths .add (fs .getPath ("dir/dir2/angel3" ));
277+ paths .add (fs .getPath ("dir/dir3/cloud" ));
278+ for (Path path : paths ) {
279+ Files .write (path , ALONE .getBytes (UTF_8 ));
280+ }
281+
282+ deleteRecursive (fs .getPath ("dir/" ));
283+ assertThat (Files .exists (fs .getPath ("dir/angel" ))).isFalse ();
284+ assertThat (Files .exists (fs .getPath ("dir/dir3/cloud" ))).isFalse ();
285+ assertThat (Files .exists (fs .getPath ("atroot" ))).isTrue ();
286+ }
287+ }
288+
289+ /**
290+ * Delete the given directory and all of its contents if non-empty.
291+ * @param directory the directory to delete
292+ * @throws IOException
293+ */
294+ private static void deleteRecursive (Path directory ) throws IOException {
295+ Files .walkFileTree (directory , new SimpleFileVisitor <Path >() {
296+ @ Override
297+ public FileVisitResult visitFile (Path file , BasicFileAttributes attrs ) throws IOException {
298+ Files .delete (file );
299+ return FileVisitResult .CONTINUE ;
300+ }
301+ @ Override
302+ public FileVisitResult postVisitDirectory (Path dir , IOException exc ) throws IOException {
303+ Files .delete (dir );
304+ return FileVisitResult .CONTINUE ;
305+ }
306+ });
307+ }
308+
190309 private void assertMatches (FileSystem fs , PathMatcher matcher , String toMatch , boolean expected ) {
191310 assertThat (matcher .matches (fs .getPath (toMatch ).getFileName ())).isEqualTo (expected );
192311 }
0 commit comments