@@ -41,12 +41,10 @@ def _get_errno(raised_error):
4141 pass
4242
4343
44- class TestCase (unittest .TestCase ):
44+ class FakeFilesystemVsRealTest (unittest .TestCase ):
4545 is_windows = sys .platform .startswith ("win" )
46- _FAKE_FS_BASE = "C:\\ fakefs" if is_windows else "/fakefs"
46+ fake_base = "C:\\ fakefs" if is_windows else "/fakefs"
4747
48-
49- class FakeFilesystemVsRealTest (TestCase ):
5048 def _paths (self , path ):
5149 """For a given path, return paths in the real and fake filesystems."""
5250 if not path :
@@ -106,7 +104,6 @@ def setUp(self):
106104 if os .path .isdir (self .real_base ):
107105 shutil .rmtree (self .real_base )
108106 os .mkdir (self .real_base )
109- self .fake_base = self ._FAKE_FS_BASE
110107
111108 # Make sure we can write to the physical testing temp directory.
112109 self .assertTrue (os .access (self .real_base , os .W_OK ))
@@ -167,7 +164,7 @@ def _compare_behaviors(
167164 to method.
168165 real: built-in system library or method from the built-in system
169166 library which takes a path as an arg and returns some value.
170- fake: fake_filsystem object or method from a fake_filesystem class
167+ fake: fake_filesystem object or method from a fake_filesystem class
171168 which takes a path as an arg and returns some value.
172169 method_returns_path: True if the method returns a path, and thus we
173170 must compensate for expected difference between real and fake.
@@ -302,7 +299,7 @@ def assertOsMethodBehaviorMatches(
302299 def diff_open_method_behavior (
303300 self , method_name , path , mode , data , method_returns_data = True
304301 ):
305- """Invoke an open method in both real and fkae contexts and compare.
302+ """Invoke an open method in both real and fake contexts and compare.
306303
307304 Args:
308305 method_name: Name of method being tested.
@@ -335,7 +332,7 @@ def diff_os_path_method_behavior(
335332
336333 For a given method name (from the os.path module) and a path, compare
337334 the behavior of the system provided module against the
338- fake_filesytem module.
335+ fake_filesystem module.
339336 We expect results and/or Exceptions raised to be identical.
340337
341338 Args:
@@ -374,24 +371,35 @@ def assertOsPathMethodBehaviorMatches(
374371 if diff :
375372 self .fail (diff )
376373
377- def assertAllOsBehaviorsMatch (self , path ):
374+ def assertAllOsBehaviorsMatch (self , path , excludes = None ):
375+ excludes = excludes or []
378376 path = sep (path )
379377 os_method_names = ["readlink" ]
380378 os_method_names_no_args = ["getcwd" ]
381- os_path_method_names = [
379+ os_path_method_names = {
382380 "isabs" ,
383381 "isdir" ,
384382 "islink" ,
385383 "lexists" ,
386384 "isfile" ,
387385 "exists" ,
388- ]
386+ } - set ( excludes )
389387
390388 wrapped_methods = [
391389 ["access" , self ._access_real , self ._access_fake ],
392- ["stat.size" , self ._stat_size_real , self ._stat_size_fake ],
390+ [
391+ "stat.size" ,
392+ lambda p : self ._stat_result_real (p , "st_size" , False ),
393+ lambda p : self ._stat_result_fake (p , "st_size" , False ),
394+ ],
395+ [
396+ "stat.mode" ,
397+ lambda p : self ._stat_result_real (p , "st_mode" ),
398+ lambda p : self ._stat_result_fake (p , "st_mode" ),
399+ ],
393400 ["lstat.size" , self ._lstat_size_real , self ._lstat_size_fake ],
394401 ]
402+ wrapped_methods = [m for m in wrapped_methods if m [0 ] not in excludes ]
395403
396404 differences = []
397405 for method_name in os_method_names :
@@ -492,19 +500,18 @@ def _access_real(path):
492500 def _access_fake (self , path ):
493501 return self .fake_os .access (path , os .R_OK )
494502
495- def _stat_size_real (self , path ):
503+ def _stat_result_real (self , path , prop , support_dir = True ):
496504 real_path , unused_fake_path = self ._paths (path )
497505 # fake_filesystem.py does not implement stat().st_size for directories
498- if os .path .isdir (real_path ):
506+ if not support_dir and os .path .isdir (real_path ):
499507 return None
500- return os .stat (real_path ). st_size
508+ return getattr ( os .stat (real_path ), prop )
501509
502- def _stat_size_fake (self , path ):
503- unused_real_path , fake_path = self ._paths (path )
504- # fake_filesystem.py does not implement stat().st_size for directories
505- if self .fake_os .path .isdir (fake_path ):
510+ def _stat_result_fake (self , path , prop , support_dir = True ):
511+ _ , fake_path = self ._paths (path )
512+ if not support_dir and self .fake_os .path .isdir (fake_path ):
506513 return None
507- return self .fake_os .stat (fake_path ). st_size
514+ return getattr ( self .fake_os .stat (fake_path ), prop )
508515
509516 def _lstat_size_real (self , path ):
510517 real_path , unused_fake_path = self ._paths (path )
@@ -544,9 +551,9 @@ def test_empty_path(self):
544551 self .assertAllOsBehaviorsMatch ("" )
545552
546553 def test_root_path (self ):
547- self .assertAllOsBehaviorsMatch ("/" )
554+ self .assertAllOsBehaviorsMatch ("/" , excludes = [ "stat.mode" ] )
548555
549- def test_non_existant_file (self ):
556+ def test_non_existent_file (self ):
550557 self .assertAllOsBehaviorsMatch ("foo" )
551558
552559 def test_empty_file (self ):
@@ -690,7 +697,7 @@ def test_bad_relative_path(self):
690697 self ._create_test_file ("f" , "a/sibling_of_b/target" , "contents" )
691698 self .assertAllOsBehaviorsMatch ("a/b/../broken/../target" )
692699
693- def test_getmtime_nonexistant_path (self ):
700+ def test_getmtime_nonexistent_path (self ):
694701 self .assertOsPathMethodBehaviorMatches ("getmtime" , "no/such/path" )
695702
696703 def test_builtin_open_modes (self ):
@@ -724,6 +731,27 @@ def test_builtin_open_modes(self):
724731 self .assertFileHandleOpenBehaviorsMatch ("write" , "w" , encoding = "utf-8" )
725732 self .assertFileHandleOpenBehaviorsMatch ("append" , "a" , encoding = "utf-8" )
726733
734+ def test_directory_permissions (self ):
735+ self ._create_test_file ("d" , "a" )
736+ self ._create_test_file ("f" , "a/write" )
737+ self ._create_test_file ("d" , "b" )
738+ self ._create_test_file ("f" , "b/write" )
739+ self ._create_test_file ("d" , "b/stat_dir" )
740+ for path , mode in [("b" , 0o555 ), ("b/stat_dir" , 0o111 )]:
741+ real_path , fake_path = self ._paths (path )
742+ os .chmod (real_path , mode )
743+ self .fake_os .chmod (fake_path , mode )
744+
745+ try :
746+ self .assertFileHandleOpenBehaviorsMatch ("a/write" , "w" )
747+ self .assertFileHandleOpenBehaviorsMatch ("b/write" , "w" )
748+ self .assertAllOsBehaviorsMatch ("b/stat_dir" )
749+ finally :
750+ for path in ["b" , "b/stat_dir" ]:
751+ real_path , fake_path = self ._paths (path )
752+ os .chmod (real_path , 0o777 )
753+ self .fake_os .chmod (fake_path , 0o777 )
754+
727755
728756def main (_ ):
729757 unittest .main ()
0 commit comments