@@ -273,6 +273,85 @@ public void testBasicChmod() throws IOException {
273273 assertTrue (aExe .delete ());
274274 }
275275
276+ /** Validate behavior of chmod commands on directories on Windows. */
277+ @ Test (timeout = 30000 )
278+ public void testBasicChmodOnDir () throws IOException {
279+ // Validate that listing a directory with no read permission fails
280+ File a = new File (TEST_DIR , "a" );
281+ File b = new File (a , "b" );
282+ a .mkdirs ();
283+ assertTrue (b .createNewFile ());
284+
285+ // Remove read permissions on directory a
286+ chmod ("300" , a );
287+ String [] files = a .list ();
288+ assertTrue ("Listing a directory without read permission should fail" ,
289+ null == files );
290+
291+ // restore permissions
292+ chmod ("700" , a );
293+ // validate that the directory can be listed now
294+ files = a .list ();
295+ assertEquals ("b" , files [0 ]);
296+
297+ // Remove write permissions on the directory and validate the
298+ // behavior for adding, deleting and renaming files
299+ chmod ("500" , a );
300+ File c = new File (a , "c" );
301+
302+ try {
303+ // Adding a new file will fail as expected because the
304+ // FILE_WRITE_DATA/FILE_ADD_FILE privilege is denied on
305+ // the dir.
306+ c .createNewFile ();
307+ assertFalse ("writeFile should have failed!" , true );
308+ } catch (IOException ex ) {
309+ LOG .info ("Expected: Failed to create a file when directory "
310+ + "permissions are 577" );
311+ }
312+
313+ // Deleting a file will succeed even if write permissions are not present
314+ // on the parent dir. Check the following link for additional details:
315+ // http://support.microsoft.com/kb/238018
316+ assertTrue ("Special behavior: deleting a file will succeed on Windows "
317+ + "even if a user does not have write permissions on the parent dir" ,
318+ b .delete ());
319+
320+ assertFalse ("Renaming a file should fail on the dir where a user does "
321+ + "not have write permissions" , b .renameTo (new File (a , "d" )));
322+
323+ // restore permissions
324+ chmod ("700" , a );
325+
326+ // Make sure adding new files and rename succeeds now
327+ assertTrue (c .createNewFile ());
328+ File d = new File (a , "d" );
329+ assertTrue (c .renameTo (d ));
330+ // at this point in the test, d is the only remaining file in directory a
331+
332+ // Removing execute permissions does not have the same behavior on
333+ // Windows as on Linux. Adding, renaming, deleting and listing files
334+ // will still succeed. Windows default behavior is to bypass directory
335+ // traverse checking (BYPASS_TRAVERSE_CHECKING privilege) for all users.
336+ // See the following link for additional details:
337+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364399(v=vs.85).aspx
338+ chmod ("600" , a );
339+
340+ // validate directory listing
341+ files = a .list ();
342+ assertEquals ("d" , files [0 ]);
343+ // validate delete
344+ assertTrue (d .delete ());
345+ // validate add
346+ File e = new File (a , "e" );
347+ assertTrue (e .createNewFile ());
348+ // validate rename
349+ assertTrue (e .renameTo (new File (a , "f" )));
350+
351+ // restore permissions
352+ chmod ("700" , a );
353+ }
354+
276355 @ Test (timeout = 30000 )
277356 public void testChmod () throws IOException {
278357 testChmodInternal ("7" , "-------rwx" );
0 commit comments