1# 2# Copyright 2009 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16"""Unit tests for fake_os.FakeOsModule.""" 17 18import errno 19import os 20import stat 21import sys 22import unittest 23 24from pyfakefs.helpers import IN_DOCKER, IS_PYPY, get_uid, get_gid 25 26from pyfakefs import fake_filesystem, fake_os, fake_open, fake_file 27from pyfakefs.fake_filesystem import ( 28 FakeFileOpen, 29 is_root, 30 set_uid, 31 set_gid, 32) 33from pyfakefs.extra_packages import ( 34 use_scandir, 35 use_scandir_package, 36 use_builtin_scandir, 37) 38 39from pyfakefs.tests.test_utils import TestCase, RealFsTestCase 40 41 42class FakeOsModuleTestBase(RealFsTestCase): 43 def createTestFile(self, path): 44 self.create_file(path) 45 self.assertTrue(self.os.path.exists(path)) 46 st = self.os.stat(path) 47 self.assertEqual(0o666, stat.S_IMODE(st.st_mode)) 48 self.assertTrue(st.st_mode & stat.S_IFREG) 49 self.assertFalse(st.st_mode & stat.S_IFDIR) 50 51 def createTestDirectory(self, path): 52 self.create_dir(path) 53 self.assertTrue(self.os.path.exists(path)) 54 st = self.os.stat(path) 55 self.assertEqual(0o777, stat.S_IMODE(st.st_mode)) 56 self.assertFalse(st.st_mode & stat.S_IFREG) 57 self.assertTrue(st.st_mode & stat.S_IFDIR) 58 59 60class FakeOsModuleTest(FakeOsModuleTestBase): 61 def setUp(self): 62 super(FakeOsModuleTest, self).setUp() 63 self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK 64 self.rw = self.os.R_OK | self.os.W_OK 65 66 def test_chdir(self): 67 """chdir should work on a directory.""" 68 directory = self.make_path("foo") 69 self.create_dir(directory) 70 self.os.chdir(directory) 71 72 def test_chdir_fails_non_exist(self): 73 """chdir should raise OSError if the target does not exist.""" 74 directory = self.make_path("no", "such", "directory") 75 self.assert_raises_os_error(errno.ENOENT, self.os.chdir, directory) 76 77 def test_chdir_fails_non_directory(self): 78 """chdir should raise OSError if the target is not a directory.""" 79 filename = self.make_path("foo", "bar") 80 self.create_file(filename) 81 self.assert_raises_os_error(errno.ENOTDIR, self.os.chdir, filename) 82 83 def test_consecutive_chdir(self): 84 """Consecutive relative chdir calls should work.""" 85 dir1 = self.make_path("foo") 86 dir2 = "bar" 87 full_dirname = self.os.path.join(dir1, dir2) 88 self.create_dir(full_dirname) 89 self.os.chdir(dir1) 90 self.os.chdir(dir2) 91 # use real path to handle symlink /var to /private/var in MacOs 92 self.assertEqual( 93 os.path.realpath(self.os.getcwd()), os.path.realpath(full_dirname) 94 ) 95 96 def test_backwards_chdir(self): 97 """chdir into '..' should behave appropriately.""" 98 # skipping real fs test - can't test root dir 99 self.skip_real_fs() 100 rootdir = self.os.getcwd() 101 dirname = "foo" 102 abs_dirname = self.os.path.abspath(dirname) 103 self.filesystem.create_dir(dirname) 104 self.os.chdir(dirname) 105 self.assertEqual(abs_dirname, self.os.getcwd()) 106 self.os.chdir("..") 107 self.assertEqual(rootdir, self.os.getcwd()) 108 self.os.chdir(self.os.path.join(dirname, "..")) 109 self.assertEqual(rootdir, self.os.getcwd()) 110 111 def test_get_cwd(self): 112 # skipping real fs test - can't test root dir 113 self.skip_real_fs() 114 dirname = self.make_path("foo", "bar") 115 self.create_dir(dirname) 116 self.assertEqual(self.filesystem.root_dir_name, self.os.getcwd()) 117 self.os.chdir(dirname) 118 self.assertEqual(dirname, self.os.getcwd()) 119 120 def test_listdir(self): 121 self.assert_raises_os_error( 122 errno.ENOENT, self.os.listdir, "non_existing/fake_dir" 123 ) 124 directory = self.make_path("xyzzy", "plugh") 125 files = ["foo", "bar", "baz"] 126 for f in files: 127 self.create_file(self.os.path.join(directory, f)) 128 files.sort() 129 self.assertEqual(files, sorted(self.os.listdir(directory))) 130 131 def test_listdir_uses_open_fd_as_path(self): 132 self.check_posix_only() 133 if os.listdir not in os.supports_fd: 134 self.skip_real_fs() 135 self.assert_raises_os_error(errno.EBADF, self.os.listdir, 500) 136 dir_path = self.make_path("xyzzy", "plugh") 137 files = ["foo", "bar", "baz"] 138 for f in files: 139 self.create_file(self.os.path.join(dir_path, f)) 140 files.sort() 141 142 path_des = self.os.open(dir_path, os.O_RDONLY) 143 self.assertEqual(files, sorted(self.os.listdir(path_des))) 144 145 def test_listdir_returns_list(self): 146 directory_root = self.make_path("xyzzy") 147 self.os.mkdir(directory_root) 148 directory = self.os.path.join(directory_root, "bug") 149 self.os.mkdir(directory) 150 self.create_file(self.make_path(directory, "foo")) 151 self.assertEqual(["foo"], self.os.listdir(directory)) 152 153 def test_listdir_on_symlink(self): 154 self.skip_if_symlink_not_supported() 155 directory = self.make_path("xyzzy") 156 files = ["foo", "bar", "baz"] 157 for f in files: 158 self.create_file(self.make_path(directory, f)) 159 self.create_symlink(self.make_path("symlink"), self.make_path("xyzzy")) 160 files.sort() 161 self.assertEqual(files, sorted(self.os.listdir(self.make_path("symlink")))) 162 163 def test_listdir_error(self): 164 file_path = self.make_path("foo", "bar", "baz") 165 self.create_file(file_path) 166 self.assert_raises_os_error(errno.ENOTDIR, self.os.listdir, file_path) 167 168 def test_exists_current_dir(self): 169 self.assertTrue(self.os.path.exists(".")) 170 171 def test_listdir_current(self): 172 files = ["foo", "bar", "baz"] 173 for f in files: 174 self.create_file(self.make_path(f)) 175 files.sort() 176 self.assertEqual(files, sorted(self.os.listdir(self.base_path))) 177 178 def test_fdopen(self): 179 file_path1 = self.make_path("some_file1") 180 self.create_file(file_path1, contents="contents here1") 181 with self.open(file_path1, "r") as fake_file1: 182 fileno = fake_file1.fileno() 183 fake_file2 = self.os.fdopen(fileno) 184 self.assertNotEqual(fake_file2, fake_file1) 185 186 with self.assertRaises(TypeError): 187 self.os.fdopen(None) 188 with self.assertRaises(TypeError): 189 self.os.fdopen("a string") 190 191 def test_out_of_range_fdopen(self): 192 # test some file descriptor that is clearly out of range 193 self.assert_raises_os_error(errno.EBADF, self.os.fdopen, 500) 194 195 def test_closed_file_descriptor(self): 196 first_path = self.make_path("some_file1") 197 second_path = self.make_path("some_file2") 198 third_path = self.make_path("some_file3") 199 self.create_file(first_path, contents="contents here1") 200 self.create_file(second_path, contents="contents here2") 201 self.create_file(third_path, contents="contents here3") 202 203 fake_file1 = self.open(first_path, "r") 204 fake_file2 = self.open(second_path, "r") 205 fake_file3 = self.open(third_path, "r") 206 fileno1 = fake_file1.fileno() 207 fileno2 = fake_file2.fileno() 208 fileno3 = fake_file3.fileno() 209 210 self.os.close(fileno2) 211 self.assert_raises_os_error(errno.EBADF, self.os.close, fileno2) 212 self.assertEqual(fileno1, fake_file1.fileno()) 213 self.assertEqual(fileno3, fake_file3.fileno()) 214 215 with self.os.fdopen(fileno1) as f: 216 self.assertFalse(f is fake_file1) 217 with self.os.fdopen(fileno3) as f: 218 self.assertFalse(f is fake_file3) 219 self.assert_raises_os_error(errno.EBADF, self.os.fdopen, fileno2) 220 221 def test_fdopen_mode(self): 222 self.skip_real_fs() 223 file_path1 = self.make_path("some_file1") 224 self.create_file(file_path1, contents="contents here1") 225 self.os.chmod(file_path1, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) 226 227 fake_file1 = self.open(file_path1, "r") 228 fileno1 = fake_file1.fileno() 229 self.os.fdopen(fileno1) 230 self.os.fdopen(fileno1, "r") 231 if not is_root(): 232 with self.assertRaises(OSError): 233 self.os.fdopen(fileno1, "w") 234 else: 235 self.os.fdopen(fileno1, "w") 236 self.os.close(fileno1) 237 238 def test_fstat(self): 239 directory = self.make_path("xyzzy") 240 file_path = self.os.path.join(directory, "plugh") 241 self.create_file(file_path, contents="ABCDE") 242 with self.open(file_path) as file_obj: 243 fileno = file_obj.fileno() 244 self.assertTrue(stat.S_IFREG & self.os.fstat(fileno)[stat.ST_MODE]) 245 self.assertTrue(stat.S_IFREG & self.os.fstat(fileno).st_mode) 246 self.assertEqual(5, self.os.fstat(fileno)[stat.ST_SIZE]) 247 248 def test_stat(self): 249 directory = self.make_path("xyzzy") 250 file_path = self.os.path.join(directory, "plugh") 251 self.create_file(file_path, contents="ABCDE") 252 self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) 253 self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) 254 self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) 255 self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) 256 257 def test_st_blocks(self): 258 self.check_posix_only() 259 file_path = self.make_path("foo1") 260 self.create_file(file_path, contents=b"") 261 self.assertEqual(0, self.os.stat(file_path).st_blocks) 262 file_path = self.make_path("foo2") 263 self.create_file(file_path, contents=b"t") 264 self.assertEqual(8, self.os.stat(file_path).st_blocks) 265 file_path = self.make_path("foo3") 266 self.create_file(file_path, contents=b"t" * 4095) 267 self.assertEqual(8, self.os.stat(file_path).st_blocks) 268 file_path = self.make_path("foo4") 269 self.create_file(file_path, contents=b"t" * 4096) 270 self.assertEqual(8, self.os.stat(file_path).st_blocks) 271 file_path = self.make_path("foo5") 272 self.create_file(file_path, contents=b"t" * 4097) 273 self.assertEqual(16, self.os.stat(file_path).st_blocks) 274 275 def test_no_st_blocks_in_windows(self): 276 self.check_windows_only() 277 file_path = self.make_path("foo") 278 self.create_file(file_path, contents=b"") 279 with self.assertRaises(AttributeError): 280 self.os.stat(file_path).st_blocks 281 282 def test_stat_with_unc_path(self): 283 self.skip_real_fs() 284 self.check_windows_only() 285 directory = "//root/share/dir" 286 file_path = self.os.path.join(directory, "plugh") 287 self.create_file(file_path, contents="ABCDE") 288 self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) 289 self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) 290 self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) 291 self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) 292 293 def test_stat_with_drive(self): 294 self.skip_real_fs() 295 self.check_windows_only() 296 directory = "C:/foo/dir" 297 file_path = self.os.path.join(directory, "plugh") 298 self.create_file(file_path, contents="ABCDE") 299 self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) 300 self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) 301 self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) 302 self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) 303 304 def test_stat_uses_open_fd_as_path(self): 305 self.skip_real_fs() 306 self.assert_raises_os_error(errno.EBADF, self.os.stat, 5) 307 file_path = self.make_path("foo", "bar") 308 self.create_file(file_path) 309 310 with self.open(file_path) as f: 311 self.assertTrue(stat.S_IFREG & self.os.stat(f.filedes)[stat.ST_MODE]) 312 313 def test_stat_no_follow_symlinks_posix(self): 314 """Test that stat with follow_symlinks=False behaves like lstat.""" 315 self.check_posix_only() 316 directory = self.make_path("xyzzy") 317 base_name = "plugh" 318 file_contents = "frobozz" 319 # Just make sure we didn't accidentally make our test data meaningless. 320 self.assertNotEqual(len(base_name), len(file_contents)) 321 file_path = self.os.path.join(directory, base_name) 322 link_path = self.os.path.join(directory, "link") 323 self.create_file(file_path, contents=file_contents) 324 self.create_symlink(link_path, base_name) 325 self.assertEqual( 326 len(file_contents), 327 self.os.stat(file_path, follow_symlinks=False)[stat.ST_SIZE], 328 ) 329 self.assertEqual( 330 len(base_name), 331 self.os.stat(link_path, follow_symlinks=False)[stat.ST_SIZE], 332 ) 333 334 def test_stat_no_follow_symlinks_windows(self): 335 """Test that stat with follow_symlinks=False behaves like lstat.""" 336 self.check_windows_only() 337 self.skip_if_symlink_not_supported() 338 directory = self.make_path("xyzzy") 339 base_name = "plugh" 340 file_contents = "frobozz" 341 # Just make sure we didn't accidentally make our test data meaningless. 342 self.assertNotEqual(len(base_name), len(file_contents)) 343 file_path = self.os.path.join(directory, base_name) 344 link_path = self.os.path.join(directory, "link") 345 self.create_file(file_path, contents=file_contents) 346 self.create_symlink(link_path, base_name) 347 self.assertEqual( 348 len(file_contents), 349 self.os.stat(file_path, follow_symlinks=False)[stat.ST_SIZE], 350 ) 351 self.assertEqual( 352 0, self.os.stat(link_path, follow_symlinks=False)[stat.ST_SIZE] 353 ) 354 355 def test_lstat_size_posix(self): 356 self.check_posix_only() 357 directory = self.make_path("xyzzy") 358 base_name = "plugh" 359 file_contents = "frobozz" 360 # Just make sure we didn't accidentally make our test data meaningless. 361 self.assertNotEqual(len(base_name), len(file_contents)) 362 file_path = self.os.path.join(directory, base_name) 363 link_path = self.os.path.join(directory, "link") 364 self.create_file(file_path, contents=file_contents) 365 self.create_symlink(link_path, base_name) 366 self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) 367 self.assertEqual(len(base_name), self.os.lstat(link_path)[stat.ST_SIZE]) 368 369 def test_lstat_size_windows(self): 370 self.check_windows_only() 371 self.skip_if_symlink_not_supported() 372 directory = self.make_path("xyzzy") 373 base_name = "plugh" 374 file_contents = "frobozz" 375 # Just make sure we didn't accidentally make our test data meaningless. 376 self.assertNotEqual(len(base_name), len(file_contents)) 377 file_path = self.os.path.join(directory, base_name) 378 link_path = self.os.path.join(directory, "link") 379 self.create_file(file_path, contents=file_contents) 380 self.create_symlink(link_path, base_name) 381 self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) 382 self.assertEqual(0, self.os.lstat(link_path)[stat.ST_SIZE]) 383 384 def test_lstat_trailing_sep(self): 385 # regression test for #342 386 stat_result = self.os.lstat(self.base_path) 387 self.assertEqual( 388 stat_result, self.os.lstat(self.base_path + self.path_separator()) 389 ) 390 self.assertEqual( 391 stat_result, 392 self.os.lstat( 393 self.base_path + self.path_separator() + self.path_separator() 394 ), 395 ) 396 397 def test_stat_with_byte_string(self): 398 stat_str = self.os.stat(self.base_path) 399 base_path_bytes = self.base_path.encode("utf8") 400 stat_bytes = self.os.stat(base_path_bytes) 401 self.assertEqual(stat_bytes, stat_str) 402 403 def test_lstat_with_byte_string(self): 404 stat_str = self.os.lstat(self.base_path) 405 base_path_bytes = self.base_path.encode("utf8") 406 stat_bytes = self.os.lstat(base_path_bytes) 407 self.assertEqual(stat_bytes, stat_str) 408 409 def test_stat_with_current_dir(self): 410 # regression test for #516 411 stat_result = self.os.stat(".") 412 lstat_result = self.os.lstat(".") 413 self.assertEqual(stat_result, lstat_result) 414 415 def test_exists_with_trailing_sep(self): 416 # regression test for #364 417 file_path = self.make_path("alpha") 418 self.create_file(file_path) 419 self.assertFalse(self.os.path.exists(file_path + self.os.sep)) 420 421 def test_mkdir_with_trailing_sep(self): 422 # regression test for #367 423 dir_path = self.make_path("foo") 424 self.os.mkdir(dir_path + self.os.sep + self.os.sep) 425 self.assertTrue(self.os.path.exists(dir_path)) 426 427 def test_readlink_empty_path(self): 428 self.check_posix_only() 429 self.assert_raises_os_error(errno.ENOENT, self.os.readlink, "") 430 431 def test_readlink_ending_with_sep_posix(self): 432 # regression test for #359 433 self.check_posix_only() 434 link_path = self.make_path("foo") 435 self.os.symlink(self.base_path, link_path) 436 self.assert_raises_os_error( 437 errno.EINVAL, self.os.readlink, link_path + self.os.sep 438 ) 439 440 def test_lstat_symlink_with_trailing_sep_linux(self): 441 # regression test for #366 442 self.check_linux_only() 443 self.skip_if_symlink_not_supported() 444 link_path = self.make_path("foo") 445 self.os.symlink(self.base_path, link_path) 446 # used to raise 447 self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) 448 449 def test_lstat_symlink_with_trailing_sep_macos(self): 450 # regression test for #366 451 self.check_macos_only() 452 self.skip_if_symlink_not_supported() 453 link_path = self.make_path("foo") 454 self.os.symlink(self.base_path, link_path) 455 # used to raise 456 self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) 457 458 def test_readlink_ending_with_sep_windows(self): 459 self.check_windows_only() 460 self.skip_if_symlink_not_supported() 461 link_path = self.make_path("foo") 462 self.os.symlink(self.base_path, link_path) 463 self.assert_equal_paths( 464 self.base_path, self.os.readlink(link_path + self.os.sep) 465 ) 466 467 def test_islink_with_trailing_sep_windows(self): 468 self.check_windows_only() 469 self.skip_if_symlink_not_supported() 470 link_path = self.make_path("foo") 471 self.os.symlink(self.base_path, link_path) 472 self.assertTrue(self.os.path.islink(link_path + self.os.path.sep)) 473 474 def test_islink_with_trailing_sep_linux(self): 475 self.check_linux_only() 476 link_path = self.make_path("foo") 477 self.os.symlink(self.base_path, link_path) 478 self.assertFalse(self.os.path.islink(link_path + self.os.sep)) 479 480 def test_islink_with_trailing_sep_macos(self): 481 self.check_macos_only() 482 link_path = self.make_path("foo") 483 self.os.symlink(self.base_path, link_path) 484 self.assertFalse(self.os.path.islink(link_path + self.os.sep)) 485 486 def check_getsize_raises_with_trailing_separator(self, error_nr): 487 file_path = self.make_path("bar") 488 self.create_file(file_path) 489 self.assert_raises_os_error( 490 error_nr, self.os.path.getsize, file_path + self.os.sep 491 ) 492 493 def test_getsize_raises_with_trailing_separator_posix(self): 494 self.check_posix_only() 495 self.check_getsize_raises_with_trailing_separator(errno.ENOTDIR) 496 497 def test_getsize_raises_with_trailing_separator_windows(self): 498 self.check_windows_only() 499 self.check_getsize_raises_with_trailing_separator(errno.EINVAL) 500 501 def check_remove_link_ending_with_sep(self, error_nr): 502 # regression test for #360 503 link_path = self.make_path("foo") 504 self.os.symlink(self.base_path, link_path) 505 self.assert_raises_os_error(error_nr, self.os.remove, link_path + self.os.sep) 506 507 def test_remove_link_ending_with_sep_linux(self): 508 self.check_linux_only() 509 self.check_remove_link_ending_with_sep(errno.ENOTDIR) 510 511 def test_remove_link_ending_with_sep_macos(self): 512 self.check_macos_only() 513 self.check_remove_link_ending_with_sep(errno.EPERM) 514 515 def test_remove_link_ending_with_sep_windows(self): 516 self.check_windows_only() 517 self.skip_if_symlink_not_supported() 518 self.check_remove_link_ending_with_sep(errno.EACCES) 519 520 def test_lstat_uses_open_fd_as_path(self): 521 self.skip_if_symlink_not_supported() 522 if os.lstat not in os.supports_fd: 523 self.skip_real_fs() 524 self.assert_raises_os_error(errno.EBADF, self.os.lstat, 5) 525 file_path = self.make_path("foo", "bar") 526 link_path = self.make_path("foo", "link") 527 file_contents = b"contents" 528 self.create_file(file_path, contents=file_contents) 529 self.create_symlink(link_path, file_path) 530 531 with self.open(file_path) as f: 532 self.assertEqual(len(file_contents), self.os.lstat(f.filedes)[stat.ST_SIZE]) 533 534 def test_stat_non_existent_file(self): 535 # set up 536 file_path = self.make_path("non", "existent", "file") 537 self.assertFalse(self.os.path.exists(file_path)) 538 # actual tests 539 try: 540 # Use try-catch to check exception attributes. 541 self.os.stat(file_path) 542 self.fail("Exception is expected.") # COV_NF_LINE 543 except OSError as os_error: 544 self.assertEqual(errno.ENOENT, os_error.errno) 545 self.assertEqual(file_path, os_error.filename) 546 547 def check_open_raises_with_trailing_separator(self, error_nr): 548 file_path = self.make_path("bar") + self.os.sep 549 self.assert_raises_os_error( 550 error_nr, 551 self.os.open, 552 file_path, 553 os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 554 ) 555 556 def test_open_raises_with_trailing_separator_linux(self): 557 self.check_linux_only() 558 self.check_open_raises_with_trailing_separator(errno.EISDIR) 559 560 def test_open_raises_with_trailing_separator_macos(self): 561 self.check_macos_only() 562 self.check_open_raises_with_trailing_separator(errno.ENOENT) 563 564 def test_open_raises_with_trailing_separator_windows(self): 565 self.check_windows_only() 566 self.check_open_raises_with_trailing_separator(errno.EINVAL) 567 568 def test_lexists_with_trailing_separator_linux_windows(self): 569 self.check_linux_and_windows() 570 self.skip_if_symlink_not_supported() 571 file_path = self.make_path("foo") 572 self.os.symlink(file_path, file_path) 573 self.assertFalse(self.os.path.lexists(file_path + self.os.sep)) 574 575 def test_lexists_with_trailing_separator_macos(self): 576 # regression test for #373 577 self.check_macos_only() 578 file_path = self.make_path("foo") 579 self.os.symlink(file_path, file_path) 580 self.assertTrue(self.os.path.lexists(file_path + self.os.sep)) 581 582 def test_islink_with_trailing_separator_linux_windows(self): 583 self.check_linux_and_windows() 584 self.skip_if_symlink_not_supported() 585 file_path = self.make_path("foo") 586 self.os.symlink(file_path, file_path) 587 self.assertFalse(self.os.path.islink(file_path + self.os.sep)) 588 589 def test_islink_with_trailing_separator_macos(self): 590 # regression test for #373 591 self.check_macos_only() 592 file_path = self.make_path("foo") 593 self.os.symlink(file_path, file_path) 594 self.assertTrue(self.os.path.islink(file_path + self.os.sep)) 595 596 def test_isfile_with_trailing_separator_linux_windows(self): 597 self.check_linux_and_windows() 598 file_path = self.make_path("foo") 599 self.create_file(file_path) 600 self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) 601 602 def test_isfile_with_trailing_separator_macos(self): 603 # regression test for #374 604 self.check_macos_only() 605 file_path = self.make_path("foo") 606 self.create_file(file_path) 607 self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) 608 609 def test_isfile_not_readable_file(self): 610 file_path = self.make_path("foo") 611 self.create_file(file_path, perm=0) 612 self.assertTrue(self.os.path.isfile(file_path)) 613 614 def check_stat_with_trailing_separator(self, error_nr): 615 # regression test for #376 616 file_path = self.make_path("foo") 617 self.create_file(file_path) 618 self.assert_raises_os_error(error_nr, self.os.stat, file_path + self.os.sep) 619 620 def test_stat_with_trailing_separator_posix(self): 621 self.check_posix_only() 622 self.check_stat_with_trailing_separator(errno.ENOTDIR) 623 624 def test_stat_with_trailing_separator_windows(self): 625 self.check_windows_only() 626 self.check_stat_with_trailing_separator(errno.EINVAL) 627 628 def check_remove_with_trailing_separator(self, error_nr): 629 # regression test for #377 630 file_path = self.make_path("foo") 631 self.create_file(file_path) 632 self.assert_raises_os_error(error_nr, self.os.remove, file_path + self.os.sep) 633 634 def test_remove_with_trailing_separator_posix(self): 635 self.check_posix_only() 636 self.check_remove_with_trailing_separator(errno.ENOTDIR) 637 638 def test_remove_with_trailing_separator_windows(self): 639 self.check_windows_only() 640 self.check_remove_with_trailing_separator(errno.EINVAL) 641 642 def test_readlink(self): 643 self.skip_if_symlink_not_supported() 644 link_path = self.make_path("foo", "bar", "baz") 645 target = self.make_path("tarJAY") 646 self.create_symlink(link_path, target) 647 self.assert_equal_paths(self.os.readlink(link_path), target) 648 649 def check_readlink_raises_if_path_is_not_a_link(self): 650 file_path = self.make_path("foo", "bar", "eleventyone") 651 self.create_file(file_path) 652 self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path) 653 654 def test_readlink_raises_if_path_is_not_a_link_windows(self): 655 self.check_windows_only() 656 self.skip_if_symlink_not_supported() 657 self.check_readlink_raises_if_path_is_not_a_link() 658 659 def test_readlink_raises_if_path_is_not_a_link_posix(self): 660 self.check_posix_only() 661 self.check_readlink_raises_if_path_is_not_a_link() 662 663 def check_readlink_raises_if_path_has_file(self, error_subtype): 664 self.create_file(self.make_path("a_file")) 665 file_path = self.make_path("a_file", "foo") 666 self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) 667 file_path = self.make_path("a_file", "foo", "bar") 668 self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) 669 670 def test_readlink_raises_if_path_has_file_windows(self): 671 self.check_windows_only() 672 self.skip_if_symlink_not_supported() 673 self.check_readlink_raises_if_path_has_file(errno.ENOENT) 674 675 def test_readlink_raises_if_path_has_file_posix(self): 676 self.check_posix_only() 677 self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) 678 679 def test_readlink_raises_if_path_does_not_exist(self): 680 self.skip_if_symlink_not_supported() 681 self.assert_raises_os_error( 682 errno.ENOENT, self.os.readlink, "/this/path/does/not/exist" 683 ) 684 685 def test_readlink_raises_if_path_is_none(self): 686 self.skip_if_symlink_not_supported() 687 with self.assertRaises(TypeError): 688 self.os.readlink(None) 689 690 def test_broken_symlink_with_trailing_separator_linux(self): 691 self.check_linux_only() 692 file_path = self.make_path("foo") 693 link_path = self.make_path("link") 694 self.os.symlink(file_path, link_path) 695 self.assert_raises_os_error( 696 errno.EEXIST, 697 self.os.symlink, 698 link_path + self.os.sep, 699 link_path + self.os.sep, 700 ) 701 702 def test_broken_symlink_with_trailing_separator_macos(self): 703 # regression test for #371 704 self.check_macos_only() 705 file_path = self.make_path("foo") 706 link_path = self.make_path("link") 707 self.os.symlink(file_path, link_path) 708 self.os.symlink(link_path + self.os.sep, link_path + self.os.sep) 709 710 def test_broken_symlink_with_trailing_separator_windows(self): 711 self.check_windows_only() 712 self.skip_if_symlink_not_supported() 713 file_path = self.make_path("foo") 714 link_path = self.make_path("link") 715 self.os.symlink(file_path, link_path) 716 self.assert_raises_os_error( 717 errno.EINVAL, 718 self.os.symlink, 719 link_path + self.os.sep, 720 link_path + self.os.sep, 721 ) 722 723 def test_circular_readlink_with_trailing_separator_linux(self): 724 # Regression test for #372 725 self.check_linux_only() 726 file_path = self.make_path("foo") 727 self.os.symlink(file_path, file_path) 728 self.assert_raises_os_error( 729 errno.ELOOP, self.os.readlink, file_path + self.os.sep 730 ) 731 732 def test_circular_readlink_with_trailing_separator_macos(self): 733 # Regression test for #372 734 self.check_macos_only() 735 file_path = self.make_path("foo") 736 self.os.symlink(file_path, file_path) 737 self.os.readlink(file_path + self.os.sep) 738 739 def test_circular_readlink_with_trailing_separator_windows(self): 740 # Regression test for #372 741 self.check_windows_only() 742 self.skip_if_symlink_not_supported() 743 file_path = self.make_path("foo") 744 self.os.symlink(file_path, file_path) 745 self.assert_raises_os_error( 746 errno.EINVAL, self.os.readlink, file_path + self.os.sep 747 ) 748 749 def test_readlink_with_links_in_path(self): 750 self.skip_if_symlink_not_supported() 751 self.create_symlink( 752 self.make_path("meyer", "lemon", "pie"), self.make_path("yum") 753 ) 754 self.create_symlink(self.make_path("geo", "metro"), self.make_path("meyer")) 755 self.assert_equal_paths( 756 self.make_path("yum"), 757 self.os.readlink(self.make_path("geo", "metro", "lemon", "pie")), 758 ) 759 760 def test_readlink_with_chained_links_in_path(self): 761 self.skip_if_symlink_not_supported() 762 self.create_symlink( 763 self.make_path("eastern", "european", "wolfhounds", "chase"), 764 self.make_path("cats"), 765 ) 766 self.create_symlink( 767 self.make_path("russian"), self.make_path("eastern", "european") 768 ) 769 self.create_symlink( 770 self.make_path("dogs"), self.make_path("russian", "wolfhounds") 771 ) 772 self.assert_equal_paths( 773 self.make_path("cats"), 774 self.os.readlink(self.make_path("dogs", "chase")), 775 ) 776 777 def check_remove_dir(self, dir_error): 778 directory = self.make_path("xyzzy") 779 dir_path = self.os.path.join(directory, "plugh") 780 self.create_dir(dir_path) 781 self.assertTrue(self.os.path.exists(dir_path)) 782 self.assert_raises_os_error(dir_error, self.os.remove, dir_path) 783 self.assertTrue(self.os.path.exists(dir_path)) 784 self.os.chdir(directory) 785 self.assert_raises_os_error(dir_error, self.os.remove, dir_path) 786 self.assertTrue(self.os.path.exists(dir_path)) 787 self.assert_raises_os_error(errno.ENOENT, self.os.remove, "/plugh") 788 789 def test_remove_dir_linux(self): 790 self.check_linux_only() 791 self.check_remove_dir(errno.EISDIR) 792 793 def test_remove_dir_mac_os(self): 794 self.check_macos_only() 795 self.check_remove_dir(errno.EPERM) 796 797 def test_remove_dir_windows(self): 798 self.check_windows_only() 799 self.check_remove_dir(errno.EACCES) 800 801 def test_remove_dir_with_drive(self): 802 # regression test for issue #337 803 self.check_windows_only() 804 self.skip_real_fs() 805 dir_path = self.os.path.join("C:", "test") 806 self.filesystem.create_dir(dir_path) 807 self.assert_raises_os_error(errno.EACCES, self.os.remove, dir_path) 808 809 def test_remove_file(self): 810 directory = self.make_path("zzy") 811 file_path = self.os.path.join(directory, "plugh") 812 self.create_file(file_path) 813 self.assertTrue(self.os.path.exists(file_path)) 814 self.os.remove(file_path) 815 self.assertFalse(self.os.path.exists(file_path)) 816 817 def test_remove_file_no_directory(self): 818 directory = self.make_path("zzy") 819 file_name = "plugh" 820 file_path = self.os.path.join(directory, file_name) 821 self.create_file(file_path) 822 self.assertTrue(self.os.path.exists(file_path)) 823 self.os.chdir(directory) 824 self.os.remove(file_name) 825 self.assertFalse(self.os.path.exists(file_path)) 826 827 def test_remove_file_with_read_permission_raises_in_windows(self): 828 self.check_windows_only() 829 path = self.make_path("foo", "bar") 830 self.create_file(path) 831 self.os.chmod(path, 0o444) 832 self.assert_raises_os_error(errno.EACCES, self.os.remove, path) 833 self.os.chmod(path, 0o666) 834 835 def test_remove_file_with_read_permission_shall_succeed_in_posix(self): 836 self.check_posix_only() 837 path = self.make_path("foo", "bar") 838 self.create_file(path) 839 self.os.chmod(path, 0o444) 840 self.os.remove(path) 841 self.assertFalse(self.os.path.exists(path)) 842 843 def test_remove_file_without_parent_permission_raises_in_posix(self): 844 self.check_posix_only() 845 parent_dir = self.make_path("foo") 846 path = self.os.path.join(parent_dir, "bar") 847 self.create_file(path) 848 self.os.chmod(parent_dir, 0o666) # missing execute permission 849 if not is_root(): 850 self.assert_raises_os_error(errno.EACCES, self.os.remove, path) 851 else: 852 self.os.remove(path) 853 self.assertFalse(self.os.path.exists(path)) 854 self.create_file(path) 855 self.os.chmod(parent_dir, 0o555) # missing write permission 856 if not is_root(): 857 self.assert_raises_os_error(errno.EACCES, self.os.remove, path) 858 else: 859 self.os.remove(path) 860 self.assertFalse(self.os.path.exists(path)) 861 self.create_file(path) 862 self.os.chmod(parent_dir, 0o333) 863 self.os.remove(path) 864 self.assertFalse(self.os.path.exists(path)) 865 866 def test_remove_open_file_fails_under_windows(self): 867 self.check_windows_only() 868 path = self.make_path("foo", "bar") 869 self.create_file(path) 870 with self.open(path, "r"): 871 self.assert_raises_os_error(errno.EACCES, self.os.remove, path) 872 self.assertTrue(self.os.path.exists(path)) 873 874 def test_remove_open_file_possible_under_posix(self): 875 self.check_posix_only() 876 path = self.make_path("foo", "bar") 877 self.create_file(path) 878 self.open(path, "r") 879 self.os.remove(path) 880 self.assertFalse(self.os.path.exists(path)) 881 882 def test_remove_file_relative_path(self): 883 self.skip_real_fs() 884 original_dir = self.os.getcwd() 885 directory = self.make_path("zzy") 886 subdirectory = self.os.path.join(directory, "zzy") 887 file_name = "plugh" 888 file_path = self.os.path.join(directory, file_name) 889 file_path_relative = self.os.path.join("..", file_name) 890 self.create_file(file_path) 891 self.assertTrue(self.os.path.exists(file_path)) 892 self.create_dir(subdirectory) 893 self.assertTrue(self.os.path.exists(subdirectory)) 894 self.os.chdir(subdirectory) 895 self.os.remove(file_path_relative) 896 self.assertFalse(self.os.path.exists(file_path_relative)) 897 self.os.chdir(original_dir) 898 self.assertFalse(self.os.path.exists(file_path)) 899 900 def check_remove_dir_raises_error(self, dir_error): 901 directory = self.make_path("zzy") 902 self.create_dir(directory) 903 self.assert_raises_os_error(dir_error, self.os.remove, directory) 904 905 def test_remove_dir_raises_error_linux(self): 906 self.check_linux_only() 907 self.check_remove_dir_raises_error(errno.EISDIR) 908 909 def test_remove_dir_raises_error_mac_os(self): 910 self.check_macos_only() 911 self.check_remove_dir_raises_error(errno.EPERM) 912 913 def test_remove_dir_raises_error_windows(self): 914 self.check_windows_only() 915 self.check_remove_dir_raises_error(errno.EACCES) 916 917 def test_remove_symlink_to_dir(self): 918 self.skip_if_symlink_not_supported() 919 directory = self.make_path("zzy") 920 link = self.make_path("link_to_dir") 921 self.create_dir(directory) 922 self.os.symlink(directory, link) 923 self.assertTrue(self.os.path.exists(directory)) 924 self.assertTrue(self.os.path.exists(link)) 925 self.os.remove(link) 926 self.assertTrue(self.os.path.exists(directory)) 927 self.assertFalse(self.os.path.exists(link)) 928 929 def test_unlink_raises_if_not_exist(self): 930 file_path = self.make_path("file", "does", "not", "exist") 931 self.assertFalse(self.os.path.exists(file_path)) 932 self.assert_raises_os_error(errno.ENOENT, self.os.unlink, file_path) 933 934 def test_rename_to_nonexistent_file(self): 935 """Can rename a file to an unused name.""" 936 directory = self.make_path("xyzzy") 937 old_file_path = self.os.path.join(directory, "plugh_old") 938 new_file_path = self.os.path.join(directory, "plugh_new") 939 self.create_file(old_file_path, contents="test contents") 940 self.assertTrue(self.os.path.exists(old_file_path)) 941 self.assertFalse(self.os.path.exists(new_file_path)) 942 self.os.rename(old_file_path, new_file_path) 943 self.assertFalse(self.os.path.exists(old_file_path)) 944 self.assertTrue(self.os.path.exists(new_file_path)) 945 self.check_contents(new_file_path, "test contents") 946 947 def test_rename_dir_to_symlink_posix(self): 948 self.check_posix_only() 949 link_path = self.make_path("link") 950 dir_path = self.make_path("dir") 951 link_target = self.os.path.join(dir_path, "link_target") 952 self.create_dir(dir_path) 953 self.os.symlink(link_target, link_path) 954 self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) 955 956 def test_rename_dir_to_symlink_windows(self): 957 self.check_windows_only() 958 self.skip_if_symlink_not_supported() 959 link_path = self.make_path("link") 960 dir_path = self.make_path("dir") 961 link_target = self.os.path.join(dir_path, "link_target") 962 self.create_dir(dir_path) 963 self.os.symlink(link_target, link_path) 964 self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) 965 966 def test_rename_file_to_symlink(self): 967 self.check_posix_only() 968 link_path = self.make_path("file_link") 969 file_path = self.make_path("file") 970 self.os.symlink(file_path, link_path) 971 self.create_file(file_path) 972 self.os.rename(file_path, link_path) 973 self.assertFalse(self.os.path.exists(file_path)) 974 self.assertTrue(self.os.path.exists(link_path)) 975 self.assertTrue(self.os.path.isfile(link_path)) 976 977 def test_rename_symlink_to_symlink(self): 978 self.check_posix_only() 979 base_path = self.make_path("foo", "bar") 980 self.create_dir(base_path) 981 link_path1 = self.os.path.join(base_path, "link1") 982 link_path2 = self.os.path.join(base_path, "link2") 983 self.os.symlink(base_path, link_path1) 984 self.os.symlink(base_path, link_path2) 985 self.os.rename(link_path1, link_path2) 986 self.assertFalse(self.os.path.exists(link_path1)) 987 self.assertTrue(self.os.path.exists(link_path2)) 988 989 def test_rename_symlink_to_symlink_for_parent_raises(self): 990 self.check_posix_only() 991 dir_link = self.make_path("dir_link") 992 dir_path = self.make_path("dir") 993 dir_in_dir_path = self.os.path.join(dir_link, "inner_dir") 994 self.create_dir(dir_path) 995 self.os.symlink(dir_path, dir_link) 996 self.create_dir(dir_in_dir_path) 997 self.assert_raises_os_error( 998 errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path 999 ) 1000 1001 def check_rename_case_with_symlink(self, result): 1002 self.skip_if_symlink_not_supported() 1003 self.check_case_insensitive_fs() 1004 dir_path_lower = self.make_path("beta") 1005 self.create_dir(dir_path_lower) 1006 link_path = self.make_path("b") 1007 self.os.symlink(self.base_path, link_path) 1008 path1 = self.os.path.join(link_path, "Beta") 1009 dir_path_upper = self.make_path("Beta") 1010 self.os.rename(path1, dir_path_upper) 1011 self.assertEqual(result, sorted(self.os.listdir(self.base_path))) 1012 1013 def test_rename_case_with_symlink_mac(self): 1014 # Regression test for #322 1015 self.check_macos_only() 1016 self.check_rename_case_with_symlink(["b", "beta"]) 1017 1018 def test_rename_case_with_symlink_windows(self): 1019 self.check_windows_only() 1020 self.check_rename_case_with_symlink(["Beta", "b"]) 1021 1022 def test_recursive_rename_raises(self): 1023 self.check_posix_only() 1024 base_path = self.make_path("foo", "bar") 1025 self.create_dir(base_path) 1026 new_path = self.os.path.join(base_path, "new_dir") 1027 self.assert_raises_os_error(errno.EINVAL, self.os.rename, base_path, new_path) 1028 1029 def test_rename_file_to_parent_dir_file(self): 1030 # Regression test for issue 230 1031 dir_path = self.make_path("dir") 1032 self.create_dir(dir_path) 1033 file_path = self.make_path("old_file") 1034 new_file_path = self.os.path.join(dir_path, "new_file") 1035 self.create_file(file_path) 1036 self.os.rename(file_path, new_file_path) 1037 1038 def test_rename_with_target_parent_file_raises_posix(self): 1039 self.check_posix_only() 1040 file_path = self.make_path("foo", "baz") 1041 self.create_file(file_path) 1042 self.assert_raises_os_error( 1043 errno.ENOTDIR, self.os.rename, file_path, file_path + "/new" 1044 ) 1045 1046 def test_rename_with_target_parent_file_raises_windows(self): 1047 self.check_windows_only() 1048 file_path = self.make_path("foo", "baz") 1049 self.create_file(file_path) 1050 self.assert_raises_os_error( 1051 errno.EACCES, 1052 self.os.rename, 1053 file_path, 1054 self.os.path.join(file_path, "new"), 1055 ) 1056 1057 def test_rename_symlink_to_source(self): 1058 self.check_posix_only() 1059 base_path = self.make_path("foo") 1060 link_path = self.os.path.join(base_path, "slink") 1061 file_path = self.os.path.join(base_path, "file") 1062 self.create_file(file_path) 1063 self.os.symlink(file_path, link_path) 1064 self.os.rename(link_path, file_path) 1065 self.assertFalse(self.os.path.exists(file_path)) 1066 1067 def test_rename_symlink_to_dir_raises(self): 1068 self.check_posix_only() 1069 base_path = self.make_path("foo", "bar") 1070 link_path = self.os.path.join(base_path, "dir_link") 1071 dir_path = self.os.path.join(base_path, "dir") 1072 self.create_dir(dir_path) 1073 self.os.symlink(dir_path, link_path) 1074 self.assert_raises_os_error(errno.EISDIR, self.os.rename, link_path, dir_path) 1075 1076 def test_rename_broken_symlink(self): 1077 self.check_posix_only() 1078 base_path = self.make_path("foo") 1079 self.create_dir(base_path) 1080 link_path = self.os.path.join(base_path, "slink") 1081 file_path = self.os.path.join(base_path, "file") 1082 self.os.symlink(file_path, link_path) 1083 self.os.rename(link_path, file_path) 1084 self.assertFalse(self.os.path.exists(file_path)) 1085 self.assertTrue(self.os.path.lexists(file_path)) 1086 self.assertFalse(self.os.path.exists(link_path)) 1087 1088 def test_rename_directory(self): 1089 """Can rename a directory to an unused name.""" 1090 for old_path, new_path in [("wxyyw", "xyzzy"), ("abccb", "cdeed")]: 1091 old_path = self.make_path(old_path) 1092 new_path = self.make_path(new_path) 1093 self.create_file(self.os.path.join(old_path, "plugh"), contents="test") 1094 self.assertTrue(self.os.path.exists(old_path)) 1095 self.assertFalse(self.os.path.exists(new_path)) 1096 self.os.rename(old_path, new_path) 1097 self.assertFalse(self.os.path.exists(old_path)) 1098 self.assertTrue(self.os.path.exists(new_path)) 1099 self.check_contents(self.os.path.join(new_path, "plugh"), "test") 1100 if not self.use_real_fs(): 1101 self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) 1102 1103 def check_rename_directory_to_existing_file_raises(self, error_nr): 1104 dir_path = self.make_path("dir") 1105 file_path = self.make_path("file") 1106 self.create_dir(dir_path) 1107 self.create_file(file_path) 1108 self.assert_raises_os_error(error_nr, self.os.rename, dir_path, file_path) 1109 1110 def test_rename_directory_to_existing_file_raises_posix(self): 1111 self.check_posix_only() 1112 self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) 1113 1114 def test_rename_directory_to_existing_file_raises_windows(self): 1115 self.check_windows_only() 1116 self.check_rename_directory_to_existing_file_raises(errno.EEXIST) 1117 1118 def test_rename_to_existing_directory_should_raise_under_windows(self): 1119 """Renaming to an existing directory raises OSError under Windows.""" 1120 self.check_windows_only() 1121 old_path = self.make_path("foo", "bar") 1122 new_path = self.make_path("foo", "baz") 1123 self.create_dir(old_path) 1124 self.create_dir(new_path) 1125 self.assert_raises_os_error(errno.EEXIST, self.os.rename, old_path, new_path) 1126 1127 def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): 1128 self.skip_real_fs_failure(skip_posix=False) 1129 self.skip_if_symlink_not_supported() 1130 file_path = self.make_path("dir", "file") 1131 self.create_file(file_path) 1132 link_path = self.make_path("link") 1133 self.os.link(file_path, link_path) 1134 self.os.rename(file_path, link_path) 1135 self.assertTrue(self.os.path.exists(file_path)) 1136 self.assertTrue(self.os.path.exists(link_path)) 1137 1138 def test_hardlink_works_with_symlink(self): 1139 self.skip_if_symlink_not_supported() 1140 base_path = self.make_path("foo") 1141 self.create_dir(base_path) 1142 symlink_path = self.os.path.join(base_path, "slink") 1143 self.os.symlink(base_path, symlink_path) 1144 file_path = self.os.path.join(base_path, "slink", "beta") 1145 self.create_file(file_path) 1146 link_path = self.os.path.join(base_path, "slink", "gamma") 1147 self.os.link(file_path, link_path) 1148 self.assertTrue(self.os.path.exists(link_path)) 1149 self.assertFalse(self.os.path.islink(link_path)) 1150 1151 def test_replace_existing_directory_should_raise_under_windows(self): 1152 """Renaming to an existing directory raises OSError under Windows.""" 1153 self.check_windows_only() 1154 old_path = self.make_path("foo", "bar") 1155 new_path = self.make_path("foo", "baz") 1156 self.create_dir(old_path) 1157 self.create_dir(new_path) 1158 self.assert_raises_os_error(errno.EACCES, self.os.replace, old_path, new_path) 1159 1160 def test_rename_to_existing_directory_under_posix(self): 1161 """Renaming to an existing directory changes the existing directory 1162 under Posix.""" 1163 self.check_posix_only() 1164 old_path = self.make_path("foo", "bar") 1165 new_path = self.make_path("xyzzy") 1166 self.create_dir(self.os.path.join(old_path, "sub")) 1167 self.create_dir(new_path) 1168 self.os.rename(old_path, new_path) 1169 self.assertTrue(self.os.path.exists(self.os.path.join(new_path, "sub"))) 1170 self.assertFalse(self.os.path.exists(old_path)) 1171 1172 def test_rename_file_to_existing_directory_raises_under_posix(self): 1173 self.check_posix_only() 1174 file_path = self.make_path("foo", "bar", "baz") 1175 new_path = self.make_path("xyzzy") 1176 self.create_file(file_path) 1177 self.create_dir(new_path) 1178 self.assert_raises_os_error(errno.EISDIR, self.os.rename, file_path, new_path) 1179 1180 def test_rename_to_existing_dir_under_posix_raises_if_not_empty(self): 1181 """Renaming to an existing directory changes the existing directory 1182 under Posix.""" 1183 self.check_posix_only() 1184 old_path = self.make_path("foo", "bar") 1185 new_path = self.make_path("foo", "baz") 1186 self.create_dir(self.os.path.join(old_path, "sub")) 1187 self.create_dir(self.os.path.join(new_path, "sub")) 1188 1189 # not testing specific subtype: 1190 # raises errno.ENOTEMPTY under Ubuntu 16.04, MacOS and pyfakefs 1191 # but raises errno.EEXIST at least under Ubunto 14.04 1192 with self.assertRaises(OSError): 1193 self.os.rename(old_path, new_path) 1194 1195 def test_rename_to_another_device_should_raise(self): 1196 """Renaming to another filesystem device raises OSError.""" 1197 self.skip_real_fs() 1198 self.filesystem.add_mount_point("/mount") 1199 old_path = "/foo/bar" 1200 new_path = "/mount/bar" 1201 self.filesystem.create_file(old_path) 1202 self.assert_raises_os_error(errno.EXDEV, self.os.rename, old_path, new_path) 1203 1204 def test_rename_to_existent_file_posix(self): 1205 """Can rename a file to a used name under Unix.""" 1206 self.check_posix_only() 1207 directory = self.make_path("xyzzy") 1208 old_file_path = self.os.path.join(directory, "plugh_old") 1209 new_file_path = self.os.path.join(directory, "plugh_new") 1210 self.create_file(old_file_path, contents="test contents 1") 1211 self.create_file(new_file_path, contents="test contents 2") 1212 self.assertTrue(self.os.path.exists(old_file_path)) 1213 self.assertTrue(self.os.path.exists(new_file_path)) 1214 self.os.rename(old_file_path, new_file_path) 1215 self.assertFalse(self.os.path.exists(old_file_path)) 1216 self.assertTrue(self.os.path.exists(new_file_path)) 1217 self.check_contents(new_file_path, "test contents 1") 1218 1219 def test_rename_to_existent_file_windows(self): 1220 """Renaming a file to a used name raises OSError under Windows.""" 1221 self.check_windows_only() 1222 directory = self.make_path("xyzzy") 1223 old_file_path = self.os.path.join(directory, "plugh_old") 1224 new_file_path = self.os.path.join(directory, "plugh_new") 1225 self.create_file(old_file_path, contents="test contents 1") 1226 self.create_file(new_file_path, contents="test contents 2") 1227 self.assertTrue(self.os.path.exists(old_file_path)) 1228 self.assertTrue(self.os.path.exists(new_file_path)) 1229 self.assert_raises_os_error( 1230 errno.EEXIST, self.os.rename, old_file_path, new_file_path 1231 ) 1232 1233 def test_replace_to_existent_file(self): 1234 """Replaces an existing file (does not work with `rename()` under 1235 Windows).""" 1236 directory = self.make_path("xyzzy") 1237 old_file_path = self.os.path.join(directory, "plugh_old") 1238 new_file_path = self.os.path.join(directory, "plugh_new") 1239 self.create_file(old_file_path, contents="test contents 1") 1240 self.create_file(new_file_path, contents="test contents 2") 1241 self.assertTrue(self.os.path.exists(old_file_path)) 1242 self.assertTrue(self.os.path.exists(new_file_path)) 1243 self.os.replace(old_file_path, new_file_path) 1244 self.assertFalse(self.os.path.exists(old_file_path)) 1245 self.assertTrue(self.os.path.exists(new_file_path)) 1246 self.check_contents(new_file_path, "test contents 1") 1247 1248 def test_rename_to_nonexistent_dir(self): 1249 """Can rename a file to a name in a nonexistent dir.""" 1250 directory = self.make_path("xyzzy") 1251 old_file_path = self.os.path.join(directory, "plugh_old") 1252 new_file_path = self.os.path.join(directory, "no_such_path", "plugh_new") 1253 self.create_file(old_file_path, contents="test contents") 1254 self.assertTrue(self.os.path.exists(old_file_path)) 1255 self.assertFalse(self.os.path.exists(new_file_path)) 1256 self.assert_raises_os_error( 1257 errno.ENOENT, self.os.rename, old_file_path, new_file_path 1258 ) 1259 self.assertTrue(self.os.path.exists(old_file_path)) 1260 self.assertFalse(self.os.path.exists(new_file_path)) 1261 self.check_contents(old_file_path, "test contents") 1262 1263 def test_rename_nonexistent_file_should_raise_error(self): 1264 """Can't rename a file that doesn't exist.""" 1265 self.assert_raises_os_error( 1266 errno.ENOENT, 1267 self.os.rename, 1268 "nonexistent-foo", 1269 "doesn't-matter-bar", 1270 ) 1271 1272 def test_rename_empty_dir(self): 1273 """Test a rename of an empty directory.""" 1274 directory = self.make_path("xyzzy") 1275 before_dir = self.os.path.join(directory, "empty") 1276 after_dir = self.os.path.join(directory, "unused") 1277 self.create_dir(before_dir) 1278 self.assertTrue(self.os.path.exists(self.os.path.join(before_dir, "."))) 1279 self.assertFalse(self.os.path.exists(after_dir)) 1280 self.os.rename(before_dir, after_dir) 1281 self.assertFalse(self.os.path.exists(before_dir)) 1282 self.assertTrue(self.os.path.exists(self.os.path.join(after_dir, "."))) 1283 1284 def test_rename_symlink(self): 1285 self.check_posix_only() 1286 base_path = self.make_path("foo", "bar") 1287 self.create_dir(base_path) 1288 link_path = self.os.path.join(base_path, "link") 1289 self.os.symlink(base_path, link_path) 1290 file_path = self.os.path.join(link_path, "file") 1291 new_file_path = self.os.path.join(link_path, "new") 1292 self.create_file(file_path) 1293 self.os.rename(file_path, new_file_path) 1294 self.assertFalse(self.os.path.exists(file_path)) 1295 self.assertTrue(self.os.path.exists(new_file_path)) 1296 1297 def check_append_mode_tell_after_truncate(self, tell_result): 1298 file_path = self.make_path("baz") 1299 with self.open(file_path, "w") as f0: 1300 with self.open(file_path, "a") as f1: 1301 f1.write("abcde") 1302 f0.seek(2) 1303 f0.truncate() 1304 self.assertEqual(tell_result, f1.tell()) 1305 with self.open(file_path, mode="rb") as f: 1306 self.assertEqual(b"\0\0abcde", f.read()) 1307 1308 def test_append_mode_tell_linux_windows(self): 1309 # Regression test for #300 1310 self.check_linux_and_windows() 1311 self.check_append_mode_tell_after_truncate(7) 1312 1313 def test_append_mode_tell_macos(self): 1314 # Regression test for #300 1315 self.check_macos_only() 1316 self.check_append_mode_tell_after_truncate(7) 1317 1318 def test_tell_after_seek_in_append_mode(self): 1319 # Regression test for #363 1320 file_path = self.make_path("foo") 1321 with self.open(file_path, "a") as f: 1322 f.seek(1) 1323 self.assertEqual(1, f.tell()) 1324 1325 def test_tell_after_seekback_in_append_mode(self): 1326 # Regression test for #414 1327 file_path = self.make_path("foo") 1328 with self.open(file_path, "a") as f: 1329 f.write("aa") 1330 f.seek(1) 1331 self.assertEqual(1, f.tell()) 1332 1333 def test_dir_with_trailing_sep_is_dir(self): 1334 # regression test for #387 1335 self.assertTrue(self, self.os.path.isdir(self.base_path + self.os.sep)) 1336 1337 def check_rename_dir_with_trailing_sep(self, error): 1338 dir_path = self.make_path("dir") + self.os.sep 1339 self.os.mkdir(dir_path) 1340 self.assert_raises_os_error(error, self.os.rename, dir_path, self.base_path) 1341 1342 def test_rename_dir_with_trailing_sep_posix(self): 1343 # regression test for #406 1344 self.check_posix_only() 1345 self.check_rename_dir_with_trailing_sep(errno.ENOTEMPTY) 1346 1347 def test_rename_dir_with_trailing_sep_windows(self): 1348 self.check_windows_only() 1349 self.check_rename_dir_with_trailing_sep(errno.EEXIST) 1350 1351 def test_rename_dir(self): 1352 """Test a rename of a directory.""" 1353 directory = self.make_path("xyzzy") 1354 before_dir = self.os.path.join(directory, "before") 1355 before_file = self.os.path.join(directory, "before", "file") 1356 after_dir = self.os.path.join(directory, "after") 1357 after_file = self.os.path.join(directory, "after", "file") 1358 self.create_dir(before_dir) 1359 self.create_file(before_file, contents="payload") 1360 self.assertTrue(self.os.path.exists(before_dir)) 1361 self.assertTrue(self.os.path.exists(before_file)) 1362 self.assertFalse(self.os.path.exists(after_dir)) 1363 self.assertFalse(self.os.path.exists(after_file)) 1364 self.os.rename(before_dir, after_dir) 1365 self.assertFalse(self.os.path.exists(before_dir)) 1366 self.assertFalse(self.os.path.exists(before_file)) 1367 self.assertTrue(self.os.path.exists(after_dir)) 1368 self.assertTrue(self.os.path.exists(after_file)) 1369 self.check_contents(after_file, "payload") 1370 1371 def test_rename_preserves_stat(self): 1372 """Test if rename preserves mtime.""" 1373 self.check_posix_only() 1374 self.skip_real_fs() 1375 directory = self.make_path("xyzzy") 1376 old_file_path = self.os.path.join(directory, "plugh_old") 1377 new_file_path = self.os.path.join(directory, "plugh_new") 1378 self.create_file(old_file_path) 1379 old_file = self.filesystem.get_object(old_file_path) 1380 old_file.st_mtime = old_file.st_mtime - 3600 1381 self.os.chown(old_file_path, 200, 200) 1382 self.os.chmod(old_file_path, 0o222) 1383 self.create_file(new_file_path) 1384 new_file = self.filesystem.get_object(new_file_path) 1385 self.assertNotEqual(new_file.st_mtime, old_file.st_mtime) 1386 self.os.rename(old_file_path, new_file_path) 1387 new_file = self.filesystem.get_object(new_file_path, check_read_perm=False) 1388 self.assertEqual(new_file.st_mtime, old_file.st_mtime) 1389 self.assertEqual(new_file.st_mode, old_file.st_mode) 1390 self.assertEqual(new_file.st_uid, old_file.st_uid) 1391 self.assertEqual(new_file.st_gid, old_file.st_gid) 1392 1393 def test_rename_same_filenames(self): 1394 """Test renaming when old and new names are the same.""" 1395 directory = self.make_path("xyzzy") 1396 file_contents = "Spam eggs" 1397 file_path = self.os.path.join(directory, "eggs") 1398 self.create_file(file_path, contents=file_contents) 1399 self.os.rename(file_path, file_path) 1400 self.check_contents(file_path, file_contents) 1401 1402 def test_rmdir(self): 1403 """Can remove a directory.""" 1404 directory = self.make_path("xyzzy") 1405 sub_dir = self.make_path("xyzzy", "abccd") 1406 other_dir = self.make_path("xyzzy", "cdeed") 1407 self.create_dir(directory) 1408 self.assertTrue(self.os.path.exists(directory)) 1409 self.os.rmdir(directory) 1410 self.assertFalse(self.os.path.exists(directory)) 1411 self.create_dir(sub_dir) 1412 self.create_dir(other_dir) 1413 self.os.chdir(sub_dir) 1414 self.os.rmdir("../cdeed") 1415 self.assertFalse(self.os.path.exists(other_dir)) 1416 self.os.chdir("..") 1417 self.os.rmdir("abccd") 1418 self.assertFalse(self.os.path.exists(sub_dir)) 1419 1420 def test_rmdir_raises_if_not_empty(self): 1421 """Raises an exception if the target directory is not empty.""" 1422 directory = self.make_path("xyzzy") 1423 file_path = self.os.path.join(directory, "plugh") 1424 self.create_file(file_path) 1425 self.assertTrue(self.os.path.exists(file_path)) 1426 self.assert_raises_os_error(errno.ENOTEMPTY, self.os.rmdir, directory) 1427 1428 def check_rmdir_raises_if_not_directory(self, error_nr): 1429 """Raises an exception if the target is not a directory.""" 1430 directory = self.make_path("xyzzy") 1431 file_path = self.os.path.join(directory, "plugh") 1432 self.create_file(file_path) 1433 self.assertTrue(self.os.path.exists(file_path)) 1434 self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, file_path) 1435 self.assert_raises_os_error(error_nr, self.os.rmdir, ".") 1436 1437 def test_rmdir_raises_if_not_directory_posix(self): 1438 self.check_posix_only() 1439 self.check_rmdir_raises_if_not_directory(errno.EINVAL) 1440 1441 def test_rmdir_raises_if_not_directory_windows(self): 1442 self.check_windows_only() 1443 self.check_rmdir_raises_if_not_directory(errno.EACCES) 1444 1445 def test_rmdir_raises_if_not_exist(self): 1446 """Raises an exception if the target does not exist.""" 1447 directory = self.make_path("xyzzy") 1448 self.assertFalse(self.os.path.exists(directory)) 1449 self.assert_raises_os_error(errno.ENOENT, self.os.rmdir, directory) 1450 1451 def test_rmdir_via_symlink(self): 1452 self.check_windows_only() 1453 self.skip_if_symlink_not_supported() 1454 base_path = self.make_path("foo", "bar") 1455 dir_path = self.os.path.join(base_path, "alpha") 1456 self.create_dir(dir_path) 1457 link_path = self.os.path.join(base_path, "beta") 1458 self.os.symlink(base_path, link_path) 1459 self.os.rmdir(link_path + "/alpha") 1460 self.assertFalse(self.os.path.exists(dir_path)) 1461 1462 def remove_dirs_check(self, directory): 1463 self.assertTrue(self.os.path.exists(directory)) 1464 self.os.removedirs(directory) 1465 return not self.os.path.exists(directory) 1466 1467 def test_removedirs(self): 1468 # no exception raised 1469 self.skip_real_fs() 1470 data = [ 1471 "test1", 1472 ("test1", "test2"), 1473 ("test1", "extra"), 1474 ("test1", "test2", "test3"), 1475 ] 1476 for directory in data: 1477 self.create_dir(self.make_path(directory)) 1478 self.assertTrue(self.os.path.exists(self.make_path(directory))) 1479 self.assert_raises_os_error( 1480 errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[0]) 1481 ) 1482 self.assert_raises_os_error( 1483 errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[1]) 1484 ) 1485 1486 self.assertTrue(self.remove_dirs_check(self.make_path(data[3]))) 1487 self.assertTrue(self.os.path.exists(self.make_path(data[0]))) 1488 self.assertFalse(self.os.path.exists(self.make_path(data[1]))) 1489 self.assertTrue(self.os.path.exists(self.make_path(data[2]))) 1490 1491 # Should raise because '/test1/extra' is all that is left, and 1492 # removedirs('/test1/extra') will eventually try to rmdir('/'). 1493 self.assert_raises_os_error( 1494 errno.EBUSY, self.remove_dirs_check, self.make_path(data[2]) 1495 ) 1496 1497 # However, it will still delete '/test1') in the process. 1498 self.assertFalse(self.os.path.exists(self.make_path(data[0]))) 1499 1500 self.create_dir(self.make_path("test1", "test2")) 1501 # Add this to the root directory to avoid raising an exception. 1502 self.filesystem.create_dir(self.make_path("test3")) 1503 self.assertTrue(self.remove_dirs_check(self.make_path("test1", "test2"))) 1504 self.assertFalse(self.os.path.exists(self.make_path("test1", "test2"))) 1505 self.assertFalse(self.os.path.exists(self.make_path("test1"))) 1506 1507 def test_removedirs_raises_if_removing_root(self): 1508 """Raises exception if asked to remove '/'.""" 1509 self.skip_real_fs() 1510 self.os.rmdir(self.base_path) 1511 directory = self.os.path.splitdrive(self.base_path)[0] + self.os.path.sep 1512 self.assertTrue(self.os.path.exists(directory)) 1513 self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) 1514 1515 def test_removedirs_raises_if_cascade_removing_root(self): 1516 """Raises exception if asked to remove '/' as part of a 1517 larger operation. 1518 1519 All of other directories should still be removed, though. 1520 """ 1521 self.skip_real_fs() 1522 directory = self.make_path("foo", "bar") 1523 self.create_dir(directory) 1524 self.assertTrue(self.os.path.exists(directory)) 1525 self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) 1526 head, unused_tail = self.os.path.split(directory) 1527 while self.os.path.splitdrive(head)[1] != self.os.path.sep: 1528 self.assertFalse(self.os.path.exists(directory)) 1529 head, unused_tail = self.os.path.split(head) 1530 1531 def test_removedirs_with_trailing_slash(self): 1532 """removedirs works on directory names with trailing slashes.""" 1533 # separate this case from the removing-root-directory case 1534 self.create_dir(self.make_path("baz")) 1535 directory = self.make_path("foo", "bar") 1536 self.create_dir(directory) 1537 self.assertTrue(self.os.path.exists(directory)) 1538 self.os.removedirs(directory) 1539 self.assertFalse(self.os.path.exists(directory)) 1540 1541 def test_remove_dirs_with_top_symlink_fails(self): 1542 self.check_posix_only() 1543 dir_path = self.make_path("dir") 1544 dir_link = self.make_path("dir_link") 1545 self.create_dir(dir_path) 1546 self.os.symlink(dir_path, dir_link) 1547 self.assert_raises_os_error(errno.ENOTDIR, self.os.removedirs, dir_link) 1548 1549 def test_remove_dirs_with_non_top_symlink_succeeds(self): 1550 self.check_posix_only() 1551 dir_path = self.make_path("dir") 1552 dir_link = self.make_path("dir_link") 1553 self.create_dir(dir_path) 1554 self.os.symlink(dir_path, dir_link) 1555 dir_in_dir = self.os.path.join(dir_link, "dir2") 1556 self.create_dir(dir_in_dir) 1557 self.os.removedirs(dir_in_dir) 1558 self.assertFalse(self.os.path.exists(dir_in_dir)) 1559 # ensure that the symlink is not removed 1560 self.assertTrue(self.os.path.exists(dir_link)) 1561 1562 def test_mkdir(self): 1563 """mkdir can create a relative directory.""" 1564 self.skip_real_fs() 1565 directory = "xyzzy" 1566 self.assertFalse(self.filesystem.exists(directory)) 1567 self.os.mkdir(directory) 1568 self.assertTrue(self.filesystem.exists("/%s" % directory)) 1569 self.os.chdir(directory) 1570 self.os.mkdir(directory) 1571 self.assertTrue(self.filesystem.exists("/%s/%s" % (directory, directory))) 1572 self.os.chdir(directory) 1573 self.os.mkdir("../abccb") 1574 self.assertTrue(self.os.path.exists("/%s/abccb" % directory)) 1575 1576 def test_mkdir_with_trailing_slash(self): 1577 """mkdir can create a directory named with a trailing slash.""" 1578 directory = self.make_path("foo") 1579 self.assertFalse(self.os.path.exists(directory)) 1580 self.os.mkdir(directory) 1581 self.assertTrue(self.os.path.exists(directory)) 1582 self.assertTrue(self.os.path.exists(self.make_path("foo"))) 1583 1584 def test_mkdir_raises_if_empty_directory_name(self): 1585 """mkdir raises exception if creating directory named ''.""" 1586 directory = "" 1587 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1588 1589 def test_mkdir_raises_if_no_parent(self): 1590 """mkdir raises exception if parent directory does not exist.""" 1591 parent = "xyzzy" 1592 directory = "%s/foo" % (parent,) 1593 self.assertFalse(self.os.path.exists(parent)) 1594 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1595 1596 def test_mkdir_raises_on_symlink_in_posix(self): 1597 self.check_posix_only() 1598 base_path = self.make_path("foo", "bar") 1599 link_path = self.os.path.join(base_path, "link_to_dir") 1600 dir_path = self.os.path.join(base_path, "dir") 1601 self.create_dir(dir_path) 1602 self.os.symlink(dir_path, link_path) 1603 self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) 1604 1605 def test_mkdir_removes_symlink_in_windows(self): 1606 self.check_windows_only() 1607 self.skip_if_symlink_not_supported() 1608 base_path = self.make_path("foo", "bar") 1609 link_path = self.os.path.join(base_path, "link_to_dir") 1610 dir_path = self.os.path.join(base_path, "dir") 1611 self.create_dir(dir_path) 1612 self.os.symlink(dir_path, link_path) 1613 self.os.rmdir(link_path) 1614 self.assertFalse(self.os.path.exists(link_path)) 1615 self.assertTrue(self.os.path.exists(dir_path)) 1616 1617 def test_mkdir_raises_if_directory_exists(self): 1618 """mkdir raises exception if directory already exists.""" 1619 directory = self.make_path("xyzzy") 1620 self.create_dir(directory) 1621 self.assertTrue(self.os.path.exists(directory)) 1622 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) 1623 1624 def test_mkdir_raises_if_file_exists(self): 1625 """mkdir raises exception if name already exists as a file.""" 1626 directory = self.make_path("xyzzy") 1627 file_path = self.os.path.join(directory, "plugh") 1628 self.create_file(file_path) 1629 self.assertTrue(self.os.path.exists(file_path)) 1630 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path) 1631 1632 def check_mkdir_raises_if_parent_is_file(self, error_type): 1633 """mkdir raises exception if name already exists as a file.""" 1634 directory = self.make_path("xyzzy") 1635 file_path = self.os.path.join(directory, "plugh") 1636 self.create_file(file_path) 1637 self.assert_raises_os_error( 1638 error_type, self.os.mkdir, self.os.path.join(file_path, "ff") 1639 ) 1640 1641 def test_mkdir_raises_if_parent_is_file_posix(self): 1642 self.check_posix_only() 1643 self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) 1644 1645 def test_mkdir_raises_if_parent_is_file_windows(self): 1646 self.check_windows_only() 1647 self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) 1648 1649 def test_mkdir_raises_with_slash_dot_posix(self): 1650 """mkdir raises exception if mkdir foo/. (trailing /.).""" 1651 self.check_posix_only() 1652 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + ".") 1653 directory = self.make_path("xyzzy", ".") 1654 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1655 self.create_dir(self.make_path("xyzzy")) 1656 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) 1657 1658 def test_mkdir_raises_with_slash_dot_windows(self): 1659 """mkdir raises exception if mkdir foo/. (trailing /.).""" 1660 self.check_windows_only() 1661 self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + ".") 1662 directory = self.make_path("xyzzy", ".") 1663 self.os.mkdir(directory) 1664 self.create_dir(self.make_path("xyzzy")) 1665 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) 1666 1667 def test_mkdir_raises_with_double_dots_posix(self): 1668 """mkdir raises exception if mkdir foo/foo2/../foo3.""" 1669 self.check_posix_only() 1670 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + "..") 1671 directory = self.make_path("xyzzy", "dir1", "dir2", "..", "..", "dir3") 1672 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1673 self.create_dir(self.make_path("xyzzy")) 1674 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1675 self.create_dir(self.make_path("xyzzy", "dir1")) 1676 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1677 self.create_dir(self.make_path("xyzzy", "dir1", "dir2")) 1678 self.os.mkdir(directory) 1679 self.assertTrue(self.os.path.exists(directory)) 1680 directory = self.make_path("xyzzy", "dir1", "..") 1681 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) 1682 1683 def test_mkdir_raises_with_double_dots_windows(self): 1684 """mkdir raises exception if mkdir foo/foo2/../foo3.""" 1685 self.check_windows_only() 1686 self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + "..") 1687 directory = self.make_path("xyzzy", "dir1", "dir2", "..", "..", "dir3") 1688 self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) 1689 self.create_dir(self.make_path("xyzzy")) 1690 self.os.mkdir(directory) 1691 self.assertTrue(self.os.path.exists(directory)) 1692 directory = self.make_path("xyzzy", "dir1", "..") 1693 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) 1694 1695 def test_mkdir_raises_if_parent_is_read_only(self): 1696 """mkdir raises exception if parent is read only.""" 1697 self.check_posix_only() 1698 directory = self.make_path("a") 1699 self.os.mkdir(directory) 1700 1701 # Change directory permissions to be read only. 1702 self.os.chmod(directory, 0o400) 1703 1704 directory = self.make_path("a", "b") 1705 if not is_root(): 1706 self.assert_raises_os_error(errno.EACCES, self.os.mkdir, directory) 1707 else: 1708 self.os.mkdir(directory) 1709 self.assertTrue(self.os.path.exists(directory)) 1710 1711 def test_mkdir_with_with_symlink_parent(self): 1712 self.check_posix_only() 1713 dir_path = self.make_path("foo", "bar") 1714 self.create_dir(dir_path) 1715 link_path = self.make_path("foo", "link") 1716 self.os.symlink(dir_path, link_path) 1717 new_dir = self.os.path.join(link_path, "new_dir") 1718 self.os.mkdir(new_dir) 1719 self.assertTrue(self.os.path.exists(new_dir)) 1720 1721 def test_makedirs(self): 1722 """makedirs can create a directory even if parent does not exist.""" 1723 parent = self.make_path("xyzzy") 1724 directory = self.os.path.join(parent, "foo") 1725 self.assertFalse(self.os.path.exists(parent)) 1726 self.os.makedirs(directory) 1727 self.assertTrue(self.os.path.exists(directory)) 1728 1729 def check_makedirs_raises_if_parent_is_file(self, error_type): 1730 """makedirs raises exception if a parent component exists as a file.""" 1731 file_path = self.make_path("xyzzy") 1732 directory = self.os.path.join(file_path, "plugh") 1733 self.create_file(file_path) 1734 self.assertTrue(self.os.path.exists(file_path)) 1735 self.assert_raises_os_error(error_type, self.os.makedirs, directory) 1736 1737 def test_makedirs_raises_if_parent_is_file_posix(self): 1738 self.check_posix_only() 1739 self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) 1740 1741 def test_makedirs_raises_if_parent_is_file_windows(self): 1742 self.check_windows_only() 1743 self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) 1744 1745 def test_makedirs_raises_if_parent_is_broken_link(self): 1746 self.check_posix_only() 1747 link_path = self.make_path("broken_link") 1748 self.os.symlink(self.make_path("bogus"), link_path) 1749 self.assert_raises_os_error( 1750 errno.ENOENT, 1751 self.os.makedirs, 1752 self.os.path.join(link_path, "newdir"), 1753 ) 1754 1755 def test_makedirs_raises_if_parent_is_looping_link(self): 1756 self.skip_if_symlink_not_supported() 1757 link_path = self.make_path("link") 1758 link_target = self.os.path.join(link_path, "link") 1759 self.os.symlink(link_target, link_path) 1760 self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) 1761 1762 def test_makedirs_if_parent_is_symlink(self): 1763 self.check_posix_only() 1764 base_dir = self.make_path("foo", "bar") 1765 self.create_dir(base_dir) 1766 link_dir = self.os.path.join(base_dir, "linked") 1767 self.os.symlink(base_dir, link_dir) 1768 new_dir = self.os.path.join(link_dir, "f") 1769 self.os.makedirs(name=new_dir) 1770 self.assertTrue(self.os.path.exists(new_dir)) 1771 1772 def test_makedirs_raises_if_access_denied(self): 1773 """makedirs raises exception if access denied.""" 1774 self.check_posix_only() 1775 directory = self.make_path("a") 1776 self.os.mkdir(directory) 1777 1778 # Change directory permissions to be read only. 1779 self.os.chmod(directory, 0o400) 1780 1781 directory = self.make_path("a", "b") 1782 if not is_root(): 1783 with self.assertRaises(OSError): 1784 self.os.makedirs(directory) 1785 else: 1786 self.os.makedirs(directory) 1787 self.assertTrue(self.os.path.exists(directory)) 1788 1789 def test_makedirs_exist_ok(self): 1790 """makedirs uses the exist_ok argument""" 1791 directory = self.make_path("xyzzy", "foo") 1792 self.create_dir(directory) 1793 self.assertTrue(self.os.path.exists(directory)) 1794 1795 self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory) 1796 self.os.makedirs(directory, exist_ok=True) 1797 self.assertTrue(self.os.path.exists(directory)) 1798 1799 def test_makedirs_in_write_protected_dir(self): 1800 self.check_posix_only() 1801 directory = self.make_path("foo") 1802 self.os.mkdir(directory, mode=0o555) 1803 subdir = self.os.path.join(directory, "bar") 1804 if not is_root(): 1805 self.assert_raises_os_error( 1806 errno.EACCES, self.os.makedirs, subdir, exist_ok=True 1807 ) 1808 self.assert_raises_os_error( 1809 errno.EACCES, self.os.makedirs, subdir, exist_ok=False 1810 ) 1811 else: 1812 self.os.makedirs(subdir) 1813 self.assertTrue(self.os.path.exists(subdir)) 1814 1815 def test_makedirs_raises_on_empty_path(self): 1816 self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, "", exist_ok=False) 1817 self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, "", exist_ok=True) 1818 1819 # test fsync and fdatasync 1820 def test_fsync_raises_on_non_int(self): 1821 with self.assertRaises(TypeError): 1822 self.os.fsync("zero") 1823 1824 def test_fdatasync_raises_on_non_int(self): 1825 self.check_linux_only() 1826 self.assertRaises(TypeError, self.os.fdatasync, "zero") 1827 1828 def test_fsync_raises_on_invalid_fd(self): 1829 self.assert_raises_os_error(errno.EBADF, self.os.fsync, 500) 1830 1831 def test_fdatasync_raises_on_invalid_fd(self): 1832 # No open files yet 1833 self.check_linux_only() 1834 self.assert_raises_os_error(errno.EINVAL, self.os.fdatasync, 0) 1835 self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, 500) 1836 1837 def test_fsync_pass_posix(self): 1838 self.check_posix_only() 1839 test_file_path = self.make_path("test_file") 1840 self.create_file(test_file_path, contents="dummy file contents") 1841 with self.open(test_file_path, "r") as test_file: 1842 test_fd = test_file.fileno() 1843 # Test that this doesn't raise anything 1844 self.os.fsync(test_fd) 1845 # And just for sanity, double-check that this still raises 1846 self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 500) 1847 1848 def test_fsync_pass_windows(self): 1849 self.check_windows_only() 1850 test_file_path = self.make_path("test_file") 1851 self.create_file(test_file_path, contents="dummy file contents") 1852 with self.open(test_file_path, "r+") as test_file: 1853 test_fd = test_file.fileno() 1854 # Test that this doesn't raise anything 1855 self.os.fsync(test_fd) 1856 # And just for sanity, double-check that this still raises 1857 self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 500) 1858 with self.open(test_file_path, "r") as test_file: 1859 test_fd = test_file.fileno() 1860 self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd) 1861 1862 def test_fdatasync_pass(self): 1863 # setup 1864 self.check_linux_only() 1865 test_file_path = self.make_path("test_file") 1866 self.create_file(test_file_path, contents="dummy file contents") 1867 test_file = self.open(test_file_path, "r") 1868 test_fd = test_file.fileno() 1869 # Test that this doesn't raise anything 1870 self.os.fdatasync(test_fd) 1871 # And just for sanity, double-check that this still raises 1872 self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, test_fd + 500) 1873 1874 def test_access700(self): 1875 # set up 1876 self.check_posix_only() 1877 path = self.make_path("some_file") 1878 self.createTestFile(path) 1879 self.os.chmod(path, 0o700) 1880 self.assert_mode_equal(0o700, self.os.stat(path).st_mode) 1881 # actual tests 1882 self.assertTrue(self.os.access(path, self.os.F_OK)) 1883 self.assertTrue(self.os.access(path, self.os.R_OK)) 1884 self.assertTrue(self.os.access(path, self.os.W_OK)) 1885 self.assertTrue(self.os.access(path, self.os.X_OK)) 1886 self.assertTrue(self.os.access(path, self.rwx)) 1887 1888 def test_access600(self): 1889 # set up 1890 self.check_posix_only() 1891 path = self.make_path("some_file") 1892 self.createTestFile(path) 1893 self.os.chmod(path, 0o600) 1894 self.assert_mode_equal(0o600, self.os.stat(path).st_mode) 1895 # actual tests 1896 self.assertTrue(self.os.access(path, self.os.F_OK)) 1897 self.assertTrue(self.os.access(path, self.os.R_OK)) 1898 self.assertTrue(self.os.access(path, self.os.W_OK)) 1899 self.assertFalse(self.os.access(path, self.os.X_OK)) 1900 self.assertFalse(self.os.access(path, self.rwx)) 1901 self.assertTrue(self.os.access(path, self.rw)) 1902 1903 def test_access400(self): 1904 # set up 1905 self.check_posix_only() 1906 path = self.make_path("some_file") 1907 self.createTestFile(path) 1908 self.os.chmod(path, 0o400) 1909 self.assert_mode_equal(0o400, self.os.stat(path).st_mode) 1910 # actual tests 1911 self.assertTrue(self.os.access(path, self.os.F_OK)) 1912 self.assertTrue(self.os.access(path, self.os.R_OK)) 1913 self.assertFalse(self.os.access(path, self.os.X_OK)) 1914 self.assertFalse(self.os.access(path, self.rwx)) 1915 if is_root(): 1916 self.assertTrue(self.os.access(path, self.os.W_OK)) 1917 self.assertTrue(self.os.access(path, self.rw)) 1918 else: 1919 self.assertFalse(self.os.access(path, self.os.W_OK)) 1920 self.assertFalse(self.os.access(path, self.rw)) 1921 1922 def test_access_symlink(self): 1923 self.skip_if_symlink_not_supported() 1924 self.skip_real_fs() 1925 path = self.make_path("some_file") 1926 self.createTestFile(path) 1927 link_path = self.make_path("link_to_some_file") 1928 self.create_symlink(link_path, path) 1929 self.os.chmod(link_path, 0o400) 1930 1931 # test file 1932 self.assertTrue(self.os.access(link_path, self.os.F_OK)) 1933 self.assertTrue(self.os.access(link_path, self.os.R_OK)) 1934 if is_root(): 1935 self.assertTrue(self.os.access(link_path, self.os.W_OK)) 1936 self.assertTrue(self.os.access(link_path, self.rw)) 1937 else: 1938 self.assertFalse(self.os.access(link_path, self.os.W_OK)) 1939 self.assertFalse(self.os.access(link_path, self.rw)) 1940 self.assertFalse(self.os.access(link_path, self.os.X_OK)) 1941 self.assertFalse(self.os.access(link_path, self.rwx)) 1942 1943 # test link itself 1944 self.assertTrue(self.os.access(link_path, self.os.F_OK, follow_symlinks=False)) 1945 self.assertTrue(self.os.access(link_path, self.os.R_OK, follow_symlinks=False)) 1946 self.assertTrue(self.os.access(link_path, self.os.W_OK, follow_symlinks=False)) 1947 self.assertTrue(self.os.access(link_path, self.os.X_OK, follow_symlinks=False)) 1948 self.assertTrue(self.os.access(link_path, self.rwx, follow_symlinks=False)) 1949 self.assertTrue(self.os.access(link_path, self.rw, follow_symlinks=False)) 1950 1951 def test_access_non_existent_file(self): 1952 # set up 1953 path = self.make_path("non", "existent", "file") 1954 self.assertFalse(self.os.path.exists(path)) 1955 # actual tests 1956 self.assertFalse(self.os.access(path, self.os.F_OK)) 1957 self.assertFalse(self.os.access(path, self.os.R_OK)) 1958 self.assertFalse(self.os.access(path, self.os.W_OK)) 1959 self.assertFalse(self.os.access(path, self.os.X_OK)) 1960 self.assertFalse(self.os.access(path, self.rwx)) 1961 self.assertFalse(self.os.access(path, self.rw)) 1962 1963 def test_effective_ids_not_supported_under_windows(self): 1964 self.check_windows_only() 1965 path = self.make_path("foo", "bar") 1966 with self.assertRaises(NotImplementedError): 1967 self.os.access(path, self.os.F_OK, effective_ids=True) 1968 1969 def test_chmod(self): 1970 # set up 1971 self.check_posix_only() 1972 self.skip_real_fs() 1973 path = self.make_path("some_file") 1974 self.createTestFile(path) 1975 # actual tests 1976 self.os.chmod(path, 0o6543) 1977 st = self.os.stat(path) 1978 self.assert_mode_equal(0o6543, st.st_mode) 1979 self.assertTrue(st.st_mode & stat.S_IFREG) 1980 self.assertFalse(st.st_mode & stat.S_IFDIR) 1981 1982 def test_chmod_uses_open_fd_as_path(self): 1983 self.check_posix_only() 1984 self.skip_real_fs() 1985 self.assert_raises_os_error(errno.EBADF, self.os.chmod, 5, 0o6543) 1986 path = self.make_path("some_file") 1987 self.createTestFile(path) 1988 1989 with self.open(path) as f: 1990 self.os.chmod(f.filedes, 0o6543) 1991 st = self.os.stat(path) 1992 self.assert_mode_equal(0o6543, st.st_mode) 1993 1994 def test_chmod_follow_symlink(self): 1995 self.check_posix_only() 1996 path = self.make_path("some_file") 1997 self.createTestFile(path) 1998 link_path = self.make_path("link_to_some_file") 1999 self.create_symlink(link_path, path) 2000 self.os.chmod(link_path, 0o6543) 2001 2002 st = self.os.stat(link_path) 2003 self.assert_mode_equal(0o6543, st.st_mode) 2004 st = self.os.stat(link_path, follow_symlinks=False) 2005 # the exact mode depends on OS and Python version 2006 self.assertEqual(stat.S_IMODE(0o700), stat.S_IMODE(st.st_mode) & 0o700) 2007 2008 def test_chmod_no_follow_symlink(self): 2009 self.check_posix_only() 2010 path = self.make_path("some_file") 2011 self.createTestFile(path) 2012 link_path = self.make_path("link_to_some_file") 2013 self.create_symlink(link_path, path) 2014 if self.os.chmod not in self.os.supports_follow_symlinks or IS_PYPY: 2015 with self.assertRaises(NotImplementedError): 2016 self.os.chmod(link_path, 0o6543, follow_symlinks=False) 2017 else: 2018 self.os.chmod(link_path, 0o6543, follow_symlinks=False) 2019 st = self.os.stat(link_path) 2020 self.assert_mode_equal(0o666, st.st_mode) 2021 st = self.os.stat(link_path, follow_symlinks=False) 2022 self.assert_mode_equal(0o6543, st.st_mode) 2023 2024 def test_lchmod(self): 2025 """lchmod shall behave like chmod with follow_symlinks=True.""" 2026 self.check_posix_only() 2027 self.skip_real_fs() 2028 path = self.make_path("some_file") 2029 self.createTestFile(path) 2030 link_path = self.make_path("link_to_some_file") 2031 self.create_symlink(link_path, path) 2032 self.os.lchmod(link_path, 0o6543) 2033 2034 st = self.os.stat(link_path) 2035 self.assert_mode_equal(0o666, st.st_mode) 2036 st = self.os.lstat(link_path) 2037 self.assert_mode_equal(0o6543, st.st_mode) 2038 2039 def test_chmod_dir(self): 2040 # set up 2041 self.check_posix_only() 2042 self.skip_real_fs() 2043 path = self.make_path("some_dir") 2044 self.createTestDirectory(path) 2045 # actual tests 2046 self.os.chmod(path, 0o1434) 2047 st = self.os.stat(path) 2048 self.assert_mode_equal(0o1434, st.st_mode) 2049 self.assertFalse(st.st_mode & stat.S_IFREG) 2050 self.assertTrue(st.st_mode & stat.S_IFDIR) 2051 2052 def test_chmod_non_existent(self): 2053 # set up 2054 path = self.make_path("non", "existent", "file") 2055 self.assertFalse(self.os.path.exists(path)) 2056 # actual tests 2057 try: 2058 # Use try-catch to check exception attributes. 2059 self.os.chmod(path, 0o777) 2060 self.fail("Exception is expected.") # COV_NF_LINE 2061 except OSError as os_error: 2062 self.assertEqual(errno.ENOENT, os_error.errno) 2063 self.assertEqual(path, os_error.filename) 2064 2065 def test_chown_existing_file(self): 2066 # set up 2067 self.skip_real_fs() 2068 file_path = self.make_path("some_file") 2069 self.create_file(file_path) 2070 # first set it make sure it's set 2071 self.os.chown(file_path, 100, 101) 2072 st = self.os.stat(file_path) 2073 self.assertEqual(st[stat.ST_UID], 100) 2074 self.assertEqual(st[stat.ST_GID], 101) 2075 # we can make sure it changed 2076 self.os.chown(file_path, 200, 201) 2077 st = self.os.stat(file_path) 2078 self.assertEqual(st[stat.ST_UID], 200) 2079 self.assertEqual(st[stat.ST_GID], 201) 2080 # setting a value to -1 leaves it unchanged 2081 self.os.chown(file_path, -1, -1) 2082 st = self.os.stat(file_path) 2083 self.assertEqual(st[stat.ST_UID], 200) 2084 self.assertEqual(st[stat.ST_GID], 201) 2085 2086 def test_chown_uses_open_fd_as_path(self): 2087 self.check_posix_only() 2088 self.skip_real_fs() 2089 self.assert_raises_os_error(errno.EBADF, self.os.chown, 5, 100, 101) 2090 file_path = self.make_path("foo", "bar") 2091 self.create_file(file_path) 2092 2093 with self.open(file_path) as f: 2094 self.os.chown(f.filedes, 100, 101) 2095 st = self.os.stat(file_path) 2096 self.assertEqual(st[stat.ST_UID], 100) 2097 2098 def test_chown_follow_symlink(self): 2099 self.skip_real_fs() 2100 file_path = self.make_path("some_file") 2101 self.create_file(file_path) 2102 link_path = self.make_path("link_to_some_file") 2103 self.create_symlink(link_path, file_path) 2104 2105 self.os.chown(link_path, 100, 101) 2106 st = self.os.stat(link_path) 2107 self.assertEqual(st[stat.ST_UID], 100) 2108 self.assertEqual(st[stat.ST_GID], 101) 2109 st = self.os.stat(link_path, follow_symlinks=False) 2110 self.assertNotEqual(st[stat.ST_UID], 100) 2111 self.assertNotEqual(st[stat.ST_GID], 101) 2112 2113 def test_chown_no_follow_symlink(self): 2114 self.skip_real_fs() 2115 file_path = self.make_path("some_file") 2116 self.create_file(file_path) 2117 link_path = self.make_path("link_to_some_file") 2118 self.create_symlink(link_path, file_path) 2119 2120 self.os.chown(link_path, 100, 101, follow_symlinks=False) 2121 st = self.os.stat(link_path) 2122 self.assertNotEqual(st[stat.ST_UID], 100) 2123 self.assertNotEqual(st[stat.ST_GID], 101) 2124 st = self.os.stat(link_path, follow_symlinks=False) 2125 self.assertEqual(st[stat.ST_UID], 100) 2126 self.assertEqual(st[stat.ST_GID], 101) 2127 2128 def test_chown_bad_arguments(self): 2129 """os.chown() with bad args (Issue #30)""" 2130 self.check_posix_only() 2131 file_path = self.make_path("some_file") 2132 self.create_file(file_path) 2133 self.assertRaises(TypeError, self.os.chown, file_path, "username", -1) 2134 self.assertRaises(TypeError, self.os.chown, file_path, -1, "groupname") 2135 2136 def test_chown_nonexisting_file_should_raise_os_error(self): 2137 self.check_posix_only() 2138 file_path = self.make_path("some_file") 2139 self.assertFalse(self.os.path.exists(file_path)) 2140 self.assert_raises_os_error(errno.ENOENT, self.os.chown, file_path, 100, 100) 2141 2142 def test_classify_directory_contents(self): 2143 """Directory classification should work correctly.""" 2144 root_directory = self.make_path("foo") 2145 test_directories = ["bar1", "baz2"] 2146 test_files = ["baz1", "bar2", "baz3"] 2147 self.create_dir(root_directory) 2148 for directory in test_directories: 2149 directory = self.os.path.join(root_directory, directory) 2150 self.create_dir(directory) 2151 for test_file in test_files: 2152 test_file = self.os.path.join(root_directory, test_file) 2153 self.create_file(test_file) 2154 2155 test_directories.sort() 2156 test_files.sort() 2157 generator = self.os.walk(root_directory) 2158 root, dirs, files = next(generator) 2159 dirs.sort() 2160 files.sort() 2161 self.assertEqual(root_directory, root) 2162 self.assertEqual(test_directories, dirs) 2163 self.assertEqual(test_files, files) 2164 2165 # os.mknod does not work under MacOS due to permission issues 2166 # so we test it under Linux only 2167 def test_mk_nod_can_create_a_file(self): 2168 self.check_linux_only() 2169 filename = self.make_path("foo") 2170 self.assertFalse(self.os.path.exists(filename)) 2171 self.os.mknod(filename) 2172 self.assertTrue(self.os.path.exists(filename)) 2173 self.assertEqual(stat.S_IFREG | 0o600, self.os.stat(filename).st_mode) 2174 2175 def test_mk_nod_raises_if_empty_file_name(self): 2176 self.check_linux_only() 2177 filename = "" 2178 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2179 2180 def test_mk_nod_raises_if_parent_dir_doesnt_exist(self): 2181 self.check_linux_only() 2182 parent = self.make_path("xyzzy") 2183 filename = self.os.path.join(parent, "foo") 2184 self.assertFalse(self.os.path.exists(parent)) 2185 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2186 2187 def test_mk_nod_raises_if_file_exists(self): 2188 self.check_linux_only() 2189 filename = self.make_path("tmp", "foo") 2190 self.create_file(filename) 2191 self.assertTrue(self.os.path.exists(filename)) 2192 self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) 2193 2194 def test_mk_nod_raises_if_filename_is_dot(self): 2195 self.check_linux_only() 2196 filename = self.make_path("tmp", ".") 2197 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2198 2199 def test_mk_nod_raises_if_filename_is_double_dot(self): 2200 self.check_linux_only() 2201 filename = self.make_path("tmp", "..") 2202 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2203 2204 def test_mknod_empty_tail_for_existing_file_raises(self): 2205 self.check_linux_only() 2206 filename = self.make_path("foo") 2207 self.create_file(filename) 2208 self.assertTrue(self.os.path.exists(filename)) 2209 self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) 2210 2211 def test_mknod_empty_tail_for_nonexistent_file_raises(self): 2212 self.check_linux_only() 2213 filename = self.make_path("tmp", "foo") 2214 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2215 2216 def test_mknod_raises_if_filename_is_empty_string(self): 2217 self.check_linux_only() 2218 filename = "" 2219 self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) 2220 2221 def test_mknod_raises_if_unsupported_options(self): 2222 self.check_posix_only() 2223 # behavior seems to have changed in ubuntu-20.04, version 20210606.1 2224 # skipping real fs tests for now 2225 self.skip_real_fs() 2226 filename = "abcde" 2227 if not is_root(): 2228 self.assert_raises_os_error( 2229 errno.EPERM, self.os.mknod, filename, stat.S_IFCHR 2230 ) 2231 else: 2232 self.os.mknod(filename, stat.S_IFCHR) 2233 self.os.remove(filename) 2234 2235 def test_mknod_raises_if_parent_is_not_a_directory(self): 2236 self.check_linux_only() 2237 filename1 = self.make_path("foo") 2238 self.create_file(filename1) 2239 self.assertTrue(self.os.path.exists(filename1)) 2240 filename2 = self.make_path("foo", "bar") 2241 self.assert_raises_os_error(errno.ENOTDIR, self.os.mknod, filename2) 2242 2243 def test_symlink(self): 2244 self.skip_if_symlink_not_supported() 2245 file_path = self.make_path("foo", "bar", "baz") 2246 self.create_dir(self.make_path("foo", "bar")) 2247 self.os.symlink("bogus", file_path) 2248 self.assertTrue(self.os.path.lexists(file_path)) 2249 self.assertFalse(self.os.path.exists(file_path)) 2250 self.create_file(self.make_path("foo", "bar", "bogus")) 2251 self.assertTrue(self.os.path.lexists(file_path)) 2252 self.assertTrue(self.os.path.exists(file_path)) 2253 2254 def test_symlink_on_nonexisting_path_raises(self): 2255 self.check_posix_only() 2256 dir_path = self.make_path("bar") 2257 link_path = self.os.path.join(dir_path, "bar") 2258 self.assert_raises_os_error(errno.ENOENT, self.os.symlink, link_path, link_path) 2259 self.assert_raises_os_error(errno.ENOENT, self.os.symlink, dir_path, link_path) 2260 2261 def test_symlink_with_path_ending_with_sep_in_posix(self): 2262 self.check_posix_only() 2263 dir_path = self.make_path("dir") 2264 self.create_dir(dir_path) 2265 self.assert_raises_os_error( 2266 errno.EEXIST, 2267 self.os.symlink, 2268 self.base_path, 2269 dir_path + self.os.sep, 2270 ) 2271 2272 dir_path = self.make_path("bar") 2273 self.assert_raises_os_error( 2274 errno.ENOENT, 2275 self.os.symlink, 2276 self.base_path, 2277 dir_path + self.os.sep, 2278 ) 2279 2280 def test_symlink_with_path_ending_with_sep_in_windows(self): 2281 self.check_windows_only() 2282 self.skip_if_symlink_not_supported() 2283 dir_path = self.make_path("dir") 2284 self.create_dir(dir_path) 2285 self.assert_raises_os_error( 2286 errno.EEXIST, 2287 self.os.symlink, 2288 self.base_path, 2289 dir_path + self.os.sep, 2290 ) 2291 2292 dir_path = self.make_path("bar") 2293 # does not raise under Windows 2294 self.os.symlink(self.base_path, dir_path + self.os.sep) 2295 2296 def test_broken_symlink_with_trailing_sep_posix(self): 2297 # Regression test for #390 2298 self.check_linux_only() 2299 path0 = self.make_path("foo") + self.os.sep 2300 self.assert_raises_os_error(errno.ENOENT, self.os.symlink, path0, path0) 2301 2302 def test_broken_symlink_with_trailing_sep_windows(self): 2303 self.check_windows_only() 2304 self.skip_if_symlink_not_supported() 2305 path0 = self.make_path("foo") + self.os.sep 2306 self.assert_raises_os_error(errno.EINVAL, self.os.symlink, path0, path0) 2307 2308 def test_rename_symlink_with_trailing_sep_linux(self): 2309 # Regression test for #391 2310 self.check_linux_only() 2311 path = self.make_path("foo") 2312 self.os.symlink(self.base_path, path) 2313 self.assert_raises_os_error( 2314 errno.ENOTDIR, self.os.rename, path + self.os.sep, self.base_path 2315 ) 2316 2317 def test_rename_symlink_with_trailing_sep_macos(self): 2318 # Regression test for #391 2319 self.check_macos_only() 2320 path = self.make_path("foo") 2321 self.os.symlink(self.base_path, path) 2322 self.os.rename(path + self.os.sep, self.base_path) 2323 2324 def test_rename_symlink_with_trailing_sep_windows(self): 2325 self.check_windows_only() 2326 self.skip_if_symlink_not_supported() 2327 path = self.make_path("foo") 2328 self.os.symlink(self.base_path, path) 2329 self.assert_raises_os_error( 2330 errno.EEXIST, self.os.rename, path + self.os.sep, self.base_path 2331 ) 2332 2333 def test_rename_symlink_to_other_case(self): 2334 # Regression test for #389 2335 self.skip_if_symlink_not_supported() 2336 link_path = self.make_path("foo") 2337 self.os.symlink(self.base_path, link_path) 2338 link_to_link_path = self.make_path("BAR") 2339 self.os.symlink(link_path, link_to_link_path) 2340 new_link_to_link_path = self.os.path.join(link_path, "bar") 2341 self.os.rename(link_to_link_path, new_link_to_link_path) 2342 self.assertEqual(["bar", "foo"], sorted(self.os.listdir(new_link_to_link_path))) 2343 2344 def create_broken_link_path_with_trailing_sep(self): 2345 # Regression tests for #396 2346 self.skip_if_symlink_not_supported() 2347 link_path = self.make_path("link") 2348 target_path = self.make_path("target") 2349 self.os.symlink(target_path, link_path) 2350 link_path += self.os.sep 2351 return link_path 2352 2353 def test_lstat_broken_link_with_trailing_sep_linux(self): 2354 self.check_linux_only() 2355 link_path = self.create_broken_link_path_with_trailing_sep() 2356 self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) 2357 2358 def test_lstat_broken_link_with_trailing_sep_macos(self): 2359 self.check_macos_only() 2360 link_path = self.create_broken_link_path_with_trailing_sep() 2361 self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) 2362 2363 def test_lstat_broken_link_with_trailing_sep_windows(self): 2364 self.check_windows_only() 2365 link_path = self.create_broken_link_path_with_trailing_sep() 2366 self.assert_raises_os_error(errno.EINVAL, self.os.lstat, link_path) 2367 2368 def test_mkdir_broken_link_with_trailing_sep_linux_windows(self): 2369 self.check_linux_and_windows() 2370 link_path = self.create_broken_link_path_with_trailing_sep() 2371 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, link_path) 2372 self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) 2373 2374 def test_mkdir_broken_link_with_trailing_sep_macos(self): 2375 self.check_macos_only() 2376 link_path = self.create_broken_link_path_with_trailing_sep() 2377 self.os.mkdir(link_path) # no error 2378 2379 def test_makedirs_broken_link_with_trailing_sep_macos(self): 2380 self.check_macos_only() 2381 link_path = self.create_broken_link_path_with_trailing_sep() 2382 self.os.makedirs(link_path) # no error 2383 2384 def test_remove_broken_link_with_trailing_sep_linux(self): 2385 self.check_linux_only() 2386 link_path = self.create_broken_link_path_with_trailing_sep() 2387 self.assert_raises_os_error(errno.ENOTDIR, self.os.remove, link_path) 2388 2389 def test_remove_broken_link_with_trailing_sep_macos(self): 2390 self.check_macos_only() 2391 link_path = self.create_broken_link_path_with_trailing_sep() 2392 self.assert_raises_os_error(errno.ENOENT, self.os.remove, link_path) 2393 2394 def test_remove_broken_link_with_trailing_sep_windows(self): 2395 self.check_windows_only() 2396 link_path = self.create_broken_link_path_with_trailing_sep() 2397 self.assert_raises_os_error(errno.EINVAL, self.os.remove, link_path) 2398 2399 def test_rename_broken_link_with_trailing_sep_linux(self): 2400 self.check_linux_only() 2401 link_path = self.create_broken_link_path_with_trailing_sep() 2402 self.assert_raises_os_error( 2403 errno.ENOTDIR, self.os.rename, link_path, self.make_path("target") 2404 ) 2405 2406 def test_rename_broken_link_with_trailing_sep_macos(self): 2407 self.check_macos_only() 2408 link_path = self.create_broken_link_path_with_trailing_sep() 2409 self.assert_raises_os_error( 2410 errno.ENOENT, self.os.rename, link_path, self.make_path("target") 2411 ) 2412 2413 def test_rename_broken_link_with_trailing_sep_windows(self): 2414 self.check_windows_only() 2415 link_path = self.create_broken_link_path_with_trailing_sep() 2416 self.assert_raises_os_error( 2417 errno.EINVAL, self.os.rename, link_path, self.make_path("target") 2418 ) 2419 2420 def test_readlink_broken_link_with_trailing_sep_posix(self): 2421 self.check_posix_only() 2422 link_path = self.create_broken_link_path_with_trailing_sep() 2423 self.assert_raises_os_error(errno.ENOENT, self.os.readlink, link_path) 2424 2425 def test_readlink_broken_link_with_trailing_sep_windows(self): 2426 self.check_windows_only() 2427 link_path = self.create_broken_link_path_with_trailing_sep() 2428 self.assert_raises_os_error(errno.EINVAL, self.os.readlink, link_path) 2429 2430 def test_islink_broken_link_with_trailing_sep(self): 2431 link_path = self.create_broken_link_path_with_trailing_sep() 2432 self.assertFalse(self.os.path.islink(link_path)) 2433 2434 def test_lexists_broken_link_with_trailing_sep(self): 2435 link_path = self.create_broken_link_path_with_trailing_sep() 2436 self.assertFalse(self.os.path.lexists(link_path)) 2437 2438 def test_rename_link_with_trailing_sep_to_self_windows(self): 2439 self.check_windows_only() 2440 self.skip_if_symlink_not_supported() 2441 path = self.make_path("foo") 2442 self.os.symlink(self.base_path, path) 2443 self.os.rename(path + self.os.sep, path) # no error 2444 2445 def test_rename_link_with_trailing_sep_to_self_posix(self): 2446 # Regression test for #395 2447 self.check_posix_only() 2448 path = self.make_path("foo") 2449 self.os.symlink(self.base_path, path) 2450 self.assert_raises_os_error( 2451 errno.ENOTDIR, self.os.rename, path + self.os.sep, path 2452 ) 2453 2454 def check_open_broken_symlink_to_path_with_trailing_sep(self, error): 2455 # Regression tests for #397 2456 self.skip_if_symlink_not_supported() 2457 target_path = self.make_path("target") + self.os.sep 2458 link_path = self.make_path("link") 2459 self.os.symlink(target_path, link_path) 2460 self.assert_raises_os_error(error, self.open, link_path, "a") 2461 self.assert_raises_os_error(error, self.open, link_path, "w") 2462 2463 def test_open_broken_symlink_to_path_with_trailing_sep_linux(self): 2464 self.check_linux_only() 2465 self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EISDIR) 2466 2467 def test_open_broken_symlink_to_path_with_trailing_sep_macos(self): 2468 self.check_macos_only() 2469 self.check_open_broken_symlink_to_path_with_trailing_sep(errno.ENOENT) 2470 2471 def test_open_broken_symlink_to_path_with_trailing_sep_windows(self): 2472 self.check_windows_only() 2473 self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EINVAL) 2474 2475 def check_link_path_ending_with_sep(self, error): 2476 # Regression tests for #399 2477 self.skip_if_symlink_not_supported() 2478 file_path = self.make_path("foo") 2479 link_path = self.make_path("link") 2480 with self.open(file_path, "w"): 2481 self.assert_raises_os_error( 2482 error, self.os.link, file_path + self.os.sep, link_path 2483 ) 2484 2485 def test_link_path_ending_with_sep_posix(self): 2486 self.check_posix_only() 2487 self.check_link_path_ending_with_sep(errno.ENOTDIR) 2488 2489 def test_link_path_ending_with_sep_windows(self): 2490 self.check_windows_only() 2491 self.check_link_path_ending_with_sep(errno.EINVAL) 2492 2493 def test_link_to_path_ending_with_sep_posix(self): 2494 # regression test for #407 2495 self.check_posix_only() 2496 path0 = self.make_path("foo") + self.os.sep 2497 path1 = self.make_path("bar") 2498 with self.open(path1, "w"): 2499 self.assert_raises_os_error(errno.ENOENT, self.os.link, path1, path0) 2500 2501 def test_link_to_path_ending_with_sep_windows(self): 2502 self.check_windows_only() 2503 self.skip_if_symlink_not_supported() 2504 path0 = self.make_path("foo") + self.os.sep 2505 path1 = self.make_path("bar") 2506 with self.open(path1, "w"): 2507 self.os.link(path1, path0) 2508 self.assertTrue(self.os.path.exists(path1)) 2509 2510 def check_rename_to_path_ending_with_sep(self, error): 2511 # Regression tests for #400 2512 file_path = self.make_path("foo") 2513 with self.open(file_path, "w"): 2514 self.assert_raises_os_error( 2515 error, self.os.rename, file_path + self.os.sep, file_path 2516 ) 2517 2518 def test_rename_to_path_ending_with_sep_posix(self): 2519 self.check_posix_only() 2520 self.check_rename_to_path_ending_with_sep(errno.ENOTDIR) 2521 2522 def test_rename_to_path_ending_with_sep_windows(self): 2523 self.check_windows_only() 2524 self.check_rename_to_path_ending_with_sep(errno.EINVAL) 2525 2526 def test_rmdir_link_with_trailing_sep_linux(self): 2527 self.check_linux_only() 2528 dir_path = self.make_path("foo") 2529 self.os.mkdir(dir_path) 2530 link_path = self.make_path("link") 2531 self.os.symlink(dir_path, link_path) 2532 self.assert_raises_os_error( 2533 errno.ENOTDIR, self.os.rmdir, link_path + self.os.sep 2534 ) 2535 2536 def test_rmdir_link_with_trailing_sep_macos(self): 2537 # Regression test for #398 2538 self.check_macos_only() 2539 dir_path = self.make_path("foo") 2540 self.os.mkdir(dir_path) 2541 link_path = self.make_path("link") 2542 self.os.symlink(dir_path, link_path) 2543 self.os.rmdir(link_path + self.os.sep) 2544 self.assertFalse(self.os.path.exists(link_path)) 2545 2546 def test_rmdir_link_with_trailing_sep_windows(self): 2547 self.check_windows_only() 2548 self.skip_if_symlink_not_supported() 2549 dir_path = self.make_path("foo") 2550 self.os.mkdir(dir_path) 2551 link_path = self.make_path("link") 2552 self.os.symlink(dir_path, link_path) 2553 self.os.rmdir(link_path + self.os.sep) 2554 self.assertFalse(self.os.path.exists(link_path)) 2555 2556 def test_readlink_circular_link_with_trailing_sep_linux(self): 2557 self.check_linux_only() 2558 path1 = self.make_path("foo") 2559 path0 = self.make_path("bar") 2560 self.os.symlink(path0, path1) 2561 self.os.symlink(path1, path0) 2562 self.assert_raises_os_error(errno.ELOOP, self.os.readlink, path0 + self.os.sep) 2563 2564 def test_readlink_circular_link_with_trailing_sep_macos(self): 2565 # Regression test for #392 2566 self.check_macos_only() 2567 path1 = self.make_path("foo") 2568 path0 = self.make_path("bar") 2569 self.os.symlink(path0, path1) 2570 self.os.symlink(path1, path0) 2571 self.assertEqual(path0, self.os.readlink(path0 + self.os.sep)) 2572 2573 def test_readlink_circular_link_with_trailing_sep_windows(self): 2574 self.check_windows_only() 2575 self.skip_if_symlink_not_supported() 2576 path1 = self.make_path("foo") 2577 path0 = self.make_path("bar") 2578 self.os.symlink(path0, path1) 2579 self.os.symlink(path1, path0) 2580 self.assert_raises_os_error(errno.EINVAL, self.os.readlink, path0 + self.os.sep) 2581 2582 # hard link related tests 2583 def test_link_bogus(self): 2584 # trying to create a link from a non-existent file should fail 2585 self.skip_if_symlink_not_supported() 2586 self.assert_raises_os_error( 2587 errno.ENOENT, self.os.link, "/nonexistent_source", "/link_dest" 2588 ) 2589 2590 def test_link_delete(self): 2591 self.skip_if_symlink_not_supported() 2592 2593 file1_path = self.make_path("test_file1") 2594 file2_path = self.make_path("test_file2") 2595 contents1 = "abcdef" 2596 # Create file 2597 self.create_file(file1_path, contents=contents1) 2598 # link to second file 2599 self.os.link(file1_path, file2_path) 2600 # delete first file 2601 self.os.unlink(file1_path) 2602 # assert that second file exists, and its contents are the same 2603 self.assertTrue(self.os.path.exists(file2_path)) 2604 with self.open(file2_path) as f: 2605 self.assertEqual(f.read(), contents1) 2606 2607 def test_link_update(self): 2608 self.skip_if_symlink_not_supported() 2609 2610 file1_path = self.make_path("test_file1") 2611 file2_path = self.make_path("test_file2") 2612 contents1 = "abcdef" 2613 contents2 = "ghijkl" 2614 # Create file and link 2615 self.create_file(file1_path, contents=contents1) 2616 self.os.link(file1_path, file2_path) 2617 # assert that the second file contains contents1 2618 with self.open(file2_path) as f: 2619 self.assertEqual(f.read(), contents1) 2620 # update the first file 2621 with self.open(file1_path, "w") as f: 2622 f.write(contents2) 2623 # assert that second file contains contents2 2624 with self.open(file2_path) as f: 2625 self.assertEqual(f.read(), contents2) 2626 2627 def test_link_non_existent_parent(self): 2628 self.skip_if_symlink_not_supported() 2629 file1_path = self.make_path("test_file1") 2630 breaking_link_path = self.make_path("nonexistent", "test_file2") 2631 contents1 = "abcdef" 2632 # Create file and link 2633 self.create_file(file1_path, contents=contents1) 2634 2635 # trying to create a link under a non-existent directory should fail 2636 self.assert_raises_os_error( 2637 errno.ENOENT, self.os.link, file1_path, breaking_link_path 2638 ) 2639 2640 def test_link_is_existing_file(self): 2641 self.skip_if_symlink_not_supported() 2642 file_path = self.make_path("foo", "bar") 2643 self.create_file(file_path) 2644 self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, file_path) 2645 2646 def test_link_target_is_dir_windows(self): 2647 self.check_windows_only() 2648 self.skip_if_symlink_not_supported() 2649 dir_path = self.make_path("foo", "bar") 2650 link_path = self.os.path.join(dir_path, "link") 2651 self.create_dir(dir_path) 2652 self.assert_raises_os_error(errno.EACCES, self.os.link, dir_path, link_path) 2653 2654 def test_link_target_is_dir_posix(self): 2655 self.check_posix_only() 2656 dir_path = self.make_path("foo", "bar") 2657 link_path = self.os.path.join(dir_path, "link") 2658 self.create_dir(dir_path) 2659 self.assert_raises_os_error(errno.EPERM, self.os.link, dir_path, link_path) 2660 2661 def test_link_count1(self): 2662 """Test that hard link counts are updated correctly.""" 2663 self.skip_if_symlink_not_supported() 2664 file1_path = self.make_path("test_file1") 2665 file2_path = self.make_path("test_file2") 2666 file3_path = self.make_path("test_file3") 2667 self.create_file(file1_path) 2668 # initial link count should be one 2669 self.assertEqual(self.os.stat(file1_path).st_nlink, 1) 2670 self.os.link(file1_path, file2_path) 2671 # the count should be incremented for each hard link created 2672 self.assertEqual(self.os.stat(file1_path).st_nlink, 2) 2673 self.assertEqual(self.os.stat(file2_path).st_nlink, 2) 2674 # Check that the counts are all updated together 2675 self.os.link(file2_path, file3_path) 2676 self.assertEqual(self.os.stat(file1_path).st_nlink, 3) 2677 self.assertEqual(self.os.stat(file2_path).st_nlink, 3) 2678 self.assertEqual(self.os.stat(file3_path).st_nlink, 3) 2679 # Counts should be decremented when links are removed 2680 self.os.unlink(file3_path) 2681 self.assertEqual(self.os.stat(file1_path).st_nlink, 2) 2682 self.assertEqual(self.os.stat(file2_path).st_nlink, 2) 2683 # check that it gets decremented correctly again 2684 self.os.unlink(file1_path) 2685 self.assertEqual(self.os.stat(file2_path).st_nlink, 1) 2686 2687 def test_nlink_for_directories(self): 2688 self.skip_real_fs() 2689 self.create_dir(self.make_path("foo", "bar")) 2690 self.create_file(self.make_path("foo", "baz")) 2691 self.assertEqual( 2692 2, 2693 self.filesystem.get_object(self.make_path("foo", "bar")).st_nlink, 2694 ) 2695 self.assertEqual(4, self.filesystem.get_object(self.make_path("foo")).st_nlink) 2696 self.create_file(self.make_path("foo", "baz2")) 2697 self.assertEqual(5, self.filesystem.get_object(self.make_path("foo")).st_nlink) 2698 2699 def test_umask(self): 2700 self.check_posix_only() 2701 umask = os.umask(0o22) 2702 os.umask(umask) 2703 self.assertEqual(umask, self.os.umask(0o22)) 2704 2705 def test_mkdir_umask_applied(self): 2706 """mkdir creates a directory with umask applied.""" 2707 self.check_posix_only() 2708 self.os.umask(0o22) 2709 dir1 = self.make_path("dir1") 2710 self.os.mkdir(dir1) 2711 self.assert_mode_equal(0o755, self.os.stat(dir1).st_mode) 2712 self.os.umask(0o67) 2713 dir2 = self.make_path("dir2") 2714 self.os.mkdir(dir2) 2715 self.assert_mode_equal(0o710, self.os.stat(dir2).st_mode) 2716 2717 def test_makedirs_umask_applied(self): 2718 """makedirs creates a directories with umask applied.""" 2719 self.check_posix_only() 2720 self.os.umask(0o22) 2721 self.os.makedirs(self.make_path("p1", "dir1")) 2722 self.assert_mode_equal(0o755, self.os.stat(self.make_path("p1")).st_mode) 2723 self.assert_mode_equal( 2724 0o755, self.os.stat(self.make_path("p1", "dir1")).st_mode 2725 ) 2726 self.os.umask(0o67) 2727 self.os.makedirs(self.make_path("p2", "dir2")) 2728 self.assert_mode_equal(0o710, self.os.stat(self.make_path("p2")).st_mode) 2729 self.assert_mode_equal( 2730 0o710, self.os.stat(self.make_path("p2", "dir2")).st_mode 2731 ) 2732 2733 def test_mknod_umask_applied(self): 2734 """mkdir creates a device with umask applied.""" 2735 # skipping MacOs due to mknod permission issues 2736 self.check_linux_only() 2737 self.os.umask(0o22) 2738 node1 = self.make_path("nod1") 2739 self.os.mknod(node1, stat.S_IFREG | 0o666) 2740 self.assert_mode_equal(0o644, self.os.stat(node1).st_mode) 2741 self.os.umask(0o27) 2742 node2 = self.make_path("nod2") 2743 self.os.mknod(node2, stat.S_IFREG | 0o666) 2744 self.assert_mode_equal(0o640, self.os.stat(node2).st_mode) 2745 2746 def test_open_umask_applied(self): 2747 """open creates a file with umask applied.""" 2748 self.check_posix_only() 2749 self.os.umask(0o22) 2750 file1 = self.make_path("file1") 2751 self.open(file1, "w").close() 2752 self.assert_mode_equal(0o644, self.os.stat(file1).st_mode) 2753 self.os.umask(0o27) 2754 file2 = self.make_path("file2") 2755 self.open(file2, "w").close() 2756 self.assert_mode_equal(0o640, self.os.stat(file2).st_mode) 2757 2758 def test_open_pipe(self): 2759 read_fd, write_fd = self.os.pipe() 2760 self.os.close(read_fd) 2761 self.os.close(write_fd) 2762 2763 def test_open_pipe_with_existing_fd(self): 2764 file1 = self.make_path("file1") 2765 fd = self.os.open(file1, os.O_CREAT) 2766 read_fd, write_fd = self.os.pipe() 2767 self.assertGreater(read_fd, fd) 2768 self.os.close(fd) 2769 self.os.close(read_fd) 2770 self.os.close(write_fd) 2771 2772 def test_open_file_with_existing_pipe(self): 2773 read_fd, write_fd = self.os.pipe() 2774 file1 = self.make_path("file1") 2775 fd = self.os.open(file1, os.O_CREAT) 2776 self.assertGreater(fd, write_fd) 2777 self.os.close(read_fd) 2778 self.os.close(write_fd) 2779 self.os.close(fd) 2780 2781 def test_read_write_pipe(self): 2782 read_fd, write_fd = self.os.pipe() 2783 self.assertEqual(4, self.os.write(write_fd, b"test")) 2784 self.assertEqual(b"test", self.os.read(read_fd, 4)) 2785 self.os.close(read_fd) 2786 self.os.close(write_fd) 2787 2788 def test_open_existing_pipe(self): 2789 # create some regular files to ensure that real and fake fd 2790 # are out of sync (see #581) 2791 fds = [] 2792 for i in range(5): 2793 path = self.make_path("file" + str(i)) 2794 fds.append(self.os.open(path, os.O_CREAT)) 2795 file_path = self.make_path("file.txt") 2796 self.create_file(file_path) 2797 with self.open(file_path): 2798 read_fd, write_fd = self.os.pipe() 2799 with self.open(write_fd, "wb") as f: 2800 self.assertEqual(4, f.write(b"test")) 2801 with self.open(read_fd, "rb") as f: 2802 self.assertEqual(b"test", f.read()) 2803 for fd in fds: 2804 self.os.close(fd) 2805 2806 def test_write_to_pipe(self): 2807 read_fd, write_fd = self.os.pipe() 2808 self.os.write(write_fd, b"test") 2809 self.assertEqual(b"test", self.os.read(read_fd, 4)) 2810 self.os.close(read_fd) 2811 self.os.close(write_fd) 2812 2813 @unittest.skipIf( 2814 sys.platform not in ("win32", "darwin", "linux"), 2815 "Pipe implementation may differ on other platforms", 2816 ) 2817 def test_write_to_read_fd(self): 2818 read_fd, write_fd = self.os.pipe() 2819 self.assert_raises_os_error(errno.EBADF, self.os.write, read_fd, b"test") 2820 self.os.close(read_fd) 2821 self.os.close(write_fd) 2822 2823 def test_truncate(self): 2824 file_path = self.make_path("foo", "bar") 2825 self.create_file(file_path, contents="012345678901234567") 2826 self.os.truncate(file_path, 10) 2827 with self.open(file_path) as f: 2828 self.assertEqual("0123456789", f.read()) 2829 2830 def test_truncate_non_existing(self): 2831 self.assert_raises_os_error(errno.ENOENT, self.os.truncate, "foo", 10) 2832 2833 def test_truncate_to_larger(self): 2834 file_path = self.make_path("foo", "bar") 2835 self.create_file(file_path, contents="0123456789") 2836 fd = self.os.open(file_path, os.O_RDWR) 2837 self.os.truncate(fd, 20) 2838 self.assertEqual(20, self.os.stat(file_path).st_size) 2839 with self.open(file_path) as f: 2840 self.assertEqual("0123456789" + "\0" * 10, f.read()) 2841 2842 def test_truncate_with_fd(self): 2843 if os.truncate not in os.supports_fd: 2844 self.skip_real_fs() 2845 self.assert_raises_os_error(errno.EBADF, self.os.ftruncate, 50, 10) 2846 file_path = self.make_path("some_file") 2847 self.create_file(file_path, contents="01234567890123456789") 2848 2849 fd = self.os.open(file_path, os.O_RDWR) 2850 self.os.truncate(fd, 10) 2851 self.assertEqual(10, self.os.stat(file_path).st_size) 2852 with self.open(file_path) as f: 2853 self.assertEqual("0123456789", f.read()) 2854 2855 def test_ftruncate(self): 2856 if self.is_pypy: 2857 # not correctly supported 2858 self.skip_real_fs() 2859 self.assert_raises_os_error(errno.EBADF, self.os.ftruncate, 50, 10) 2860 file_path = self.make_path("some_file") 2861 self.create_file(file_path, contents="0123456789012345") 2862 2863 fd = self.os.open(file_path, os.O_RDWR) 2864 self.os.truncate(fd, 10) 2865 self.assertEqual(10, self.os.stat(file_path).st_size) 2866 with self.open(file_path) as f: 2867 self.assertEqual("0123456789", f.read()) 2868 2869 def test_capabilities(self): 2870 """Make sure that the fake capabilities are the same as the real ones.""" 2871 self.assertEqual( 2872 self.os.stat in self.os.supports_follow_symlinks, 2873 os.stat in os.supports_follow_symlinks, 2874 ) 2875 self.assertEqual(self.os.stat in self.os.supports_fd, os.stat in os.supports_fd) 2876 self.assertEqual( 2877 self.os.stat in self.os.supports_dir_fd, os.stat in os.supports_dir_fd 2878 ) 2879 self.assertEqual( 2880 self.os.stat in self.os.supports_effective_ids, 2881 os.stat in os.supports_effective_ids, 2882 ) 2883 2884 2885class RealOsModuleTest(FakeOsModuleTest): 2886 def use_real_fs(self): 2887 return True 2888 2889 2890class FakeOsModuleTestCaseInsensitiveFS(FakeOsModuleTestBase): 2891 def setUp(self): 2892 super(FakeOsModuleTestCaseInsensitiveFS, self).setUp() 2893 self.check_case_insensitive_fs() 2894 self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK 2895 self.rw = self.os.R_OK | self.os.W_OK 2896 2897 def test_chdir_fails_non_directory(self): 2898 """chdir should raise OSError if the target is not a directory.""" 2899 filename = self.make_path("foo", "bar") 2900 self.create_file(filename) 2901 filename1 = self.make_path("Foo", "Bar") 2902 self.assert_raises_os_error(errno.ENOTDIR, self.os.chdir, filename1) 2903 2904 def test_listdir_returns_list(self): 2905 directory_root = self.make_path("xyzzy") 2906 self.os.mkdir(directory_root) 2907 directory = self.os.path.join(directory_root, "bug") 2908 self.os.mkdir(directory) 2909 directory_upper = self.make_path("XYZZY", "BUG") 2910 self.create_file(self.make_path(directory, "foo")) 2911 self.assertEqual(["foo"], self.os.listdir(directory_upper)) 2912 2913 def test_listdir_on_symlink(self): 2914 self.skip_if_symlink_not_supported() 2915 directory = self.make_path("xyzzy") 2916 files = ["foo", "bar", "baz"] 2917 for f in files: 2918 self.create_file(self.make_path(directory, f)) 2919 self.create_symlink(self.make_path("symlink"), self.make_path("xyzzy")) 2920 files.sort() 2921 self.assertEqual(files, sorted(self.os.listdir(self.make_path("SymLink")))) 2922 2923 def test_fdopen_mode(self): 2924 self.skip_real_fs() 2925 file_path1 = self.make_path("some_file1") 2926 file_path2 = self.make_path("Some_File1") 2927 file_path3 = self.make_path("SOME_file1") 2928 self.create_file(file_path1, contents="contents here1") 2929 self.os.chmod(file_path2, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) 2930 2931 fake_file1 = self.open(file_path3, "r") 2932 fileno1 = fake_file1.fileno() 2933 self.os.fdopen(fileno1) 2934 self.os.fdopen(fileno1, "r") 2935 if not is_root(): 2936 self.assertRaises(OSError, self.os.fdopen, fileno1, "w") 2937 else: 2938 self.os.fdopen(fileno1, "w") 2939 2940 def test_stat(self): 2941 directory = self.make_path("xyzzy") 2942 directory1 = self.make_path("XYZZY") 2943 file_path = self.os.path.join(directory, "plugh") 2944 self.create_file(file_path, contents="ABCDE") 2945 self.assertTrue(stat.S_IFDIR & self.os.stat(directory1)[stat.ST_MODE]) 2946 file_path1 = self.os.path.join(directory1, "Plugh") 2947 self.assertTrue(stat.S_IFREG & self.os.stat(file_path1)[stat.ST_MODE]) 2948 self.assertTrue(stat.S_IFREG & self.os.stat(file_path1).st_mode) 2949 self.assertEqual(5, self.os.stat(file_path1)[stat.ST_SIZE]) 2950 2951 def test_stat_no_follow_symlinks_posix(self): 2952 """Test that stat with follow_symlinks=False behaves like lstat.""" 2953 self.check_posix_only() 2954 directory = self.make_path("xyzzy") 2955 base_name = "plugh" 2956 file_contents = "frobozz" 2957 # Just make sure we didn't accidentally make our test data meaningless. 2958 self.assertNotEqual(len(base_name), len(file_contents)) 2959 file_path = self.os.path.join(directory, base_name) 2960 link_path = self.os.path.join(directory, "link") 2961 self.create_file(file_path, contents=file_contents) 2962 self.create_symlink(link_path, base_name) 2963 self.assertEqual( 2964 len(file_contents), 2965 self.os.stat(file_path.upper(), follow_symlinks=False)[stat.ST_SIZE], 2966 ) 2967 self.assertEqual( 2968 len(base_name), 2969 self.os.stat(link_path.upper(), follow_symlinks=False)[stat.ST_SIZE], 2970 ) 2971 2972 def test_lstat_posix(self): 2973 self.check_posix_only() 2974 directory = self.make_path("xyzzy") 2975 base_name = "plugh" 2976 file_contents = "frobozz" 2977 # Just make sure we didn't accidentally make our test data meaningless. 2978 self.assertNotEqual(len(base_name), len(file_contents)) 2979 file_path = self.os.path.join(directory, base_name) 2980 link_path = self.os.path.join(directory, "link") 2981 self.create_file(file_path, contents=file_contents) 2982 self.create_symlink(link_path, base_name) 2983 self.assertEqual( 2984 len(file_contents), self.os.lstat(file_path.upper())[stat.ST_SIZE] 2985 ) 2986 self.assertEqual(len(base_name), self.os.lstat(link_path.upper())[stat.ST_SIZE]) 2987 2988 def test_readlink(self): 2989 self.skip_if_symlink_not_supported() 2990 link_path = self.make_path("foo", "bar", "baz") 2991 target = self.make_path("tarJAY") 2992 self.create_symlink(link_path, target) 2993 self.assert_equal_paths(self.os.readlink(link_path.upper()), target) 2994 2995 def check_readlink_raises_if_path_not_a_link(self): 2996 file_path = self.make_path("foo", "bar", "eleventyone") 2997 self.create_file(file_path) 2998 self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path.upper()) 2999 3000 def test_readlink_raises_if_path_not_a_link_windows(self): 3001 self.check_windows_only() 3002 self.skip_if_symlink_not_supported() 3003 self.check_readlink_raises_if_path_not_a_link() 3004 3005 def test_readlink_raises_if_path_not_a_link_posix(self): 3006 self.check_posix_only() 3007 self.check_readlink_raises_if_path_not_a_link() 3008 3009 def check_readlink_raises_if_path_has_file(self, error_subtype): 3010 self.create_file(self.make_path("a_file")) 3011 file_path = self.make_path("a_file", "foo") 3012 self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) 3013 file_path = self.make_path("a_file", "foo", "bar") 3014 self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) 3015 3016 def test_readlink_raises_if_path_has_file_windows(self): 3017 self.check_windows_only() 3018 self.skip_if_symlink_not_supported() 3019 self.check_readlink_raises_if_path_has_file(errno.ENOENT) 3020 3021 def test_readlink_raises_if_path_has_file_posix(self): 3022 self.check_posix_only() 3023 self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) 3024 3025 def test_readlink_with_links_in_path(self): 3026 self.skip_if_symlink_not_supported() 3027 self.create_symlink( 3028 self.make_path("meyer", "lemon", "pie"), self.make_path("yum") 3029 ) 3030 self.create_symlink(self.make_path("geo", "metro"), self.make_path("Meyer")) 3031 self.assert_equal_paths( 3032 self.make_path("yum"), 3033 self.os.readlink(self.make_path("Geo", "Metro", "Lemon", "Pie")), 3034 ) 3035 3036 def test_readlink_with_chained_links_in_path(self): 3037 self.skip_if_symlink_not_supported() 3038 self.create_symlink( 3039 self.make_path("eastern", "european", "wolfhounds", "chase"), 3040 self.make_path("cats"), 3041 ) 3042 self.create_symlink( 3043 self.make_path("russian"), self.make_path("Eastern", "European") 3044 ) 3045 self.create_symlink( 3046 self.make_path("dogs"), self.make_path("Russian", "Wolfhounds") 3047 ) 3048 self.assert_equal_paths( 3049 self.make_path("cats"), 3050 self.os.readlink(self.make_path("DOGS", "Chase")), 3051 ) 3052 3053 def check_remove_dir(self, dir_error): 3054 directory = self.make_path("xyzzy") 3055 dir_path = self.os.path.join(directory, "plugh") 3056 self.create_dir(dir_path) 3057 dir_path = dir_path.upper() 3058 self.assertTrue(self.os.path.exists(dir_path.upper())) 3059 self.assert_raises_os_error(dir_error, self.os.remove, dir_path) 3060 self.assertTrue(self.os.path.exists(dir_path)) 3061 self.os.chdir(directory) 3062 self.assert_raises_os_error(dir_error, self.os.remove, dir_path) 3063 self.assertTrue(self.os.path.exists(dir_path)) 3064 self.assert_raises_os_error(errno.ENOENT, self.os.remove, "/Plugh") 3065 3066 def test_remove_dir_mac_os(self): 3067 self.check_macos_only() 3068 self.check_remove_dir(errno.EPERM) 3069 3070 def test_remove_dir_windows(self): 3071 self.check_windows_only() 3072 self.check_remove_dir(errno.EACCES) 3073 3074 def test_remove_file(self): 3075 directory = self.make_path("zzy") 3076 file_path = self.os.path.join(directory, "plugh") 3077 self.create_file(file_path) 3078 self.assertTrue(self.os.path.exists(file_path.upper())) 3079 self.os.remove(file_path.upper()) 3080 self.assertFalse(self.os.path.exists(file_path)) 3081 3082 def test_remove_file_no_directory(self): 3083 directory = self.make_path("zzy") 3084 file_name = "plugh" 3085 file_path = self.os.path.join(directory, file_name) 3086 self.create_file(file_path) 3087 self.assertTrue(self.os.path.exists(file_path)) 3088 self.os.chdir(directory.upper()) 3089 self.os.remove(file_name.upper()) 3090 self.assertFalse(self.os.path.exists(file_path)) 3091 3092 def test_remove_open_file_fails_under_windows(self): 3093 self.check_windows_only() 3094 path = self.make_path("foo", "bar") 3095 self.create_file(path) 3096 with self.open(path, "r"): 3097 self.assert_raises_os_error(errno.EACCES, self.os.remove, path.upper()) 3098 self.assertTrue(self.os.path.exists(path)) 3099 3100 def test_remove_open_file_possible_under_posix(self): 3101 self.check_posix_only() 3102 path = self.make_path("foo", "bar") 3103 self.create_file(path) 3104 self.open(path, "r") 3105 self.os.remove(path.upper()) 3106 self.assertFalse(self.os.path.exists(path)) 3107 3108 def test_remove_file_relative_path(self): 3109 self.skip_real_fs() 3110 original_dir = self.os.getcwd() 3111 directory = self.make_path("zzy") 3112 subdirectory = self.os.path.join(directory, "zzy") 3113 file_name = "plugh" 3114 file_path = self.os.path.join(directory, file_name) 3115 file_path_relative = self.os.path.join("..", file_name) 3116 self.create_file(file_path.upper()) 3117 self.assertTrue(self.os.path.exists(file_path)) 3118 self.create_dir(subdirectory) 3119 self.assertTrue(self.os.path.exists(subdirectory)) 3120 self.os.chdir(subdirectory.upper()) 3121 self.os.remove(file_path_relative.upper()) 3122 self.assertFalse(self.os.path.exists(file_path_relative)) 3123 self.os.chdir(original_dir.upper()) 3124 self.assertFalse(self.os.path.exists(file_path)) 3125 3126 def check_remove_dir_raises_error(self, dir_error): 3127 directory = self.make_path("zzy") 3128 self.create_dir(directory) 3129 self.assert_raises_os_error(dir_error, self.os.remove, directory.upper()) 3130 3131 def test_remove_dir_raises_error_mac_os(self): 3132 self.check_macos_only() 3133 self.check_remove_dir_raises_error(errno.EPERM) 3134 3135 def test_remove_dir_raises_error_windows(self): 3136 self.check_windows_only() 3137 self.check_remove_dir_raises_error(errno.EACCES) 3138 3139 def test_remove_symlink_to_dir(self): 3140 self.skip_if_symlink_not_supported() 3141 directory = self.make_path("zzy") 3142 link = self.make_path("link_to_dir") 3143 self.create_dir(directory) 3144 self.os.symlink(directory, link) 3145 self.assertTrue(self.os.path.exists(directory)) 3146 self.assertTrue(self.os.path.exists(link)) 3147 self.os.remove(link.upper()) 3148 self.assertTrue(self.os.path.exists(directory)) 3149 self.assertFalse(self.os.path.exists(link)) 3150 3151 def test_rename_dir_to_symlink_posix(self): 3152 self.check_posix_only() 3153 link_path = self.make_path("link") 3154 dir_path = self.make_path("dir") 3155 link_target = self.os.path.join(dir_path, "link_target") 3156 self.create_dir(dir_path) 3157 self.os.symlink(link_target.upper(), link_path.upper()) 3158 self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) 3159 3160 def test_rename_dir_to_symlink_windows(self): 3161 self.check_windows_only() 3162 self.skip_if_symlink_not_supported() 3163 link_path = self.make_path("link") 3164 dir_path = self.make_path("dir") 3165 link_target = self.os.path.join(dir_path, "link_target") 3166 self.create_dir(dir_path) 3167 self.os.symlink(link_target.upper(), link_path.upper()) 3168 self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) 3169 3170 def test_rename_dir_to_existing_dir(self): 3171 # Regression test for #317 3172 self.check_posix_only() 3173 dest_dir_path = self.make_path("Dest") 3174 # seems to behave differently under different MacOS versions 3175 self.skip_real_fs() 3176 new_dest_dir_path = self.make_path("dest") 3177 self.os.mkdir(dest_dir_path) 3178 source_dir_path = self.make_path("src") 3179 self.os.mkdir(source_dir_path) 3180 self.os.rename(source_dir_path, new_dest_dir_path) 3181 self.assertEqual(["dest"], self.os.listdir(self.base_path)) 3182 3183 def test_rename_file_to_symlink(self): 3184 self.check_posix_only() 3185 link_path = self.make_path("file_link") 3186 file_path = self.make_path("file") 3187 self.os.symlink(file_path, link_path) 3188 self.create_file(file_path) 3189 self.os.rename(file_path.upper(), link_path) 3190 self.assertFalse(self.os.path.exists(file_path)) 3191 self.assertTrue(self.os.path.exists(link_path.upper())) 3192 self.assertTrue(self.os.path.isfile(link_path.upper())) 3193 3194 def test_rename_symlink_to_symlink(self): 3195 self.check_posix_only() 3196 base_path = self.make_path("foo", "bar") 3197 self.create_dir(base_path) 3198 link_path1 = self.os.path.join(base_path, "link1") 3199 link_path2 = self.os.path.join(base_path, "link2") 3200 self.os.symlink(base_path.upper(), link_path1) 3201 self.os.symlink(base_path, link_path2) 3202 self.os.rename(link_path1.upper(), link_path2.upper()) 3203 self.assertFalse(self.os.path.exists(link_path1)) 3204 self.assertTrue(self.os.path.exists(link_path2)) 3205 3206 def test_rename_symlink_to_symlink_for_parent_raises(self): 3207 self.check_posix_only() 3208 dir_link = self.make_path("dir_link") 3209 dir_path = self.make_path("dir") 3210 dir_in_dir_path = self.os.path.join(dir_link, "inner_dir") 3211 self.create_dir(dir_path) 3212 self.os.symlink(dir_path.upper(), dir_link) 3213 self.create_dir(dir_in_dir_path) 3214 self.assert_raises_os_error( 3215 errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path.upper() 3216 ) 3217 3218 def test_rename_directory_to_linked_dir(self): 3219 # Regression test for #314 3220 self.skip_if_symlink_not_supported() 3221 link_path = self.make_path("link") 3222 self.os.symlink(self.base_path, link_path) 3223 link_subdir = self.os.path.join(link_path, "dir") 3224 dir_path = self.make_path("Dir") 3225 self.os.mkdir(dir_path) 3226 self.os.rename(dir_path, link_subdir) 3227 self.assertEqual(["dir", "link"], sorted(self.os.listdir(self.base_path))) 3228 3229 def test_recursive_rename_raises(self): 3230 self.check_posix_only() 3231 base_path = self.make_path("foo", "bar") 3232 self.create_dir(base_path) 3233 new_path = self.os.path.join(base_path, "new_dir") 3234 self.assert_raises_os_error( 3235 errno.EINVAL, self.os.rename, base_path.upper(), new_path 3236 ) 3237 3238 def test_rename_with_target_parent_file_raises_posix(self): 3239 self.check_posix_only() 3240 file_path = self.make_path("foo", "baz") 3241 self.create_file(file_path) 3242 self.assert_raises_os_error( 3243 errno.ENOTDIR, 3244 self.os.rename, 3245 file_path, 3246 file_path.upper() + "/new", 3247 ) 3248 3249 def test_rename_with_target_parent_file_raises_windows(self): 3250 self.check_windows_only() 3251 file_path = self.make_path("foo", "baz") 3252 self.create_file(file_path) 3253 self.assert_raises_os_error( 3254 errno.EACCES, 3255 self.os.rename, 3256 file_path, 3257 self.os.path.join(file_path.upper(), "new"), 3258 ) 3259 3260 def test_rename_looping_symlink(self): 3261 # Regression test for #315 3262 self.skip_if_symlink_not_supported() 3263 path_lower = self.make_path("baz") 3264 path_upper = self.make_path("BAZ") 3265 self.os.symlink(path_lower, path_upper) 3266 self.os.rename(path_upper, path_lower) 3267 self.assertEqual(["baz"], self.os.listdir(self.base_path)) 3268 3269 def test_rename_symlink_to_source(self): 3270 self.check_posix_only() 3271 base_path = self.make_path("foo") 3272 link_path = self.os.path.join(base_path, "slink") 3273 file_path = self.os.path.join(base_path, "file") 3274 self.create_file(file_path) 3275 self.os.symlink(file_path, link_path) 3276 self.os.rename(link_path.upper(), file_path.upper()) 3277 self.assertFalse(self.os.path.exists(file_path)) 3278 3279 def test_rename_symlink_to_dir_raises(self): 3280 self.check_posix_only() 3281 base_path = self.make_path("foo", "bar") 3282 link_path = self.os.path.join(base_path, "dir_link") 3283 dir_path = self.os.path.join(base_path, "dir") 3284 self.create_dir(dir_path) 3285 self.os.symlink(dir_path, link_path.upper()) 3286 self.assert_raises_os_error( 3287 errno.EISDIR, self.os.rename, link_path, dir_path.upper() 3288 ) 3289 3290 def test_rename_broken_symlink(self): 3291 self.check_posix_only() 3292 base_path = self.make_path("foo") 3293 self.create_dir(base_path) 3294 link_path = self.os.path.join(base_path, "slink") 3295 file_path = self.os.path.join(base_path, "file") 3296 self.os.symlink(file_path.upper(), link_path) 3297 self.os.rename(link_path.upper(), file_path) 3298 self.assertFalse(self.os.path.exists(file_path)) 3299 self.assertTrue(self.os.path.lexists(file_path)) 3300 self.assertFalse(self.os.path.exists(link_path)) 3301 3302 def test_change_case_in_case_insensitive_file_system(self): 3303 """Can use `rename()` to change filename case in a case-insensitive 3304 file system.""" 3305 old_file_path = self.make_path("fileName") 3306 new_file_path = self.make_path("FileNAME") 3307 self.create_file(old_file_path, contents="test contents") 3308 self.assertEqual(["fileName"], self.os.listdir(self.base_path)) 3309 self.os.rename(old_file_path, new_file_path) 3310 self.assertTrue(self.os.path.exists(old_file_path)) 3311 self.assertTrue(self.os.path.exists(new_file_path)) 3312 self.assertEqual(["FileNAME"], self.os.listdir(self.base_path)) 3313 3314 def test_rename_symlink_with_changed_case(self): 3315 # Regression test for #313 3316 self.skip_if_symlink_not_supported() 3317 link_path = self.make_path("link") 3318 self.os.symlink(self.base_path, link_path) 3319 link_path = self.os.path.join(link_path, "link") 3320 link_path_upper = self.make_path("link", "LINK") 3321 self.os.rename(link_path_upper, link_path) 3322 3323 def test_rename_directory(self): 3324 """Can rename a directory to an unused name.""" 3325 for old_path, new_path in [("wxyyw", "xyzzy"), ("abccb", "cdeed")]: 3326 old_path = self.make_path(old_path) 3327 new_path = self.make_path(new_path) 3328 self.create_file(self.os.path.join(old_path, "plugh"), contents="test") 3329 self.assertTrue(self.os.path.exists(old_path)) 3330 self.assertFalse(self.os.path.exists(new_path)) 3331 self.os.rename(old_path.upper(), new_path.upper()) 3332 self.assertFalse(self.os.path.exists(old_path)) 3333 self.assertTrue(self.os.path.exists(new_path)) 3334 self.check_contents(self.os.path.join(new_path, "plugh"), "test") 3335 if not self.use_real_fs(): 3336 self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) 3337 3338 def check_rename_directory_to_existing_file_raises(self, error_nr): 3339 dir_path = self.make_path("dir") 3340 file_path = self.make_path("file") 3341 self.create_dir(dir_path) 3342 self.create_file(file_path) 3343 self.assert_raises_os_error( 3344 error_nr, self.os.rename, dir_path, file_path.upper() 3345 ) 3346 3347 def test_rename_directory_to_existing_file_raises_posix(self): 3348 self.check_posix_only() 3349 self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) 3350 3351 def test_rename_directory_to_existing_file_raises_windows(self): 3352 self.check_windows_only() 3353 self.check_rename_directory_to_existing_file_raises(errno.EEXIST) 3354 3355 def test_rename_to_existing_directory_should_raise_under_windows(self): 3356 """Renaming to an existing directory raises OSError under Windows.""" 3357 self.check_windows_only() 3358 old_path = self.make_path("foo", "bar") 3359 new_path = self.make_path("foo", "baz") 3360 self.create_dir(old_path) 3361 self.create_dir(new_path) 3362 self.assert_raises_os_error( 3363 errno.EEXIST, self.os.rename, old_path.upper(), new_path.upper() 3364 ) 3365 3366 def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): 3367 self.skip_real_fs_failure(skip_posix=False) 3368 self.skip_if_symlink_not_supported() 3369 file_path = self.make_path("dir", "file") 3370 self.create_file(file_path) 3371 link_path = self.make_path("link") 3372 self.os.link(file_path.upper(), link_path) 3373 self.os.rename(file_path, link_path.upper()) 3374 self.assertTrue(self.os.path.exists(file_path)) 3375 self.assertTrue(self.os.path.exists(link_path)) 3376 3377 def test_rename_with_incorrect_source_case(self): 3378 # Regression test for #308 3379 base_path = self.make_path("foo") 3380 path0 = self.os.path.join(base_path, "bar") 3381 path1 = self.os.path.join(base_path, "Bar") 3382 self.create_dir(path0) 3383 self.os.rename(path1, path0) 3384 self.assertTrue(self.os.path.exists(path0)) 3385 3386 def test_rename_symlink_to_other_case_does_nothing_in_mac_os(self): 3387 # Regression test for #318 3388 self.check_macos_only() 3389 path0 = self.make_path("beta") 3390 self.os.symlink(self.base_path, path0) 3391 path0 = self.make_path("beta", "Beta") 3392 path1 = self.make_path("Beta") 3393 self.os.rename(path0, path1) 3394 self.assertEqual(["beta"], sorted(self.os.listdir(path0))) 3395 3396 def test_rename_symlink_to_other_case_works_in_windows(self): 3397 self.check_windows_only() 3398 self.skip_if_symlink_not_supported() 3399 path0 = self.make_path("beta") 3400 self.os.symlink(self.base_path, path0) 3401 path0 = self.make_path("beta", "Beta") 3402 path1 = self.make_path("Beta") 3403 self.os.rename(path0, path1) 3404 self.assertEqual(["Beta"], sorted(self.os.listdir(path0))) 3405 3406 def test_renames_creates_missing_dirs(self): 3407 old_path = self.make_path("foo.txt") 3408 self.create_file(old_path) 3409 new_path = self.make_path("new", "dir", "bar.txt") 3410 self.os.renames(old_path, new_path) 3411 self.assertTrue(self.os.path.exists(new_path)) 3412 self.assertFalse(self.os.path.exists(old_path)) 3413 3414 def test_renames_removes_empty_dirs(self): 3415 old_base_path = self.make_path("old") 3416 old_path = self.make_path("old", "dir1", "dir2", "foo.txt") 3417 other_file = self.os.path.join(old_base_path, "foo.png") 3418 self.create_file(old_path) 3419 self.create_file(other_file) 3420 new_path = self.make_path("new", "bar.txt") 3421 self.os.renames(old_path, new_path) 3422 self.assertTrue(self.os.path.exists(new_path)) 3423 self.assertFalse(self.os.path.exists(old_path)) 3424 self.assertTrue(self.os.path.exists(old_base_path)) 3425 removed_path = self.os.path.join(old_base_path, "dir1") 3426 self.assertFalse(self.os.path.exists(removed_path)) 3427 3428 def test_stat_with_mixed_case(self): 3429 # Regression test for #310 3430 self.skip_if_symlink_not_supported() 3431 base_path = self.make_path("foo") 3432 path = self.os.path.join(base_path, "bar") 3433 self.create_dir(path) 3434 path = self.os.path.join(path, "Bar") 3435 self.os.symlink(base_path, path) 3436 path = self.os.path.join(path, "Bar") 3437 # used to raise 3438 self.os.stat(path) 3439 3440 def test_hardlink_works_with_symlink(self): 3441 self.skip_if_symlink_not_supported() 3442 base_path = self.make_path("foo") 3443 self.create_dir(base_path) 3444 symlink_path = self.os.path.join(base_path, "slink") 3445 self.os.symlink(base_path.upper(), symlink_path) 3446 file_path = self.os.path.join(base_path, "slink", "beta") 3447 self.create_file(file_path) 3448 link_path = self.os.path.join(base_path, "Slink", "gamma") 3449 self.os.link(file_path, link_path) 3450 self.assertTrue(self.os.path.exists(link_path)) 3451 3452 def test_replace_existing_directory_should_raise_under_windows(self): 3453 """Renaming to an existing directory raises OSError under Windows.""" 3454 self.check_windows_only() 3455 old_path = self.make_path("foo", "bar") 3456 new_path = self.make_path("foo", "baz") 3457 self.create_dir(old_path) 3458 self.create_dir(new_path) 3459 self.assert_raises_os_error( 3460 errno.EACCES, self.os.replace, old_path, new_path.upper() 3461 ) 3462 3463 def test_rename_to_existing_directory_under_posix(self): 3464 """Renaming to an existing directory changes the existing directory 3465 under Posix.""" 3466 self.check_posix_only() 3467 old_path = self.make_path("foo", "bar") 3468 new_path = self.make_path("xyzzy") 3469 self.create_dir(self.os.path.join(old_path, "sub")) 3470 self.create_dir(new_path) 3471 self.os.rename(old_path.upper(), new_path.upper()) 3472 self.assertTrue(self.os.path.exists(self.os.path.join(new_path, "sub"))) 3473 self.assertFalse(self.os.path.exists(old_path)) 3474 3475 def test_rename_file_to_existing_directory_raises_under_posix(self): 3476 self.check_posix_only() 3477 file_path = self.make_path("foo", "bar", "baz") 3478 new_path = self.make_path("xyzzy") 3479 self.create_file(file_path) 3480 self.create_dir(new_path) 3481 self.assert_raises_os_error( 3482 errno.EISDIR, self.os.rename, file_path.upper(), new_path.upper() 3483 ) 3484 3485 def test_rename_to_existent_file_posix(self): 3486 """Can rename a file to a used name under Unix.""" 3487 self.check_posix_only() 3488 directory = self.make_path("xyzzy") 3489 old_file_path = self.os.path.join(directory, "plugh_old") 3490 new_file_path = self.os.path.join(directory, "plugh_new") 3491 self.create_file(old_file_path, contents="test contents 1") 3492 self.create_file(new_file_path, contents="test contents 2") 3493 self.assertTrue(self.os.path.exists(old_file_path)) 3494 self.assertTrue(self.os.path.exists(new_file_path)) 3495 self.os.rename(old_file_path.upper(), new_file_path.upper()) 3496 self.assertFalse(self.os.path.exists(old_file_path)) 3497 self.assertTrue(self.os.path.exists(new_file_path)) 3498 self.check_contents(new_file_path, "test contents 1") 3499 3500 def test_rename_to_existent_file_windows(self): 3501 """Renaming a file to a used name raises OSError under Windows.""" 3502 self.check_windows_only() 3503 directory = self.make_path("xyzzy") 3504 old_file_path = self.os.path.join(directory, "plugh_old") 3505 new_file_path = self.os.path.join(directory, "plugh_new") 3506 self.create_file(old_file_path, contents="test contents 1") 3507 self.create_file(new_file_path, contents="test contents 2") 3508 self.assertTrue(self.os.path.exists(old_file_path)) 3509 self.assertTrue(self.os.path.exists(new_file_path)) 3510 self.assert_raises_os_error( 3511 errno.EEXIST, 3512 self.os.rename, 3513 old_file_path.upper(), 3514 new_file_path.upper(), 3515 ) 3516 3517 def test_replace_to_existent_file(self): 3518 """Replaces an existing file (does not work with `rename()` under 3519 Windows).""" 3520 directory = self.make_path("xyzzy") 3521 old_file_path = self.os.path.join(directory, "plugh_old") 3522 new_file_path = self.os.path.join(directory, "plugh_new") 3523 self.create_file(old_file_path, contents="test contents 1") 3524 self.create_file(new_file_path, contents="test contents 2") 3525 self.assertTrue(self.os.path.exists(old_file_path)) 3526 self.assertTrue(self.os.path.exists(new_file_path)) 3527 self.os.replace(old_file_path.upper(), new_file_path.upper()) 3528 self.assertFalse(self.os.path.exists(old_file_path)) 3529 self.assertTrue(self.os.path.exists(new_file_path)) 3530 self.check_contents(new_file_path, "test contents 1") 3531 3532 def test_rename_to_nonexistent_dir(self): 3533 """Can rename a file to a name in a nonexistent dir.""" 3534 directory = self.make_path("xyzzy") 3535 old_file_path = self.os.path.join(directory, "plugh_old") 3536 new_file_path = self.os.path.join(directory, "no_such_path", "plugh_new") 3537 self.create_file(old_file_path, contents="test contents") 3538 self.assertTrue(self.os.path.exists(old_file_path)) 3539 self.assertFalse(self.os.path.exists(new_file_path)) 3540 self.assert_raises_os_error( 3541 errno.ENOENT, 3542 self.os.rename, 3543 old_file_path.upper(), 3544 new_file_path.upper(), 3545 ) 3546 self.assertTrue(self.os.path.exists(old_file_path)) 3547 self.assertFalse(self.os.path.exists(new_file_path)) 3548 self.check_contents(old_file_path, "test contents") 3549 3550 def check_rename_case_only_with_symlink_parent(self): 3551 # Regression test for #319 3552 self.os.symlink(self.base_path, self.make_path("link")) 3553 dir_upper = self.make_path("link", "Alpha") 3554 self.os.mkdir(dir_upper) 3555 dir_lower = self.make_path("alpha") 3556 self.os.rename(dir_upper, dir_lower) 3557 self.assertEqual(["alpha", "link"], sorted(self.os.listdir(self.base_path))) 3558 3559 def test_rename_case_only_with_symlink_parent_windows(self): 3560 self.check_windows_only() 3561 self.skip_if_symlink_not_supported() 3562 self.check_rename_case_only_with_symlink_parent() 3563 3564 def test_rename_case_only_with_symlink_parent_macos(self): 3565 self.check_macos_only() 3566 self.check_rename_case_only_with_symlink_parent() 3567 3568 def test_rename_dir(self): 3569 """Test a rename of a directory.""" 3570 directory = self.make_path("xyzzy") 3571 before_dir = self.os.path.join(directory, "before") 3572 before_file = self.os.path.join(directory, "before", "file") 3573 after_dir = self.os.path.join(directory, "after") 3574 after_file = self.os.path.join(directory, "after", "file") 3575 self.create_dir(before_dir) 3576 self.create_file(before_file, contents="payload") 3577 self.assertTrue(self.os.path.exists(before_dir.upper())) 3578 self.assertTrue(self.os.path.exists(before_file.upper())) 3579 self.assertFalse(self.os.path.exists(after_dir.upper())) 3580 self.assertFalse(self.os.path.exists(after_file.upper())) 3581 self.os.rename(before_dir.upper(), after_dir) 3582 self.assertFalse(self.os.path.exists(before_dir.upper())) 3583 self.assertFalse(self.os.path.exists(before_file.upper())) 3584 self.assertTrue(self.os.path.exists(after_dir.upper())) 3585 self.assertTrue(self.os.path.exists(after_file.upper())) 3586 self.check_contents(after_file, "payload") 3587 3588 def test_rename_same_filenames(self): 3589 """Test renaming when old and new names are the same.""" 3590 directory = self.make_path("xyzzy") 3591 file_contents = "Spam eggs" 3592 file_path = self.os.path.join(directory, "eggs") 3593 self.create_file(file_path, contents=file_contents) 3594 self.os.rename(file_path, file_path.upper()) 3595 self.check_contents(file_path, file_contents) 3596 3597 def test_rmdir(self): 3598 """Can remove a directory.""" 3599 directory = self.make_path("xyzzy") 3600 sub_dir = self.make_path("xyzzy", "abccd") 3601 other_dir = self.make_path("xyzzy", "cdeed") 3602 self.create_dir(directory) 3603 self.assertTrue(self.os.path.exists(directory)) 3604 self.os.rmdir(directory) 3605 self.assertFalse(self.os.path.exists(directory)) 3606 self.create_dir(sub_dir) 3607 self.create_dir(other_dir) 3608 self.os.chdir(sub_dir) 3609 self.os.rmdir("../CDEED") 3610 self.assertFalse(self.os.path.exists(other_dir)) 3611 self.os.chdir("..") 3612 self.os.rmdir("AbcCd") 3613 self.assertFalse(self.os.path.exists(sub_dir)) 3614 3615 def test_rmdir_via_symlink(self): 3616 self.check_windows_only() 3617 self.skip_if_symlink_not_supported() 3618 base_path = self.make_path("foo", "bar") 3619 dir_path = self.os.path.join(base_path, "alpha") 3620 self.create_dir(dir_path) 3621 link_path = self.os.path.join(base_path, "beta") 3622 self.os.symlink(base_path, link_path) 3623 self.os.rmdir(link_path + "/Alpha") 3624 self.assertFalse(self.os.path.exists(dir_path)) 3625 3626 def test_remove_dirs_with_non_top_symlink_succeeds(self): 3627 self.check_posix_only() 3628 dir_path = self.make_path("dir") 3629 dir_link = self.make_path("dir_link") 3630 self.create_dir(dir_path) 3631 self.os.symlink(dir_path, dir_link) 3632 dir_in_dir = self.os.path.join(dir_link, "dir2") 3633 self.create_dir(dir_in_dir) 3634 self.os.removedirs(dir_in_dir.upper()) 3635 self.assertFalse(self.os.path.exists(dir_in_dir)) 3636 # ensure that the symlink is not removed 3637 self.assertTrue(self.os.path.exists(dir_link)) 3638 3639 def test_mkdir_raises_on_symlink_in_posix(self): 3640 self.check_posix_only() 3641 base_path = self.make_path("foo", "bar") 3642 link_path = self.os.path.join(base_path, "link_to_dir") 3643 dir_path = self.os.path.join(base_path, "dir") 3644 self.create_dir(dir_path) 3645 self.os.symlink(dir_path.upper(), link_path.upper()) 3646 self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) 3647 3648 def test_mkdir_removes_symlink_in_windows(self): 3649 self.check_windows_only() 3650 self.skip_if_symlink_not_supported() 3651 base_path = self.make_path("foo", "bar") 3652 link_path = self.os.path.join(base_path, "link_to_dir") 3653 dir_path = self.os.path.join(base_path, "dir") 3654 self.create_dir(dir_path) 3655 self.os.symlink(dir_path.upper(), link_path.upper()) 3656 self.os.rmdir(link_path) 3657 self.assertFalse(self.os.path.exists(link_path)) 3658 self.assertTrue(self.os.path.exists(dir_path)) 3659 3660 def test_mkdir_raises_if_directory_exists(self): 3661 """mkdir raises exception if directory already exists.""" 3662 directory = self.make_path("xyzzy") 3663 self.create_dir(directory) 3664 self.assertTrue(self.os.path.exists(directory)) 3665 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory.upper()) 3666 3667 def test_mkdir_raises_if_file_exists(self): 3668 """mkdir raises exception if name already exists as a file.""" 3669 directory = self.make_path("xyzzy") 3670 file_path = self.os.path.join(directory, "plugh") 3671 self.create_file(file_path) 3672 self.assertTrue(self.os.path.exists(file_path)) 3673 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path.upper()) 3674 3675 def test_mkdir_raises_if_symlink_exists(self): 3676 # Regression test for #309 3677 self.skip_if_symlink_not_supported() 3678 path1 = self.make_path("baz") 3679 self.os.symlink(path1, path1) 3680 path2 = self.make_path("Baz") 3681 self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, path2) 3682 3683 def check_mkdir_raises_if_parent_is_file(self, error_type): 3684 """mkdir raises exception if name already exists as a file.""" 3685 directory = self.make_path("xyzzy") 3686 file_path = self.os.path.join(directory, "plugh") 3687 self.create_file(file_path) 3688 self.assert_raises_os_error( 3689 error_type, 3690 self.os.mkdir, 3691 self.os.path.join(file_path.upper(), "ff"), 3692 ) 3693 3694 def test_mkdir_raises_if_parent_is_file_posix(self): 3695 self.check_posix_only() 3696 self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) 3697 3698 def test_mkdir_raises_if_parent_is_file_windows(self): 3699 self.check_windows_only() 3700 self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) 3701 3702 def test_makedirs(self): 3703 """makedirs can create a directory even if parent does not exist.""" 3704 parent = self.make_path("xyzzy") 3705 directory = self.os.path.join(parent, "foo") 3706 self.assertFalse(self.os.path.exists(parent)) 3707 self.os.makedirs(directory.upper()) 3708 self.assertTrue(self.os.path.exists(directory)) 3709 3710 def check_makedirs_raises_if_parent_is_file(self, error_type): 3711 """makedirs raises exception if a parent component exists as a file.""" 3712 file_path = self.make_path("xyzzy") 3713 directory = self.os.path.join(file_path, "plugh") 3714 self.create_file(file_path) 3715 self.assertTrue(self.os.path.exists(file_path)) 3716 self.assert_raises_os_error(error_type, self.os.makedirs, directory.upper()) 3717 3718 def test_makedirs_raises_if_parent_is_file_posix(self): 3719 self.check_posix_only() 3720 self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) 3721 3722 def test_makedirs_raises_if_parent_is_file_windows(self): 3723 self.check_windows_only() 3724 self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) 3725 3726 def test_makedirs_raises_if_parent_is_broken_link(self): 3727 self.check_posix_only() 3728 link_path = self.make_path("broken_link") 3729 self.os.symlink(self.make_path("bogus"), link_path) 3730 self.assert_raises_os_error( 3731 errno.ENOENT, 3732 self.os.makedirs, 3733 self.os.path.join(link_path.upper(), "newdir"), 3734 ) 3735 3736 def test_makedirs_exist_ok(self): 3737 """makedirs uses the exist_ok argument""" 3738 directory = self.make_path("xyzzy", "foo") 3739 self.create_dir(directory) 3740 self.assertTrue(self.os.path.exists(directory)) 3741 3742 self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory.upper()) 3743 self.os.makedirs(directory.upper(), exist_ok=True) 3744 self.assertTrue(self.os.path.exists(directory)) 3745 3746 # test fsync and fdatasync 3747 def test_fsync_pass(self): 3748 test_file_path = self.make_path("test_file") 3749 self.create_file(test_file_path, contents="dummy file contents") 3750 test_file = self.open(test_file_path.upper(), "r+") 3751 test_fd = test_file.fileno() 3752 # Test that this doesn't raise anything 3753 self.os.fsync(test_fd) 3754 # And just for sanity, double-check that this still raises 3755 self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 10) 3756 test_file.close() 3757 3758 def test_chmod(self): 3759 # set up 3760 self.check_posix_only() 3761 self.skip_real_fs() 3762 path = self.make_path("some_file") 3763 self.createTestFile(path) 3764 # actual tests 3765 self.os.chmod(path.upper(), 0o6543) 3766 st = self.os.stat(path) 3767 self.assert_mode_equal(0o6543, st.st_mode) 3768 self.assertTrue(st.st_mode & stat.S_IFREG) 3769 self.assertFalse(st.st_mode & stat.S_IFDIR) 3770 3771 def test_symlink(self): 3772 self.skip_if_symlink_not_supported() 3773 file_path = self.make_path("foo", "bar", "baz") 3774 self.create_dir(self.make_path("foo", "bar")) 3775 self.os.symlink("bogus", file_path.upper()) 3776 self.assertTrue(self.os.path.lexists(file_path)) 3777 self.assertFalse(self.os.path.exists(file_path)) 3778 self.create_file(self.make_path("Foo", "Bar", "Bogus")) 3779 self.assertTrue(self.os.path.lexists(file_path)) 3780 self.assertTrue(self.os.path.exists(file_path)) 3781 3782 # hard link related tests 3783 def test_link_delete(self): 3784 self.skip_if_symlink_not_supported() 3785 3786 file1_path = self.make_path("test_file1") 3787 file2_path = self.make_path("test_file2") 3788 contents1 = "abcdef" 3789 # Create file 3790 self.create_file(file1_path, contents=contents1) 3791 # link to second file 3792 self.os.link(file1_path.upper(), file2_path) 3793 # delete first file 3794 self.os.unlink(file1_path) 3795 # assert that second file exists, and its contents are the same 3796 self.assertTrue(self.os.path.exists(file2_path)) 3797 with self.open(file2_path.upper()) as f: 3798 self.assertEqual(f.read(), contents1) 3799 3800 def test_link_is_existing_file(self): 3801 self.skip_if_symlink_not_supported() 3802 file_path = self.make_path("foo", "bar") 3803 self.create_file(file_path) 3804 self.assert_raises_os_error( 3805 errno.EEXIST, self.os.link, file_path.upper(), file_path.upper() 3806 ) 3807 3808 def test_link_is_broken_symlink(self): 3809 # Regression test for #311 3810 self.skip_if_symlink_not_supported() 3811 self.check_case_insensitive_fs() 3812 file_path = self.make_path("baz") 3813 self.create_file(file_path) 3814 path_lower = self.make_path("foo") 3815 self.os.symlink(path_lower, path_lower) 3816 path_upper = self.make_path("Foo") 3817 self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, path_upper) 3818 3819 def test_link_with_changed_case(self): 3820 # Regression test for #312 3821 self.skip_if_symlink_not_supported() 3822 self.check_case_insensitive_fs() 3823 link_path = self.make_path("link") 3824 self.os.symlink(self.base_path, link_path) 3825 link_path = self.os.path.join(link_path, "Link") 3826 self.assertTrue(self.os.lstat(link_path)) 3827 3828 3829class RealOsModuleTestCaseInsensitiveFS(FakeOsModuleTestCaseInsensitiveFS): 3830 def use_real_fs(self): 3831 return True 3832 3833 3834class FakeOsModuleTimeTest(FakeOsModuleTestBase): 3835 def test_chmod_st_ctime(self): 3836 with self.mock_time(start=200): 3837 file_path = "some_file" 3838 self.filesystem.create_file(file_path) 3839 self.assertTrue(self.os.path.exists(file_path)) 3840 3841 st = self.os.stat(file_path) 3842 self.assertEqual(200, st.st_ctime) 3843 # tests 3844 self.os.chmod(file_path, 0o765) 3845 st = self.os.stat(file_path) 3846 self.assertEqual(220, st.st_ctime) 3847 3848 def test_utime_sets_current_time_if_args_is_none(self): 3849 path = self.make_path("some_file") 3850 self.createTestFile(path) 3851 3852 with self.mock_time(start=200): 3853 self.os.utime(path, times=None) 3854 st = self.os.stat(path) 3855 self.assertEqual(200, st.st_atime) 3856 self.assertEqual(200, st.st_mtime) 3857 3858 def test_utime_sets_specified_time(self): 3859 # set up 3860 path = self.make_path("some_file") 3861 self.createTestFile(path) 3862 self.os.stat(path) 3863 # actual tests 3864 self.os.utime(path, times=(1, 2)) 3865 st = self.os.stat(path) 3866 self.assertEqual(1, st.st_atime) 3867 self.assertEqual(2, st.st_mtime) 3868 3869 def test_utime_dir(self): 3870 # set up 3871 path = "/some_dir" 3872 self.createTestDirectory(path) 3873 # actual tests 3874 self.os.utime(path, times=(1.0, 2.0)) 3875 st = self.os.stat(path) 3876 self.assertEqual(1.0, st.st_atime) 3877 self.assertEqual(2.0, st.st_mtime) 3878 3879 def test_utime_follow_symlinks(self): 3880 path = self.make_path("some_file") 3881 self.createTestFile(path) 3882 link_path = "/link_to_some_file" 3883 self.filesystem.create_symlink(link_path, path) 3884 3885 self.os.utime(link_path, times=(1, 2)) 3886 st = self.os.stat(link_path) 3887 self.assertEqual(1, st.st_atime) 3888 self.assertEqual(2, st.st_mtime) 3889 3890 def test_utime_no_follow_symlinks(self): 3891 path = self.make_path("some_file") 3892 self.createTestFile(path) 3893 link_path = "/link_to_some_file" 3894 self.filesystem.create_symlink(link_path, path) 3895 3896 self.os.utime(link_path, times=(1, 2), follow_symlinks=False) 3897 st = self.os.stat(link_path) 3898 self.assertNotEqual(1, st.st_atime) 3899 self.assertNotEqual(2, st.st_mtime) 3900 st = self.os.stat(link_path, follow_symlinks=False) 3901 self.assertEqual(1, st.st_atime) 3902 self.assertEqual(2, st.st_mtime) 3903 3904 def test_utime_non_existent(self): 3905 path = "/non/existent/file" 3906 self.assertFalse(self.os.path.exists(path)) 3907 self.assert_raises_os_error(errno.ENOENT, self.os.utime, path, (1, 2)) 3908 3909 def test_utime_invalid_times_arg_raises(self): 3910 path = "/some_dir" 3911 self.createTestDirectory(path) 3912 3913 # the error message differs with different Python versions 3914 # we don't expect the same message here 3915 self.assertRaises(TypeError, self.os.utime, path, (1, 2, 3)) 3916 self.assertRaises(TypeError, self.os.utime, path, (1, "str")) 3917 3918 def test_utime_sets_specified_time_in_ns(self): 3919 # set up 3920 path = self.make_path("some_file") 3921 self.createTestFile(path) 3922 3923 self.os.stat(path) 3924 # actual tests 3925 self.os.utime(path, ns=(200000000, 400000000)) 3926 st = self.os.stat(path) 3927 self.assertEqual(0.2, st.st_atime) 3928 self.assertEqual(0.4, st.st_mtime) 3929 3930 def test_utime_incorrect_ns_argument_raises(self): 3931 file_path = "some_file" 3932 self.filesystem.create_file(file_path) 3933 3934 self.assertRaises(TypeError, self.os.utime, file_path, ns=200000000) 3935 self.assertRaises(TypeError, self.os.utime, file_path, ns=("a", "b")) 3936 self.assertRaises( 3937 ValueError, self.os.utime, file_path, times=(1, 2), ns=(100, 200) 3938 ) 3939 3940 def test_utime_uses_open_fd_as_path(self): 3941 if os.utime not in os.supports_fd: 3942 self.skip_real_fs() 3943 self.assert_raises_os_error(errno.EBADF, self.os.utime, 5, (1, 2)) 3944 path = self.make_path("some_file") 3945 self.createTestFile(path) 3946 3947 with FakeFileOpen(self.filesystem)(path) as f: 3948 self.os.utime(f.filedes, times=(1, 2)) 3949 st = self.os.stat(path) 3950 self.assertEqual(1, st.st_atime) 3951 self.assertEqual(2, st.st_mtime) 3952 3953 3954class FakeOsModuleLowLevelFileOpTest(FakeOsModuleTestBase): 3955 """Test low level functions `os.open()`, `os.read()` and `os.write()`.""" 3956 3957 def setUp(self): 3958 os.umask(0o022) 3959 super(FakeOsModuleLowLevelFileOpTest, self).setUp() 3960 3961 def test_open_read_only(self): 3962 file_path = self.make_path("file1") 3963 self.create_file(file_path, contents=b"contents") 3964 3965 file_des = self.os.open(file_path, os.O_RDONLY) 3966 self.assertEqual(b"contents", self.os.read(file_des, 8)) 3967 self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"test") 3968 self.os.close(file_des) 3969 3970 def test_open_read_only_write_zero_bytes_posix(self): 3971 self.check_posix_only() 3972 file_path = self.make_path("file1") 3973 self.create_file(file_path, contents=b"contents") 3974 3975 file_des = self.os.open(file_path, os.O_RDONLY) 3976 self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"test") 3977 self.os.close(file_des) 3978 3979 def test_open_read_only_write_zero_bytes_windows(self): 3980 # under Windows, writing an empty string to a read only file 3981 # is not an error 3982 self.check_windows_only() 3983 file_path = self.make_path("file1") 3984 self.create_file(file_path, contents=b"contents") 3985 file_des = self.os.open(file_path, os.O_RDONLY) 3986 self.assertEqual(0, self.os.write(file_des, b"")) 3987 self.os.close(file_des) 3988 3989 def test_open_write_only(self): 3990 file_path = self.make_path("file1") 3991 self.create_file(file_path, contents=b"contents") 3992 3993 file_des = self.os.open(file_path, os.O_WRONLY) 3994 self.assertEqual(4, self.os.write(file_des, b"test")) 3995 self.check_contents(file_path, b"testents") 3996 self.os.close(file_des) 3997 3998 def test_open_write_only_raises_on_read(self): 3999 file_path = self.make_path("file1") 4000 self.create_file(file_path, contents=b"contents") 4001 4002 file_des = self.os.open(file_path, os.O_WRONLY) 4003 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4004 self.os.close(file_des) 4005 file_des = self.os.open(file_path, os.O_WRONLY | os.O_TRUNC) 4006 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4007 self.os.close(file_des) 4008 file_path2 = self.make_path("file2") 4009 file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY) 4010 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4011 self.os.close(file_des) 4012 file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4013 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4014 self.os.close(file_des) 4015 4016 def test_open_write_only_read_zero_bytes_posix(self): 4017 self.check_posix_only() 4018 file_path = self.make_path("file1") 4019 file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) 4020 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 0) 4021 self.os.close(file_des) 4022 4023 def test_open_write_only_read_zero_bytes_windows(self): 4024 # under Windows, reading 0 bytes from a write only file is not an error 4025 self.check_windows_only() 4026 file_path = self.make_path("file1") 4027 file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) 4028 self.assertEqual(b"", self.os.read(file_des, 0)) 4029 self.os.close(file_des) 4030 4031 def test_open_read_write(self): 4032 file_path = self.make_path("file1") 4033 self.create_file(file_path, contents=b"contents") 4034 4035 file_des = self.os.open(file_path, os.O_RDWR) 4036 self.assertEqual(4, self.os.write(file_des, b"test")) 4037 self.check_contents(file_path, b"testents") 4038 self.os.close(file_des) 4039 4040 def test_open_create_is_read_only(self): 4041 file_path = self.make_path("file1") 4042 file_des = self.os.open(file_path, os.O_CREAT) 4043 self.assertEqual(b"", self.os.read(file_des, 1)) 4044 self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"foo") 4045 self.os.close(file_des) 4046 4047 def test_open_create_truncate_is_read_only(self): 4048 file_path = self.make_path("file1") 4049 file_des = self.os.open(file_path, os.O_CREAT | os.O_TRUNC) 4050 self.assertEqual(b"", self.os.read(file_des, 1)) 4051 self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"foo") 4052 self.os.close(file_des) 4053 4054 def test_open_raises_if_does_not_exist(self): 4055 file_path = self.make_path("file1") 4056 self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDONLY) 4057 self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_WRONLY) 4058 self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDWR) 4059 4060 def test_exclusive_open_raises_without_create_mode(self): 4061 self.skip_real_fs() 4062 file_path = self.make_path("file1") 4063 self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL) 4064 self.assertRaises( 4065 NotImplementedError, 4066 self.os.open, 4067 file_path, 4068 os.O_EXCL | os.O_WRONLY, 4069 ) 4070 self.assertRaises( 4071 NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_RDWR 4072 ) 4073 self.assertRaises( 4074 NotImplementedError, 4075 self.os.open, 4076 file_path, 4077 os.O_EXCL | os.O_TRUNC | os.O_APPEND, 4078 ) 4079 4080 def test_open_raises_if_parent_does_not_exist(self): 4081 path = self.make_path("alpha", "alpha") 4082 self.assert_raises_os_error( 4083 errno.ENOENT, 4084 self.os.open, 4085 path, 4086 os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 4087 ) 4088 4089 def test_open_truncate(self): 4090 file_path = self.make_path("file1") 4091 self.create_file(file_path, contents=b"contents") 4092 4093 file_des = self.os.open(file_path, os.O_RDWR | os.O_TRUNC) 4094 self.assertEqual(b"", self.os.read(file_des, 8)) 4095 self.assertEqual(4, self.os.write(file_des, b"test")) 4096 self.check_contents(file_path, b"test") 4097 self.os.close(file_des) 4098 4099 @unittest.skipIf(not TestCase.is_windows, "O_TEMPORARY only present in Windows") 4100 def test_temp_file(self): 4101 file_path = self.make_path("file1") 4102 fd = self.os.open(file_path, os.O_CREAT | os.O_RDWR | os.O_TEMPORARY) 4103 self.assertTrue(self.os.path.exists(file_path)) 4104 self.os.close(fd) 4105 self.assertFalse(self.os.path.exists(file_path)) 4106 4107 def test_open_append(self): 4108 file_path = self.make_path("file1") 4109 self.create_file(file_path, contents=b"contents") 4110 4111 file_des = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) 4112 self.assertEqual(4, self.os.write(file_des, b"test")) 4113 self.check_contents(file_path, b"contentstest") 4114 self.os.close(file_des) 4115 4116 def test_open_create(self): 4117 file_path = self.make_path("file1") 4118 file_des = self.os.open(file_path, os.O_RDWR | os.O_CREAT) 4119 self.assertTrue(self.os.path.exists(file_path)) 4120 self.assertEqual(4, self.os.write(file_des, b"test")) 4121 self.check_contents(file_path, "test") 4122 self.os.close(file_des) 4123 4124 def test_can_read_after_create_exclusive(self): 4125 self.check_posix_only() 4126 path1 = self.make_path("alpha") 4127 file_des = self.os.open(path1, os.O_CREAT | os.O_EXCL) 4128 self.assertEqual(b"", self.os.read(file_des, 0)) 4129 self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"") 4130 self.os.close(file_des) 4131 4132 def test_open_create_mode_posix(self): 4133 self.check_posix_only() 4134 file_path = self.make_path("file1") 4135 file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) 4136 self.assertTrue(self.os.path.exists(file_path)) 4137 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4138 self.assertEqual(4, self.os.write(file_des, b"test")) 4139 self.assert_mode_equal(0o700, self.os.stat(file_path).st_mode) 4140 self.os.close(file_des) 4141 4142 def test_open_create_mode_windows(self): 4143 self.check_windows_only() 4144 file_path = self.make_path("file1") 4145 file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) 4146 self.assertTrue(self.os.path.exists(file_path)) 4147 self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) 4148 self.assertEqual(4, self.os.write(file_des, b"test")) 4149 self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) 4150 self.os.close(file_des) 4151 4152 def testOpenCreateMode444Windows(self): 4153 self.check_windows_only() 4154 file_path = self.make_path("file1") 4155 file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o442) 4156 self.assert_mode_equal(0o444, self.os.stat(file_path).st_mode) 4157 self.os.close(file_des) 4158 self.os.chmod(file_path, 0o666) 4159 4160 def testOpenCreateMode666Windows(self): 4161 self.check_windows_only() 4162 file_path = self.make_path("file1") 4163 file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o224) 4164 self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) 4165 self.os.close(file_des) 4166 4167 def test_open_exclusive(self): 4168 file_path = self.make_path("file1") 4169 file_des = self.os.open(file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT) 4170 self.assertTrue(self.os.path.exists(file_path)) 4171 self.os.close(file_des) 4172 4173 def test_open_exclusive_raises_if_file_exists(self): 4174 file_path = self.make_path("file1") 4175 self.create_file(file_path, contents=b"contents") 4176 self.assert_raises_os_error( 4177 errno.EEXIST, 4178 self.os.open, 4179 file_path, 4180 os.O_RDWR | os.O_EXCL | os.O_CREAT, 4181 ) 4182 self.assert_raises_os_error( 4183 errno.EEXIST, 4184 self.os.open, 4185 file_path, 4186 os.O_RDWR | os.O_EXCL | os.O_CREAT, 4187 ) 4188 4189 def test_open_exclusive_raises_if_symlink_exists_in_posix(self): 4190 self.check_posix_only() 4191 link_path = self.make_path("link") 4192 link_target = self.make_path("link_target") 4193 self.os.symlink(link_target, link_path) 4194 self.assert_raises_os_error( 4195 errno.EEXIST, 4196 self.os.open, 4197 link_path, 4198 os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL, 4199 ) 4200 4201 def test_open_exclusive_if_symlink_exists_works_in_windows(self): 4202 self.check_windows_only() 4203 self.skip_if_symlink_not_supported() 4204 link_path = self.make_path("link") 4205 link_target = self.make_path("link_target") 4206 self.os.symlink(link_target, link_path) 4207 fd = self.os.open(link_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL) 4208 self.os.close(fd) 4209 4210 def test_open_directory_raises_under_windows(self): 4211 self.check_windows_only() 4212 dir_path = self.make_path("dir") 4213 self.create_dir(dir_path) 4214 self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDONLY) 4215 self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_WRONLY) 4216 self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDWR) 4217 4218 def test_open_directory_for_writing_raises_under_posix(self): 4219 self.check_posix_only() 4220 dir_path = self.make_path("dir") 4221 self.create_dir(dir_path) 4222 self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) 4223 self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_RDWR) 4224 4225 def test_open_directory_read_only_under_posix(self): 4226 self.check_posix_only() 4227 self.skip_real_fs() 4228 dir_path = self.make_path("dir") 4229 self.create_dir(dir_path) 4230 file_des = self.os.open(dir_path, os.O_RDONLY) 4231 self.assertEqual(3, file_des) 4232 self.os.close(file_des) 4233 4234 def test_opening_existing_directory_in_creation_mode(self): 4235 self.check_linux_only() 4236 dir_path = self.make_path("alpha") 4237 self.os.mkdir(dir_path) 4238 self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_CREAT) 4239 4240 def test_writing_to_existing_directory(self): 4241 self.check_macos_only() 4242 dir_path = self.make_path("alpha") 4243 self.os.mkdir(dir_path) 4244 fd = self.os.open(dir_path, os.O_CREAT) 4245 self.assert_raises_os_error(errno.EBADF, self.os.write, fd, b"") 4246 4247 def test_opening_existing_directory_in_write_mode(self): 4248 self.check_posix_only() 4249 dir_path = self.make_path("alpha") 4250 self.os.mkdir(dir_path) 4251 self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) 4252 4253 def test_open_mode_posix(self): 4254 self.check_posix_only() 4255 self.skip_real_fs() 4256 file_path = self.make_path("baz") 4257 file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4258 stat0 = self.os.fstat(file_des) 4259 # not a really good test as this replicates the code, 4260 # but we don't know the umask at the test system 4261 self.assertEqual(0o100777 & ~self.os._umask(), stat0.st_mode) 4262 self.os.close(file_des) 4263 4264 def test_open_mode_windows(self): 4265 self.check_windows_only() 4266 file_path = self.make_path("baz") 4267 file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4268 stat0 = self.os.fstat(file_des) 4269 self.assertEqual(0o100666, stat0.st_mode) 4270 self.os.close(file_des) 4271 4272 def test_write_read(self): 4273 file_path = self.make_path("file1") 4274 self.create_file(file_path, contents=b"orig contents") 4275 new_contents = b"1234567890abcdef" 4276 4277 with self.open(file_path, "wb") as fh: 4278 fileno = fh.fileno() 4279 self.assertEqual(len(new_contents), self.os.write(fileno, new_contents)) 4280 self.check_contents(file_path, new_contents) 4281 4282 with self.open(file_path, "rb") as fh: 4283 fileno = fh.fileno() 4284 self.assertEqual(b"", self.os.read(fileno, 0)) 4285 self.assertEqual(new_contents[0:2], self.os.read(fileno, 2)) 4286 self.assertEqual(new_contents[2:10], self.os.read(fileno, 8)) 4287 self.assertEqual(new_contents[10:], self.os.read(fileno, 100)) 4288 self.assertEqual(b"", self.os.read(fileno, 10)) 4289 4290 self.assert_raises_os_error(errno.EBADF, self.os.write, fileno, new_contents) 4291 self.assert_raises_os_error(errno.EBADF, self.os.read, fileno, 10) 4292 4293 def test_write_from_different_f_ds(self): 4294 # Regression test for #211 4295 file_path = self.make_path("baz") 4296 fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4297 fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4298 self.os.write(fd0, b"aaaa") 4299 self.os.write(fd1, b"bb") 4300 self.assertEqual(4, self.os.path.getsize(file_path)) 4301 self.check_contents(file_path, b"bbaa") 4302 self.os.close(fd1) 4303 self.os.close(fd0) 4304 4305 def test_write_from_different_fds_with_append(self): 4306 # Regression test for #268 4307 file_path = self.make_path("baz") 4308 fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4309 fd1 = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) 4310 self.os.write(fd0, b"aaa") 4311 self.os.write(fd1, b"bbb") 4312 self.assertEqual(6, self.os.path.getsize(file_path)) 4313 self.check_contents(file_path, b"aaabbb") 4314 self.os.close(fd1) 4315 self.os.close(fd0) 4316 4317 def test_read_only_read_after_write(self): 4318 # Regression test for #269 4319 self.check_posix_only() 4320 file_path = self.make_path("foo", "bar", "baz") 4321 self.create_file(file_path, contents=b"test") 4322 fd0 = self.os.open(file_path, os.O_CREAT) 4323 fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4324 self.assertEqual(b"", self.os.read(fd0, 0)) 4325 self.os.close(fd1) 4326 self.os.close(fd0) 4327 4328 def test_read_after_closing_write_descriptor(self): 4329 # Regression test for #271 4330 file_path = self.make_path("baz") 4331 fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4332 fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4333 fd2 = self.os.open(file_path, os.O_CREAT) 4334 self.os.write(fd1, b"abc") 4335 self.os.close(fd0) 4336 self.assertEqual(b"abc", self.os.read(fd2, 3)) 4337 self.os.close(fd2) 4338 self.os.close(fd1) 4339 4340 def test_writing_behind_end_of_file(self): 4341 # Regression test for #273 4342 file_path = self.make_path("baz") 4343 fd1 = self.os.open(file_path, os.O_CREAT) 4344 fd2 = self.os.open(file_path, os.O_RDWR) 4345 self.os.write(fd2, b"m") 4346 fd3 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) 4347 self.assertEqual(b"", self.os.read(fd2, 1)) 4348 self.os.write(fd2, b"m") 4349 self.assertEqual(b"\x00m", self.os.read(fd1, 2)) 4350 self.os.close(fd1) 4351 self.os.close(fd2) 4352 self.os.close(fd3) 4353 4354 def test_devnull_posix(self): 4355 self.check_posix_only() 4356 # make sure os.devnull is correctly set after changing the filesystem 4357 self.setup_fake_fs() 4358 self.assertTrue(self.os.path.exists(self.os.devnull)) 4359 4360 def test_devnull_windows(self): 4361 self.check_windows_only() 4362 # make sure os.devnull is correctly set after changing the filesystem 4363 self.setup_fake_fs() 4364 if sys.version_info < (3, 8): 4365 self.assertFalse(self.os.path.exists(self.os.devnull)) 4366 else: 4367 self.assertTrue(self.os.path.exists(self.os.devnull)) 4368 4369 def test_write_devnull(self): 4370 fd = self.os.open(self.os.devnull, os.O_RDWR) 4371 self.assertEqual(4, self.os.write(fd, b"test")) 4372 self.assertEqual(b"", self.os.read(fd, 4)) 4373 self.os.close(fd) 4374 fd = self.os.open(self.os.devnull, os.O_RDONLY) 4375 self.assertEqual(b"", self.os.read(fd, 4)) 4376 self.os.close(fd) 4377 4378 def test_sendfile_with_invalid_fd(self): 4379 self.check_linux_only() 4380 self.assert_raises_os_error(errno.EBADF, self.os.sendfile, 100, 101, 0, 100) 4381 src_file_path = self.make_path("foo") 4382 dst_file_path = self.make_path("bar") 4383 self.create_file(src_file_path, "testcontent") 4384 self.create_file(dst_file_path) 4385 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4386 fd2 = self.os.open(dst_file_path, os.O_RDONLY) 4387 self.assert_raises_os_error(errno.EBADF, self.os.sendfile, fd2, fd1, 0, 4) 4388 4389 def test_sendfile_no_offset(self): 4390 self.check_linux_only() 4391 src_file_path = self.make_path("foo") 4392 dst_file_path = self.make_path("bar") 4393 self.create_file(src_file_path, "testcontent") 4394 self.create_file(dst_file_path) 4395 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4396 fd2 = self.os.open(dst_file_path, os.O_RDWR) 4397 self.os.sendfile(fd2, fd1, 0, 3) 4398 self.os.close(fd2) 4399 self.os.close(fd1) 4400 with self.open(dst_file_path) as f: 4401 self.assertEqual("tes", f.read()) 4402 4403 def test_sendfile_with_offset(self): 4404 self.check_linux_only() 4405 src_file_path = self.make_path("foo") 4406 dst_file_path = self.make_path("bar") 4407 self.create_file(src_file_path, "testcontent") 4408 self.create_file(dst_file_path) 4409 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4410 fd2 = self.os.open(dst_file_path, os.O_RDWR) 4411 self.os.sendfile(fd2, fd1, 4, 4) 4412 self.os.close(fd2) 4413 self.os.close(fd1) 4414 with self.open(dst_file_path) as f: 4415 self.assertEqual("cont", f.read()) 4416 4417 def test_sendfile_twice(self): 4418 self.check_linux_only() 4419 src_file_path = self.make_path("foo") 4420 dst_file_path = self.make_path("bar") 4421 self.create_file(src_file_path, "testcontent") 4422 self.create_file(dst_file_path) 4423 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4424 fd2 = self.os.open(dst_file_path, os.O_RDWR) 4425 self.os.sendfile(fd2, fd1, 4, 4) 4426 self.os.sendfile(fd2, fd1, 4, 4) 4427 self.os.close(fd2) 4428 self.os.close(fd1) 4429 with self.open(dst_file_path) as f: 4430 self.assertEqual("contcont", f.read()) 4431 4432 def test_sendfile_offset_none(self): 4433 self.check_linux_only() 4434 src_file_path = self.make_path("foo") 4435 dst_file_path = self.make_path("bar") 4436 self.create_file(src_file_path, "testcontent") 4437 self.create_file(dst_file_path) 4438 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4439 fd2 = self.os.open(dst_file_path, os.O_RDWR) 4440 self.os.sendfile(fd2, fd1, None, 4) 4441 self.os.sendfile(fd2, fd1, None, 3) 4442 self.os.close(fd2) 4443 self.os.close(fd1) 4444 with self.open(dst_file_path) as f: 4445 self.assertEqual("testcon", f.read()) 4446 4447 @unittest.skipIf(not TestCase.is_macos, "Testing MacOs only behavior") 4448 def test_no_sendfile_to_regular_file_under_macos(self): 4449 src_file_path = self.make_path("foo") 4450 dst_file_path = self.make_path("bar") 4451 self.create_file(src_file_path, "testcontent") 4452 self.create_file(dst_file_path) 4453 fd1 = self.os.open(src_file_path, os.O_RDONLY) 4454 fd2 = self.os.open(dst_file_path, os.O_RDWR) 4455 # raises socket operation on non-socket 4456 self.assertRaises(OSError, self.os.sendfile, fd2, fd1, 0, 3) 4457 self.os.close(fd2) 4458 self.os.close(fd1) 4459 4460 4461class RealOsModuleLowLevelFileOpTest(FakeOsModuleLowLevelFileOpTest): 4462 def use_real_fs(self): 4463 return True 4464 4465 4466class FakeOsModuleWalkTest(FakeOsModuleTestBase): 4467 def assertWalkResults(self, expected, top, topdown=True, followlinks=False): 4468 # as the result of walk is unsorted, we have to check against 4469 # sorted results 4470 result = list( 4471 step for step in self.os.walk(top, topdown=topdown, followlinks=followlinks) 4472 ) 4473 result = sorted(result, key=lambda lst: lst[0]) 4474 expected = sorted(expected, key=lambda lst: lst[0]) 4475 self.assertEqual(len(expected), len(result)) 4476 for entry, expected_entry in zip(result, expected): 4477 self.assertEqual(expected_entry[0], entry[0]) 4478 self.assertEqual(expected_entry[1], sorted(entry[1])) 4479 self.assertEqual(expected_entry[2], sorted(entry[2])) 4480 4481 def ResetErrno(self): 4482 """Reset the last seen errno.""" 4483 self.last_errno = False 4484 4485 def StoreErrno(self, os_error): 4486 """Store the last errno we saw.""" 4487 self.last_errno = os_error.errno 4488 4489 def GetErrno(self): 4490 """Return the last errno we saw.""" 4491 return self.last_errno 4492 4493 def test_walk_top_down(self): 4494 """Walk down ordering is correct.""" 4495 base_dir = self.make_path("foo") 4496 self.create_file(self.os.path.join(base_dir, "1.txt")) 4497 self.create_file(self.os.path.join(base_dir, "bar1", "2.txt")) 4498 self.create_file(self.os.path.join(base_dir, "bar1", "baz", "3.txt")) 4499 self.create_file(self.os.path.join(base_dir, "bar2", "4.txt")) 4500 expected = [ 4501 (base_dir, ["bar1", "bar2"], ["1.txt"]), 4502 (self.os.path.join(base_dir, "bar1"), ["baz"], ["2.txt"]), 4503 (self.os.path.join(base_dir, "bar1", "baz"), [], ["3.txt"]), 4504 (self.os.path.join(base_dir, "bar2"), [], ["4.txt"]), 4505 ] 4506 self.assertWalkResults(expected, base_dir) 4507 4508 def test_walk_bottom_up(self): 4509 """Walk up ordering is correct.""" 4510 base_dir = self.make_path("foo") 4511 self.create_file(self.os.path.join(base_dir, "bar1", "baz", "1.txt")) 4512 self.create_file(self.os.path.join(base_dir, "bar1", "2.txt")) 4513 self.create_file(self.os.path.join(base_dir, "bar2", "3.txt")) 4514 self.create_file(self.os.path.join(base_dir, "4.txt")) 4515 4516 expected = [ 4517 (self.os.path.join(base_dir, "bar1", "baz"), [], ["1.txt"]), 4518 (self.os.path.join(base_dir, "bar1"), ["baz"], ["2.txt"]), 4519 (self.os.path.join(base_dir, "bar2"), [], ["3.txt"]), 4520 (base_dir, ["bar1", "bar2"], ["4.txt"]), 4521 ] 4522 self.assertWalkResults(expected, self.make_path("foo"), topdown=False) 4523 4524 def test_walk_raises_if_non_existent(self): 4525 """Raises an exception when attempting to walk 4526 non-existent directory.""" 4527 directory = self.make_path("foo", "bar") 4528 self.assertEqual(False, self.os.path.exists(directory)) 4529 generator = self.os.walk(directory) 4530 self.assertRaises(StopIteration, next, generator) 4531 4532 def test_walk_raises_if_not_directory(self): 4533 """Raises an exception when attempting to walk a non-directory.""" 4534 filename = self.make_path("foo", "bar") 4535 self.create_file(filename) 4536 generator = self.os.walk(filename) 4537 self.assertRaises(StopIteration, next, generator) 4538 4539 def test_walk_calls_on_error_if_non_existent(self): 4540 """Calls onerror with correct errno when walking 4541 non-existent directory.""" 4542 self.ResetErrno() 4543 directory = self.make_path("foo", "bar") 4544 self.assertEqual(False, self.os.path.exists(directory)) 4545 # Calling os.walk on a non-existent directory should trigger 4546 # a call to the onerror method. 4547 # We do not actually care what, if anything, is returned. 4548 for _ in self.os.walk(directory, onerror=self.StoreErrno): 4549 pass 4550 self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.ENOENT)) 4551 4552 def test_walk_calls_on_error_if_not_directory(self): 4553 """Calls onerror with correct errno when walking non-directory.""" 4554 self.ResetErrno() 4555 filename = self.make_path("foo" "bar") 4556 self.create_file(filename) 4557 self.assertEqual(True, self.os.path.exists(filename)) 4558 # Calling `os.walk` on a file should trigger a call to the 4559 # `onerror` method. 4560 # We do not actually care what, if anything, is returned. 4561 for _ in self.os.walk(filename, onerror=self.StoreErrno): 4562 pass 4563 self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.EACCES)) 4564 4565 def test_walk_skips_removed_directories(self): 4566 """Caller can modify list of directories to visit while walking.""" 4567 root = self.make_path("foo") 4568 visit = "visit" 4569 no_visit = "no_visit" 4570 self.create_file(self.os.path.join(root, "bar")) 4571 self.create_file(self.os.path.join(root, visit, "1.txt")) 4572 self.create_file(self.os.path.join(root, visit, "2.txt")) 4573 self.create_file(self.os.path.join(root, no_visit, "3.txt")) 4574 self.create_file(self.os.path.join(root, no_visit, "4.txt")) 4575 4576 generator = self.os.walk(self.make_path("foo")) 4577 root_contents = next(generator) 4578 root_contents[1].remove(no_visit) 4579 4580 visited_visit_directory = False 4581 4582 for root, _dirs, _files in iter(generator): 4583 self.assertEqual(False, root.endswith(self.os.path.sep + no_visit)) 4584 if root.endswith(self.os.path.sep + visit): 4585 visited_visit_directory = True 4586 4587 self.assertEqual(True, visited_visit_directory) 4588 4589 def test_walk_followsymlink_disabled(self): 4590 self.check_posix_only() 4591 base_dir = self.make_path("foo") 4592 link_dir = self.make_path("linked") 4593 self.create_file(self.os.path.join(link_dir, "subfile")) 4594 self.create_file(self.os.path.join(base_dir, "bar", "baz")) 4595 self.create_file(self.os.path.join(base_dir, "bar", "xyzzy", "plugh")) 4596 self.create_symlink(self.os.path.join(base_dir, "created_link"), link_dir) 4597 4598 expected = [ 4599 (base_dir, ["bar", "created_link"], []), 4600 (self.os.path.join(base_dir, "bar"), ["xyzzy"], ["baz"]), 4601 (self.os.path.join(base_dir, "bar", "xyzzy"), [], ["plugh"]), 4602 ] 4603 self.assertWalkResults(expected, base_dir, followlinks=False) 4604 4605 expected = [(self.os.path.join(base_dir, "created_link"), [], ["subfile"])] 4606 self.assertWalkResults( 4607 expected, 4608 self.os.path.join(base_dir, "created_link"), 4609 followlinks=False, 4610 ) 4611 4612 def test_walk_followsymlink_enabled(self): 4613 self.check_posix_only() 4614 base_dir = self.make_path("foo") 4615 link_dir = self.make_path("linked") 4616 self.create_file(self.os.path.join(link_dir, "subfile")) 4617 self.create_file(self.os.path.join(base_dir, "bar", "baz")) 4618 self.create_file(self.os.path.join(base_dir, "bar", "xyzzy", "plugh")) 4619 self.create_symlink( 4620 self.os.path.join(base_dir, "created_link"), 4621 self.os.path.join(link_dir), 4622 ) 4623 4624 expected = [ 4625 (base_dir, ["bar", "created_link"], []), 4626 (self.os.path.join(base_dir, "bar"), ["xyzzy"], ["baz"]), 4627 (self.os.path.join(base_dir, "bar", "xyzzy"), [], ["plugh"]), 4628 (self.os.path.join(base_dir, "created_link"), [], ["subfile"]), 4629 ] 4630 self.assertWalkResults(expected, base_dir, followlinks=True) 4631 4632 expected = [(self.os.path.join(base_dir, "created_link"), [], ["subfile"])] 4633 self.assertWalkResults( 4634 expected, 4635 self.os.path.join(base_dir, "created_link"), 4636 followlinks=True, 4637 ) 4638 4639 def test_walk_linked_file_in_subdir(self): 4640 # regression test for #559 (tested for link on incomplete path) 4641 self.check_posix_only() 4642 # need to have a top-level link to reproduce the bug - skip real fs 4643 self.skip_real_fs() 4644 file_path = "/foo/bar/baz" 4645 self.create_file(file_path) 4646 self.create_symlink("bar", file_path) 4647 expected = [("/foo", ["bar"], []), ("/foo/bar", [], ["baz"])] 4648 self.assertWalkResults(expected, "/foo") 4649 4650 def test_base_dirpath(self): 4651 # regression test for #512 4652 file_path = self.make_path("foo", "bar", "baz") 4653 self.create_file(file_path) 4654 variants = [ 4655 self.make_path("foo", "bar"), 4656 self.make_path("foo", "..", "foo", "bar"), 4657 self.make_path("foo", "..", "foo", "bar") + self.os.path.sep * 3, 4658 self.make_path("foo") + self.os.path.sep * 3 + "bar", 4659 ] 4660 for base_dir in variants: 4661 for dirpath, _dirnames, _filenames in self.os.walk(base_dir): 4662 self.assertEqual(dirpath, base_dir) 4663 4664 file_path = self.make_path("foo", "bar", "dir", "baz") 4665 self.create_file(file_path) 4666 for base_dir in variants: 4667 for dirpath, _dirnames, _filenames in self.os.walk(base_dir): 4668 self.assertTrue(dirpath.startswith(base_dir)) 4669 4670 4671class RealOsModuleWalkTest(FakeOsModuleWalkTest): 4672 def use_real_fs(self): 4673 return True 4674 4675 4676class FakeOsModuleDirFdTest(FakeOsModuleTestBase): 4677 def setUp(self): 4678 super(FakeOsModuleDirFdTest, self).setUp() 4679 self.os.supports_dir_fd.clear() 4680 self.filesystem.is_windows_fs = False 4681 self.filesystem.create_dir("/foo/bar") 4682 self.dir_fd = self.os.open("/foo", os.O_RDONLY) 4683 self.filesystem.create_file("/foo/baz") 4684 4685 def test_access(self): 4686 self.assertRaises( 4687 NotImplementedError, 4688 self.os.access, 4689 "baz", 4690 self.os.F_OK, 4691 dir_fd=self.dir_fd, 4692 ) 4693 self.os.supports_dir_fd.add(self.os.access) 4694 self.assertTrue(self.os.access("baz", self.os.F_OK, dir_fd=self.dir_fd)) 4695 4696 def test_chmod(self): 4697 self.assertRaises( 4698 NotImplementedError, 4699 self.os.chmod, 4700 "baz", 4701 0o6543, 4702 dir_fd=self.dir_fd, 4703 ) 4704 self.os.supports_dir_fd.add(self.os.chmod) 4705 self.os.chmod("baz", 0o6543, dir_fd=self.dir_fd) 4706 st = self.os.stat("/foo/baz") 4707 self.assert_mode_equal(0o6543, st.st_mode) 4708 4709 @unittest.skipIf(not hasattr(os, "chown"), "chown not on all platforms available") 4710 def test_chown(self): 4711 self.assertRaises( 4712 NotImplementedError, 4713 self.os.chown, 4714 "baz", 4715 100, 4716 101, 4717 dir_fd=self.dir_fd, 4718 ) 4719 self.os.supports_dir_fd.add(self.os.chown) 4720 self.os.chown("baz", 100, 101, dir_fd=self.dir_fd) 4721 st = self.os.stat("/foo/baz") 4722 self.assertEqual(st[stat.ST_UID], 100) 4723 self.assertEqual(st[stat.ST_GID], 101) 4724 4725 def test_link_src_fd(self): 4726 self.assertRaises( 4727 NotImplementedError, 4728 self.os.link, 4729 "baz", 4730 "/bat", 4731 src_dir_fd=self.dir_fd, 4732 ) 4733 self.os.supports_dir_fd.add(self.os.link) 4734 self.os.link("baz", "/bat", src_dir_fd=self.dir_fd) 4735 self.assertTrue(self.os.path.exists("/bat")) 4736 4737 def test_link_dst_fd(self): 4738 self.assertRaises( 4739 NotImplementedError, 4740 self.os.link, 4741 "baz", 4742 "/bat", 4743 dst_dir_fd=self.dir_fd, 4744 ) 4745 self.os.supports_dir_fd.add(self.os.link) 4746 self.os.link("/foo/baz", "bat", dst_dir_fd=self.dir_fd) 4747 self.assertTrue(self.os.path.exists("/foo/bat")) 4748 4749 def test_symlink(self): 4750 self.assertRaises( 4751 NotImplementedError, 4752 self.os.symlink, 4753 "baz", 4754 "/bat", 4755 dir_fd=self.dir_fd, 4756 ) 4757 self.os.supports_dir_fd.add(self.os.symlink) 4758 self.os.symlink("baz", "/bat", dir_fd=self.dir_fd) 4759 self.assertTrue(self.os.path.exists("/bat")) 4760 4761 def test_readlink(self): 4762 self.skip_if_symlink_not_supported() 4763 self.filesystem.create_symlink("/meyer/lemon/pie", "/foo/baz") 4764 self.filesystem.create_symlink("/geo/metro", "/meyer") 4765 self.assertRaises( 4766 NotImplementedError, 4767 self.os.readlink, 4768 "/geo/metro/lemon/pie", 4769 dir_fd=self.dir_fd, 4770 ) 4771 self.os.supports_dir_fd.add(self.os.readlink) 4772 self.assertEqual( 4773 "/foo/baz", 4774 self.os.readlink("/geo/metro/lemon/pie", dir_fd=self.dir_fd), 4775 ) 4776 4777 def test_stat(self): 4778 self.assertRaises(NotImplementedError, self.os.stat, "baz", dir_fd=self.dir_fd) 4779 self.os.supports_dir_fd.add(self.os.stat) 4780 st = self.os.stat("baz", dir_fd=self.dir_fd) 4781 self.assertEqual(st.st_mode, 0o100666) 4782 4783 def test_lstat(self): 4784 self.assertRaises(NotImplementedError, self.os.lstat, "baz", dir_fd=self.dir_fd) 4785 self.os.supports_dir_fd.add(self.os.lstat) 4786 st = self.os.lstat("baz", dir_fd=self.dir_fd) 4787 self.assertEqual(st.st_mode, 0o100666) 4788 4789 def test_mkdir(self): 4790 self.assertRaises( 4791 NotImplementedError, self.os.mkdir, "newdir", dir_fd=self.dir_fd 4792 ) 4793 self.os.supports_dir_fd.add(self.os.mkdir) 4794 self.os.mkdir("newdir", dir_fd=self.dir_fd) 4795 self.assertTrue(self.os.path.exists("/foo/newdir")) 4796 4797 def test_rmdir(self): 4798 self.assertRaises(NotImplementedError, self.os.rmdir, "bar", dir_fd=self.dir_fd) 4799 self.os.supports_dir_fd.add(self.os.rmdir) 4800 self.os.rmdir("bar", dir_fd=self.dir_fd) 4801 self.assertFalse(self.os.path.exists("/foo/bar")) 4802 4803 @unittest.skipIf(not hasattr(os, "mknod"), "mknod not on all platforms available") 4804 def test_mknod(self): 4805 self.assertRaises( 4806 NotImplementedError, self.os.mknod, "newdir", dir_fd=self.dir_fd 4807 ) 4808 self.os.supports_dir_fd.add(self.os.mknod) 4809 self.os.mknod("newdir", dir_fd=self.dir_fd) 4810 self.assertTrue(self.os.path.exists("/foo/newdir")) 4811 4812 def test_rename_src_fd(self): 4813 self.assertRaises( 4814 NotImplementedError, 4815 self.os.rename, 4816 "baz", 4817 "/foo/batz", 4818 src_dir_fd=self.dir_fd, 4819 ) 4820 self.os.supports_dir_fd.add(self.os.rename) 4821 self.os.rename("bar", "/foo/batz", src_dir_fd=self.dir_fd) 4822 self.assertTrue(self.os.path.exists("/foo/batz")) 4823 4824 def test_rename_dst_fd(self): 4825 self.assertRaises( 4826 NotImplementedError, 4827 self.os.rename, 4828 "baz", 4829 "/foo/batz", 4830 dst_dir_fd=self.dir_fd, 4831 ) 4832 self.os.supports_dir_fd.add(self.os.rename) 4833 self.os.rename("/foo/bar", "batz", dst_dir_fd=self.dir_fd) 4834 self.assertTrue(self.os.path.exists("/foo/batz")) 4835 4836 def test_replace_src_fd(self): 4837 self.assertRaises( 4838 NotImplementedError, 4839 self.os.rename, 4840 "baz", 4841 "/foo/batz", 4842 src_dir_fd=self.dir_fd, 4843 ) 4844 self.os.supports_dir_fd.add(self.os.rename) 4845 self.os.replace("bar", "/foo/batz", src_dir_fd=self.dir_fd) 4846 self.assertTrue(self.os.path.exists("/foo/batz")) 4847 4848 def test_replace_dst_fd(self): 4849 self.assertRaises( 4850 NotImplementedError, 4851 self.os.rename, 4852 "baz", 4853 "/foo/batz", 4854 dst_dir_fd=self.dir_fd, 4855 ) 4856 self.os.supports_dir_fd.add(self.os.rename) 4857 self.os.replace("/foo/bar", "batz", dst_dir_fd=self.dir_fd) 4858 self.assertTrue(self.os.path.exists("/foo/batz")) 4859 4860 def test_remove(self): 4861 self.assertRaises( 4862 NotImplementedError, self.os.remove, "baz", dir_fd=self.dir_fd 4863 ) 4864 self.os.supports_dir_fd.add(self.os.remove) 4865 self.os.remove("baz", dir_fd=self.dir_fd) 4866 self.assertFalse(self.os.path.exists("/foo/baz")) 4867 4868 def test_unlink(self): 4869 self.assertRaises( 4870 NotImplementedError, self.os.unlink, "baz", dir_fd=self.dir_fd 4871 ) 4872 self.os.supports_dir_fd.add(self.os.unlink) 4873 self.os.unlink("baz", dir_fd=self.dir_fd) 4874 self.assertFalse(self.os.path.exists("/foo/baz")) 4875 4876 def test_utime(self): 4877 self.assertRaises( 4878 NotImplementedError, 4879 self.os.utime, 4880 "baz", 4881 (1, 2), 4882 dir_fd=self.dir_fd, 4883 ) 4884 self.os.supports_dir_fd.add(self.os.utime) 4885 self.os.utime("baz", times=(1, 2), dir_fd=self.dir_fd) 4886 st = self.os.stat("/foo/baz") 4887 self.assertEqual(1, st.st_atime) 4888 self.assertEqual(2, st.st_mtime) 4889 4890 def test_open(self): 4891 self.assertRaises( 4892 NotImplementedError, 4893 self.os.open, 4894 "baz", 4895 os.O_RDONLY, 4896 dir_fd=self.dir_fd, 4897 ) 4898 self.os.supports_dir_fd.add(self.os.open) 4899 fd = self.os.open("baz", os.O_RDONLY, dir_fd=self.dir_fd) 4900 self.assertLess(0, fd) 4901 4902 4903class StatPropagationTest(TestCase): 4904 def setUp(self): 4905 self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") 4906 self.os = fake_os.FakeOsModule(self.filesystem) 4907 self.open = fake_open.FakeFileOpen(self.filesystem) 4908 4909 def test_file_size_updated_via_close(self): 4910 """test that file size gets updated via close().""" 4911 file_dir = "xyzzy" 4912 file_path = "xyzzy/close" 4913 content = "This is a test." 4914 self.os.mkdir(file_dir) 4915 fh = self.open(file_path, "w") 4916 self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) 4917 self.assertEqual("", self.filesystem.get_object(file_path).contents) 4918 fh.write(content) 4919 self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) 4920 self.assertEqual("", self.filesystem.get_object(file_path).contents) 4921 fh.close() 4922 self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) 4923 self.assertEqual(content, self.filesystem.get_object(file_path).contents) 4924 4925 def test_file_size_not_reset_after_close(self): 4926 file_dir = "xyzzy" 4927 file_path = "xyzzy/close" 4928 self.os.mkdir(file_dir) 4929 size = 1234 4930 # The file has size, but no content. When the file is opened for 4931 # reading, its size should be preserved. 4932 self.filesystem.create_file(file_path, st_size=size) 4933 fh = self.open(file_path, "r") 4934 fh.close() 4935 self.assertEqual(size, self.open(file_path, "r").size()) 4936 4937 def test_file_size_after_write(self): 4938 file_path = "test_file" 4939 original_content = "abcdef" 4940 original_size = len(original_content) 4941 self.filesystem.create_file(file_path, contents=original_content) 4942 added_content = "foo bar" 4943 expected_size = original_size + len(added_content) 4944 fh = self.open(file_path, "a") 4945 fh.write(added_content) 4946 self.assertEqual(original_size, fh.size()) 4947 fh.close() 4948 self.assertEqual(expected_size, self.open(file_path, "r").size()) 4949 4950 def test_large_file_size_after_write(self): 4951 file_path = "test_file" 4952 original_content = "abcdef" 4953 original_size = len(original_content) 4954 self.filesystem.create_file(file_path, st_size=original_size) 4955 added_content = "foo bar" 4956 fh = self.open(file_path, "a") 4957 self.assertRaises( 4958 fake_file.FakeLargeFileIoException, 4959 lambda: fh.write(added_content), 4960 ) 4961 4962 def test_file_size_updated_via_flush(self): 4963 """test that file size gets updated via flush().""" 4964 file_dir = "xyzzy" 4965 file_name = "flush" 4966 file_path = self.os.path.join(file_dir, file_name) 4967 content = "This might be a test." 4968 self.os.mkdir(file_dir) 4969 fh = self.open(file_path, "w") 4970 self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) 4971 self.assertEqual("", self.filesystem.get_object(file_path).contents) 4972 fh.write(content) 4973 self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) 4974 self.assertEqual("", self.filesystem.get_object(file_path).contents) 4975 fh.flush() 4976 self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) 4977 self.assertEqual(content, self.filesystem.get_object(file_path).contents) 4978 fh.close() 4979 self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) 4980 self.assertEqual(content, self.filesystem.get_object(file_path).contents) 4981 4982 def test_file_size_truncation(self): 4983 """test that file size gets updated via open().""" 4984 file_dir = "xyzzy" 4985 file_path = "xyzzy/truncation" 4986 content = "AAA content." 4987 4988 # pre-create file with content 4989 self.os.mkdir(file_dir) 4990 fh = self.open(file_path, "w") 4991 fh.write(content) 4992 fh.close() 4993 self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) 4994 self.assertEqual(content, self.filesystem.get_object(file_path).contents) 4995 4996 # test file truncation 4997 fh = self.open(file_path, "w") 4998 self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) 4999 self.assertEqual("", self.filesystem.get_object(file_path).contents) 5000 fh.close() 5001 5002 5003@unittest.skipIf(not use_scandir, "only run if scandir is available") 5004class FakeScandirTest(FakeOsModuleTestBase): 5005 FILE_SIZE = 50 5006 LINKED_FILE_SIZE = 10 5007 5008 def setUp(self): 5009 super(FakeScandirTest, self).setUp() 5010 self.supports_symlinks = not self.is_windows or not self.use_real_fs() 5011 5012 if use_scandir_package: 5013 if self.use_real_fs(): 5014 from scandir import scandir 5015 else: 5016 import pyfakefs.fake_scandir 5017 5018 def fake_scan_dir(p): 5019 return pyfakefs.fake_scandir.scandir(self.filesystem, p) 5020 5021 scandir = fake_scan_dir 5022 else: 5023 scandir = self.os.scandir 5024 self.scandir = scandir 5025 5026 self.directory = self.make_path("xyzzy", "plugh") 5027 link_dir = self.make_path("linked", "plugh") 5028 self.linked_file_path = self.os.path.join(link_dir, "file") 5029 self.linked_dir_path = self.os.path.join(link_dir, "dir") 5030 self.rel_linked_dir_path = self.os.path.join( 5031 "..", "..", "linked", "plugh", "dir" 5032 ) 5033 self.rel_linked_file_path = self.os.path.join( 5034 "..", "..", "linked", "plugh", "file" 5035 ) 5036 self.dir_path = self.os.path.join(self.directory, "dir") 5037 self.file_path = self.os.path.join(self.directory, "file") 5038 self.file_link_path = self.os.path.join(self.directory, "link_file") 5039 self.dir_link_path = self.os.path.join(self.directory, "link_dir") 5040 self.file_rel_link_path = self.os.path.join(self.directory, "rel_link_file") 5041 self.dir_rel_link_path = self.os.path.join(self.directory, "rel_link_dir") 5042 5043 self.create_dir(self.dir_path) 5044 self.create_file(self.file_path, contents=b"b" * self.FILE_SIZE) 5045 if self.supports_symlinks: 5046 self.create_dir(self.linked_dir_path) 5047 self.create_file( 5048 self.linked_file_path, contents=b"a" * self.LINKED_FILE_SIZE 5049 ), 5050 self.create_symlink(self.dir_link_path, self.linked_dir_path) 5051 self.create_symlink(self.file_link_path, self.linked_file_path) 5052 self.create_symlink(self.dir_rel_link_path, self.rel_linked_dir_path) 5053 self.create_symlink(self.file_rel_link_path, self.rel_linked_file_path) 5054 5055 # Changing the working directory below is to make sure relative paths 5056 # to the files and directories created above are reasonable. 5057 # Corner-cases about relative paths are better checked in tests created 5058 # for that purpose. 5059 # 5060 # WARNING: This is self.pretest_cwd and not self.cwd as the latter is 5061 # used by superclass RealFsTestCase. 5062 self.pretest_cwd = self.os.getcwd() 5063 self.os.chdir(self.base_path) 5064 5065 self.dir_entries = list(self.do_scandir()) 5066 self.dir_entries.sort(key=lambda entry: entry.name) 5067 5068 def tearDown(self): 5069 self.os.chdir(self.pretest_cwd) 5070 super().tearDown() 5071 5072 def do_scandir(self): 5073 """Hook to override how scandir is called.""" 5074 return self.scandir(self.directory) 5075 5076 def scandir_path(self): 5077 """Hook to override the expected scandir() path in DirEntry.path.""" 5078 return self.directory 5079 5080 def test_paths(self): 5081 sorted_names = ["dir", "file"] 5082 if self.supports_symlinks: 5083 sorted_names.extend( 5084 ["link_dir", "link_file", "rel_link_dir", "rel_link_file"] 5085 ) 5086 5087 self.assertEqual(len(sorted_names), len(self.dir_entries)) 5088 self.assertEqual(sorted_names, [entry.name for entry in self.dir_entries]) 5089 sorted_paths = [ 5090 self.os.path.join(self.scandir_path(), name) for name in sorted_names 5091 ] 5092 self.assertEqual(sorted_paths, [entry.path for entry in self.dir_entries]) 5093 5094 def test_isfile(self): 5095 self.assertFalse(self.dir_entries[0].is_file()) 5096 self.assertTrue(self.dir_entries[1].is_file()) 5097 if self.supports_symlinks: 5098 self.assertFalse(self.dir_entries[2].is_file()) 5099 self.assertFalse(self.dir_entries[2].is_file(follow_symlinks=False)) 5100 self.assertTrue(self.dir_entries[3].is_file()) 5101 self.assertFalse(self.dir_entries[3].is_file(follow_symlinks=False)) 5102 self.assertFalse(self.dir_entries[4].is_file()) 5103 self.assertFalse(self.dir_entries[4].is_file(follow_symlinks=False)) 5104 self.assertTrue(self.dir_entries[5].is_file()) 5105 self.assertFalse(self.dir_entries[5].is_file(follow_symlinks=False)) 5106 5107 def test_isdir(self): 5108 self.assertTrue(self.dir_entries[0].is_dir()) 5109 self.assertFalse(self.dir_entries[1].is_dir()) 5110 if self.supports_symlinks: 5111 self.assertTrue(self.dir_entries[2].is_dir()) 5112 self.assertFalse(self.dir_entries[2].is_dir(follow_symlinks=False)) 5113 self.assertFalse(self.dir_entries[3].is_dir()) 5114 self.assertFalse(self.dir_entries[3].is_dir(follow_symlinks=False)) 5115 self.assertTrue(self.dir_entries[4].is_dir()) 5116 self.assertFalse(self.dir_entries[4].is_dir(follow_symlinks=False)) 5117 self.assertFalse(self.dir_entries[5].is_dir()) 5118 self.assertFalse(self.dir_entries[5].is_dir(follow_symlinks=False)) 5119 5120 def test_is_link(self): 5121 if self.supports_symlinks: 5122 self.assertFalse(self.dir_entries[0].is_symlink()) 5123 self.assertFalse(self.dir_entries[1].is_symlink()) 5124 self.assertTrue(self.dir_entries[2].is_symlink()) 5125 self.assertTrue(self.dir_entries[3].is_symlink()) 5126 self.assertTrue(self.dir_entries[4].is_symlink()) 5127 self.assertTrue(self.dir_entries[5].is_symlink()) 5128 5129 def test_path_links_not_resolved(self): 5130 # regression test for #350 5131 self.skip_if_symlink_not_supported() 5132 dir_path = self.make_path("A", "B", "C") 5133 self.os.makedirs(self.os.path.join(dir_path, "D")) 5134 link_path = self.make_path("A", "C") 5135 self.os.symlink(dir_path, link_path) 5136 self.assertEqual( 5137 [self.os.path.join(link_path, "D")], 5138 [f.path for f in self.scandir(link_path)], 5139 ) 5140 5141 def test_inode(self): 5142 if use_scandir and self.use_real_fs(): 5143 if self.is_windows: 5144 self.skipTest("inode seems not to work in scandir module under Windows") 5145 if IN_DOCKER: 5146 self.skipTest("inode seems not to work in a Docker container") 5147 self.assertEqual( 5148 self.os.stat(self.dir_path).st_ino, self.dir_entries[0].inode() 5149 ) 5150 self.assertEqual( 5151 self.os.stat(self.file_path).st_ino, self.dir_entries[1].inode() 5152 ) 5153 if self.supports_symlinks: 5154 self.assertEqual( 5155 self.os.lstat(self.dir_link_path).st_ino, 5156 self.dir_entries[2].inode(), 5157 ) 5158 self.assertEqual( 5159 self.os.lstat(self.file_link_path).st_ino, 5160 self.dir_entries[3].inode(), 5161 ) 5162 self.assertEqual( 5163 self.os.lstat(self.dir_rel_link_path).st_ino, 5164 self.dir_entries[4].inode(), 5165 ) 5166 self.assertEqual( 5167 self.os.lstat(self.file_rel_link_path).st_ino, 5168 self.dir_entries[5].inode(), 5169 ) 5170 5171 def test_scandir_stat_nlink(self): 5172 # regression test for #350 5173 stat_nlink = self.os.stat(self.file_path).st_nlink 5174 self.assertEqual(1, stat_nlink) 5175 dir_iter = self.scandir(self.directory) 5176 for item in dir_iter: 5177 if item.path == self.file_path: 5178 scandir_stat_nlink = item.stat().st_nlink 5179 if self.is_windows_fs: 5180 self.assertEqual(0, scandir_stat_nlink) 5181 else: 5182 self.assertEqual(1, scandir_stat_nlink) 5183 self.assertEqual(1, self.os.stat(self.file_path).st_nlink) 5184 5185 @unittest.skipIf(not hasattr(os, "O_DIRECTORY"), "opening directory not supported") 5186 @unittest.skipIf(sys.version_info < (3, 7), "fd not supported for scandir") 5187 def test_scandir_with_fd(self): 5188 # regression test for #723 5189 temp_dir = self.make_path("tmp", "dir") 5190 self.create_dir(temp_dir) 5191 self.create_file(self.os.path.join(temp_dir, "file1")) 5192 self.create_file(self.os.path.join(temp_dir, "file2")) 5193 self.create_dir(self.os.path.join(temp_dir, "subdir")) 5194 self.os.chdir(temp_dir) 5195 fd = self.os.open(temp_dir, flags=os.O_RDONLY | os.O_DIRECTORY) 5196 children = [dir_entry.name for dir_entry in self.os.scandir(fd)] 5197 assert sorted(children) == ["file1", "file2", "subdir"] 5198 5199 def check_stat( 5200 self, absolute_symlink_expected_size, relative_symlink_expected_size 5201 ): 5202 self.assertEqual(self.FILE_SIZE, self.dir_entries[1].stat().st_size) 5203 if not self.is_windows_fs or sys.version_info < (3, 12): 5204 # behavior of st_ctime changed in 3.12, to be adapted later 5205 self.assertEqual( 5206 int(self.os.stat(self.dir_path).st_ctime), 5207 int(self.dir_entries[0].stat().st_ctime), 5208 ) 5209 5210 if self.supports_symlinks: 5211 self.assertEqual(self.LINKED_FILE_SIZE, self.dir_entries[3].stat().st_size) 5212 self.assertEqual( 5213 absolute_symlink_expected_size, 5214 self.dir_entries[3].stat(follow_symlinks=False).st_size, 5215 ) 5216 self.assertEqual( 5217 int(self.os.stat(self.linked_dir_path).st_mtime), 5218 int(self.dir_entries[2].stat().st_mtime), 5219 ) 5220 self.assertEqual(self.LINKED_FILE_SIZE, self.dir_entries[5].stat().st_size) 5221 self.assertEqual( 5222 relative_symlink_expected_size, 5223 self.dir_entries[5].stat(follow_symlinks=False).st_size, 5224 ) 5225 self.assertEqual( 5226 int(self.os.stat(self.linked_dir_path).st_mtime), 5227 int(self.dir_entries[4].stat().st_mtime), 5228 ) 5229 5230 @unittest.skipIf(TestCase.is_windows, "POSIX specific behavior") 5231 def test_stat_posix(self): 5232 self.check_stat(len(self.linked_file_path), len(self.rel_linked_file_path)) 5233 5234 @unittest.skipIf(not TestCase.is_windows, "Windows specific behavior") 5235 def test_stat_windows(self): 5236 self.check_stat(0, 0) 5237 5238 def test_index_access_to_stat_times_returns_int(self): 5239 if not self.is_windows_fs or sys.version_info < (3, 12): 5240 # behavior of st_ctime changed in 3.12, to be adapted later 5241 self.assertEqual( 5242 self.os.stat(self.dir_path)[stat.ST_CTIME], 5243 int(self.dir_entries[0].stat().st_ctime), 5244 ) 5245 if self.supports_symlinks: 5246 self.assertEqual( 5247 self.os.stat(self.linked_dir_path)[stat.ST_MTIME], 5248 int(self.dir_entries[2].stat().st_mtime), 5249 ) 5250 self.assertEqual( 5251 self.os.stat(self.linked_dir_path)[stat.ST_MTIME], 5252 int(self.dir_entries[4].stat().st_mtime), 5253 ) 5254 5255 def test_stat_ino_dev(self): 5256 if self.supports_symlinks: 5257 file_stat = self.os.stat(self.linked_file_path) 5258 self.assertEqual(file_stat.st_ino, self.dir_entries[3].stat().st_ino) 5259 self.assertEqual(file_stat.st_dev, self.dir_entries[3].stat().st_dev) 5260 self.assertEqual(file_stat.st_ino, self.dir_entries[5].stat().st_ino) 5261 self.assertEqual(file_stat.st_dev, self.dir_entries[5].stat().st_dev) 5262 5263 @unittest.skipIf( 5264 sys.version_info < (3, 6) or not use_builtin_scandir, 5265 "Path-like objects have been introduced in Python 3.6", 5266 ) 5267 def test_path_like(self): 5268 self.assertTrue(isinstance(self.dir_entries[0], os.PathLike)) 5269 self.assertEqual( 5270 self.os.path.join(self.scandir_path(), "dir"), 5271 os.fspath(self.dir_entries[0]), 5272 ) 5273 self.assertEqual( 5274 self.os.path.join(self.scandir_path(), "file"), 5275 os.fspath(self.dir_entries[1]), 5276 ) 5277 5278 def test_non_existing_dir(self): 5279 # behaves differently in different systems, so we skip the real fs test 5280 self.skip_real_fs() 5281 self.assert_raises_os_error(errno.ENOENT, self.scandir, "non_existing/fake_dir") 5282 5283 5284class RealScandirTest(FakeScandirTest): 5285 def use_real_fs(self): 5286 return True 5287 5288 5289class FakeScandirRelTest(FakeScandirTest): 5290 def scandir_path(self): 5291 # When scandir is called with a relative path, that relative path is 5292 # used in the path attribute of the DirEntry objects. 5293 return self.os.path.relpath(self.directory) 5294 5295 def do_scandir(self): 5296 return self.scandir(self.os.path.relpath(self.directory)) 5297 5298 5299class RealScandirRelTest(FakeScandirRelTest): 5300 def use_real_fs(self): 5301 return True 5302 5303 5304@unittest.skipIf(TestCase.is_windows, "dir_fd not supported for os.scandir in Windows") 5305@unittest.skipIf(use_scandir_package, "no dir_fd support for scandir package") 5306class FakeScandirFdTest(FakeScandirTest): 5307 def tearDown(self): 5308 self.os.close(self.dir_fd) 5309 super(FakeScandirFdTest, self).tearDown() 5310 5311 def scandir_path(self): 5312 # When scandir is called with a filedescriptor, only the name of the 5313 # entry is returned in the path attribute of the DirEntry objects. 5314 return "" 5315 5316 def do_scandir(self): 5317 self.dir_fd = self.os.open(self.directory, os.O_RDONLY) 5318 return self.scandir(self.dir_fd) 5319 5320 5321class RealScandirFdTest(FakeScandirFdTest): 5322 def use_real_fs(self): 5323 return True 5324 5325 5326class FakeScandirFdRelTest(FakeScandirFdTest): 5327 def do_scandir(self): 5328 self.dir_fd = self.os.open(self.os.path.relpath(self.directory), os.O_RDONLY) 5329 return self.scandir(self.dir_fd) 5330 5331 5332class RealScandirFdRelTest(FakeScandirFdRelTest): 5333 def use_real_fs(self): 5334 return True 5335 5336 5337class FakeExtendedAttributeTest(FakeOsModuleTestBase): 5338 def setUp(self): 5339 super(FakeExtendedAttributeTest, self).setUp() 5340 self.check_linux_only() 5341 self.dir_path = self.make_path("foo") 5342 self.file_path = self.os.path.join(self.dir_path, "bar") 5343 self.create_file(self.file_path) 5344 5345 def test_empty_xattr(self): 5346 self.assertEqual([], self.os.listxattr(self.dir_path)) 5347 self.assertEqual([], self.os.listxattr(self.file_path)) 5348 5349 def test_setxattr(self): 5350 self.assertRaises(TypeError, self.os.setxattr, self.file_path, "test", "value") 5351 self.assert_raises_os_error( 5352 errno.EEXIST, 5353 self.os.setxattr, 5354 self.file_path, 5355 "test", 5356 b"value", 5357 self.os.XATTR_REPLACE, 5358 ) 5359 self.os.setxattr(self.file_path, "test", b"value") 5360 self.assertEqual(b"value", self.os.getxattr(self.file_path, "test")) 5361 self.assert_raises_os_error( 5362 errno.ENODATA, 5363 self.os.setxattr, 5364 self.file_path, 5365 "test", 5366 b"value", 5367 self.os.XATTR_CREATE, 5368 ) 5369 5370 def test_removeattr(self): 5371 self.os.removexattr(self.file_path, "test") 5372 self.assertEqual([], self.os.listxattr(self.file_path)) 5373 self.os.setxattr(self.file_path, b"test", b"value") 5374 self.assertEqual(["test"], self.os.listxattr(self.file_path)) 5375 self.assertEqual(b"value", self.os.getxattr(self.file_path, "test")) 5376 self.os.removexattr(self.file_path, "test") 5377 self.assertEqual([], self.os.listxattr(self.file_path)) 5378 self.assertIsNone(self.os.getxattr(self.file_path, "test")) 5379 5380 def test_default_path(self): 5381 self.os.chdir(self.dir_path) 5382 self.os.setxattr(self.dir_path, b"test", b"value") 5383 self.assertEqual(["test"], self.os.listxattr()) 5384 self.assertEqual(b"value", self.os.getxattr(self.dir_path, "test")) 5385 5386 5387class FakeOsUnreadableDirTest(FakeOsModuleTestBase): 5388 def setUp(self): 5389 if self.use_real_fs(): 5390 # unreadable dirs in Windows are only simulated 5391 # and cannot be created in the real OS using file system 5392 # functions only 5393 self.check_posix_only() 5394 super(FakeOsUnreadableDirTest, self).setUp() 5395 self.dir_path = self.make_path("some_dir") 5396 self.file_path = self.os.path.join(self.dir_path, "some_file") 5397 self.create_file(self.file_path) 5398 self.chmod(self.dir_path, 0o000) 5399 5400 def chmod(self, path, mode): 5401 if self.is_windows_fs: 5402 self.filesystem.chmod(path, mode, force_unix_mode=True) 5403 else: 5404 self.os.chmod(path, mode) 5405 5406 def test_getuid(self): 5407 self.skip_real_fs() # won't change user in real fs 5408 self.check_posix_only() 5409 uid = self.os.getuid() 5410 set_uid(uid + 10) 5411 self.assertEqual(uid + 10, self.os.getuid()) 5412 self.assertEqual(uid + 10, get_uid()) 5413 set_uid(uid) 5414 self.assertEqual(uid, self.os.getuid()) 5415 5416 def test_getgid(self): 5417 self.skip_real_fs() # won't change group in real fs 5418 self.check_posix_only() 5419 gid = self.os.getgid() 5420 set_gid(gid + 10) 5421 self.assertEqual(gid + 10, self.os.getgid()) 5422 self.assertEqual(gid + 10, get_gid()) 5423 set_gid(gid) 5424 self.assertEqual(gid, self.os.getgid()) 5425 5426 def test_listdir_unreadable_dir(self): 5427 if not is_root(): 5428 self.assert_raises_os_error(errno.EACCES, self.os.listdir, self.dir_path) 5429 else: 5430 self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) 5431 5432 def test_listdir_user_readable_dir(self): 5433 self.chmod(self.dir_path, 0o600) 5434 self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) 5435 self.chmod(self.dir_path, 0o000) 5436 5437 def test_listdir_user_readable_dir_from_other_user(self): 5438 self.skip_real_fs() # won't change user in real fs 5439 self.check_posix_only() 5440 user_id = get_uid() 5441 set_uid(user_id + 1) 5442 dir_path = self.make_path("dir1") 5443 self.create_dir(dir_path, perm=0o600) 5444 self.assertTrue(self.os.path.exists(dir_path)) 5445 set_uid(user_id) 5446 if not is_root(): 5447 with self.assertRaises(PermissionError): 5448 self.os.listdir(dir_path) 5449 else: 5450 self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) 5451 5452 def test_listdir_group_readable_dir_from_other_user(self): 5453 self.skip_real_fs() # won't change user in real fs 5454 user_id = get_uid() 5455 set_uid(user_id + 1) 5456 dir_path = self.make_path("dir1") 5457 self.create_dir(dir_path, perm=0o660) 5458 self.assertTrue(self.os.path.exists(dir_path)) 5459 set_uid(user_id) 5460 self.assertEqual([], self.os.listdir(dir_path)) 5461 5462 def test_listdir_group_readable_dir_from_other_group(self): 5463 self.skip_real_fs() # won't change user in real fs 5464 self.check_posix_only() 5465 group_id = self.os.getgid() 5466 set_gid(group_id + 1) 5467 dir_path = self.make_path("dir1") 5468 self.create_dir(dir_path, perm=0o060) 5469 self.assertTrue(self.os.path.exists(dir_path)) 5470 set_gid(group_id) 5471 if not is_root(): 5472 with self.assertRaises(PermissionError): 5473 self.os.listdir(dir_path) 5474 else: 5475 self.assertEqual([], self.os.listdir(dir_path)) 5476 5477 def test_listdir_other_readable_dir_from_other_group(self): 5478 self.skip_real_fs() # won't change user in real fs 5479 group_id = get_gid() 5480 set_gid(group_id + 1) 5481 dir_path = self.make_path("dir1") 5482 self.create_dir(dir_path, perm=0o004) 5483 self.assertTrue(self.os.path.exists(dir_path)) 5484 set_gid(group_id) 5485 self.assertEqual([], self.os.listdir(dir_path)) 5486 5487 def test_stat_unreadable_dir(self): 5488 self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666) 5489 5490 def test_chmod_unreadable_dir(self): 5491 self.chmod(self.dir_path, 0o666) 5492 self.assertEqual(0o666, self.os.stat(self.dir_path).st_mode & 0o666) 5493 self.chmod(self.dir_path, 0o000) 5494 self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666) 5495 5496 def test_stat_file_in_unreadable_dir(self): 5497 if not is_root(): 5498 self.assert_raises_os_error(errno.EACCES, self.os.stat, self.file_path) 5499 else: 5500 self.assertEqual(0, self.os.stat(self.file_path).st_size) 5501 5502 def test_remove_unreadable_dir(self): 5503 self.check_posix_only() 5504 dir_path = self.make_path("dir1") 5505 self.create_dir(dir_path, perm=0o000) 5506 self.assertTrue(self.os.path.exists(dir_path)) 5507 self.os.rmdir(dir_path) 5508 self.assertFalse(self.os.path.exists(dir_path)) 5509 5510 def test_remove_unreadable_dir_from_other_user(self): 5511 self.skip_real_fs() # won't change user in real fs 5512 user_id = get_uid() 5513 set_uid(user_id + 1) 5514 dir_path = self.make_path("dir1") 5515 self.create_dir(dir_path, perm=0o000) 5516 self.assertTrue(self.os.path.exists(dir_path)) 5517 set_uid(user_id) 5518 if not is_root(): 5519 with self.assertRaises(PermissionError): 5520 self.os.rmdir(dir_path) 5521 self.assertTrue(self.os.path.exists(dir_path)) 5522 else: 5523 self.os.rmdir(dir_path) 5524 self.assertFalse(self.os.path.exists(dir_path)) 5525 5526 5527class RealOsUnreadableDirTest(FakeOsUnreadableDirTest): 5528 def use_real_fs(self): 5529 return True 5530